def insert_media_list(self, album, media_list, tags='', user='******', photo_name=None, caption=None): """Insert photos or videos into an album. Keyword arguments: album: The album entry of the album getting the media. media_list: A list of paths, each path a picture or video on the local host. tags: Text of the tags to be added to each item, e.g. 'Islands, Vacation' (Default ''). caption: Caption/summary to give each item. Default None for no caption. """ album_url = ('/data/feed/api/user/%s/albumid/%s' % (user, album.gphoto_id.text)) keywords = tags if caption is None: caption = '' failures = [] for path in media_list: LOG.info( safe_encode('Loading file ' + path + ' to album ' + safe_decode(album.title.text))) ext = googlecl.get_extension_from_path(path) if not ext: LOG.debug('No extension match on path ' + path) content_type = 'image/jpeg' else: ext = ext.lower() try: content_type = SUPPORTED_VIDEO_TYPES[ext] except KeyError: content_type = 'image/' + ext.lower() title = photo_name if not title: title = os.path.split(path)[1] try: self.InsertPhotoSimple(album_url, title=title, summary=caption, filename_or_handle=path, keywords=keywords, content_type=content_type) except GooglePhotosException, err: LOG.error('Failed to upload %s. (%s: %s)', path, err.args[0], err.args[1]) failures.append(file) except Exception, err: # Don't let a stray error wreck an upload of 1000 photos LOG.error(safe_encode('Unexpected error -- ' + unicode(err))) failures.append(file)
def insert_media_list(self, album, media_list, tags='', user='******', photo_name=None, caption=None): """Insert photos or videos into an album. Keyword arguments: album: The album entry of the album getting the media. media_list: A list of paths, each path a picture or video on the local host. tags: Text of the tags to be added to each item, e.g. 'Islands, Vacation' (Default ''). caption: Caption/summary to give each item. Default None for no caption. """ album_url = ('/data/feed/api/user/%s/albumid/%s' % (user, album.gphoto_id.text)) keywords = tags if caption is None: caption = '' failures = [] for path in media_list: LOG.info(safe_encode('Loading file ' + path + ' to album ' + safe_decode(album.title.text))) ext = googlecl.get_extension_from_path(path) if not ext: LOG.debug('No extension match on path ' + path) content_type = 'image/jpeg' else: ext = ext.lower() try: content_type = SUPPORTED_VIDEO_TYPES[ext] except KeyError: content_type = 'image/' + ext.lower() title = photo_name if not title: title = os.path.split(path)[1] try: self.InsertPhotoSimple(album_url, title=title, summary=caption, filename_or_handle=path, keywords=keywords, content_type=content_type) except GooglePhotosException, err: LOG.error('Failed to upload %s. (%s: %s)', path, err.args[0], err.args[1]) failures.append(file) except Exception, err: # Don't let a stray error wreck an upload of 1000 photos LOG.error(safe_encode('Unexpected error -- ' + unicode(err))) failures.append(file)
def export(self, entry_or_id_or_url, file_path, gid=None, extra_params=None): """Export old and new version docs. Ripped from gdata.docs.DocsService, adds 'format' parameter to make new version documents happy. """ ext = googlecl.get_extension_from_path(file_path) if ext: if extra_params is None: extra_params = {} # Fix issue with new-style docs always downloading to PDF # (gdata-issues Issue 2157) extra_params['format'] = ext self.Download(entry_or_id_or_url, file_path, ext, gid, extra_params)
def safe_move(src, dst): """Move file from src to dst. If file with same name already exists at dst, rename the new file while preserving the extension. Returns: path to new file. """ new_dir = os.path.abspath(dst) ext = googlecl.get_extension_from_path(src) if not ext: dotted_ext = '' else: dotted_ext = '.' + ext filename = os.path.basename(src).rstrip(dotted_ext) rename_num = 1 new_path = os.path.join(new_dir, filename + dotted_ext) while os.path.exists(new_path): new_filename = filename + '-' + str(rename_num) + dotted_ext new_path = os.path.join(new_dir, new_filename) shutil.move(src, new_path) return new_path
def upload_single_doc(self, path, title=None, folder_entry=None, file_ext=None, **kwargs): """Upload one file to Google Docs. Args: path: str Path to file to upload. title: str (optional) Title to give the upload. Defaults to the filename. folder_entry: DocsEntry (optional) (sub)Folder to upload into. file_ext: str (optional) Extension used to determine MIME type of upload. If not specified, uses mimetypes module to guess it. kwargs: Should contain value for 'convert', either True or False. Indicates if upload should be converted. Only Apps Premier users can specify False. Returns: Entry corresponding to the document on Google Docs """ filename = os.path.basename(path) try: convert = kwargs['convert'] except KeyError: convert = True if not file_ext: file_ext = googlecl.get_extension_from_path(filename) file_title = filename.split('.')[0] else: file_title = filename content_type = self._determine_content_type(file_ext) if not content_type: LOG.debug( 'Could not find content type using gdata, trying mimetypes') import mimetypes content_type = mimetypes.guess_type(path)[0] if not content_type: if convert: content_type = 'text/plain' else: content_type = 'application/octet-stream' entry_title = title or filename else: entry_title = title or file_title else: entry_title = title or file_title LOG.debug('Uploading with content type %s', content_type) LOG.info('Loading %s', path) if folder_entry: post_uri = folder_entry.content.src else: post_uri = self.DOCLIST_FEED_URI if not convert: post_uri += '?convert=false' try: new_entry = self._transmit_doc(path, entry_title, post_uri, content_type, file_ext) except self.request_error, err: LOG.error('Failed to upload %s: %s', path, err) if (str(err).find('ServiceForbiddenException') != -1 or str(err).find('Unsupported Media Type') != -1): # Attempt to catch older gdata users and warn them when they try to upload # unsupported file types print "\n\nYour version of python-gdata may not support this action. " print "Please see the wiki page for more details: " print "http://code.google.com/p/googlecl/wiki/UploadingGoogleDocs\n\n" if convert: LOG.info( 'You may have to specify a format with --format. Try ' + '--format=txt') return None
def get_docs(self, base_path, entries, file_ext=None, grid_id=None): """Download documents. Keyword arguments: base_path: The path to download files to. This plus an entry's title plus its format-specific extension will form the complete path. entries: List of DocEntry items representing the files to download. file_ext: Suffix to give the file(s) when downloading. For example, "txt", "csv", "xcl". Default None to let get_extension_from_doctype decide the extension. Ignored when downloading arbitrary files. """ if not os.path.isdir(base_path): if len(entries) > 1: raise DocsError( safe_encode(u'Specified multiple source files, but ' + u'destination "' + base_path + u'" is not a directory')) format_from_filename = googlecl.get_extension_from_path(base_path) if format_from_filename and not file_ext: # Strip the extension off here if it exists. Don't want to double up # on extension in for loop. (+1 for '.') base_path = base_path[:-(len(format_from_filename) + 1)] # We can just set the file_ext here, since there's only one file. file_ext = format_from_filename for entry in entries: # Don't set file_ext if we cannot do export. # get_extension_from_doctype will check the config file for 'format' # which will set an undesired entry_file_ext for # unconverted downloads if not file_ext and can_export(entry): entry_file_ext = googlecl.docs.get_extension_from_doctype( googlecl.docs.get_document_type(entry), self.config) else: entry_file_ext = file_ext if entry_file_ext: LOG.debug('Decided file_ext is ' + entry_file_ext) extension = '.' + entry_file_ext else: LOG.debug('Could not (or would not) set file_ext') if can_export(entry): extension = '.txt' else: # Files that cannot be exported typically have a file extension # in their name / title. extension = '' entry_title = safe_decode(entry.title.text) if os.path.isdir(base_path): entry_title_safe = self.to_safe_filename(entry_title) path = os.path.join(base_path, entry_title_safe + extension) else: path = base_path + extension LOG.info(safe_encode('Downloading ' + entry_title + ' to ' + path)) try: if can_export(entry): self.Export(entry, path, grid_id) else: if hasattr(self, 'Download'): self.Download(entry, path) else: self.DownloadResource(entry, path) except self.request_error, err: LOG.error( safe_encode('Download of ' + entry_title + ' failed: ' + unicode(err))) except EnvironmentError, err: LOG.error(err) LOG.info( 'Does your destination filename contain invalid characters?' )
def upload_single_doc(self, path, title=None, folder_entry=None, file_ext=None, **kwargs): """Upload one file to Google Docs. Args: path: str Path to file to upload. title: str (optional) Title to give the upload. Defaults to the filename. folder_entry: DocsEntry (optional) (sub)Folder to upload into. file_ext: str (optional) Extension used to determine MIME type of upload. If not specified, uses mimetypes module to guess it. kwargs: Should contain value for 'convert', either True or False. Indicates if upload should be converted. Only Apps Premier users can specify False. Returns: Entry corresponding to the document on Google Docs """ filename = os.path.basename(path) try: convert = kwargs['convert'] except KeyError: convert = True if not file_ext: file_ext = googlecl.get_extension_from_path(filename) file_title = filename.split('.')[0] else: file_title = filename content_type = self._determine_content_type(file_ext) if not content_type: LOG.debug('Could not find content type using gdata, trying mimetypes') import mimetypes content_type = mimetypes.guess_type(path)[0] if not content_type: if convert: content_type = 'text/plain' else: content_type = 'application/octet-stream' entry_title = title or filename else: entry_title = title or file_title else: entry_title = title or file_title LOG.debug('Uploading with content type %s', content_type) LOG.info('Loading %s', path) if folder_entry: post_uri = folder_entry.content.src else: post_uri = self.DOCLIST_FEED_URI if not convert: post_uri += '?convert=false' try: new_entry = self._transmit_doc(path, entry_title, post_uri, content_type, file_ext) except self.request_error, err: LOG.error('Failed to upload %s: %s', path, err) if (str(err).find('ServiceForbiddenException') != -1 or str(err).find('Unsupported Media Type') != -1): # Attempt to catch older gdata users and warn them when they try to upload # unsupported file types print "\n\nYour version of python-gdata may not support this action. " print "Please see the wiki page for more details: " print "http://code.google.com/p/googlecl/wiki/UploadingGoogleDocs\n\n" if convert: LOG.info('You may have to specify a format with --format. Try ' + '--format=txt') return None
def get_docs(self, base_path, entries, file_ext=None, grid_id=None): """Download documents. Keyword arguments: base_path: The path to download files to. This plus an entry's title plus its format-specific extension will form the complete path. entries: List of DocEntry items representing the files to download. file_ext: Suffix to give the file(s) when downloading. For example, "txt", "csv", "xcl". Default None to let get_extension_from_doctype decide the extension. Ignored when downloading arbitrary files. """ if not os.path.isdir(base_path): if len(entries) > 1: raise DocsError(safe_encode(u'Specified multiple source files, but ' + u'destination "' + base_path + u'" is not a directory')) format_from_filename = googlecl.get_extension_from_path(base_path) if format_from_filename and not file_ext: # Strip the extension off here if it exists. Don't want to double up # on extension in for loop. (+1 for '.') base_path = base_path[:-(len(format_from_filename)+1)] # We can just set the file_ext here, since there's only one file. file_ext = format_from_filename for entry in entries: # Don't set file_ext if we cannot do export. # get_extension_from_doctype will check the config file for 'format' # which will set an undesired entry_file_ext for # unconverted downloads if not file_ext and can_export(entry): entry_file_ext = googlecl.docs.get_extension_from_doctype( googlecl.docs.get_document_type(entry), self.config) else: entry_file_ext = file_ext if entry_file_ext: LOG.debug('Decided file_ext is ' + entry_file_ext) extension = '.' + entry_file_ext else: LOG.debug('Could not (or would not) set file_ext') if can_export(entry): extension = '.txt' else: # Files that cannot be exported typically have a file extension # in their name / title. extension = '' entry_title = safe_decode(entry.title.text) if os.path.isdir(base_path): entry_title_safe = self.to_safe_filename(entry_title) path = os.path.join(base_path, entry_title_safe + extension) else: path = base_path + extension LOG.info(safe_encode('Downloading ' + entry_title + ' to ' + path)) try: if can_export(entry): self.Export(entry, path, grid_id) else: if hasattr(self, 'Download'): self.Download(entry, path) else: self.DownloadResource(entry, path) except self.request_error, err: LOG.error(safe_encode('Download of ' + entry_title + ' failed: ' + unicode(err))) except EnvironmentError, err: LOG.error(err) LOG.info('Does your destination filename contain invalid characters?')