1

I am using DevExtreme's File Manager and I want to add data from my google drive. Below is the structure for File Managers' files data:

[
    {
      "name": "Documents",
      "isDirectory": true,
      "items": [
        {
          "name": "Projects",
          "isDirectory": true,
          "items": [
            {
              "name": "About.rtf",
              "isDirectory": false
            },
            {
              "name": "Passwords.rtf",
              "isDirectory": false
            }
          ]
        },
        {
          "name": "About.xml",
          "isDirectory": false
        },
        {
          "name": "Managers.rtf",
          "isDirectory": false
        },
        {
          "name": "ToDo.txt",
          "isDirectory": false
        }
      ]
    },
    {
      "name": "Images",
      "isDirectory": true,
      "items": [
        {
          "name": "logo.png",
          "isDirectory": false
        },
        {
          "name": "banner.gif",
          "isDirectory": false
        }
      ]
    },
    {
      "name": "System",
      "isDirectory": true,
      "items": [
        {
          "name": "Employees.txt",
          "isDirectory": false
        },
        {
          "name": "PasswordList.txt",
          "isDirectory": false
        }
      ]
    },
    {
      "name": "Description.rtf",
      "isDirectory": false
    },
    {
      "name": "Description.txt",
      "isDirectory": false
    }
  ]

I am getting list of files and folders in my google drive with this:

from pydrive2.auth import GoogleAuth
from pydrive2.drive import GoogleDrive

gauth = GoogleAuth()

# # ---Try to load saved client credentials ---#

gauth.LoadCredentialsFile("mycreds.txt")
if gauth.credentials is None:
    # Authenticate if they're not there
    gauth.LocalWebserverAuth()
elif gauth.access_token_expired:
    # Refresh them if expired
    gauth.Refresh()
else:
    # Initialize the saved creds
    gauth.Authorize()
# Save the current credentials to a file
gauth.SaveCredentialsFile("mycreds.txt")

# ------------------------------------------ # 

gauth.LocalWebserverAuth()
drive = GoogleDrive(gauth) 

drive_data = []
folder_names = []
folders = drive.ListFile({'q': "trashed=false"}).GetList()
for folder in folders:
    if folder['lastModifyingUser']['isAuthenticatedUser'] == True:
        folder_names.append(folder['title'])


folder_ids = ['root']
while True:
    new_id_list = []
    for folder_id in folder_ids:
        folders = drive.ListFile({'q': f"'{folder_id}' in parents and trashed=false"}).GetList()
        for folder in folders:
            if folder['mimeType'] == 'application/vnd.google-apps.folder': data_type = True
            else: data_type = False

            if folder_id == 'root':
                drive_data.append(
                    {
                        'name': folder['title'],
                        'isDirectory': data_type,
                        'id': folder['id']
                    }
                )

            else:  
                drive_data[2]['items'] = [
                    {
                        'name': folder['title'],
                        'isDirectory': data_type,
                        'id': folder['id']
                    }
                ]

            new_id_list.append(folder['id'], )
            folder_names.remove(folder['title'])
    
    folder_ids = new_id_list
    if len(folder_names) == 0:
        break

print(drive_data)

The above script is not complete and I am working for a day on it. I want the array drive_data to look like the array structure which the DevExtreme's file manager requires. All I can think of is to manually add if and else statement because I will be knowing exactly how folders (nested) are there in my drive. But that wont be logical because if I change my drive folder structure than I also have to change the code.

According to the suggestion by @stuck creating a model class might help. I made a class somthing like this:

import json
from collections import namedtuple
from json import JSONEncoder
class RootFolders:
    def __init__(self, name, isDirectory, items):
        self.name, self.isDirectory, self.items = name, isDirectory, items

class SubFolders:
    def __init__(self, name, isDirectory):
        self.name, self.isDirectory = name, isDirectory

    def returnList(self):
        return [{'name': self.name, 'isDirectory': self.isDirectory, 'items': SubFolders('Owner', True)}]

class DriveEncoder(JSONEncoder):
    def default(self, o):
        return o.__dict__

sub_folders = SubFolders('Antelia', True)
drive_folders = RootFolders('Properties', True, sub_folders.returnList())
driveJson = json.dumps(drive_folders, indent=4, cls=DriveEncoder)
print(driveJson)

This is the output I am getting:

{
    "name": "Properties",
    "isDirectory": true,
    "items": [
        {
            "name": "Antelia",
            "isDirectory": true,
            "items": {
                "name": "Owner",
                "isDirectory": true
            }
        }
    ]
}

I want the items to be a list which contains dictionary:

"items": [
    {
        "name": "Owner",
        "isDirectory": True
    }
]

In doing so I keep on creating RecursionError because the items will have many nested list.

def returnList(self):
    return [{'name': self.name, 'isDirectory': self.isDirectory, 'items': SubFolders('Owner', True).returnList()}]

Can anyone please guide me into doing this? I am stuck for 3 days.

Meet Gondaliya
  • 387
  • 4
  • 18
  • 1
    You are basically creating a JSON array; so if you use some model class and parse the values by that, you can do whole operation automatically. – stuck Jun 24 '22 at 04:50
  • @stuck I added a class in my question. Is this what you were talking about? – Meet Gondaliya Jun 24 '22 at 07:15

0 Answers0