3 from __future__
import print_function
6 from distutils.version
import LooseVersion
12 from httplib2
import ServerNotFoundError
13 from pydrive.auth
import GoogleAuth
14 from pydrive.drive
import GoogleDrive
15 from pydrive.files
import ApiRequestError
18 from gdrive_ros.srv
import MultipleUpload
19 from gdrive_ros.srv
import MultipleUploadResponse
20 from gdrive_ros.srv
import Upload
21 from gdrive_ros.srv
import UploadResponse
24 if sys.version_info.major < 3
and \
25 LooseVersion(pkg_resources.get_distribution(
"rsa").version) \
26 >= LooseVersion(
'4.6.0'):
27 print(
'''rsa < 4.6.0 is required: 28 pip install oauth2client==4.2.3 rsa==4.5 pydrive==1.3.1 29 For more detailed information, 30 please read https://github.com/jsk-ros-pkg/jsk_3rdparty/tree/master/gdrive_ros#trouble-shooting 36 folder_mime_type =
'application/vnd.google-apps.folder' 37 folder_url_format =
'https://drive.google.com/drive/folders/{}' 38 file_url_format =
'https://drive.google.com/uc?id={}' 41 settings_yaml = rospy.get_param(
'~settings_yaml',
None)
42 self.
share_type = rospy.get_param(
'~share_type',
'anyone')
44 self.
share_role = rospy.get_param(
'~share_role',
'reader')
46 auth_max_trial = rospy.get_param(
'~auth_max_trial', -1)
47 auth_wait_seconds = rospy.get_param(
'~auth_wait_seconds', 10.0)
48 if settings_yaml
is not None:
49 self.
gauth = GoogleAuth(settings_yaml)
51 dir_path = os.path.dirname(os.path.realpath(settings_yaml))
52 for file
in [
'client_config_file',
'save_credentials_file']:
53 if not os.path.isfile(self.
gauth.settings[file]):
54 rospy.logwarn(
"{}:{} is not found, try to use {}".format(file, self.
gauth.settings[file], os.path.join(dir_path, self.
gauth.settings[file])))
55 self.
gauth.settings[file] = os.path.join(dir_path, self.
gauth.settings[file])
57 rospy.logerr(
'param: ~settings_yaml is not correctly set.')
60 rospy.loginfo(
'Google drive authentication starts.')
63 while (
not auth_success
and 64 (auth_max_trial < 0
or auth_count < auth_max_trial)):
66 self.
gauth.LocalWebserverAuth()
68 except ServerNotFoundError
as e:
69 rospy.logerr(
'Authentication failed: {}'.format(e))
70 auth_count = auth_count + 1
71 time.sleep(auth_wait_seconds)
74 'Authentication failed {} times.'.format(auth_max_trial))
77 rospy.loginfo(
'Google drive authentication finished.')
83 timestamp =
'{0:%Y%m%d%H%M%S}'.format(datetime.datetime.now())
84 parents_path = req.parents_path
85 parents_id = req.parents_id
88 res = UploadResponse()
93 if parents_id
and parents_path:
94 rospy.logerr(
'parents_path and parents_id is both set.')
96 'parents_id: {} is selected to upload.'.format(parents_id))
102 parents_path, mkdir=
True)
103 except (ValueError, ApiRequestError, ServerNotFoundError)
as e:
106 'Failed to get parents_id: {}'.format(parents_path))
109 elif parents_id ==
'' and parents_path ==
'':
112 if req.use_timestamp_folder:
115 [timestamp], parents_id=parents_id, mkdir=
True)
116 except (ValueError, ApiRequestError, ServerNotFoundError)
as e:
119 'Failed to get parents_id: {} in {}'.format(
124 req.file_path, req.file_title, parents_id,
125 req.use_timestamp_file_title, timestamp)
126 res.success = success
127 res.file_id = file_id
128 res.file_url = file_url
129 res.parents_id = parents_id
134 timestamp =
'{0:%Y%m%d%H%M%S}'.format(datetime.datetime.now())
135 parents_path = req.parents_path
136 parents_id = req.parents_id
139 res = MultipleUploadResponse()
140 res.successes = [
False] * len(req.file_titles)
141 res.file_ids = [
''] * len(req.file_titles)
142 res.file_urls = [
''] * len(req.file_titles)
144 if parents_id
and parents_path:
145 rospy.logerr(
'parents_path and parents_id is both set.')
147 'parents_id: {} is selected to upload.'.format(parents_id))
153 parents_path, mkdir=
True)
154 except (ValueError, ApiRequestError, ServerNotFoundError)
as e:
157 'Failed to get parents_id: {}'.format(parents_path))
160 elif parents_id ==
'' and parents_path ==
'':
163 if req.use_timestamp_folder:
166 [timestamp], parents_id=parents_id, mkdir=
True)
167 except (ValueError, ApiRequestError, ServerNotFoundError)
as e:
170 'Failed to get parents_id: {} in {}'.format(
174 for i, (file_path, file_title)
in enumerate(
175 zip(req.file_paths, req.file_titles)):
177 file_path, file_title, parents_id,
178 req.use_timestamp_file_title, timestamp)
179 res.successes[i] = success
180 res.file_ids[i] = file_id
181 res.file_urls[i] = file_url
182 res.parents_id = parents_id
186 def _upload_step(self, file_path, file_title, parents_id,
187 use_timestamp_file_title=False, timestamp=None):
188 file_title = file_title
if file_title
else file_path.split(
'/')[-1]
189 file_path = os.path.expanduser(file_path)
190 if use_timestamp_file_title:
191 file_title =
'{}_{}'.format(timestamp, file_title)
199 file_path, file_title, parents_id=parents_id)
203 'Success to upload: {} -> {}'.format(file_path, file_url))
204 except (OSError, ApiRequestError, ServerNotFoundError)
as e:
207 'Failed to upload: {} -> {}'.format(file_path, folder_url))
208 return success, file_id, file_url
211 if not os.path.exists(file_path):
212 raise OSError(
'File not found: {}'.format(file_path))
213 rospy.loginfo(
'Start uploading a file: {}'.format(file_title))
215 gfile = self.
gdrive.CreateFile(
216 {
'parents': [{
'id': parents_id}]})
218 gfile = self.
gdrive.CreateFile()
219 gfile.SetContentFile(file_path)
220 gfile[
'title'] = file_title
222 gfile.InsertPermission({
228 rospy.loginfo(
'Finish uploading a file: {}'.format(file_title))
232 rospy.loginfo(
'Start making a folder: {}'.format(folder_title))
234 gfolder = self.
gdrive.CreateFile(
235 {
'title': folder_title,
236 'parents': [{
'id': parents_id}],
237 'mimeType':
'application/vnd.google-apps.folder'})
239 gfolder = self.
gdrive.CreateFile(
240 {
'title': folder_title,
241 'mimeType':
'application/vnd.google-apps.folder'})
243 rospy.loginfo(
'Finish making a folder: {}'.format(folder_title))
247 if parents_path ==
'':
250 if not isinstance(parents_path, list):
251 parents_path = [p
for p
in parents_path.split(
'/')
if p !=
'']
253 folder_title = parents_path[0]
254 parent = parents_id
if parents_id
else 'root' 255 gfiles = self.
gdrive.ListFile(
256 {
'q':
"'{}' in parents and trashed=false".format(parent)})
257 gfiles = gfiles.GetList()
261 and gf[
'title'] == folder_title):
264 if len(parents_path) == 1:
265 if len(gfolders) > 0:
266 return gfolders[0][
'id']
269 folder_title, parents_id=parents_id)
273 'Folder is not found: {}'.format(folder_title))
275 if len(gfolders) > 0
or mkdir:
276 if len(gfolders) > 0:
277 next_parents_id = gfolders[0][
'id']
280 folder_title, parents_id=parents_id)
282 parents_path[1:], parents_id=next_parents_id,
286 raise ValueError(
'folder is not found: {}', folder_title)
289 if __name__ ==
'__main__':
290 rospy.init_node(
'gdrive_server')
def _upload_folder(self, folder_title, parents_id=None)
def _upload_file(self, file_path, file_title, parents_id=None)
def _upload_multi_cb(self, req)
def _upload_step(self, file_path, file_title, parents_id, use_timestamp_file_title=False, timestamp=None)
def _get_parents_id(self, parents_path, parents_id=None, mkdir=False)
def _upload_cb(self, req)