diff --git a/gapi/drive_api.py b/gapi/drive_api.py index 08b2d7c..c363714 100644 --- a/gapi/drive_api.py +++ b/gapi/drive_api.py @@ -1,12 +1,32 @@ from magic import from_file from gapi.api import API +from posixpath import join as pathjoin from googleapiclient.http import MediaFileUpload import re +import os + APPLICATION_NAME = "Google Calendar API Python" +def path_translate( + root, + want, + path, + file + ): + l = len(root)+1 + rel = path[l:] + new_rel = rel.replace(os.sep,'/') + return pathjoin(want,new_rel,file) def is_folder(element): return element['mimeType'] == 'application/vnd.google-apps.folder' +def split_path_nt(path,rev=False): + s = re.findall(r'?:[a-zA-Z]:\\)|[^/\\\?%\*:\|\"\<\>]+',path) + if rev: + return s[::-1] + else: + return s + def split_path(path,rev=False): s = re.findall(r'(?:^/|[^/\x00]+)',path) if rev: @@ -14,6 +34,11 @@ def split_path(path,rev=False): else: return s +if os.name == 'nt': + local_split_path = split_path_nt +else: + local_split_path = split_path + def without(node,*keys): node_meta = set(node.keys()) nope = set(keys) @@ -22,6 +47,15 @@ def without(node,*keys): ret[key] = node[key] return ret +def remote_path_join(path,*paths): + ret = path + for path in paths: + if not ret.endswith('/'): + ret += '/' + else: + ret += path + return ret + class drive_api(API): def __init__( @@ -45,6 +79,8 @@ class drive_api(API): '''gets a file or folder by remote path''' if isinstance(path,str): path = split_path(path) + else: + path = path.copy() parent = self.filesystem end = path.pop() for sub in path: @@ -59,46 +95,25 @@ class drive_api(API): if not 'files' in parent.keys(): self.__fill_in__(parent) ret = parent['files'][end] + if no_parent: + ret = without(ret,'parent') + 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 no_parent: + ret[0] = without(ret[0],'parent') return ret except KeyError: raise FileNotFoundError - def __upload_file__(self,local_path,remote_path): - '''creates file if it does not exists otherwise update the file''' - mimetype = from_file(local_path,mime_type=True) - _upload = MeduaFileUpload(local_path,mimeType=mimetype) - try: - fid = get_file_by_path(remote_path) - self.service.files().update(fileId=fid,mediaBody=_upload) - except FileNotFoundError: - path = split_path(remote_path) - end = path.pop() - parent = mkdirs(path) - parent_id = parent[0]['id'] - meta = { - 'name':end, - 'parents':[parent_id] - } - new_f_meta = self.service.files().create( - body = meta, - mediaBody = _upload - ).execute() - parent['files']['end'] = new_f_meta - - - - - def mkdirs(self,path): '''makes directories if they do not exist already''' if isinstance(path,str): path = split_path(path) + else: + path = path.copy() missing = [] for i in range(len(path),-1,-1): try: @@ -108,7 +123,8 @@ class drive_api(API): missing.append(path[i-1]) while len(missing) > 0: - new_folder = {'folders':{}} + new_folder = {'folders':{},'files':{}} + new_folder['parent'] = parent name = missing.pop() new_meta = self.__create_remote_folder__(name,parent) del new_meta['name'] @@ -117,6 +133,49 @@ class drive_api(API): parent['folders'][name] = new_folder parent = new_folder return parent + def upload(self,local_path,remote_path): + if not isinstance(remote_path,str): + remote_path = pathjoin(*remote_path) + if os.path.isdir(local_path): + for root,dirs,files in os.walk(local_path,topdown = False): + 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) + else: + return self.__upload_file__(local_path,remote_path) + + def __upload_file__(self,local_path,remote_path): + '''creates file if it does not exists otherwise update the file''' + if isinstance(remote_path,str): + remote_path = split_path(remote_path) + else: + remote_path = remote_path.copy() + _upload = MediaFileUpload(local_path) + + try: + old_file = self.get_file_by_path(remote_path) + 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'] + meta = { + 'name':end, + 'parents':[parent_id] + } + new_f_meta = self.service.files().create( + body = meta, + 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 def __create_remote_folder__(self,name,parent): meta = { diff --git a/test_drive.py b/test_drive.py index 38f8150..84c638b 100644 --- a/test_drive.py +++ b/test_drive.py @@ -1,3 +1,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') -file = my_api.get_file_by_path('/Python/Lib/site-packages/sympy/calculus/tests/__init__.py') \ No newline at end of file +# 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')