You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
4.4 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. from magic import from_file
  2. from gapi.api import API
  3. import re
  4. APPLICATION_NAME = "Google Calendar API Python"
  5. def is_folder(element):
  6. return element['mimeType'] == 'application/vnd.google-apps.folder'
  7. def split_path(path,rev=False):
  8. s = re.findall(r'(?:^/|[^/\x00]+)',path)
  9. if rev:
  10. return s[::-1]
  11. else:
  12. return s
  13. def without(node,*keys):
  14. node_meta = set(node.keys())
  15. nope = set(keys)
  16. ret = {}
  17. for key in node_meta-nope:
  18. ret[key] = node[key]
  19. return ret
  20. class drive_api(API):
  21. def __init__(
  22. self,
  23. app_name,
  24. client_secret_file,
  25. credentials_dir,
  26. scopes = 'https://www.googleapis.com/auth/drive',
  27. version = 'v3',
  28. ):
  29. super().__init__('drive',scopes,app_name,client_secret_file,credentials_dir,version)
  30. root = {}
  31. self.filesystem = {'folders':{'/':root}}
  32. root_meta = self.service.files().get(fileId='root').execute()
  33. del root_meta['kind']
  34. root[0] = root_meta
  35. root['parent'] = self.filesystem
  36. self.__fill_in__(root)
  37. def get_file_by_path(self,path,ret_file = True,no_parent = True):
  38. if isinstance(path,str):
  39. path = split_path(path)
  40. parent = self.filesystem
  41. end = path.pop()
  42. for sub in path:
  43. try:
  44. if not 'folders' in parent.keys():
  45. self.__fill_in__(parent)
  46. parent = parent['folders'][sub]
  47. except KeyError:
  48. raise FileNotFoundError()
  49. try:
  50. if ret_file:
  51. if not 'files' in parent.keys():
  52. self.__fill_in__(parent)
  53. ret = parent['files'][end]
  54. else:
  55. if not 'folders' in parent.keys():
  56. self.__fill_in__(parent)
  57. ret = parent['folders'][end]
  58. if no_parent:
  59. ret[0] = without(ret[0],'parent')
  60. return ret
  61. except KeyError:
  62. raise FileNotFoundError()
  63. def upload(self,local_path,remote_path):
  64. isdir = os.path.isdir(local_path)
  65. try:
  66. fid = get_file_by_path(remote_path)
  67. except FileNotFoundError:
  68. def mkdirs(self,path):
  69. '''makes directories if they do not exist already'''
  70. if isinstance(path,str):
  71. path = split_path(path)
  72. missing = []
  73. for i in range(len(path),-1,-1):
  74. try:
  75. parent = self.get_file_by_path(path[:i],False,no_parent = False)
  76. break
  77. except FileNotFoundError:
  78. missing.append(path[i-1])
  79. while len(missing) > 0:
  80. new_folder = {'folders':{}}
  81. name = missing.pop()
  82. new_meta = self.__create_remote_folder__(name,parent)
  83. del new_meta['name']
  84. del new_meta['kind']
  85. new_folder[0] = new_meta
  86. parent['folders'][name] = new_folder
  87. parent = new_folder
  88. return parent
  89. def __create_remote_folder__(self,name,parent):
  90. meta = {
  91. 'name':name,
  92. 'mimeType':'application/vnd.google-apps.folder',
  93. 'parents' : [parent[0]['id']]
  94. }
  95. return self.service.files().create(body = meta).execute()
  96. # finds all files and folders from a parent
  97. def __fill_in__(self,parent):
  98. parent_id = parent[0]['id']
  99. child_list = self.__list_children__(parent_id)
  100. parent['files'] = {}
  101. parent['folders'] = {}
  102. for child in child_list:
  103. del child['kind']
  104. name = child.pop('name')
  105. child['parent'] = parent
  106. if is_folder(child):
  107. parent['folders'][name] = {}
  108. parent['folders'][name][0] = child
  109. else:
  110. parent['files'][name] = child
  111. def __list_children__(self,parent_id):
  112. page_token = None
  113. first = True
  114. while page_token or first:
  115. first = False
  116. response = self.service.files().list(q = "'{}' in parents and trashed = false".format(parent_id),pageToken=page_token).execute()
  117. page_token = response.get('nextPageToken',None)
  118. for file in response['files']:
  119. yield file
  120. if __name__ == "__main__":
  121. my_api = drive_api(APPLICATION_NAME,r'..\test\drive\client_secret.json',r'..\test\drive')
  122. service = my_api.service