Пример #1
0
    def deleteEpisode(self, episode):
        def delete():
            episode.delete_episode()
            self.root.main.episodeUpdated(episode.id)
            self.update_subset_stats()
            self.root.mygpo_client.on_delete([episode])
            self.root.mygpo_client.flush()
            self.root.on_episode_deleted(episode)
            self.root.episode_model.sort()

        self.confirm_action(_('Delete this episode?'), _('Delete'), delete)
Пример #2
0
        def get_flattr_info():
            flattrs, flattred = self._flattr.get_thing_info(
                                    episode.payment_url
                                )

            if flattred:
                self.setFlattrButtonText(_('Flattred (%(count)d)') % {
                    'count': flattrs
                })
            else:
                self.setFlattrButtonText(_('Flattr this (%(count)d)') % {
                    'count': flattrs
                })
Пример #3
0
        def upload_proc(self):
            self.root.start_progress(_('Uploading subscriptions...'))

            try:
                try:
                    self.root.mygpo_client.set_subscriptions([podcast.url
                        for podcast in self.root.podcast_model.get_podcasts()])
                except Exception, e:
                    self.root.show_message(
                        '\n'.join((_('Error on upload:'), unicode(e)))
                    )
            finally:
                self.root.end_progress()
Пример #4
0
    def playback_episodes(self, episodes):
        # We need to create a list, because we run through it more than once
        episodes = list(Model.sort_episodes_by_pubdate(e for e in episodes if \
               e.was_downloaded(and_exists=True) or self.streaming_possible()))

        try:
            self.playback_episodes_for_real(episodes)
        except Exception, e:
            logger.error('Error in playback!', exc_info=True)
            self.root.show_message(
                _('Please check your media player settings in the preferences dialog.'),
                _('Error opening player'), widget=self.root.toolPreferences
            )
Пример #5
0
    def request_connection(self):
        """Request an internet connection

        Returns True if a connection is available, False otherwise
        """
        if not util.connection_available():
            # TODO: Try to request the network connection dialog, and wait
            # for a connection - if a connection is available, return True

            self.root.show_message('\n\n'.join((_('No network connection'),
                _('Please connect to a network, then try again.'))))
            return False

        return True
Пример #6
0
    def updateFlattrButtonText(self, qepisode):
        self.setFlattrButtonText('')

        if qepisode is None:
            return

        episode = qepisode._episode

        if not episode.payment_url:
            return
        if not self._flattr.has_token():
            self.setFlattrButtonText(_('Sign in'))
            return

        @util.run_in_background
        def get_flattr_info():
            flattrs, flattred = self._flattr.get_thing_info(
                                    episode.payment_url
                                )

            if flattred:
                self.setFlattrButtonText(_('Flattred (%(count)d)') % {
                    'count': flattrs
                })
            else:
                self.setFlattrButtonText(_('Flattr this (%(count)d)') % {
                    'count': flattrs
                })
Пример #7
0
    def on_offer_download_resume(self):
        if self.resumable_episodes:
            def download_episodes():
                for episode in self.resumable_episodes:
                    qepisode = self.wrap_simple_episode(episode)
                    self.controller.downloadEpisode(qepisode)

            def delete_episodes():
                logger.debug('Deleting incomplete downloads.')
                common.clean_up_downloads(delete_partial=True)

            message = _(
                'Incomplete downloads from a previous session were found.'
            )
            title = _('Resume')

            self.controller.confirm_action(
                message, title, download_episodes, delete_episodes
            )
Пример #8
0
 def subscribe_proc(self, urls):
     self.root.start_progress(_('Adding podcasts...'))
     try:
         for idx, url in enumerate(urls):
             print idx, url
             self.root.start_progress(
                 _('Adding podcasts...') + ' (%d/%d)' % (idx, len(urls))
             )
             try:
                 podcast = self.root.model.load_podcast(
                     url=url,
                     create=True,
                     max_episodes=self.root.config.max_episodes_per_feed
                 )
                 podcast.save()
                 self.root.insert_podcast(qml.model.QPodcast(podcast))
             except Exception, e:
                 logger.warn('Cannot add pocast: %s', e)
                 # XXX: Visual feedback in the QML UI
     finally:
         self.root.end_progress()
Пример #9
0
    def flattrEpisode(self, qepisode):
        if not qepisode:
            return

        episode = qepisode._episode

        if not episode.payment_url:
            return
        if not self._flattr.has_token():
            self.root.show_message(_('Sign in to Flattr in the settings.'))
            return

        self.root.start_progress(_('Flattring episode...'))

        @util.run_in_background
        def flattr_episode():
            try:
                success, message = self._flattr.flattr_url(episode.payment_url)
                if success:
                    self.updateFlattrButtonText(qepisode)
                else:
                    self.root.show_message(message)
            finally:
                self.root.end_progress()
Пример #10
0
        def merge_proc(self):
            self.root.start_progress(_('Merging episode actions...'))

            def find_episode(podcast_url, episode_url, counter):
                counter['x'] += 1
                self.root.start_progress(_('Merging episode actions (%d)')
                        % counter['x'])
                return self.find_episode(podcast_url, episode_url)

            try:
                # Used to "remember" the counter inside find_episode
                d = {'x': 0}

                self.root.mygpo_client.process_episode_actions(lambda x, y:
                        find_episode(x, y, d))
            finally:
                self.root.end_progress()
Пример #11
0
    def multiEpisodeAction(self, selected, action):
        if not selected:
            return

        count = len(selected)
        episodes = map(self.root.episode_model.get_object_by_index, selected)

        def delete():
            for episode in episodes:
                if not episode.qarchive:
                    episode.delete_episode()
            self.update_subset_stats()
            self.root.mygpo_client.on_delete(episodes)
            self.root.mygpo_client.flush()
            for episode in episodes:
                self.root.on_episode_deleted(episode)
            self.root.episode_model.sort()

        if action == 'delete':
            msg = N_(
                'Delete %(count)d episode?',
                'Delete %(count)d episodes?',
                count
                ) % {'count': count}

            self.confirm_action(msg, _('Delete'), delete)
        elif action == 'download':
            for episode in episodes:
                if episode.qdownloaded:
                    print '    XXX     already downloaded'
                    continue
                self.downloadEpisode(episode)
            self.root.mygpo_client.on_download(episodes)
            self.root.mygpo_client.flush()
        elif action == 'play':
            for episode in episodes:
                self.root.enqueue_episode(episode)
Пример #12
0
    def episodeContextMenu(self, episode):
        menu = []

        toggle_new = _('Mark as old') if episode.is_new else _('Mark as new')
        menu.append(helper.Action(toggle_new, 'episode-toggle-new', episode))

        toggle_archive = \
            _('Allow deletion') if episode.archive else _('Archive')

        menu.append(helper.Action(
            toggle_archive, 'episode-toggle-archive', episode
        ))

        if episode.state != gpodder.STATE_DELETED:
            menu.append(helper.Action(_('Delete'), 'episode-delete', episode))

        menu.append(helper.Action(
            _('Add to play queue'), 'episode-enqueue', episode
        ))

        self.show_context_menu(menu)
Пример #13
0
    def thread_func(self, tab, param=None):
        if tab == TabType.ChannelChooser:
            url = param
            if url is None:
                url = self.getInitialOMPLUrl()

            if self.is_search_term(url):
                url = 'http://gpodder.net/search.opml?q=' + urllib.quote(url)

            model = OpmlListModel(opml.Importer(url))

            if model.rowCount() == 0:
                self.notification(
                    _('The specified URL does not provide any valid OPML podcast items.'),
                    _('No feeds found')
                )

        elif tab == TabType.TopPodcasts:
            model = OpmlListModel(opml.Importer(my.TOPLIST_OPML))

            if model.rowCount() == 0:
                self.notification(
                    _('The specified URL does not provide any valid OPML podcast items.'),
                    _('No feeds found')
                )

        elif tab == TabType.Youtube:
            model = OpmlListModel(youtube.find_youtube_channels(param))

            if model.rowCount() == 0:
                self.notification(
                    _('There are no YouTube channels that would match this query.'),
                    _('No channels found')
                )

        self.setModel(tab, model)
Пример #14
0
    def podcastContextMenu(self, podcast):
        menu = []

        if isinstance(podcast, qml.model.EpisodeSubsetView):
            menu.append(helper.Action(_('Update all'), 'update-all', podcast))
        else:
            menu.append(helper.Action(_('Update'), 'update', podcast))
            menu.append(helper.Action(
                _('Mark episodes as old'), 'mark-as-read', podcast
            ))
            menu.append(helper.Action(_('Rename'), 'rename-podcast', podcast))
            menu.append(helper.Action(
                _('Change section'), 'change-section', podcast
            ))
            menu.append(helper.Action(
                _('Unsubscribe'), 'unsubscribe', podcast
            ))

        # menu.append(helper.Action(
        #    'Force update all', 'force-update-all', podcast
        # ))
        # menu.append(helper.Action('Force update', 'force-update', podcast))

        self.show_context_menu(menu)
Пример #15
0
 def set_podcasts(self, db, podcasts):
     views = [EpisodeSubsetView(db, self, _("All episodes"), "")]
     self.set_objects(views + podcasts)
Пример #16
0
 def show_input_dialog(self, message, value='', accept=_('OK'),
         reject=_('Cancel'), is_text=True):
     self.main.showInputDialog(message, value, accept, reject, is_text)
Пример #17
0
 def find_episode(podcast_url, episode_url, counter):
     counter['x'] += 1
     self.root.start_progress(_('Merging episode actions (%d)')
             % counter['x'])
     return self.find_episode(podcast_url, episode_url)
Пример #18
0
 def progress_callback(title, progress):
     self.start_progress('%s (%d%%)' % (
         _('Loading incomplete downloads'),
         progress * 100))
Пример #19
0
 def start_progress_callback(count):
     self.start_progress(_('Loading incomplete downloads'))
Пример #20
0
    def contextMenuResponse(self, index):
        assert index < len(self.context_menu_actions)
        action = self.context_menu_actions[index]
        if action.action == 'update':
            if not self.request_connection():
                return
            podcast = action.target
            if not podcast.pause_subscription:
                podcast.qupdate(finished_callback=self.update_subset_stats)
        elif action.action == 'force-update':
            action.target.qupdate(force=True, \
                    finished_callback=self.update_subset_stats)
        elif action.action == 'update-all':
            self.updateAllPodcasts()
        elif action.action == 'force-update-all':
            for podcast in self.root.podcast_model.get_objects():
                podcast.qupdate(
                    force=True, finished_callback=self.update_subset_stats
                )
        if action.action == 'unsubscribe':
            def unsubscribe():
                action.target.remove_downloaded()
                action.target.delete()
                self.root.remove_podcast(action.target)

            self.confirm_action(_('Remove this podcast and episodes?'),
                    _('Unsubscribe'), unsubscribe)
        elif action.action == 'episode-toggle-new':
            action.target.toggle_new()
            self.root.main.episodeUpdated(action.target.id)
            self.update_subset_stats()
        elif action.action == 'episode-toggle-archive':
            action.target.toggle_archive()
            self.root.main.episodeUpdated(action.target.id)
            self.update_subset_stats()
        elif action.action == 'episode-delete':
            self.deleteEpisode(action.target)
        elif action.action == 'episode-enqueue':
            self.root.enqueue_episode(action.target)
        elif action.action == 'mark-as-read':
            for episode in action.target.get_all_episodes():
                if not episode.was_downloaded(and_exists=True):
                    episode.mark(is_played=True)
            action.target.changed.emit()
            self.update_subset_stats()
        elif action.action == 'change-section':
            def section_changer(podcast):
                section = yield (_('New section name:'), podcast.section,
                        _('Rename'))
                if section and section != podcast.section:
                    podcast.set_section(section)
                    self.root.resort_podcast_list()

            self.start_input_dialog(section_changer(action.target))
        elif action.action == 'rename-podcast':
            def title_changer(podcast):
                title = yield (_('New name:'), podcast.title,
                        _('Rename'))
                if title and title != podcast.title:
                    podcast.rename(title)
                    self.root.resort_podcast_list()

            self.start_input_dialog(title_changer(action.target))
Пример #21
0
 def on_entryURL_changed(self, url):
     if self.is_search_term(url):
         return _('Search')
     else:
         return _('Download')
Пример #22
0
 def processFlattrCode(self, url):
     if not self._flattr.process_retrieved_code(url):
         self.root.show_message(_('Could not log in to Flattr.'))
Пример #23
0
    def playback_episodes_for_real(self, episodes):
        groups = collections.defaultdict(list)
        for episode in episodes:
            file_type = episode.file_type()
            if file_type == 'video' and self.config.videoplayer and \
                    self.config.videoplayer != 'default':
                player = self.config.videoplayer
            elif file_type == 'audio' and self.config.player and \
                    self.config.player != 'default':
                player = self.config.player
            else:
                player = 'default'

            # Mark episode as played in the database
            episode.playback_mark()
            self.root.mygpo_client.on_playback([episode])

            fmt_ids = youtube.get_fmt_ids(self.config.youtube)

            allow_partial = (player != 'default')
            filename = episode.get_playback_url(fmt_ids, allow_partial)

            # Determine the playback resume position - if the file
            # was played 100%, we simply start from the beginning
            resume_position = episode.current_position
            if resume_position == episode.total_time:
                resume_position = 0

            # If Panucci is configured, use D-Bus to call it
            if player == 'panucci':
                try:
                    PANUCCI_NAME = 'org.panucci.panucciInterface'
                    PANUCCI_PATH = '/panucciInterface'
                    PANUCCI_INTF = 'org.panucci.panucciInterface'
                    o = gpodder.dbus_session_bus.get_object(
                        PANUCCI_NAME, PANUCCI_PATH
                    )
                    i = dbus.Interface(o, PANUCCI_INTF)

                    def on_reply(*args):
                        pass

                    def error_handler(filename, err):
                        logger.error('Exception in D-Bus call: %s', str(err))

                        # Fallback: use the command line client
                        for command in util.format_desktop_command('panucci', \
                                [filename]):
                            logger.info('Executing: %s', repr(command))
                            subprocess.Popen(command)

                    on_error = lambda err: error_handler(filename, err)

                    # This method only exists in Panucci > 0.9 ('new Panucci')
                    i.playback_from(filename, resume_position, \
                            reply_handler=on_reply, error_handler=on_error)

                    continue  # This file was handled by the D-Bus call
                except Exception, e:
                    logger.error('Calling Panucci using D-Bus', exc_info=True)

            # flattr episode if auto-flattr is enabled
            if (episode.payment_url and self.config.flattr.token and
                    self.config.flattr.flattr_on_play):
                success, message = self.flattr.flattr_url(episode.payment_url)
                self.show_message(message, title=_('Flattr status'),
                        important=not success)

            groups[player].append(filename)
Пример #24
0
 def section_changer(podcast):
     section = yield (_('New section name:'), podcast.section,
             _('Rename'))
     if section and section != podcast.section:
         podcast.set_section(section)
         self.root.resort_podcast_list()
Пример #25
0
 def title_changer(podcast):
     title = yield (_('New name:'), podcast.title,
             _('Rename'))
     if title and title != podcast.title:
         podcast.rename(title)
         self.root.resort_podcast_list()
Пример #26
0
 def translate(self, x):
     return _(x)
Пример #27
0
 def start_progress(self, text=_('Please wait...'), progress=0):
     self.do_start_progress.emit(text, progress)
Пример #28
0
 def confirm(message, affirmative, callback, negative_callback):
     args = (message, '', affirmative, _('Cancel'), False)
     if (yield args):
         callback()
     elif negative_callback is not None:
         negative_callback()