0

Currently, I have a list containing a few more lists as follows:

enter image description here

Each index contains the name of the folder that I want to create and at the next index contains the image that I want to upload to google drive. When uploading, I want to rename each image according to the folder names:

Example:

enter image description here

The first index of the list has a few information as above.

I want to create a folder named "13910171322" and since there are 3 JPEG files when uploaded to the "13910171322" folder, they will be renamed "13910171322-1, 13910171322-2, 13910171322-3".

This process will be done for each index in the "list_image" list meaning that I would expect the google drive parent folder to have 6 folders with different names containing JPEG image files that are already renamed according to their folder name

*plus numbering 1/2/3 according to the amount of JPEG files in the folder.

(Ex: if in the list there are 5 JPEG files, the naming of each image will go up to 5).

Expected Result (this example is created manually)

enter image description here

There are 6 folders (since the length of the "list_image" list is 6)

enter image description here

The folder "13910171322" will have 3 images renamed accordingly.

From my research and tutorial (https://www.youtube.com/watch?v=uI220BJ0yXc), I found that the way is to create a folder first, then upload the images. For creating new folders, I found that the following code can be used:

import pickle
import os
from google_auth_oauthlib.flow import Flow, InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload, MediaIoBaseDownload
from google.auth.transport.requests import Request

def Create_Service(client_secret_file, api_name, api_version, *scopes):
  print(client_secret_file, api_name, api_version, scopes, sep='-')
  CLIENT_SECRET_FILE = client_secret_file
  API_SERVICE_NAME = api_name
  API_VERSION = api_version
  SCOPES = [scope for scope in scopes[0]]
  print(SCOPES)

  cred = None

  pickle_file = f'token_{API_SERVICE_NAME}_{API_VERSION}.pickle'
  #print(pickle_file)

  if os.path.exists(pickle_file):
    with open(pickle_file, 'rb') as token:
        cred = pickle.load(token)

  if not cred or not cred.valid:
    if cred and cred.expired and cred.refresh_token:
        cred.refresh(Request())
    else:
        flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES)
        cred = flow.run_local_server()

    with open(pickle_file, 'wb') as token:
        pickle.dump(cred, token)

  try:
    service = build(API_SERVICE_NAME, API_VERSION, credentials=cred)
    print(API_SERVICE_NAME, 'service created successfully')
    return service
  except Exception as e:
    print('Unable to connect.')
    print(e)
    return None

def convert_to_RFC_datetime(year=1900, month=1, day=1, hour=0, minute=0):
  dt = datetime.datetime(year, month, day, hour, minute, 0).isoformat() + 'Z'
  return dt

After creating the functions, then we execute them. I use the following code to execute the function:

CLIENT_SECRET_FILE = r'/content/drive/MyDrive/2. Tools/Product Image Downloader/client_secret_GoogleCloudDemo.json'
API_NAME = 'drive'
API_VERSION = 'v3'
SCOPES = ['https://www.googleapis.com/auth/drive']

service = Create_Service(CLIENT_SECRET_FILE, API_NAME, API_VERSION, SCOPES)

It returns an error as follows:

/content/drive/MyDrive/2. Tools/Product Image Downloader/client_secret_GoogleCloudDemo.json-drive-v3-(['https://www.googleapis.com/auth/drive'],)
['https://www.googleapis.com/auth/drive']
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-14-8479496aee48> in <module>()
      4 SCOPES = ['https://www.googleapis.com/auth/drive']
      5 
----> 6 service = Create_Service(CLIENT_SECRET_FILE, API_NAME, API_VERSION, SCOPES)

6 frames
/usr/lib/python3.7/socketserver.py in server_bind(self)
    464         if self.allow_reuse_address:
    465             self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
--> 466         self.socket.bind(self.server_address)
    467         self.server_address = self.socket.getsockname()
    468 

OSError: [Errno 98] Address already in use

Actually I have the following code below it to create the folders:

kodeproduk = [13910171322, 13703488271, 13504034138, 13303499936, 13004044291, 12803211256]

for i in kodeproduk:
  file_metadata = {
      'name': i,
      'mimetype': 'application/vnd.google-apps.folder',
      'parents': exportID 
  }

  service.files().create(body= file_metadata).execute()

FULL SCRIPT

#Library Install
import pandas as pd
import numpy as np
import glob
import openpyxl

#Connecting Drive with Colab
from google.colab import drive
drive.mount('/content/drive')

from google.colab import auth
auth.authenticate_user()

import gspread
from google.auth import default
creds, _ = default()

gc = gspread.authorize(creds)

# Import PyDrive and associated libraries.
# This only needs to be done once per notebook.
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from google.colab import auth
from oauth2client.client import GoogleCredentials

import os 

# Authenticate and create the PyDrive client.
# This only needs to be done once per notebook.
auth.authenticate_user()
gauth = GoogleAuth()
gauth.credentials = GoogleCredentials.get_application_default()
drive = GoogleDrive(gauth)

from PIL import Image
import requests
from io import BytesIO

from __future__ import print_function

import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

path_list = []
path_awal = r'/content/drive/MyDrive/2. Tools/Product Image Downloader/Upload Data Here (Image Downloader)'

path1 = glob.glob(path_awal + "/*.xlsx")
path2 = glob.glob(path_awal + "/*.xlsm")

path_list.extend(path1)
path_list.extend(path2)

path = path_list[0]

df = pd.read_excel(path)
df = df[['Kode Produk', 'Foto Sampul', 'Foto Produk 1', 'Foto Produk 2', 'Foto Produk 3', 'Foto Produk 4', 'Foto Produk 5', 'Foto Produk 6', 'Foto Produk 7', 'Foto Produk 8']]
df = df.fillna('')

kodeproduk = list(df['Kode Produk'])
jumlahproduk = list(range(0, len(df)))
jumlahgambar = list(range(1, (len(df.columns))))

list_image = []

for i in jumlahproduk:
  local_image = []
  local_image.append(kodeproduk[i]) 
  
  for a in jumlahgambar:  
    if (df.loc[i][a]) != "":
      url = df.loc[i][a]
      response = requests.get(url)
      img = Image.open(BytesIO(response.content))
      local_image.append(img)    
    else:
      pass
  list_image.append(local_image)

exportID = '1NIXxYlJybN9ihUx5EfOllpxpwUWEqm4f'

def createRemoteFolder(folderName=None, parentID = None):
        # Create a folder on Drive, returns the newely created folders ID
        body = {
          'name': folderName,
          'mimeType': "application/vnd.google-apps.folder"
        }
        if parentID:
            body['parents'] = [parentID]
        root_folder = drive.files().create(body = body).execute()
        return root_folder['id']

import pickle
import os
from google_auth_oauthlib.flow import Flow, InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload, MediaIoBaseDownload
from google.auth.transport.requests import Request

def Create_Service(client_secret_file, api_name, api_version, *scopes):
  print(client_secret_file, api_name, api_version, scopes, sep='-')
  CLIENT_SECRET_FILE = client_secret_file
  API_SERVICE_NAME = api_name
  API_VERSION = api_version
  SCOPES = [scope for scope in scopes[0]]
  print(SCOPES)

  cred = None

  pickle_file = f'token_{API_SERVICE_NAME}_{API_VERSION}.pickle'
  #print(pickle_file)

  if os.path.exists(pickle_file):
    with open(pickle_file, 'rb') as token:
        cred = pickle.load(token)

  if not cred or not cred.valid:
    if cred and cred.expired and cred.refresh_token:
        cred.refresh(Request())
    else:
        flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES)
        cred = flow.run_local_server()

    with open(pickle_file, 'wb') as token:
        pickle.dump(cred, token)

  try:
    service = build(API_SERVICE_NAME, API_VERSION, credentials=cred)
    print(API_SERVICE_NAME, 'service created successfully')
    return service
  except Exception as e:
    print('Unable to connect.')
    print(e)
    return None

def convert_to_RFC_datetime(year=1900, month=1, day=1, hour=0, minute=0):
  dt = datetime.datetime(year, month, day, hour, minute, 0).isoformat() + 'Z'
  return dt

CLIENT_SECRET_FILE = r'/content/drive/MyDrive/2. Tools/Product Image Downloader/client_secret_GoogleCloudDemo.json'
API_NAME = 'drive'
API_VERSION = 'v3'
SCOPES = ['https://www.googleapis.com/auth/drive']

service = Create_Service(CLIENT_SECRET_FILE, API_NAME, API_VERSION, SCOPES)

for i in kodeproduk:
  file_metadata = {
      'name': i,
      'mimetype': 'application/vnd.google-apps.folder',
      'parents': exportID 
  }

  service.files().create(body= file_metadata).execute()
Chriz
  • 201
  • 1
  • 2
  • 9
  • Where can I see `list_image` in your showing script? – Tanaike Jul 20 '22 at 07:44
  • Just added my full script at the very bottom of the post – Chriz Jul 20 '22 at 07:53
  • Thank you for replying and updating your question. About `list_image`, can I ask you about the relationship between `list_image` and your showing script and your showing error message? Your question is to remove your current error message? I apologize for my poor English skill. – Tanaike Jul 20 '22 at 08:17
  • Can you provide a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example)? Doesn't seem like the error you are getting has any relation to `list_image` nor to the general workflow you are following. Is [this](https://stackoverflow.com/q/4465959) useful to you? – Iamblichus Jul 20 '22 at 13:27

0 Answers0