From d15b421eacc131aea101a6c406b524caee1fab03 Mon Sep 17 00:00:00 2001 From: Raphael Roberts Date: Sun, 18 Nov 2018 14:25:39 -0600 Subject: [PATCH 1/6] partial made node classes --- gapi/drive_api.py | 118 +++++++++++++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 43 deletions(-) diff --git a/gapi/drive_api.py b/gapi/drive_api.py index ef067ef..82095ba 100644 --- a/gapi/drive_api.py +++ b/gapi/drive_api.py @@ -44,6 +44,64 @@ def remote_path_join(path,*paths): ret += path return ret +class drive_file: + def __init__(self, + api, + info, + parent + ): + self.id = info.pop('id') + self.name = info.pop('name') + self.api = api + self.info = info + self.parent = parent + + @classmethod + def from_id(cls,id,api,parent): + info = api.service.files().get(fileId='root').execute() + return cls(api,info,parent) + +class drive_folder(drive_file): + def __init__(self, + api, + info, + parent + ): + super().__init__(api,info,parent) + self.folders = {} + self.files = {} + + def create_folder(self,name): + meta = { + 'name':name, + 'mimeType':'application/vnd.google-apps.folder', + 'parents' : [self.id] + } + info = self.api.service.files().create(body = meta).execute() + self.folders['name'] = drive_folder(self.api,info,self) + + def refresh(self): + '''finds all files and folders from a parent''' + parent_id = self.id + child_list = self.__list_children__() + for child in child_list: + name = child['name'] + if is_folder(child): + parent.folders[name] = drive_folder(self.api,child,self) + else: + parent.files[name] = drive_file(self.api,child,self) + + def __list_children__(self): + page_token = None + first = True + while page_token or first: + first = False + response = self.api.service.files().list(q = "'{}' in parents and trashed = false".format(self.id),pageToken=page_token).execute() + page_token = response.get('nextPageToken',None) + for file in response['files']: + yield file + + # def create_file(self, class drive_api(API): def __init__( @@ -55,29 +113,29 @@ class drive_api(API): version = 'v3', ): super().__init__('drive',scopes,app_name,client_secret_file,credentials_dir,version) - root = {} - self.filesystem = {'folders':{'/':root}} - root_meta = self.service.files().get(fileId='root').execute() - del root_meta['kind'] - root[0] = root_meta - root['parent'] = self.filesystem - self.__fill_in__(root) + self.root = drive_folder.from_id('root',self,None) + root def get_file_by_path(self,path,ret_file = True,no_parent = True): + if path == '/': + return self.root '''gets a file or folder by remote path''' if isinstance(path,str): path = split_path(path) else: path = path.copy() - parent = self.filesystem + parent = self.root end = path.pop() for sub in path: - try: - if not 'folders' in parent.keys(): - self.__fill_in__(parent) - parent = parent['folders'][sub] - except KeyError: - raise FileNotFoundError + if sub == '/': + pass + else: + try: + if not parent.folders: + parent.refresh() + parent = parent.folders[sub] + except KeyError: + raise FileNotFoundError try: if ret_file: if not 'files' in parent.keys(): @@ -166,38 +224,12 @@ class drive_api(API): return new_f_meta def __create_remote_folder__(self,name,parent): - meta = { - 'name':name, - 'mimeType':'application/vnd.google-apps.folder', - 'parents' : [parent[0]['id']] - } - return self.service.files().create(body = meta).execute() + def __fill_in__(self,parent): - '''finds all files and folders from a parent''' - parent_id = parent[0]['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['folders'][name] = {} - parent['folders'][name][0] = child - else: - parent['files'][name] = child - def __list_children__(self,parent_id): - page_token = None - first = True - while page_token or first: - first = False - response = self.service.files().list(q = "'{}' in parents and trashed = false".format(parent_id),pageToken=page_token).execute() - page_token = response.get('nextPageToken',None) - for file in response['files']: - yield file + + if __name__ == "__main__": my_api = drive_api(APPLICATION_NAME,r'..\test\drive\client_secret.json',r'..\test\drive') From 9a9544b4547b3a750a32e4eca139097b252e3876 Mon Sep 17 00:00:00 2001 From: Raphael Roberts Date: Sun, 18 Nov 2018 15:02:09 -0600 Subject: [PATCH 2/6] testing phase --- gapi/drive_api.py | 41 ++++++++++------------------------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/gapi/drive_api.py b/gapi/drive_api.py index 82095ba..c3eeb63 100644 --- a/gapi/drive_api.py +++ b/gapi/drive_api.py @@ -72,7 +72,7 @@ class drive_folder(drive_file): self.files = {} def create_folder(self,name): - meta = { + meta = { 'name':name, 'mimeType':'application/vnd.google-apps.folder', 'parents' : [self.id] @@ -116,7 +116,7 @@ class drive_api(API): self.root = drive_folder.from_id('root',self,None) root - def get_file_by_path(self,path,ret_file = True,no_parent = True): + def get_file_by_path(self,path,ret_file = True): if path == '/': return self.root '''gets a file or folder by remote path''' @@ -138,18 +138,13 @@ class drive_api(API): raise FileNotFoundError try: if ret_file: - if not 'files' in parent.keys(): - self.__fill_in__(parent) - ret = parent['files'][end] - if no_parent: - ret = without(ret,'parent') - + if not parent.files: + parent.refresh() + ret = parent.files[end] else: - if not 'folders' in parent.keys(): - self.__fill_in__(parent) - ret = parent['folders'][end] - if no_parent: - ret[0] = without(ret[0],'parent') + if not parent.folders: + parent.refresh() + ret = parent.folders[end] return ret except KeyError: raise FileNotFoundError @@ -163,21 +158,13 @@ class drive_api(API): missing = [] for i in range(len(path),-1,-1): try: - parent = self.get_file_by_path(path[:i],False,no_parent = False) + parent = self.get_file_by_path(path[:i],False) break except FileNotFoundError: missing.append(path[i-1]) while len(missing) > 0: - - new_folder = {'folders':{},'files':{}} - new_folder['parent'] = parent 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 + parent = parent.folders[name] return parent def upload(self,local_path,remote_path): if not isinstance(remote_path,str): @@ -223,14 +210,6 @@ class drive_api(API): parent['files'][end] = new_f_meta return new_f_meta - def __create_remote_folder__(self,name,parent): - - - def __fill_in__(self,parent): - - - - if __name__ == "__main__": my_api = drive_api(APPLICATION_NAME,r'..\test\drive\client_secret.json',r'..\test\drive') service = my_api.service From defad1727af1bd5f311bcd71a10d0133abf9c601 Mon Sep 17 00:00:00 2001 From: Raphael Roberts Date: Sun, 18 Nov 2018 15:20:51 -0600 Subject: [PATCH 3/6] get_file_by_path works and added fullpath property --- gapi/drive_api.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/gapi/drive_api.py b/gapi/drive_api.py index c3eeb63..c1b00ba 100644 --- a/gapi/drive_api.py +++ b/gapi/drive_api.py @@ -55,12 +55,29 @@ class drive_file: self.api = api self.info = info self.parent = parent + self._fullpath = None @classmethod def from_id(cls,id,api,parent): info = api.service.files().get(fileId='root').execute() return cls(api,info,parent) + @property + def fullpath(self): + if self._fullpath is None: + if self.parent is None: + path = '/' + else: + path = pathjoin(self.parent.fullpath,self.name) + self._fullpath = path + return self._fullpath + + def __str__(self): + return '{}@{}'.format(type(self).__name__,self.fullpath) + + def __repr__(self): + return str(self) + class drive_folder(drive_file): def __init__(self, api, @@ -87,9 +104,9 @@ class drive_folder(drive_file): for child in child_list: name = child['name'] if is_folder(child): - parent.folders[name] = drive_folder(self.api,child,self) + self.folders[name] = drive_folder(self.api,child,self) else: - parent.files[name] = drive_file(self.api,child,self) + self.files[name] = drive_file(self.api,child,self) def __list_children__(self): page_token = None @@ -114,7 +131,6 @@ class drive_api(API): ): super().__init__('drive',scopes,app_name,client_secret_file,credentials_dir,version) self.root = drive_folder.from_id('root',self,None) - root def get_file_by_path(self,path,ret_file = True): if path == '/': From 3ebc07e781d5f30d5e77b25a1af6bf8521a542dd Mon Sep 17 00:00:00 2001 From: Raphael Roberts Date: Sun, 18 Nov 2018 16:52:49 -0600 Subject: [PATCH 4/6] mkdirs and upload work --- gapi/drive_api.py | 27 +++++++++++++++------------ test_drive.py | 7 ++++--- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/gapi/drive_api.py b/gapi/drive_api.py index c1b00ba..68e44d4 100644 --- a/gapi/drive_api.py +++ b/gapi/drive_api.py @@ -95,7 +95,7 @@ class drive_folder(drive_file): 'parents' : [self.id] } info = self.api.service.files().create(body = meta).execute() - self.folders['name'] = drive_folder(self.api,info,self) + self.folders[name] = drive_folder(self.api,info,self) def refresh(self): '''finds all files and folders from a parent''' @@ -133,8 +133,6 @@ class drive_api(API): self.root = drive_folder.from_id('root',self,None) def get_file_by_path(self,path,ret_file = True): - if path == '/': - return self.root '''gets a file or folder by remote path''' if isinstance(path,str): path = split_path(path) @@ -142,6 +140,8 @@ class drive_api(API): path = path.copy() parent = self.root end = path.pop() + if end == '/': + return self.root for sub in path: if sub == '/': pass @@ -172,7 +172,7 @@ class drive_api(API): else: path = path.copy() missing = [] - for i in range(len(path),-1,-1): + for i in range(len(path),0,-1): try: parent = self.get_file_by_path(path[:i],False) break @@ -180,9 +180,11 @@ class drive_api(API): missing.append(path[i-1]) while len(missing) > 0: name = missing.pop() + parent.create_folder(name) parent = parent.folders[name] return parent - def upload(self,local_path,remote_path): + + def upload(self,local_path,remote_path,verbose = False): if not isinstance(remote_path,str): remote_path = pathjoin(*remote_path) if os.path.isdir(local_path): @@ -190,8 +192,9 @@ class drive_api(API): for file in files: new_path = path_translate(local_path,remote_path,root,file) self.__upload_file__(os.path.join(root,file),new_path) - print(new_path) - return self.get_file_by_path(remote_path,False,False) + if verbose: + print(new_path) + return self.get_file_by_path(remote_path,False) else: return self.__upload_file__(local_path,remote_path) @@ -205,14 +208,14 @@ class drive_api(API): try: old_file = self.get_file_by_path(remote_path) - self.service.files().update(fileId=old_file['id'],media_body=_upload).execute() + self.service.files().update(fileId=old_file.id,media_body=_upload).execute() return old_file except FileNotFoundError: path = remote_path end = path.pop() parent = self.mkdirs(path) - parent_id = parent[0]['id'] + parent_id = parent.id meta = { 'name':end, 'parents':[parent_id] @@ -222,9 +225,9 @@ class drive_api(API): media_body = _upload ).execute() new_f_meta = without(new_f_meta,'kind') - new_f_meta['parent'] = parent - parent['files'][end] = new_f_meta - return new_f_meta + new_f = drive_file(self,new_f_meta,parent) + parent.files[end] = new_f + return new_f if __name__ == "__main__": my_api = drive_api(APPLICATION_NAME,r'..\test\drive\client_secret.json',r'..\test\drive') diff --git a/test_drive.py b/test_drive.py index 84c638b..9cab088 100644 --- a/test_drive.py +++ b/test_drive.py @@ -2,6 +2,7 @@ import os import gapi from gapi.drive_api import drive_api,APPLICATION_NAME my_api = drive_api(APPLICATION_NAME,r'test\drive\client_secret.json',r'test\drive') -# t1 = my_api.get_file_by_path('/Python/Lib',False) -##t1 = my_api.mkdirs('/test/t1/this/is/a/path/why/isnt/this/working') -t1 = my_api.upload('test','/test/t3') +# t1 = my_api.get_file_by_path('/Python/Lib/site-packages',False) +# t1.refresh() +t2 = my_api.mkdirs('/test/t1/this/is/a/path/why/isnt/this/working') +t3 = my_api.upload(os.getcwd(),'/test/t3') \ No newline at end of file From 01dc4fca14c99ff70471c0b91cd126763b4b56d9 Mon Sep 17 00:00:00 2001 From: Raphael Roberts Date: Sun, 18 Nov 2018 17:02:33 -0600 Subject: [PATCH 5/6] Simply changed if pass to not equal --- gapi/drive_api.py | 4 +--- test_drive.py | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/gapi/drive_api.py b/gapi/drive_api.py index 68e44d4..ecc7331 100644 --- a/gapi/drive_api.py +++ b/gapi/drive_api.py @@ -143,9 +143,7 @@ class drive_api(API): if end == '/': return self.root for sub in path: - if sub == '/': - pass - else: + if sub != '/': try: if not parent.folders: parent.refresh() diff --git a/test_drive.py b/test_drive.py index 9cab088..0dcbf1d 100644 --- a/test_drive.py +++ b/test_drive.py @@ -2,7 +2,7 @@ import os import gapi from gapi.drive_api import drive_api,APPLICATION_NAME my_api = drive_api(APPLICATION_NAME,r'test\drive\client_secret.json',r'test\drive') -# t1 = my_api.get_file_by_path('/Python/Lib/site-packages',False) +t1 = my_api.get_file_by_path('/Python/Lib/site-packages',False) # t1.refresh() -t2 = my_api.mkdirs('/test/t1/this/is/a/path/why/isnt/this/working') -t3 = my_api.upload(os.getcwd(),'/test/t3') \ No newline at end of file +# t2 = my_api.mkdirs('/test/t1/this/is/a/path/why/isnt/this/working') +# t3 = my_api.upload(os.getcwd(),'/test/t3') \ No newline at end of file From 78ee774585aa6c8993d24a9fdcc4604dc5522da9 Mon Sep 17 00:00:00 2001 From: Raphael Roberts Date: Mon, 19 Nov 2018 09:24:36 -0600 Subject: [PATCH 6/6] Removed comment hinting at upload being in drive_folder --- gapi/drive_api.py | 1 - 1 file changed, 1 deletion(-) diff --git a/gapi/drive_api.py b/gapi/drive_api.py index ecc7331..5aef2be 100644 --- a/gapi/drive_api.py +++ b/gapi/drive_api.py @@ -118,7 +118,6 @@ class drive_folder(drive_file): for file in response['files']: yield file - # def create_file(self, class drive_api(API): def __init__(