示例#1
0
 def load_sys_list(self):
     if not self.sys:
         self.sys = FeedContainer()
         self.sys.load_directory(SYS_FEEDS_DIR)
     self.sys_model.clear()
     names = self.sys.feeds.keys()
     names.sort(key=str.lower)
     for feed in names:
         self.sys_model.append((feed, self.sys.feeds[feed].filename))
示例#2
0
 def load_sys_list(self):
     if not self.sys:
         self.sys = FeedContainer()
         self.sys.load_directory(SYS_FEEDS_DIR)
     self.sys_model.clear()
     names = self.sys.feeds.keys()
     names.sort(key=str.lower)
     for feed in names:
         self.sys_model.append((feed, self.sys.feeds[feed].filename))
示例#3
0
if __name__ == '__main__':
    # Initialise threading
    gobject.threads_init()
    gtk.gdk.threads_init()
    # Make sure that all required directories exist
    if not os.access(USER_DIR, os.W_OK):
        if os.access(ALT_USER_DIR, os.W_OK):
            os.symlink(ALT_USER_DIR, USER_DIR)
        else:
            os.makedirs(USER_DIR)
    if not os.access(USER_FEEDS_DIR, os.W_OK):
        os.makedirs(USER_FEEDS_DIR)

    # Load the feeds
    feeds = FeedContainer()
    feeds.load_directory(USER_FEEDS_DIR)

    #Initialise AWN and create the applet
    awn.init(sys.argv[1:])
    applet = ComicApplet(awn.uid, awn.panel_id, feeds)

    # Initialize user agent string
    import urllib

    user_agent = applet.configuration.get_string(config.GROUP_DEFAULT,
                                                 'user_agent')

    class ComicURLOpener(urllib.FancyURLopener):
        version = user_agent
    urllib._urlopener = ComicURLOpener()
示例#4
0
if __name__ == '__main__':
    # Initialise threading
    gobject.threads_init()
    gtk.gdk.threads_init()
    # Make sure that all required directories exist
    if not os.access(USER_DIR, os.W_OK):
        if os.access(ALT_USER_DIR, os.W_OK):
            os.symlink(ALT_USER_DIR, USER_DIR)
        else:
            os.makedirs(USER_DIR)
    if not os.access(USER_FEEDS_DIR, os.W_OK):
        os.makedirs(USER_FEEDS_DIR)

    # Load the feeds
    feeds = FeedContainer()
    feeds.load_directory(USER_FEEDS_DIR)

    #Initialise AWN and create the applet
    awn.init(sys.argv[1:])
    applet = ComicApplet(awn.uid, awn.panel_id, feeds)

    # Initialize user agent string
    import urllib

    user_agent = applet.configuration.get_string(config.GROUP_DEFAULT,
                                                 'user_agent')

    class ComicURLOpener(urllib.FancyURLopener):
        version = user_agent
示例#5
0
class ComicsAdder:
    """A program to add image feeds."""

    __name__ = 'Comics!'
    __version__ = '1.0'
    __author__ = 'Moses'

    ########################################################################
    # Helper methods                                                       #
    ########################################################################

    def process_error(self, result):
        label = self.ui.get_object('intro_label')
        if result == Feed.DOWNLOAD_FAILED:
            label.set_text(_('''\
Failed to download %s. Press "next" to try again.''') % self.url)
            self.assistant.set_current_page(0)
            return False

        elif result == Feed.DOWNLOAD_NOT_FEED:
            label.set_text(_('''\
The URL is not a valid comic feed. Press "next" to try again'''))
            self.assistant.set_current_page(0)
            return False

        return True

    def load_sys_list(self):
        if not self.sys:
            self.sys = FeedContainer()
            self.sys.load_directory(SYS_FEEDS_DIR)
        self.sys_model.clear()
        names = self.sys.feeds.keys()
        names.sort(key=str.lower)
        for feed in names:
            self.sys_model.append((feed, self.sys.feeds[feed].filename))

    def on_screen(self):
        return len(self.assistant) != 0

    def present(self):
        self.assistant.present()

    ########################################################################
    # Standard python methods                                              #
    ########################################################################

    def __init__(self, parent):
        """Create a new ComicsAdder instance."""
        self.__parent = parent
        self.feeds = parent.feeds
        self.name = ''
        self.url = ''
        self.feed = None
        self.__update = None

        # Connect dialogue events
        self.ui = gtk.Builder()
        self.ui.add_from_file(UI_FILE)
        self.ui.connect_signals(self)
        self.assistant = self.ui.get_object('add_assistant')
        self.image_list = self.ui.get_object('image_list')

        self.sys = None
        self.sys_list = self.ui.get_object('pre_list')
        self.sys_model = gtk.ListStore(gobject.TYPE_STRING,
                                       gobject.TYPE_STRING)
        self.sys_col = self.ui.get_object('pre_col')
        self.load_sys_list()
        self.sys_list.set_model(self.sys_model)

        self.from_list = True
        self.radio_button = self.ui.get_object('list_radio')
        self.radio_button.set_active(self.from_list)

        self.model = gtk.ListStore(gobject.TYPE_PYOBJECT, gtk.gdk.Pixbuf)
        self.image_list.set_model(self.model)

        selection = self.sys_list.get_selection()
        selection.connect('changed', self.on_list_selection_changed)
        selection.set_mode(gtk.SELECTION_MULTIPLE)
        # Show window
        self.assistant.set_page_complete(self.ui.get_object('intro_page'),
            True)
        self.assistant.set_page_complete(self.ui.get_object('last_page'),
            True)
        self.assistant.show()

    ########################################################################
    # Event hooks                                                          #
    ########################################################################

    def on_add_assistant_close(self, widget):
        if self.__update:
            self.feed.disconnect(self.__update)
        self.assistant.destroy()

    def on_add_assistant_cancel(self, widget):
        if self.__update:
            self.feed.disconnect(self.__update)
        self.assistant.destroy()

    def on_add_assistant_apply(self, widget):
        try:
            os.mkdir(USER_FEEDS_DIR)
        except Exception:
            pass

        if self.from_list:
            model, paths = self.sys_list.get_selection().get_selected_rows()
            for path in paths:
                self.name = model.get_value(model.get_iter(path), 0)
                src = model.get_value(model.get_iter(path), 1)
                filename = USER_FEEDS_DIR + src[len(SYS_FEEDS_DIR):]
                with open(src, 'r') as fp:
                    src_content = fp.read()
                try:
                    with open(filename, 'r') as fp:
                        f = fp.read()
                except IOError:
                    f = None
                if f:
                    if cmp(src_content, f) == 0:
                        continue
                    msg = _("Overwrite comic \"%s\"?") % self.name
                    sec = _(
                 "This comic is already installed with different settings.")
                    dialog = gtk.MessageDialog(parent=self.assistant,
                                   flags=gtk.DIALOG_DESTROY_WITH_PARENT,
                                   type=gtk.MESSAGE_WARNING,
                                   message_format=msg)
                    dialog.format_secondary_markup(sec)
                    if path != paths[-1]:
                        dialog.add_buttons(
                                       gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
                    dialog.add_buttons(gtk.STOCK_NO, gtk.RESPONSE_NO,
                                       gtk.STOCK_YES, gtk.RESPONSE_YES)
                    response = dialog.run()
                    dialog.destroy()
                    if response == gtk.RESPONSE_NO:
                        continue
                    if response != gtk.RESPONSE_YES:
                        return
                with open(filename, 'w') as fp:
                    fp.write(src_content)
                self.feeds.add_feed(filename)
                self.feeds.update()
                self.__parent.toggle_feed(self.name, True)
        else:
            self.name = self.ui.get_object('name_entry').get_text()
            f, filename = tempfile.mkstemp('.feed', '', USER_FEEDS_DIR, True)
            os.close(f)
            settings = Settings(filename)
            settings.description = 'Automatically generated by comics'
            settings[NAME] = self.name
            settings[URL] = self.url
            settings[IMG_INDEX] = self.image[0] + 1
            settings.comments[IMG_INDEX] = \
                'The index of the image in the HTML-code'
            if self.feed.__module__.startswith('feed.plugins.'):
                settings[PLUGIN] = self.feed.__module__[13:]
            settings.save()
            self.feeds.add_feed(filename)
            self.feeds.update()
            self.__parent.toggle_feed(self.name, True)

    def on_add_assistant_prepare(self, widget, page):
        if page is self.ui.get_object('url_page'):
            if self.from_list:
                self.ui.get_object('list_box').show()
                self.ui.get_object('url_box').hide()
            else:
                self.ui.get_object('list_box').hide()
                self.ui.get_object('url_box').show()

        elif page is self.ui.get_object('wait_page'):
            if self.from_list:
                self.ui.get_object('name_box').hide()
                last_label = self.ui.get_object('last_label')
                last_label.set_markup(_('''\
This guide has finished.\n\
Press "apply" to add the comic.'''))
                self.assistant.set_current_page(4)
            else:
                self.assistant.set_page_complete(page, False)
                self.url = self.ui.get_object('url_entry').get_text()

                self.ui.get_object('wait_label').set_markup(
                    _('Connecting to <i>%s</i>...') % self.url)

                # Download feed
                self.feed = self.feeds.get_feed_for_url(self.url)
                self.__update = self.feed.connect('updated',
                                                  self.on_feed_updated)
                self.feed.update()

    def on_radio_button_toggled(self, widget):
        self.from_list = self.radio_button.get_active()

    def on_url_entry_changed(self, widget):
        text = widget.get_text()
        if not self.from_list:
            self.assistant.set_page_complete(self.ui.get_object('url_page'),
                not URL_RE.match(text) is None)

    def on_list_selection_changed(self, widget):
        if self.from_list:
            self.assistant.set_page_complete(self.ui.get_object('url_page'),
                self.sys_list.get_selection().count_selected_rows() > 0)

    def on_name_entry_changed(self, widget):
        text = widget.get_text()
        self.assistant.set_page_complete(self.ui.get_object('last_page'),
            not text == '')

    def on_image_list_unselect_all(self, widget):
        self.assistant.set_page_complete(self.ui.get_object('image_page'),
            False)

    def on_image_list_selection_changed(self, widget):
        selection = self.image_list.get_selected_items()
        if len(selection) == 1:
            self.assistant.set_page_complete(self.ui.get_object('image_page'),
                True)
            self.image = self.model.get_value(
                self.model.get_iter(selection[0]), 0)
        else:
            self.assistant.set_page_complete(self.ui.get_object('image_page'),
                False)

    def on_feed_updated(self, feed, result):
        if not self.process_error(result):
            return

        self.name = feed.name

        last_label = self.ui.get_object('last_label')
        last_label.set_markup(_('''\
This guide has finished.\n\
You can change the name of this comic. Press "apply" to add it.'''))
        name_entry = self.ui.get_object('name_entry')
        name_entry.set_text(self.name)

        # Can we skip the image page?
        images = feed.get_unique_images()
        if len(images) > 1:
            # Download images for the image list
            self.model.clear()
            for image in images:
                iterator = self.model.append((image, None))
                downloader = Downloader(image[1])
                downloader.connect('completed',
                    self.on_image_download_completed, iterator)
                downloader.download()
            self.ui.get_object('image_page').show()
        else:
            self.ui.get_object('image_page').hide()
            try:
                self.image = images[0]
            except IndexError:
                self.process_error(Feed.DOWNLOAD_NOT_FEED)
                return

        # Complete page
        self.assistant.set_page_complete(self.ui.get_object('wait_page'),
                                         True)
        self.ui.get_object('wait_label').set_markup(
                _('Found <b>%(name)s</b>!\n\n<i>%(description)s</i>')
                % {'name': self.name,
                    'description': self.feed.description})

    def on_image_download_completed(self, o, code, iterator):
        """Update the image list with a newly downloaded image."""
        if code != Downloader.OK:
            self.model.remove(iterator)
        else:
            try:
                pixbuf = gtk.gdk.pixbuf_new_from_file(o.filename)
                self.model.set_value(iterator, 1, pixbuf)
            except Exception:
                self.model.remove(iterator)
            os.remove(o.filename)
示例#6
0
class ComicsAdder:
    """A program to add image feeds."""

    __name__ = 'Comics!'
    __version__ = '1.0'
    __author__ = 'Moses'

    ########################################################################
    # Helper methods                                                       #
    ########################################################################

    def process_error(self, result):
        label = self.ui.get_object('intro_label')
        if result == Feed.DOWNLOAD_FAILED:
            label.set_text(
                _('''\
Failed to download %s. Press "next" to try again.''') % self.url)
            self.assistant.set_current_page(0)
            return False

        elif result == Feed.DOWNLOAD_NOT_FEED:
            label.set_text(
                _('''\
The URL is not a valid comic feed. Press "next" to try again'''))
            self.assistant.set_current_page(0)
            return False

        return True

    def load_sys_list(self):
        if not self.sys:
            self.sys = FeedContainer()
            self.sys.load_directory(SYS_FEEDS_DIR)
        self.sys_model.clear()
        names = self.sys.feeds.keys()
        names.sort(key=str.lower)
        for feed in names:
            self.sys_model.append((feed, self.sys.feeds[feed].filename))

    def on_screen(self):
        return len(self.assistant) != 0

    def present(self):
        self.assistant.present()

    ########################################################################
    # Standard python methods                                              #
    ########################################################################

    def __init__(self, parent):
        """Create a new ComicsAdder instance."""
        self.__parent = parent
        self.feeds = parent.feeds
        self.name = ''
        self.url = ''
        self.feed = None
        self.__update = None

        # Connect dialogue events
        self.ui = gtk.Builder()
        self.ui.add_from_file(UI_FILE)
        self.ui.connect_signals(self)
        self.assistant = self.ui.get_object('add_assistant')
        self.image_list = self.ui.get_object('image_list')

        self.sys = None
        self.sys_list = self.ui.get_object('pre_list')
        self.sys_model = gtk.ListStore(gobject.TYPE_STRING,
                                       gobject.TYPE_STRING)
        self.sys_col = self.ui.get_object('pre_col')
        self.load_sys_list()
        self.sys_list.set_model(self.sys_model)

        self.from_list = True
        self.radio_button = self.ui.get_object('list_radio')
        self.radio_button.set_active(self.from_list)

        self.model = gtk.ListStore(gobject.TYPE_PYOBJECT, gtk.gdk.Pixbuf)
        self.image_list.set_model(self.model)

        selection = self.sys_list.get_selection()
        selection.connect('changed', self.on_list_selection_changed)
        selection.set_mode(gtk.SELECTION_MULTIPLE)
        # Show window
        self.assistant.set_page_complete(self.ui.get_object('intro_page'),
                                         True)
        self.assistant.set_page_complete(self.ui.get_object('last_page'), True)
        self.assistant.show()

    ########################################################################
    # Event hooks                                                          #
    ########################################################################

    def on_add_assistant_close(self, widget):
        if self.__update:
            self.feed.disconnect(self.__update)
        self.assistant.destroy()

    def on_add_assistant_cancel(self, widget):
        if self.__update:
            self.feed.disconnect(self.__update)
        self.assistant.destroy()

    def on_add_assistant_apply(self, widget):
        try:
            os.mkdir(USER_FEEDS_DIR)
        except Exception:
            pass

        if self.from_list:
            model, paths = self.sys_list.get_selection().get_selected_rows()
            for path in paths:
                self.name = model.get_value(model.get_iter(path), 0)
                src = model.get_value(model.get_iter(path), 1)
                filename = USER_FEEDS_DIR + src[len(SYS_FEEDS_DIR):]
                with open(src, 'r') as fp:
                    src_content = fp.read()
                try:
                    with open(filename, 'r') as fp:
                        f = fp.read()
                except IOError:
                    f = None
                if f:
                    if cmp(src_content, f) == 0:
                        continue
                    msg = _("Overwrite comic \"%s\"?") % self.name
                    sec = _(
                        "This comic is already installed with different settings."
                    )
                    dialog = gtk.MessageDialog(
                        parent=self.assistant,
                        flags=gtk.DIALOG_DESTROY_WITH_PARENT,
                        type=gtk.MESSAGE_WARNING,
                        message_format=msg)
                    dialog.format_secondary_markup(sec)
                    if path != paths[-1]:
                        dialog.add_buttons(gtk.STOCK_CANCEL,
                                           gtk.RESPONSE_CANCEL)
                    dialog.add_buttons(gtk.STOCK_NO, gtk.RESPONSE_NO,
                                       gtk.STOCK_YES, gtk.RESPONSE_YES)
                    response = dialog.run()
                    dialog.destroy()
                    if response == gtk.RESPONSE_NO:
                        continue
                    if response != gtk.RESPONSE_YES:
                        return
                with open(filename, 'w') as fp:
                    fp.write(src_content)
                self.feeds.add_feed(filename)
                self.feeds.update()
                self.__parent.toggle_feed(self.name, True)
        else:
            self.name = self.ui.get_object('name_entry').get_text()
            f, filename = tempfile.mkstemp('.feed', '', USER_FEEDS_DIR, True)
            os.close(f)
            settings = Settings(filename)
            settings.description = 'Automatically generated by comics'
            settings[NAME] = self.name
            settings[URL] = self.url
            settings[IMG_INDEX] = self.image[0] + 1
            settings.comments[IMG_INDEX] = \
                'The index of the image in the HTML-code'
            if self.feed.__module__.startswith('feed.plugins.'):
                settings[PLUGIN] = self.feed.__module__[13:]
            settings.save()
            self.feeds.add_feed(filename)
            self.feeds.update()
            self.__parent.toggle_feed(self.name, True)

    def on_add_assistant_prepare(self, widget, page):
        if page is self.ui.get_object('url_page'):
            if self.from_list:
                self.ui.get_object('list_box').show()
                self.ui.get_object('url_box').hide()
            else:
                self.ui.get_object('list_box').hide()
                self.ui.get_object('url_box').show()

        elif page is self.ui.get_object('wait_page'):
            if self.from_list:
                self.ui.get_object('name_box').hide()
                last_label = self.ui.get_object('last_label')
                last_label.set_markup(
                    _('''\
This guide has finished.\n\
Press "apply" to add the comic.'''))
                self.assistant.set_current_page(4)
            else:
                self.assistant.set_page_complete(page, False)
                self.url = self.ui.get_object('url_entry').get_text()

                self.ui.get_object('wait_label').set_markup(
                    _('Connecting to <i>%s</i>...') % self.url)

                # Download feed
                self.feed = self.feeds.get_feed_for_url(self.url)
                self.__update = self.feed.connect('updated',
                                                  self.on_feed_updated)
                self.feed.update()

    def on_radio_button_toggled(self, widget):
        self.from_list = self.radio_button.get_active()

    def on_url_entry_changed(self, widget):
        text = widget.get_text()
        if not self.from_list:
            self.assistant.set_page_complete(self.ui.get_object('url_page'),
                                             not URL_RE.match(text) is None)

    def on_list_selection_changed(self, widget):
        if self.from_list:
            self.assistant.set_page_complete(
                self.ui.get_object('url_page'),
                self.sys_list.get_selection().count_selected_rows() > 0)

    def on_name_entry_changed(self, widget):
        text = widget.get_text()
        self.assistant.set_page_complete(self.ui.get_object('last_page'),
                                         not text == '')

    def on_image_list_unselect_all(self, widget):
        self.assistant.set_page_complete(self.ui.get_object('image_page'),
                                         False)

    def on_image_list_selection_changed(self, widget):
        selection = self.image_list.get_selected_items()
        if len(selection) == 1:
            self.assistant.set_page_complete(self.ui.get_object('image_page'),
                                             True)
            self.image = self.model.get_value(
                self.model.get_iter(selection[0]), 0)
        else:
            self.assistant.set_page_complete(self.ui.get_object('image_page'),
                                             False)

    def on_feed_updated(self, feed, result):
        if not self.process_error(result):
            return

        self.name = feed.name

        last_label = self.ui.get_object('last_label')
        last_label.set_markup(
            _('''\
This guide has finished.\n\
You can change the name of this comic. Press "apply" to add it.'''))
        name_entry = self.ui.get_object('name_entry')
        name_entry.set_text(self.name)

        # Can we skip the image page?
        images = feed.get_unique_images()
        if len(images) > 1:
            # Download images for the image list
            self.model.clear()
            for image in images:
                iterator = self.model.append((image, None))
                downloader = Downloader(image[1])
                downloader.connect('completed',
                                   self.on_image_download_completed, iterator)
                downloader.download()
            self.ui.get_object('image_page').show()
        else:
            self.ui.get_object('image_page').hide()
            try:
                self.image = images[0]
            except IndexError:
                self.process_error(Feed.DOWNLOAD_NOT_FEED)
                return

        # Complete page
        self.assistant.set_page_complete(self.ui.get_object('wait_page'), True)
        self.ui.get_object('wait_label').set_markup(
            _('Found <b>%(name)s</b>!\n\n<i>%(description)s</i>') % {
                'name': self.name,
                'description': self.feed.description
            })

    def on_image_download_completed(self, o, code, iterator):
        """Update the image list with a newly downloaded image."""
        if code != Downloader.OK:
            self.model.remove(iterator)
        else:
            try:
                pixbuf = gtk.gdk.pixbuf_new_from_file(o.filename)
                self.model.set_value(iterator, 1, pixbuf)
            except Exception:
                self.model.remove(iterator)
            os.remove(o.filename)