Example #1
0
    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)
Example #2
0
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
Example #3
0
        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
Example #4
0
    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')
Example #5
0
    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')
Example #6
0
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})
Example #7
0
 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)
Example #9
0
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})
Example #10
0
 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()
Example #11
0
File: opml.py Project: cool-RR/Miro
 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()
Example #12
0
    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
Example #13
0
 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()
Example #14
0
 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()
Example #15
0
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)})
Example #16
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')
Example #17
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')
Example #18
0
 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))
Example #19
0
 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()
Example #20
0
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})
Example #21
0
    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
Example #22
0
    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')
Example #23
0
 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()
Example #24
0
 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()
Example #25
0
    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')
Example #26
0
 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()
Example #27
0
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
Example #28
0
 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()
Example #29
0
    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
Example #30
0
    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))
Example #31
0
    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))
Example #32
0
    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))
Example #33
0
    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))
Example #34
0
 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
Example #35
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
Example #36
0
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})
Example #37
0
def mins_string(secs):
    t_min = int(round(secs / 60.0))
    return ngettext('%(num)d min', '%(num)d mins', t_min, {"num": t_min})
Example #38
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.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
Example #39
0
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()
Example #40
0
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})
Example #41
0
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})
Example #42
0
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})
Example #43
0
def secs_string(secs):
    return ngettext('%(num)d sec', '%(num)d secs', secs, {"num": secs})
Example #44
0
def mins_string(secs):
    t_min = int(round(secs / 60.0))
    return ngettext('%(num)d min', '%(num)d mins', t_min,
                    {"num": t_min})
Example #45
0
def secs_string(secs):
    return ngettext('%(num)d sec', '%(num)d secs', secs, {"num": secs})
Example #46
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 = []
        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
Example #47
0
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()
Example #48
0
    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