-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgoogledrive_utils.py
171 lines (150 loc) · 5.8 KB
/
googledrive_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import os
import string
from datetime import datetime
class GoogleDriveUtilsError(ValueError):
pass
class GoogleDriveUtils(object):
MODIFIED_TIME = "modifiedTime"
TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ"
API = "drive"
API_VERSION = "v3"
ROOT_ID = "root"
NAME = "name"
MIME_TYPE = "mimeType"
PARENTS = "parents"
SIZE = "size"
ID_PARENTS_FIELDS = "id, parents"
ID = "id"
TRUE = "true"
FALSE = "false"
FOLDER = "application/vnd.google-apps.folder"
SPREADSHEET = "application/vnd.google-apps.spreadsheet"
GOOGLE_DOCUMENT = "application/vnd.google-apps.document"
CSV = "text/csv"
GOOGLE_APPS = "google-apps"
BINARY_STREAM = "binary/octet-stream"
LIST_FIELDS = "nextPageToken, files(id, name, size, parents, mimeType, createdTime, modifiedTime)"
GOOGLE_DOC_MIME_EQUIVALENCE = {
SPREADSHEET: CSV,
GOOGLE_DOCUMENT: "text/plain",
"application/vnd.google-apps.drawing": "image/svg+xml",
"application/vnd.google-apps.presentation": "application/vnd.openxmlformats-officedocument.presentationml.presentation"
}
DEFAULT_MIME_TYPE = CSV
@staticmethod
def split_path(path_and_file):
path, file = os.path.split(path_and_file)
folders = []
while 1:
path, folder = os.path.split(path)
if folder != '':
folders.append(folder)
else:
if path != '':
folders.append(path)
break
folders.reverse()
if file != "":
folders.append(file)
return folders
@staticmethod
def is_directory(file):
return file['mimeType'] == GoogleDriveUtils.FOLDER
@staticmethod
def get_id(item):
return item[GoogleDriveUtils.ID]
@staticmethod
def keep_files_with(items, name=None, name_starting_with=None):
ret = []
for item in items:
if name_starting_with is not None:
if GoogleDriveUtils.get_name(item).startswith(name_starting_with):
ret.append(item)
if name is not None:
if GoogleDriveUtils.get_name(item) == name:
ret.append(item)
return ret
# from http://helpful-nerd.com/2018/01/30/folder-and-directory-management-for-google-drive-using-python/
@staticmethod
def get_name(file):
return file[GoogleDriveUtils.NAME]
@staticmethod
def is_file(file):
return file[GoogleDriveUtils.MIME_TYPE] != GoogleDriveUtils.FOLDER
@staticmethod
def get_files_ids(files):
parents = []
for file in files:
parents.append(GoogleDriveUtils.get_id(file))
return GoogleDriveUtils.remove_duplicates(parents)
@staticmethod
def remove_duplicates(to_filter):
return list(set(to_filter))
@staticmethod
def get_last_modified(item):
if GoogleDriveUtils.MODIFIED_TIME in item:
return int(GoogleDriveUtils.format_date(item[GoogleDriveUtils.MODIFIED_TIME]))
@staticmethod
def format_date(date):
if date is not None:
utc_time = datetime.strptime(date, GoogleDriveUtils.TIME_FORMAT)
epoch_time = (utc_time - datetime(1970, 1, 1)).total_seconds()
return int(epoch_time) * 1000
else:
return None
@staticmethod
def is_file_google_doc(file):
return GoogleDriveUtils.GOOGLE_APPS in file[GoogleDriveUtils.MIME_TYPE]
@staticmethod
def get_google_doc_type(file):
return file[GoogleDriveUtils.MIME_TYPE]
@staticmethod
def get_google_doc_mime_equivalence(gdoc_type):
return GoogleDriveUtils.GOOGLE_DOC_MIME_EQUIVALENCE.get(gdoc_type, GoogleDriveUtils.DEFAULT_MIME_TYPE)
@staticmethod
def file_size(item):
if GoogleDriveUtils.is_directory(item):
return 0
else:
if GoogleDriveUtils.SIZE in item:
return int(item[GoogleDriveUtils.SIZE])
else:
return 1 # have to lie to get DSS to read virtual files
@staticmethod
def check_path_format(path):
special_names = [".", ".."]
if not all(c in string.printable for c in path):
raise GoogleDriveUtilsError('The path contains non-printable char(s)')
for element in path.split('/'):
if len(element) > 1024:
raise GoogleDriveUtilsError('An element of the path is longer than the allowed 1024 characters')
if element in special_names:
raise GoogleDriveUtilsError('Special name "{0}" is not allowed in a box.com path'.format(element))
if element.endswith(' '):
raise GoogleDriveUtilsError('An element of the path contains a trailing space')
if element.startswith('.well-known/acme-challenge'):
raise GoogleDriveUtilsError('An element of the path starts with ".well-known/acme-challenge"')
@staticmethod
def query_parents_in(parent_ids, name=None, name_contains=None, trashed=None):
query = "("
is_first = True
for parent_id in parent_ids:
if is_first:
is_first = False
else:
query = query + " or "
query = query + "'{}' in parents".format(parent_id)
query = query + ")"
if trashed is not None:
query = query + ' and trashed=' + (GoogleDriveUtils.TRUE if trashed else GoogleDriveUtils.FALSE)
if name is not None:
query = query + " and name='" + name + "'"
if name_contains is not None:
query = query + " and name contains '" + name_contains + "'"
return query
@staticmethod
def get_root_id(config):
root_id = config.get("googledrive_root_id")
if not root_id:
root_id = GoogleDriveUtils.ROOT_ID
return root_id