def _update_full_section(self, downloads, items, autoqueued_count): if self._search_text == '': itemtext = ngettext("%(count)d Item", "%(count)d Items", items, {"count": items}) downloadingtext = ngettext("%(count)d Downloading", "%(count)d Downloading", downloads, {"count": downloads}) if autoqueued_count: queuedtext = ngettext("%(count)d Download Queued Due To " "Unplayed Items (See Settings)", "%(count)d Downloads Queued Due To " "Unplayed Items (See Settings)", autoqueued_count, {"count": autoqueued_count}) text = u"| %s" % itemtext if downloads: text = text + u" | %s" % downloadingtext if autoqueued_count: text = text + u" | %s" % queuedtext else: text = ngettext("%(count)d Item Matches Search", "%(count)d Items Match Search", items, {"count": items}) text = u"| %s" % text self.full_section.set_info(text)
def get_formatted_default_expiration(): """Returns the 'system' expiration delay as a formatted string """ expiration = float(app.config.get(prefs.EXPIRE_AFTER_X_DAYS)) formatted_expiration = u'' if expiration < 0: formatted_expiration = _('never') elif expiration < 1.0: hours = int(expiration * 24.0) formatted_expiration = ngettext("%(count)d hour ago", "%(count)d hours ago", hours, {"count": hours}) elif expiration >= 1 and expiration < 30: days = int(expiration) formatted_expiration = ngettext("%(count)d day ago", "%(count)d days ago", days, {"count": days}) elif expiration >= 30: months = int(expiration / 30) formatted_expiration = ngettext("%(count)d month ago", "%(count)d months ago", months, {"count": months}) return formatted_expiration
def make_progress(): if self.cancelled: self.gathered_media_files = [] self.finder = None progress_label.set_text("") return try: num_parsed, found = self.finder.next() self.gathered_media_files = found num_found = len(found) num_files = ngettext("parsed %(count)s file", "parsed %(count)s files", num_parsed, {"count": num_parsed}) num_media_files = ngettext("found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found}) progress_label.set_text(u"%s - %s" % (num_files, num_media_files)) threads.call_on_ui_thread(make_progress) except StopIteration: handle_cancel_clicked(None) self.finder = None
def test_ngettext(self): # french uses singular for 0, 1 and plural for everything else. self.assertEqual( gtcache.ngettext("%(count)d video found", "%(count)d videos found", 0), u'%(count)d vid\xe9o trouv\xe9e') self.assertEqual( gtcache.ngettext("%(count)d video found", "%(count)d videos found", 1), u'%(count)d vid\xe9o trouv\xe9e') self.assertEqual( gtcache.ngettext("%(count)d video found", "%(count)d videos found", 2), u'%(count)d vid\xe9os trouv\xe9es')
def test_ngettext(self): # french uses singular for 0, 1 and plural for everything else. self.assertEqual(gtcache.ngettext("%(count)d video found", "%(count)d videos found", 0), u'%(count)d vid\xe9o trouv\xe9e') self.assertEqual(gtcache.ngettext("%(count)d video found", "%(count)d videos found", 1), u'%(count)d vid\xe9o trouv\xe9e') self.assertEqual(gtcache.ngettext("%(count)d video found", "%(count)d videos found", 2), u'%(count)d vid\xe9os trouv\xe9es')
def expiration_date_short(exp_date): offset = exp_date - datetime.datetime.now() if offset.days > 0: return ngettext("Expires: %(count)d day", "Expires: %(count)d days", offset.days, {"count": offset.days}) elif offset.seconds > 3600: hours = int(round(offset.seconds / 3600.0)) return ngettext("Expires: %(count)d hour", "Expires: %(count)d hours", hours, {"count": hours}) else: minutes = int(round(offset.seconds / 60.0)) return ngettext("Expires: %(count)d minute", "Expires: %(count)d minutes", minutes, {"count": minutes})
def show_import_summary(self): imported_feeds = len(self.result[0].get('feed', [])) ignored_feeds = len(self.result[1].get('feed', [])) title = _("OPML Import summary") message = ngettext("Successfully imported %(count)d podcast.", "Successfully imported %(count)d podcasts.", imported_feeds, {"count": imported_feeds}) if self.ignored_feeds > 0: message += "\n" message += ngettext("Skipped %(count)d podcast already present.", "Skipped %(count)d podcasts already present.", ignored_feeds, {"count": ignored_feeds}) dialog = dialogs.MessageBoxDialog(title, message) dialog.run()
def _build_progress_label(self, num_found, num_parsed): num_files = ngettext( "Searched %(count)s file", "Searched %(count)s files", num_parsed, {"count": num_parsed}) num_media_files = ngettext( "found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found}) return u"%s - %s" % (num_files, num_media_files)
def time_string(secs): if secs >= (60 * 60 * 24): t_dy = secs * 1.0 / (60 * 60 * 24) return ngettext('%(num).0f day', '%(num).0f days', int(t_dy), {"num": t_dy}) if secs >= (60 * 60): t_hr = secs * 1.0 / (60 * 60) return ngettext('%(num).0f hr', '%(num).0f hrs', int(t_hr), {"num": t_hr}) if secs >= 60: t_min = secs * 1.0 / 60 return ngettext('%(num).0f min', '%(num).0f mins', int(t_min), {"num": t_min}) return ngettext('%(num)d sec', '%(num)d secs', secs, {"num": secs})
def _update_downloading_section(self, downloads): if downloads > 0: text = ngettext("%(count)d Downloading", "%(count)d Downloading", downloads, {"count": downloads}) self.downloading_section.set_header(text) self.downloading_section.show() else: self.downloading_section.hide()
def show_import_summary(self): imported_feeds = len(self.result[0].get('feed', [])) ignored_feeds = len(self.result[1].get('feed', [])) title = _("OPML Import summary") message = ngettext("Successfully imported %(count)d feed.", "Successfully imported %(count)d feeds.", imported_feeds, {"count": imported_feeds}) if self.ignored_feeds > 0: message += "\n" message += ngettext("Skipped %(count)d feed already present.", "Skipped %(count)d feeds already present.", ignored_feeds, {"count": ignored_feeds}) dialog = dialogs.MessageBoxDialog(title, message) dialog.run()
def make_search_progress(self): if self.cancelled: self.finder = None return try: num_parsed, found = self.finder.next() self.gathered_media_files = found num_found = len(found) num_files = ngettext("parsed %(count)s file", "parsed %(count)s files", num_parsed, {"count": num_parsed}) num_media_files = ngettext("found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found}) self.progress_label.set_text(u"%s - %s" % ( num_files, num_media_files)) threads.call_on_ui_thread(self.make_search_progress) except StopIteration: num_found = len(self.gathered_media_files) self.search_complete( ngettext( "found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found})) self.finder = None except Exception: # this is here to get more data for bug #17422 logging.exception("exception thrown in make_search_progress") # we want to clean up after this exception, too. num_found = len(self.gathered_media_files) self.search_complete( ngettext( "found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found})) self.finder = None
def _update_downloaded_section(self, watchable): if watchable > 0: text = ngettext("%(count)d Item", "%(count)d Items", watchable, {"count": watchable}) text = u"| %s " % text self.downloaded_section.set_info(text) self.downloaded_section.show() else: self.downloaded_section.hide()
def expiration_date_short(exp_date): offset = exp_date - datetime.datetime.now() if offset.days > 0: return ngettext("Expires: %(count)d day", "Expires: %(count)d days", offset.days, {"count": offset.days}) elif offset.seconds > 3600: return ngettext("Expires: %(count)d hour", "Expires: %(count)d hours", math.ceil(offset.seconds/3600.0), {"count": math.ceil(offset.seconds/3600.0)}) else: return ngettext("Expires: %(count)d minute", "Expires: %(count)d minutes", math.ceil(offset.seconds/60.0), {"count": math.ceil(offset.seconds/60.0)})
def test_ngettext_counts(self): # test that it always truncates the count arg and we # should always get the singular form. self.assertEqual( gtcache.ngettext("%(count)d video found", "%(count)d videos found", 1.0), u'%(count)d vid\xe9o trouv\xe9e') self.assertEqual( gtcache.ngettext("%(count)d video found", "%(count)d videos found", 1.5), u'%(count)d vid\xe9o trouv\xe9e') self.assertEqual( gtcache.ngettext("%(count)d video found", "%(count)d videos found", 1.9), u'%(count)d vid\xe9o trouv\xe9e') self.assertEqual( gtcache.ngettext("%(count)d video found", "%(count)d videos found", 2.0), u'%(count)d vid\xe9os trouv\xe9es') self.assertEqual( gtcache.ngettext("%(count)d video found", "%(count)d videos found", 2.5), u'%(count)d vid\xe9os trouv\xe9es') self.assertEqual( gtcache.ngettext("%(count)d video found", "%(count)d videos found", 2.9), u'%(count)d vid\xe9os trouv\xe9es') self.assertEqual( gtcache.ngettext("%(count)d video found", "%(count)d videos found", int(2.5)), u'%(count)d vid\xe9os trouv\xe9es')
def test_ngettext_counts(self): # test that it always truncates the count arg and we # should always get the singular form. self.assertEqual(gtcache.ngettext("%(count)d video found", "%(count)d videos found", 1.0), u'%(count)d vid\xe9o trouv\xe9e') self.assertEqual(gtcache.ngettext("%(count)d video found", "%(count)d videos found", 1.5), u'%(count)d vid\xe9o trouv\xe9e') self.assertEqual(gtcache.ngettext("%(count)d video found", "%(count)d videos found", 1.9), u'%(count)d vid\xe9o trouv\xe9e') self.assertEqual(gtcache.ngettext("%(count)d video found", "%(count)d videos found", 2.0), u'%(count)d vid\xe9os trouv\xe9es') self.assertEqual(gtcache.ngettext("%(count)d video found", "%(count)d videos found", 2.5), u'%(count)d vid\xe9os trouv\xe9es') self.assertEqual(gtcache.ngettext("%(count)d video found", "%(count)d videos found", 2.9), u'%(count)d vid\xe9os trouv\xe9es') self.assertEqual(gtcache.ngettext("%(count)d video found", "%(count)d videos found", int(2.5)), u'%(count)d vid\xe9os trouv\xe9es')
def current_sync_information(self, video_count, audio_count): if video_count == 0 and audio_count == 0: self.sync_state.set_text(_('Up to date')) self.sync_button.disable() else: self.sync_button.enable() counts = [] if video_count: counts.append(ngettext('%(count)d video file', '%(count)d video files', video_count, {"count": video_count})) if audio_count: counts.append(ngettext('%(count)d audio file', '%(count)d audio files', audio_count, {"count": audio_count})) self.sync_state.set_text('\n'.join(counts))
def make_search_progress(self): if self.cancelled: self.finder = None return try: num_parsed, found = self.finder.next() self.gathered_media_files = found num_found = len(found) num_files = ngettext("parsed %(count)s file", "parsed %(count)s files", num_parsed, {"count": num_parsed}) num_media_files = ngettext("found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found}) self.progress_label.set_text(u"%s - %s" % (num_files, num_media_files)) threads.call_on_ui_thread(self.make_search_progress) except StopIteration: num_found = len(self.gathered_media_files) self.search_complete( ngettext("found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found})) self.finder = None except Exception: # this is here to get more data for bug #17422 logging.exception("exception thrown in make_search_progress") # we want to clean up after this exception, too. num_found = len(self.gathered_media_files) self.search_complete( ngettext("found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found})) self.finder = None
def test_ngettext_values(self): # try the bad translation with no values self.assertEqual(gtcache.ngettext("bad %(count)d video found", "bad %(count)d videos found", 0), u'bad %(count) vid\xe9o trouv\xe9e') # try the bad translation with values self.assertEqual(gtcache.ngettext("bad %(count)d video found", "bad %(count)d videos found", 0, {"count": 0}), u'bad 0 videos found') self.assertEqual(gtcache.ngettext("bad %(count)d video found", "bad %(count)d videos found", 1, {"count": 1}), u'bad 1 video found') self.assertEqual(gtcache.ngettext("bad %(count)d video found", "bad %(count)d videos found", 2, {"count": 2}), u'bad 2 videos found')
def set_sync_state(self, count): if self.in_progress: # don't update sync state while we're syncing return if count: self.sync_button.set_text( ngettext('Sync 1 File', 'Sync %(count)i Files', count, {'count': count})) self.sync_button.enable() else: self.sync_button.set_text(_("Up to date")) self.sync_button.disable()
def set_sync_state(self, count): if self.in_progress: # don't update sync state while we're syncing return if count: self.sync_label.set_text( ngettext('1 file selected to sync', '%(count)i files selected to sync', count, {'count': count})) self.sync_button.enable() else: self.sync_label.set_text(_("Up to date")) self.sync_button.disable()
def test_ngettext_values(self): # try the bad translation with no values self.assertEqual( gtcache.ngettext("bad %(count)d video found", "bad %(count)d videos found", 0), u'bad %(count) vid\xe9o trouv\xe9e') # try the bad translation with values self.assertEqual( gtcache.ngettext("bad %(count)d video found", "bad %(count)d videos found", 0, {"count": 0}), u'bad 0 videos found') self.assertEqual( gtcache.ngettext("bad %(count)d video found", "bad %(count)d videos found", 1, {"count": 1}), u'bad 1 video found') self.assertEqual( gtcache.ngettext("bad %(count)d video found", "bad %(count)d videos found", 2, {"count": 2}), u'bad 2 videos found')
def make_search_progress(self): if self.cancelled: self.finder = None return try: num_parsed, found = self.finder.next() self.gathered_media_files = found num_found = len(found) num_files = ngettext("parsed %(count)s file", "parsed %(count)s files", num_parsed, {"count": num_parsed}) num_media_files = ngettext("found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found}) self.progress_label.set_text(u"%s - %s" % ( num_files, num_media_files)) threads.call_on_ui_thread(self.make_search_progress) except StopIteration: if self.gathered_media_files: num_found = len(self.gathered_media_files) else: num_found = 0 self.search_complete( ngettext( "found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found})) self.finder = None
def _make_label(self, tab_type, selected_tabs): label_parts = [] # NOTE: we need to use ngettext because some languages have multiple # plural forms. if self.folder_count > 0: if tab_type == 'feed': label_parts.append(ngettext( '%(count)d Podcast Folder Selected', '%(count)d Podcast Folders Selected', self.folder_count, {"count": self.folder_count})) label_parts.append(ngettext( '(contains %(count)d podcast)', '(contains %(count)d podcasts)', self.folder_child_count, {"count": self.folder_child_count})) else: label_parts.append(ngettext( '%(count)d Playlist Folder Selected', '%(count)d Playlist Folders Selected', self.folder_count, {"count": self.folder_count})) label_parts.append(ngettext( '(contains %(count)d playlist)', '(contains %(count)d playlists)', self.folder_child_count, {"count": self.folder_child_count})) if self.child_count > 0 and self.folder_count > 0: label_parts.append('') if self.child_count > 0: if tab_type == 'feed': label_parts.append(ngettext( '%(count)d Podcast Selected', '%(count)d Podcasts Selected', self.child_count, {"count": self.child_count})) elif tab_type == "site": label_parts.append(ngettext( '%(count)d Source Selected', '%(count)d Sources Selected', self.child_count, {"count": self.child_count})) else: label_parts.append(ngettext( '%(count)d Playlist Selected', '%(count)d Playlists Selected', self.child_count, {"count": self.child_count})) return widgetset.Label('\n'.join(label_parts))
def _pack_top(self): """Pack the top row into the VBox; these components are visible in all panels. """ self.vbox.pack_start(widgetutil.align_center(self.toggler, top_pad=10)) items = len(self.items) if items > 1: # text1 is included because ngettext requires text1 to have all the # same placeholders as text2; it won't be used text = ngettext("%(items)d", "%(items)d items selected to edit", items, {"items": items}) label = widgetset.Label(text) label.set_bold(True) self.vbox.pack_start(widgetutil.align_center(label, top_pad=10, bottom_pad=3)) text = _( "To change a field for all the selected items, check the " "checkbox next to the field you'd like to change." ) label = widgetset.Label(text) label.set_size(widgetconst.SIZE_SMALL) self.vbox.pack_start(widgetutil.align_center(label, bottom_pad=20))
def _pack_top(self): """Pack the top row into the VBox; these components are visible in all panels. """ self.vbox.pack_start(widgetutil.align_center(self.toggler, top_pad=10)) items = len(self.items) if items > 1: # text1 is included because ngettext requires text1 to have all the # same placeholders as text2; it won't be used text = ngettext("%(items)d", "%(items)d items selected to edit", items, {'items': items}) label = widgetset.Label(text) label.set_bold(True) self.vbox.pack_start( widgetutil.align_center(label, top_pad=10, bottom_pad=3)) text = _("To change a field for all the selected items, check the " "checkbox next to the field you'd like to change.") label = widgetset.Label(text) label.set_size(widgetconst.SIZE_SMALL) self.vbox.pack_start(widgetutil.align_center(label, bottom_pad=20))
def _expand_lists_initially(self): item_downloaded = self.downloaded_view.item_list.get_count() > 0 feed_info = widgetutil.get_feed_info(self.id) autodownload_mode = feed_info.autodownload_mode self.downloaded_section.expand() self.full_section.show() all_items = self.full_view.item_list.get_items() viewed_items = [item for item in all_items \ if item.downloaded or item.item_viewed] if not (item_downloaded and len(all_items) == len(viewed_items)): self.full_section.expand() if item_downloaded and 0 < len(viewed_items) < len(all_items): text = ngettext('Show %(count)d More Item', 'Show %(count)d More Items', len(viewed_items), {"count": len(viewed_items)}) self.show_more_button.set_text(text + u" >>") self.show_more_button.set_size(widgetconst.SIZE_SMALL) self.show_more_container.show() self.full_view.item_list.set_new_only(True) self.full_view.model_changed() self._show_more_count = len(viewed_items) else: self._show_more_count = 0
def _make_context_menu_multiple(self, selection): """Make the context menu for multiple items.""" # XXX why are these lists rather than boolean? device = [] remote = [] watched = [] unwatched = [] downloaded = [] playable = [] downloading = [] container = [] available = [] paused = [] uploadable = [] expiring = [] net_lookup_enabled = [] net_lookup_disabled = [] editable = False # local functions def mark_unwatched(): messages.SetItemsWatched(watched, False).send_to_backend() def mark_watched(): messages.SetItemsWatched(unwatched, True).send_to_backend() def keep_videos(): for item in expiring: if item.expiration_date: messages.KeepVideo(item.id).send_to_backend() def download_all(): for item in available: messages.StartDownload(item.id).send_to_backend() def cancel_all(): for item in downloading: messages.CancelDownload(item.id).send_to_backend() def pause_all(): for item in downloading: messages.PauseDownload(item.id).send_to_backend() def resume_all(): for item in paused: messages.ResumeDownload(item.id).send_to_backend() def restart_all(): for item in uploadable: messages.StartUpload(item.id).send_to_backend() for info in selection: if info.downloaded: downloaded.append(info) if info.is_playable: if info.net_lookup_enabled: net_lookup_enabled.append(info) else: net_lookup_disabled.append(info) playable.append(info) if info.device: device.append(info) if info.remote: remote.append(info) if info.video_watched: watched.append(info) if info.expiration_date: expiring.append(info) else: unwatched.append(info) if info.is_container_item: container.append(info) if not (info.device or info.remote): editable = True elif info.state == 'paused': paused.append(info) elif info.state == 'downloading': downloading.append(info) if item.is_torrent and not item.is_seeding: uploadable.append(info) else: available.append(info) menu = [] if downloaded: if device: menu.append( (ngettext('%(count)d Device Item', '%(count)d Device Items', len(downloaded), {"count": len(downloaded)}), None)) else: menu.append((ngettext('%(count)d Downloaded Item', '%(count)d Downloaded Items', len(downloaded), {"count": len(downloaded)}), None)) if playable: menu.append((_('Play'), app.widgetapp.play_selection)), if not (device or remote or container): menu.append( (_('Add to Playlist'), app.widgetapp.add_to_playlist)) self._add_remove_context_menu_item(menu, selection) if watched: menu.append((_('Mark as Unplayed'), mark_unwatched)) if unwatched: menu.append((_('Mark as Played'), mark_watched)) if expiring: menu.append((_('Keep'), keep_videos)) if playable and not (device or remote) and not container: menu.append(None) convert_menu = self._make_convert_menu() menu.append((_('Convert to...'), convert_menu)) menu.append( (_('Set media kind as...'), self._make_edit_metadata_menu())) if downloaded and not remote and not device: if net_lookup_enabled: label = _("Don't Use Online Lookup Data") callback = app.widgetapp.disable_net_lookup_for_selection menu.append((label, callback)) if net_lookup_disabled: label = _("Use Online Lookup Data") callback = app.widgetapp.enable_net_lookup_for_selection menu.append((label, callback)) if available: if len(menu) > 0: menu.append(None) menu.append((ngettext('%(count)d Available Item', '%(count)d Available Items', len(available), {"count": len(available)}), None)) menu.append((_('Download'), download_all)) if downloading: if len(menu) > 0: menu.append(None) menu.append((ngettext('%(count)d Downloading Item', '%(count)d Downloading Items', len(downloading), {"count": len(downloading)}), None)) menu.append((_('Cancel Download'), cancel_all)) menu.append((_('Pause Download'), pause_all)) if paused: if len(menu) > 0: menu.append(None) menu.append( (ngettext('%(count)d Paused Item', '%(count)d Paused Items', len(paused), {"count": len(paused)}), None)) menu.append((_('Resume Download'), resume_all)) menu.append((_('Cancel Download'), cancel_all)) if uploadable: menu.append((_('Restart Upload'), restart_all)) if editable: menu.append((_("Edit Items"), app.widgetapp.edit_items)) return menu
def hrs_string(secs): t_hr = int(round(secs / (60.0 * 60.0))) return ngettext('%(num)d hr', '%(num)d hrs', t_hr, {"num": t_hr})
def mins_string(secs): t_min = int(round(secs / 60.0)) return ngettext('%(num)d min', '%(num)d mins', t_min, {"num": t_min})
def _make_context_menu_multiple(self, selection): """Make the context menu for multiple items.""" # XXX why are these lists rather than boolean? device = [] remote = [] watched = [] unwatched = [] downloaded = [] playable = [] downloading = [] container = [] available = [] paused = [] uploadable = [] expiring = [] net_lookup_enabled = [] net_lookup_disabled = [] editable = False # local functions def mark_unwatched(): messages.SetItemsWatched(watched, False).send_to_backend() def mark_watched(): messages.SetItemsWatched(unwatched, True).send_to_backend() def keep_videos(): for item in expiring: if item.expiration_date: messages.KeepVideo(item.id).send_to_backend() def download_all(): for item in available: messages.StartDownload(item.id).send_to_backend() def cancel_all(): for item in downloading: messages.CancelDownload(item.id).send_to_backend() def pause_all(): for item in downloading: messages.PauseDownload(item.id).send_to_backend() def resume_all(): for item in paused: messages.ResumeDownload(item.id).send_to_backend() def restart_all(): for item in uploadable: messages.StartUpload(item.id).send_to_backend() for info in selection: if info.downloaded: downloaded.append(info) if info.is_playable: if info.net_lookup_enabled: net_lookup_enabled.append(info) else: net_lookup_disabled.append(info) playable.append(info) if info.device: device.append(info) if info.remote: remote.append(info) if info.video_watched: watched.append(info) if info.expiration_date: expiring.append(info) else: unwatched.append(info) if info.is_container_item: container.append(info) if not (info.device or info.remote): editable = True elif info.is_paused: paused.append(info) elif info.is_download: downloading.append(info) if info.is_torrent and not info.is_seeding: uploadable.append(info) else: available.append(info) menu = [] if downloaded: if device: menu.append( ( ngettext( "%(count)d Device Item", "%(count)d Device Items", len(downloaded), {"count": len(downloaded)}, ), None, ) ) else: menu.append( ( ngettext( "%(count)d Downloaded Item", "%(count)d Downloaded Items", len(downloaded), {"count": len(downloaded)}, ), None, ) ) if playable: menu.append((_("Play"), app.widgetapp.play_selection)), if not (device or remote or container): menu.append((_("Add to Playlist"), app.widgetapp.add_to_playlist)) self._add_remove_context_menu_item(menu, selection) if watched: menu.append((_("Mark as Unplayed"), mark_unwatched)) if unwatched: menu.append((_("Mark as Played"), mark_watched)) if expiring: menu.append((_("Keep"), keep_videos)) if playable and not (device or remote) and not container: menu.append(None) convert_menu = self._make_convert_menu() menu.append((_("Convert to..."), convert_menu)) menu.append((_("Set media kind as..."), self._make_edit_metadata_menu())) if downloaded and not remote and not device: if net_lookup_enabled: label = _("Don't Use Online Lookup Data") callback = app.widgetapp.disable_net_lookup_for_selection menu.append((label, callback)) if net_lookup_disabled: label = _("Use Online Lookup Data") callback = app.widgetapp.enable_net_lookup_for_selection menu.append((label, callback)) if available: if len(menu) > 0: menu.append(None) menu.append( ( ngettext( "%(count)d Available Item", "%(count)d Available Items", len(available), {"count": len(available)}, ), None, ) ) menu.append((_("Download"), download_all)) if downloading: if len(menu) > 0: menu.append(None) menu.append( ( ngettext( "%(count)d Downloading Item", "%(count)d Downloading Items", len(downloading), {"count": len(downloading)}, ), None, ) ) menu.append((_("Cancel Download"), cancel_all)) menu.append((_("Pause Download"), pause_all)) if paused: if len(menu) > 0: menu.append(None) menu.append( (ngettext("%(count)d Paused Item", "%(count)d Paused Items", len(paused), {"count": len(paused)}), None) ) menu.append((_("Resume Download"), resume_all)) menu.append((_("Cancel Download"), cancel_all)) if uploadable: menu.append((_("Restart Upload"), restart_all)) if editable: menu.append((_("Edit Items"), app.widgetapp.edit_items)) return menu
def run_dialog(channel_infos, downloaded_items, downloading_items, has_watched_feeds): """Displays the remove feeds dialog. """ title = ngettext('Remove Podcast', 'Remove Podcasts', len(channel_infos)) rc_window = MainDialog(title) try: try: v = widgetset.VBox(spacing=5) lab = widgetset.Label( ngettext("Are you sure you want to remove this podcast:", "Are you sure you want to remove these podcasts:", len(channel_infos))) lab.set_wrap(True) v.pack_start(widgetutil.align_left(lab)) v2 = widgetset.VBox() lab_height = None for mem in channel_infos: lab_mem = widgetset.Label(util.clamp_text(mem.name, 40)) if lab_height is None: dummy, lab_height = lab_mem.get_size_request() v2.pack_start(widgetutil.align_left(lab_mem, left_pad=15)) if len(channel_infos) > 5: scroller = widgetset.Scroller(False, True) scroller.set_has_borders(True) scroller.add(v2) scroller_width, scroller_height = scroller.get_size_request() if scroller_height == 0: scroller.set_size_request(scroller_width, 5 * (lab_height + 1)) v2 = scroller v.pack_start(v2, padding=10) cbx_downloaded = None if downloaded_items: cbx_downloaded = widgetset.Checkbox( _("Keep items that have been downloaded in my library.")) v.pack_start( widgetutil.align_left(cbx_downloaded, bottom_pad=5)) if has_watched_feeds: lab = widgetset.Label( _( "Watched folders will be removed from the sidebar but " "their contents will still appear in your library. " "You can stop watching watched folders completely " "in the %(appname)s preference panel.", {"appname": app.config.get(prefs.SHORT_APP_NAME)})) lab.set_wrap(True) lab.set_size_request(390, -1) v.pack_start(widgetutil.align_left(lab, bottom_pad=5)) if downloading_items: lab_downloading = widgetset.Label( ngettext( "Are you sure you want to remove this podcast? " "The downloads currently in progress will be canceled.", "Are you sure you want to remove these podcasts? " "The downloads currently in progress will be canceled.", len(channel_infos))) lab_downloading.set_wrap(True) lab_downloading.set_size_request(390, -1) v.pack_start(widgetutil.align_left(lab_downloading)) rc_window.set_extra_widget(v) rc_window.add_button(BUTTON_REMOVE.text) rc_window.add_button(BUTTON_CANCEL.text) ret = rc_window.run() if ret == 0: # this is silly, but it sets us up for adding additional # bits later. ret = {KEEP_ITEMS: False} if downloaded_items: ret[KEEP_ITEMS] = cbx_downloaded.get_checked() return ret except StandardError: logging.exception("removefeeds threw exception.") finally: rc_window.destroy()
def days_string(secs): t_dy = int(round(secs / (60.0 * 60.0 * 24.0))) return ngettext('%(num)d day', '%(num)d days', t_dy, {"num": t_dy})
def secs_string(secs): return ngettext('%(num)d sec', '%(num)d secs', secs, {"num": secs})
def _make_context_menu_multiple(self, selection): """Make the context menu for multiple items.""" # XXX why are these lists rather than boolean? device = [] remote = [] watched = [] unwatched = [] downloaded = [] playable = [] downloading = [] container = [] available = [] paused = [] uploadable = [] expiring = [] editable = False # local functions def mark_unwatched(): messages.SetItemsWatched(watched, False).send_to_backend() def mark_watched(): messages.SetItemsWatched(unwatched, True).send_to_backend() def keep_videos(): for item in expiring: if item.expiration_date: messages.KeepVideo(item.id).send_to_backend() def download_all(): for item in available: messages.StartDownload(item.id).send_to_backend() def cancel_all(): for item in downloading: messages.CancelDownload(item.id).send_to_backend() def pause_all(): for item in downloading: messages.PauseDownload(item.id).send_to_backend() def resume_all(): for item in paused: messages.ResumeDownload(item.id).send_to_backend() def restart_all(): for item in uploadable: messages.StartUpload(item.id).send_to_backend() for info in selection: if info.downloaded: downloaded.append(info) if info.is_playable: playable.append(info) if info.device: device.append(info) if info.remote: remote.append(info) if info.video_watched: watched.append(info) if info.expiration_date: expiring.append(info) else: unwatched.append(info) if info.is_container_item: container.append(info) if not (info.device or info.remote): editable = True elif info.state == 'paused': paused.append(info) elif info.state == 'downloading': downloading.append(info) if (info.download_info.torrent and info.download_info.state != 'uploading'): uploadable.append(info) else: available.append(info) menu = [] if downloaded: if device: menu.append((ngettext('%(count)d Device Item', '%(count)d Device Items', len(downloaded), {"count": len(downloaded)}), None)) else: menu.append((ngettext('%(count)d Downloaded Item', '%(count)d Downloaded Items', len(downloaded), {"count": len(downloaded)}), None)) if playable: menu.append((_('Play'), app.widgetapp.play_selection)), if not (device or remote or container): menu.append((_('Add to Playlist'), app.widgetapp.add_to_playlist)) self._add_remove_context_menu_item(menu, selection) if watched: menu.append((_('Mark as Unplayed'), mark_unwatched)) if unwatched: menu.append((_('Mark as Played'), mark_watched)) if expiring: menu.append((_('Keep'), keep_videos)) if playable and not (device or remote) and not container: menu.append(None) convert_menu = self._make_convert_menu() menu.append((_('Convert to...'), convert_menu)) if available: if len(menu) > 0: menu.append(None) menu.append((ngettext('%(count)d Available Item', '%(count)d Available Items', len(available), {"count": len(available)}), None)) menu.append((_('Download'), download_all)) if downloading: if len(menu) > 0: menu.append(None) menu.append((ngettext('%(count)d Downloading Item', '%(count)d Downloading Items', len(downloading), {"count": len(downloading)}), None)) menu.append((_('Cancel Download'), cancel_all)) menu.append((_('Pause Download'), pause_all)) if paused: if len(menu) > 0: menu.append(None) menu.append((ngettext('%(count)d Paused Item', '%(count)d Paused Items', len(paused), {"count": len(paused)}), None)) menu.append((_('Resume Download'), resume_all)) menu.append((_('Cancel Download'), cancel_all)) if uploadable: menu.append((_('Restart Upload'), restart_all)) if editable: menu.append((_("Edit Items"), app.widgetapp.edit_items)) return menu
def run_dialog(channel_infos, downloaded_items, downloading_items, has_watched_feeds): """Displays the remove feeds dialog.""" title = ngettext('Remove Feed', 'Remove Feeds', len(channel_infos)) rc_window = MainDialog(title) try: try: v = widgetset.VBox(spacing=5) lab = widgetset.Label(ngettext( "Are you sure you want to remove this feed:", "Are you sure you want to remove these feeds:", len(channel_infos) )) lab.set_wrap(True) v.pack_start(widgetutil.align_left(lab)) v2 = widgetset.VBox() lab_height = None for mem in channel_infos: lab_mem = widgetset.Label(util.clamp_text(mem.name, 40)) if lab_height is None: dummy, lab_height = lab_mem.get_size_request() v2.pack_start(widgetutil.align_left(lab_mem, left_pad=15)) if len(channel_infos) > 5: scroller = widgetset.Scroller(False, True) scroller.set_has_borders(True) scroller.add(v2) scroller_width, scroller_height = scroller.get_size_request() if scroller_height == 0: scroller.set_size_request(scroller_width, 5 * (lab_height + 1)) v2 = scroller v.pack_start(v2, padding=10) cbx_downloaded = None if downloaded_items: cbx_downloaded = widgetset.Checkbox(_("Keep items that have been downloaded in my library.")) v.pack_start(widgetutil.align_left(cbx_downloaded, bottom_pad=5)) if has_watched_feeds: lab = widgetset.Label(_( "Watched folders will be removed from the sidebar but their contents will " "still appear in your library. You can stop watching watched folders completely " "in the %(appname)s preference panel.", {"appname": app.config.get(prefs.SHORT_APP_NAME)} )) lab.set_wrap(True) lab.set_size_request(390, -1) v.pack_start(widgetutil.align_left(lab, bottom_pad=5)) if downloading_items: lab_downloading = widgetset.Label(ngettext( "Are you sure you want to remove this feed? " "The downloads currently in progress will be canceled.", "Are you sure you want to remove these feeds? " "The downloads currently in progress will be canceled.", len(channel_infos) )) lab_downloading.set_wrap(True) lab_downloading.set_size_request(390, -1) v.pack_start(widgetutil.align_left(lab_downloading)) rc_window.set_extra_widget(v) rc_window.add_button(BUTTON_REMOVE.text) rc_window.add_button(BUTTON_CANCEL.text) ret = rc_window.run() if ret == 0: # this is silly, but it sets us up for adding additional # bits later. ret = {KEEP_ITEMS: False} if downloaded_items: ret[KEEP_ITEMS] = cbx_downloaded.get_checked() return ret except StandardError: logging.exception("removefeeds threw exception.") finally: rc_window.destroy()
def _make_context_menu_multiple(self, selection): """Make the context menu for multiple items.""" device = [] watched = [] unwatched = [] downloaded = [] downloading = [] available = [] paused = [] uploadable = [] expiring = [] for info in selection: if info.downloaded: downloaded.append(info) if info.device: device.append(info) elif info.video_watched: watched.append(info) if info.expiration_date: expiring.append(info) else: unwatched.append(info) elif info.state == 'paused': paused.append(info) elif info.state == 'downloading': downloading.append(info) if (info.download_info.torrent and info.download_info.state != 'uploading'): uploadable.append(info) else: available.append(info) menu = [] if downloaded: if device: menu.append((ngettext('%(count)d Device Item', '%(count)d Device Items', len(downloaded), {"count": len(downloaded)}), None)) else: menu.append((ngettext('%(count)d Downloaded Item', '%(count)d Downloaded Items', len(downloaded), {"count": len(downloaded)}), None)) menu.append((_('Play'), app.widgetapp.play_selection)), if not device: menu.append((_('Add to Playlist'), app.widgetapp.add_to_playlist)) self._add_remove_context_menu_item(menu, selection) if watched: def mark_unwatched(): for item in watched: messages.MarkItemUnwatched(item.id).send_to_backend() menu.append((_('Mark as Unplayed'), mark_unwatched)) if unwatched: def mark_watched(): for item in unwatched: messages.MarkItemWatched(item.id).send_to_backend() menu.append((_('Mark as Played'), mark_watched)) if expiring: def keep_videos(): for item in expiring: if item.expiration_date: messages.KeepVideo(item.id).send_to_backend() menu.append((_('Keep'), keep_videos)) if not device: menu.append(None) convert_menu = self._make_convert_menu() menu.append((_('Convert to...'), convert_menu)) if available: if len(menu) > 0: menu.append(None) menu.append((ngettext('%(count)d Available Item', '%(count)d Available Items', len(available), {"count": len(available)}), None)) def download_all(): for item in available: messages.StartDownload(item.id).send_to_backend() menu.append((_('Download'), download_all)) if downloading: if len(menu) > 0: menu.append(None) menu.append((ngettext('%(count)d Downloading Item', '%(count)d Downloading Items', len(downloading), {"count": len(downloading)}), None)) def cancel_all(): for item in downloading: messages.CancelDownload(item.id).send_to_backend() def pause_all(): for item in downloading: messages.PauseDownload(item.id).send_to_backend() menu.append((_('Cancel Download'), cancel_all)) menu.append((_('Pause Download'), pause_all)) if paused: if len(menu) > 0: menu.append(None) menu.append((ngettext('%(count)d Paused Item', '%(count)d Paused Items', len(paused), {"count": len(paused)}), None)) def resume_all(): for item in paused: messages.ResumeDownload(item.id).send_to_backend() menu.append((_('Resume Download'), resume_all)) def cancel_all(): for item in paused: messages.CancelDownload(item.id).send_to_backend() menu.append((_('Cancel Download'), cancel_all)) if uploadable: def restart_all(): for item in uploadable: messages.StartUpload(item.id).send_to_backend() menu.append((_('Restart Upload'), restart_all)) return menu