iterative / PyDrive2

Google Drive API Python wrapper library. Maintained fork of PyDrive.
https://docs.iterative.ai/PyDrive2
Other
565 stars 70 forks source link

fetch a specific folder id by folder name #309

Closed jayofelony closed 10 months ago

jayofelony commented 10 months ago

I am using this part in my script but it is not working, is there any way? Or does it require API v3?

The folder name it looks up does NOT exist, and hence needs to be created.

def get_folder_id_by_name(self, drive, folder_name):
        file_list = drive.ListFile({'q': "mimeType='application/vnd.google-apps.folder' and trashed=false"}).GetList()
        for file in file_list:
            if file['title'] == folder_name:
                return file['id']
            return None

if not self.backup:
    # Use self.options['backup_folder'] as the folder ID where backups are stored
    backup_folder_name = self.options['backup_folder']
    backup_folder_id = self.get_folder_id_by_name(self.drive, backup_folder_name)

    if not backup_folder_id:
    # If the folder doesn't exist, create it
        folder = self.drive.CreateFile({'title': backup_folder_name, 'mimeType': 'application/vnd.google-apps.folder'})
        folder.Upload()
        backup_folder_id = folder['id']
        print(f"Created folder '{backup_folder_name}' with ID: {backup_folder_id}")

Error given is: [ERROR] Error: <HttpError 400 when requesting https://www.googleapis.com/drive/v2/files?q=%271n_7-tyjIjpc2JkIMI_W_xWuEXGleVDc1%27+and+trashed%3Dfalse&maxResults=1000&supportsAllDrives=true&includeItemsFromAllDrives=true&alt=json returned "Invalid query". Details: "[{'message': 'Invalid query', 'domain': 'global', 'reason': 'invalid', 'location': 'q', 'locationType': 'parameter'}]">

If I edit the query like so:

def get_folder_id_by_name(self, drive, folder_name):
        file_list = drive.ListFile({'q': "'"+folder_name+"' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false"}).GetList()
        for file in file_list:
            if file['title'] == folder_name:
                return file['id']
            return None

Then the error is like so:

Error: <HttpError 404 when requesting [googleapis.com/drive/v2/…](https://www.googleapis.com/drive/v2/files?q=%27PwnagotchiBackups%27+in+parents+and+mimeType%3D%27application%2Fvnd.google-apps.folder%27+and+trashed%3Dfalse&maxResults=1000&supportsAllDrives=true&includeItemsFromAllDrives=true&alt=json) returned "File not found:". Details: "[{'message': 'File not found: ', 'domain': 'global', 'reason': 'notFound', 'location': 'file', 'locationType': 'other'}]">

shcheklein commented 10 months ago

@jayofelony so, what exactly doesn't work in this case?

it should be possible to get a ID by its name and it should be possible to create a new directory. So the approach makes sense overall. We just need to see where exactly it breaks.

jayofelony commented 10 months ago

My bad, I am searching in the drive for a folder that does not exist. I edited the post a little with errors thrown.

SO basiscally I know the folder does not exist, so I need it to be created. Because a user can change the backup folder if they want.

shcheklein commented 10 months ago

Could you check this example https://github.com/iterative/PyDrive2/blob/main/examples/Upload-and-autoconvert-to-Google-Drive-Format-Example/upload.py#L38 and try to "play" with a query a bit? I think you might need to pass something like this:

query = {'q': f"title = '{filename}' and mimeType='{mimetype}'"}

Check also this doc. And also I would try to run it first on the online sandbox here.

jayofelony commented 10 months ago

Right, I have come to a succesful edit.

def get_folder_id_by_name(self, drive, folder_name):
        file_list = drive.ListFile({'q': "mimeType='application/vnd.google-apps.folder' and trashed=false"}).GetList()
        for file in file_list:
            if file['title'] == folder_name:
                return file['id']
            return None

 if not self.backup:
    # Use self.options['backup_folder'] as the folder ID where backups are stored
    backup_folder_id = self.get_folder_id_by_name(self.drive, self.options['backup_folder'])
     if backup_folder_id is None:
         # If the folder doesn't exist, create it
         folder = self.drive.CreateFile(
                        {'title': self.options['backup_folder'], 'mimeType': 'application/vnd.google-apps.folder'})
         folder.Upload()
         backup_folder_id = folder['id']
         logging.info(f"[gDriveSync] Created folder '{self.options['backup_folder']}' with ID: {backup_folder_id}")

     # Continue with the rest of the code using backup_folder_id
     file_list = self.drive.ListFile({'q': f"'{backup_folder_id}' in parents and mimeType = 'application/vnd.google-apps.folder' and trashed=false"}).GetList()