def post_videos(self, paths, category, title=None, desc=None, tags=None, devtags=None, is_private=None): """Post video(s) to YouTube. Keyword arguments: paths: List of paths to videos. category: YouTube category for the video. title: Title of the video. (Default is the filename of the video). desc: Video summary (Default None). tags: Tags of the video as a string, separated by commas (Default None). devtags: Developer tags for the video (Default None). """ from gdata.media import Group, Title, Description, Keywords, Private if isinstance(paths, basestring): paths = [paths] set_private = lambda private: Private() if private else None for path in paths: filename = os.path.basename(path).split('.')[0] my_media_group = Group( title=Title(text=title or filename), description=Description(text=desc or 'A video'), keywords=Keywords(text=tags), category=build_category(category), private=set_private(is_private)) video_entry = gdata.youtube.YouTubeVideoEntry(media=my_media_group) if devtags: taglist = devtags.replace(', ', ',') taglist = taglist.split(',') video_entry.AddDeveloperTags(taglist) LOG.info(safe_encode('Loading ' + path)) try: entry = self.InsertVideoEntry(video_entry, path) except gdata.service.RequestError, err: LOG.error('Failed to upload video: %s' % err) except gdata.youtube.service.YouTubeError, err: err_str = str(err) if err_str.find('path name or a file-like object') != -1: err_str = safe_encode('Could not find file ' + path) if (err.args[0]['body'].find('invalid_value') != -1 and err.args[0]['body'].find('media:category') != -1): err_str = 'Invalid category: %s' % category err_str += ( '\nFor a list of valid categories, see ' 'http://code.google.com/p/googlecl/wiki/Manual#YouTube' ) LOG.error(err_str)
def post_videos(self, paths, category, title=None, desc=None, tags=None, devtags=None, is_private=None): """Post video(s) to YouTube. Keyword arguments: paths: List of paths to videos. category: YouTube category for the video. title: Title of the video. (Default is the filename of the video). desc: Video summary (Default None). tags: Tags of the video as a string, separated by commas (Default None). devtags: Developer tags for the video (Default None). """ from gdata.media import Group, Title, Description, Keywords, Private if isinstance(paths, basestring): paths = [paths] set_private = lambda private: Private() if private else None for path in paths: filename = os.path.basename(path).split(".")[0] my_media_group = Group( title=Title(text=title or filename), description=Description(text=desc or "A video"), keywords=Keywords(text=tags), category=build_category(category), private=set_private(is_private), ) video_entry = gdata.youtube.YouTubeVideoEntry(media=my_media_group) if devtags: taglist = devtags.replace(", ", ",") taglist = taglist.split(",") video_entry.AddDeveloperTags(taglist) LOG.info(safe_encode("Loading " + path)) try: entry = self.InsertVideoEntry(video_entry, path) except gdata.service.RequestError, err: LOG.error("Failed to upload video: %s" % err) except gdata.youtube.service.YouTubeError, err: err_str = str(err) if err_str.find("path name or a file-like object") != -1: err_str = safe_encode("Could not find file " + path) if err.args[0]["body"].find("invalid_value") != -1 and err.args[0]["body"].find("media:category") != -1: err_str = "Invalid category: %s" % category err_str += ( "\nFor a list of valid categories, see " "http://code.google.com/p/googlecl/wiki/Manual#YouTube" ) LOG.error(err_str)
def _run_get(client, options, args): if not hasattr(client, 'Download'): LOG.error('Downloading documents is not supported for' + ' gdata-python-client < 2.0') return titles_list = googlecl.build_titles_list(options.title, args) folder_entries = client.get_folder(options.folder) entries = client.get_doclist(titles_list, folder_entries) if not os.path.isdir(options.dest) and len(entries) > 1: LOG.error(googlecl.safe_encode(u'Specified multiple source files, but ' + u'destination "' + options.dest + u'" is not a directory')) return client.get_docs(options.dest, entries, file_ext=options.format)
def upload_posts(self, content_list, blog_title=None, post_title=None, is_draft=False): """Uploads posts. Args: content_list: List of filenames or content to upload. blog_title: Name of the blog to upload to. post_title: Name to give the post(s). is_draft: Set True to upload as private draft(s), False to make upload(s) public. Returns: List of entries of successful posts. """ max_size = 500000 entry_list = [] blog_id = self._get_blog_id(blog_title) if not blog_id: return [] for content_string in content_list: if os.path.exists(content_string): with open(content_string, 'r') as content_file: content = content_file.read(max_size) if content_file.read(1): LOG.warning('Only read first %s bytes of file %s' % (max_size, content_string)) if not post_title: title = os.path.basename(content_string).split('.')[0] else: if not post_title: title = 'New post' content = content_string try: entry = self._upload_content(post_title or title, content, blog_id=blog_id, is_draft=is_draft) except self.request_error, err: LOG.error(safe_encode('Failed to post: ' + unicode(err))) else: entry_list.append(entry) if entry.control and entry.control.draft.text == 'yes': html_link = _build_draft_html(entry) else: html_link = entry.GetHtmlLink().href LOG.info('Post created: %s', html_link)
def delete_recurring_events(self, events, start_date, end_date, cal_user, prompt): """Delete recurring events from a calendar. Keyword arguments: events: List of non-expanded calendar events to delete. start_date: Date specifying the start of events (inclusive). end_date: Date specifying the end of events (inclusive). None for no end date. cal_user: "******" of the calendar to delete events from. prompt: True if we should prompt before deleting events, False otherwise. """ # option_list is a list of tuples, (prompt_string, deletion_instruction) # prompt_string gets displayed to the user, # deletion_instruction is a special value that will let the program know # what to do. # 'ALL' -- delete all events in the series. # 'NONE' -- don't delete anything. # 'TWIXT' -- delete events between start_date and end_date. # 'ON' -- delete events on the single date given. # 'ONAFTER' -- delete events on and after the date given. deletion_choice = "ALL" option_list = [("All events in this series", deletion_choice)] if start_date and end_date: deletion_choice = "TWIXT" option_list.append(("Instances between %s and %s" % (start_date, end_date), deletion_choice)) elif start_date or end_date: delete_date = start_date or end_date option_list.append(("Instances on %s" % delete_date, "ON")) option_list.append(("All events on and after %s" % delete_date, "ONAFTER")) deletion_choice = "ON" option_list.append(("Do not delete", "NONE")) prompt_str = "" for i, option in enumerate(option_list): prompt_str += str(i) + ") " + option[0] + "\n" # Condense events so that the user isn't prompted for the same event # multiple times. This is assuming that recurring events have been # expanded. events = googlecl.calendar.condense_recurring_events(events) for event in events: if prompt: delete_selection = -1 while delete_selection < 0 or delete_selection > len(option_list) - 1: msg = 'Delete "%s"?\n%s' % (safe_decode(event.title.text), prompt_str) try: delete_selection = int(raw_input(safe_encode(msg))) except ValueError: continue deletion_choice = option_list[delete_selection][1] # deletion_choice has either been picked by the prompt, or is the default # value. The default value is determined by the date info passed in, # and should be the "least destructive" option. if deletion_choice == "ALL": self._delete_original_event(event, cal_user) elif deletion_choice == "TWIXT": self._batch_delete_recur(event, cal_user, start_date=start_date, end_date=end_date) elif deletion_choice == "ON": self._batch_delete_recur(event, cal_user, start_date=delete_date, end_date=delete_date) elif deletion_choice == "ONAFTER": self._batch_delete_recur(event, cal_user, start_date=delete_date) elif deletion_choice != "NONE": raise CalendarError("Got unexpected batch deletion command!")
def delete_recurring_events(self, events, start_date, end_date, cal_user, prompt): """Delete recurring events from a calendar. Keyword arguments: events: List of non-expanded calendar events to delete. start_date: Date specifying the start of events (inclusive). end_date: Date specifying the end of events (inclusive). None for no end date. cal_user: "******" of the calendar to delete events from. prompt: True if we should prompt before deleting events, False otherwise. """ # option_list is a list of tuples, (prompt_string, deletion_instruction) # prompt_string gets displayed to the user, # deletion_instruction is a special value that will let the program know # what to do. # 'ALL' -- delete all events in the series. # 'NONE' -- don't delete anything. # 'TWIXT' -- delete events between start_date and end_date. # 'ON' -- delete events on the single date given. # 'ONAFTER' -- delete events on and after the date given. deletion_choice = 'ALL' option_list = [('All events in this series', deletion_choice)] if start_date and end_date: deletion_choice = 'TWIXT' option_list.append(('Instances between %s and %s' % (start_date, end_date), deletion_choice)) elif start_date or end_date: delete_date = (start_date or end_date) option_list.append(('Instances on %s' % delete_date, 'ON')) option_list.append(('All events on and after %s' % delete_date, 'ONAFTER')) deletion_choice = 'ON' option_list.append(('Do not delete', 'NONE')) prompt_str = '' for i, option in enumerate(option_list): prompt_str += str(i) + ') ' + option[0] + '\n' # Condense events so that the user isn't prompted for the same event # multiple times. This is assuming that recurring events have been # expanded. events = googlecl.calendar.condense_recurring_events(events) for event in events: if prompt: delete_selection = -1 while delete_selection < 0 or delete_selection > len(option_list) - 1: msg = 'Delete "%s"?\n%s' %\ (safe_decode(event.title.text), prompt_str) try: delete_selection = int(raw_input(safe_encode(msg))) except ValueError: continue deletion_choice = option_list[delete_selection][1] # deletion_choice has either been picked by the prompt, or is the default # value. The default value is determined by the date info passed in, # and should be the "least destructive" option. if deletion_choice == 'ALL': self._delete_original_event(event, cal_user) elif deletion_choice == 'TWIXT': self._batch_delete_recur(event, cal_user, start_date=start_date, end_date=end_date) elif deletion_choice == 'ON': self._batch_delete_recur(event, cal_user, start_date=delete_date, end_date=delete_date) elif deletion_choice == 'ONAFTER': self._batch_delete_recur(event, cal_user, start_date=delete_date) elif deletion_choice != 'NONE': raise CalendarError('Got unexpected batch deletion command!')
def post_videos(self, paths, category, title=None, desc=None, tags=None, devtags=None, access=None): """Post video(s) to YouTube. Keyword arguments: paths: List of paths to videos. category: YouTube category for the video. title: Title of the video. (Default is the filename of the video). desc: Video summary (Default None). tags: Tags of the video as a string, separated by commas (Default None). devtags: Developer tags for the video (Default None). access: 'private' or 'unlisted', anything else = 'public' """ from gdata.media import Group, Title, Description, Keywords, Private if isinstance(paths, basestring): paths = [paths] if access is None: access = 'public' access = access.lower() private = None if access == 'private': private = Private() for path in paths: filename = os.path.basename(path).split('.')[0] my_media_group = Group(title=Title(text=title or filename), description=Description(text=desc or 'A video'), keywords=Keywords(text=tags), category=build_category(category), private=private) if access == 'unlisted': extension_elements=[atom.ExtensionElement('accessControl', namespace=gdata.media.YOUTUBE_NAMESPACE, attributes={'action':'list', 'permission':'denied'})] video_entry = gdata.youtube.YouTubeVideoEntry(media=my_media_group, extension_elements=extension_elements) else: video_entry = gdata.youtube.YouTubeVideoEntry(media=my_media_group) if devtags: taglist = devtags.replace(', ', ',') taglist = taglist.split(',') video_entry.AddDeveloperTags(taglist) LOG.info(safe_encode('Loading ' + path)) try: entry = self.InsertVideoEntry(video_entry, path) except gdata.service.RequestError, err: LOG.error('Failed to upload video: %s' % err) except gdata.youtube.service.YouTubeError, err: err_str = str(err) if err_str.find('path name or a file-like object') != -1: err_str = safe_encode('Could not find file ' + path) if (err.args[0]['body'].find('invalid_value') != -1 and err.args[0]['body'].find('media:category') != -1): err_str = 'Invalid category: %s' % category err_str += ('\nFor a list of valid categories, see ' 'http://code.google.com/p/googlecl/wiki/Manual#YouTube') LOG.error(err_str)
def post_videos(self, paths, category, title=None, desc=None, tags=None, devtags=None, access=None): """Post video(s) to YouTube. Keyword arguments: paths: List of paths to videos. category: YouTube category for the video. title: Title of the video. (Default is the filename of the video). desc: Video summary (Default None). tags: Tags of the video as a string, separated by commas (Default None). devtags: Developer tags for the video (Default None). access: 'private' or 'unlisted', anything else = 'public' """ from gdata.media import Group, Title, Description, Keywords, Private if isinstance(paths, basestring): paths = [paths] if access is None: access = 'public' access = access.lower() private = None if access == 'private': private = Private() for path in paths: filename = os.path.basename(path).split('.')[0] my_media_group = Group( title=Title(text=title or filename), description=Description(text=desc or 'A video'), keywords=Keywords(text=tags), category=build_category(category), private=private) if access == 'unlisted': extension_elements = [ atom.ExtensionElement( 'accessControl', namespace=gdata.media.YOUTUBE_NAMESPACE, attributes={ 'action': 'list', 'permission': 'denied' }) ] video_entry = gdata.youtube.YouTubeVideoEntry( media=my_media_group, extension_elements=extension_elements) else: video_entry = gdata.youtube.YouTubeVideoEntry( media=my_media_group) if devtags: taglist = devtags.replace(', ', ',') taglist = taglist.split(',') video_entry.AddDeveloperTags(taglist) LOG.info(safe_encode('Loading ' + path)) try: entry = self.InsertVideoEntry(video_entry, path) except gdata.service.RequestError, err: LOG.error('Failed to upload video: %s' % err) except gdata.youtube.service.YouTubeError, err: err_str = str(err) if err_str.find('path name or a file-like object') != -1: err_str = safe_encode('Could not find file ' + path) if (err.args[0]['body'].find('invalid_value') != -1 and err.args[0]['body'].find('media:category') != -1): err_str = 'Invalid category: %s' % category err_str += ( '\nFor a list of valid categories, see ' 'http://code.google.com/p/googlecl/wiki/Manual#YouTube' ) LOG.error(err_str)