From c0a8156cd0d9f0b2a43d54369e9b0d929ba81c67 Mon Sep 17 00:00:00 2001 From: Raphael Roberts Date: Fri, 16 Nov 2018 19:21:50 -0600 Subject: [PATCH] Found the right way to handle if queried folder has not yet been filled in Started on iterative mkdirs func --- gapi/drive_api.py | 99 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 77 insertions(+), 22 deletions(-) diff --git a/gapi/drive_api.py b/gapi/drive_api.py index 1fdd2a7..5772e5d 100644 --- a/gapi/drive_api.py +++ b/gapi/drive_api.py @@ -1,3 +1,4 @@ +from magic import from_file from gapi.api import API import re APPLICATION_NAME = "Google Calendar API Python" @@ -11,6 +12,14 @@ def split_path(path,rev=False): else: return s +def without(node,*keys): + node_meta = set(node.keys()) + nope = set(keys) + ret = {} + for key in node_meta-nope: + ret[key] = node[key] + return ret + class drive_api(API): def __init__( self, @@ -21,44 +30,90 @@ class drive_api(API): version = 'v3', ): super().__init__('drive',scopes,app_name,client_secret_file,credentials_dir,version) - self.filesystem = {'/':{}} + root = {} + self.filesystem = {'folders':{'/':root}} root_meta = self.service.files().get(fileId='root').execute() del root_meta['kind'] - self.filesystem['/'][0] = root_meta + root[0] = root_meta + root['parent'] = self.filesystem + self.__fill_in__(root) - def get_file_by_path(self,path): - path = split_path(path) + def get_file_by_path(self,path,ret_file = True,no_parent = True): + if isinstance(path,str): + path = split_path(path) parent = self.filesystem - for sub in path[:-1]: + end = path.pop() + for sub in path: try: - parent = parent[sub] + if not 'folders' in parent.keys(): + self.__fill_in__(parent) + parent = parent['folders'][sub] except KeyError: - self.fill_in(parent) - parent = parent[sub] - end = path[-1] - for _try in range(2): + raise FileNotFoundError() + try: + if ret_file: + if not 'files' in parent.keys(): + self.__fill_in__(parent) + ret = parent['files'][end] + else: + if not 'folders' in parent.keys(): + self.__fill_in__(parent) + ret = parent['folders'][end][0] + if no_parent: + ret = without(ret,'parent') + return ret + except KeyError: + raise FileNotFoundError() + def upload(self,local_path,remote_path): + try: + fid = get_file_by_path(remote_path) + except FileNotFoundError: + pass + + def mkdirs(self,path): + if isinstance(path,str): + path = split_path(path) + missing = [] + for i in range(len(path),-1,-1): try: - return parent[end] - except KeyError: - if _try == 0: - self.fill_in(parent) - else: - raise FileNotFoundError() + parent = self.get_file_by_path(path[:i],True) + break + except FileNotFoundError: + missing.append(path[i-1]) + while len(missing) > 0: + new_folder = {} + name = missing.pop() + new_meta = self.__create_remote_folder__(name,parent) + del new_meta['name'] + del new_meta['kind'] + new_folder[0] = new_meta + parent['folders'][name] = new_folder + parent = new_folder + def __create_remote_folder__(self,name,parent): + meta = { + 'name':name, + 'mimeType':'application/vnd.google-apps.folder', + 'parents' : [parent[0]['id']] + } + return self.files().create(body = meta).execute() # finds all files and folders from a parent - def fill_in(self,parent): + def __fill_in__(self,parent): parent_id = parent[0]['id'] - child_list = self.list_children(parent_id) + child_list = self.__list_children__(parent_id) + parent['files'] = {} + parent['folders'] = {} for child in child_list: del child['kind'] name = child.pop('name') + child['parent'] = parent if is_folder(child): - parent[name] = {} - parent[name][0] = child + parent['folders'][name] = {} + parent['folders'][name][0] = child else: - parent[name] = child + parent['files'][name] = child - def list_children(self,parent_id): + def __list_children__(self,parent_id): page_token = None first = True while page_token or first: