Пример #1
0
        def _go():
            self.thumbs_window = ThumbsWindow(screen=self.screen,
                                              position=options.position,
                                              breadth=options.breadth)
            try:
                icon = varietyconfig.get_data_file("media", "variety.svg")
                self.thumbs_window.set_icon_from_file(icon)
            except Exception:
                logger.exception(lambda: "Could not set thumbs window icon")

            if self.type == "history":
                title = _("Variety History")
            elif self.type == "downloads":
                title = _("Variety Recent Downloads")
            else:
                title = _("Variety Images")

            self.thumbs_window.set_title(title)
            self.thumbs_window.connect("clicked", self.on_click)

            def _on_close(window, event):
                self.hide(force=True)

            self.thumbs_window.connect("delete-event", _on_close)

            self.mark_active(self.active_file, self.active_position)

            self.thumbs_window.start(self.images)
Пример #2
0
    def browse(self, widget=None):
        try:
            self.chooser = Gtk.FileChooserDialog(
                _("Choose a folder"),
                parent=self.button.get_toplevel(),
                action=Gtk.FileChooserAction.SELECT_FOLDER,
                buttons=[
                    _("Cancel"), Gtk.ResponseType.CANCEL,
                    _("OK"), Gtk.ResponseType.OK
                ])
            self.chooser.set_filename(self.folder)
            self.chooser.set_select_multiple(False)
            self.chooser.set_local_only(False)

            if self.chooser.run() == Gtk.ResponseType.OK:
                self.set_folder(_u(self.chooser.get_filename()))
                try:
                    if self.on_change:
                        self.on_change()
                except Exception:
                    logger.exception(
                        lambda: "Exception during FolderChooser on_change:")
        finally:
            if self.chooser:
                try:
                    self.chooser.destroy()
                    self.chooser = None
                except Exception:
                    logger.exception(
                        lambda: "Exception during FolderChooser destroying:")
Пример #3
0
    def initialize_thumbs_window(self, gdk_thread=False):
        try:
            if not gdk_thread:
                Gdk.threads_enter()
            options = self.load_options()
            self.thumbs_window = ThumbsWindow(
                screen=self.screen, position=options.position, breadth=options.breadth)
            try:
                icon = varietyconfig.get_data_file("media", "variety.svg")
                self.thumbs_window.set_icon_from_file(icon)
            except Exception:
                logger.exception(lambda: "Could not set thumbs window icon")

            if self.type == "history":
                title = _("Variety History")
            elif self.type == "downloads":
                title = _("Variety Recent Downloads")
            else:
                title = _("Variety Images")

            self.thumbs_window.set_title(title)
            self.thumbs_window.connect("clicked", self.on_click)
            def _on_close(window, event):
                self.hide(gdk_thread=True, force=True)
            self.thumbs_window.connect("delete-event", _on_close)

            self.mark_active(self.active_file, self.active_position)

            self.thumbs_window.start(self.images)
        finally:
            if not gdk_thread:
                Gdk.threads_leave()
Пример #4
0
    def validate(self, query):
        if not '/' in query:
            query = 'https://www.reddit.com/r/%s' % query
        else:
            if not query.startswith("http://") and not query.startswith("https://"):
                query = "https://" + query
            if not '//reddit.com' in query and not '//www.reddit.com' in query:
                return query, False, _("This does not seem to be a valid Reddit URL")

        valid = RedditDownloader.validate(query, self.parent)
        return query, None if valid else _("We could not find any image submissions there.")
Пример #5
0
    def validate(self, query):
        if not "/" in query:
            query = "https://www.reddit.com/r/%s" % query
        else:
            if not query.startswith("http://") and not query.startswith(
                    "https://"):
                query = "https://" + query
            if not "//reddit.com" in query and not "//www.reddit.com" in query:
                return query, False, _(
                    "This does not seem to be a valid Reddit URL")

        valid = RedditDownloader.validate(query, self.parent)
        return (query, None if valid else
                _("We could not find any image submissions there."))
Пример #6
0
 def validate(self, url):
     if not url.startswith("http://") and not url.startswith("https://"):
         url = "https://" + url
     valid = MediaRssDownloader.validate(url)
     return url, None if valid else _(
         "This does not seem to be a valid Media RSS feed URL or there is no content there."
     )
Пример #7
0
 def get_info(cls):
     return {
         "name": "Goodreads",
         "description": _("Fetches quotes from Goodreads.com"),
         "author": "Peter Levi",
         "version": "0.1"
     }
Пример #8
0
 def get_info(cls):
     return {
         "name": "TheQuotationsPage.com",
         "description": _("Fetches quotes from TheQuotationsPage.com"),
         "author": "Peter Levi",
         "version": "0.1"
     }
Пример #9
0
 def get_info(cls):
     return {
         "name": "Goodreads",
         "description": _("Fetches quotes from Goodreads.com"),
         "author": "Peter Levi",
         "version": "0.1"
     }
Пример #10
0
 def _set_rating(widget, rating=rating):
     try:
         Util.set_rating(file, rating)
         main_window.on_rating_changed(file)
     except Exception:
         logger.exception(lambda: "Could not set EXIF rating")
         main_window.show_notification(_("Could not set EXIF rating"))
Пример #11
0
 def get_info(cls):
     return {
         "name": "TheQuotationsPage.com",
         "description": _("Fetches quotes from TheQuotationsPage.com"),
         "author": "Peter Levi",
         "version": "0.1"
     }
Пример #12
0
class BingDownloader(SimpleDownloader):
    DESCRIPTION = _("Bing Photo of the Day")
    BING_JSON_URL = (
        "https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=100&mkt=en-US"
    )  # n=100, but max 8 images are actually returned... Pity.

    @classmethod
    def get_info(cls):
        return {
            "name": "BingDownloader",
            "description": BingDownloader.DESCRIPTION,
            "author": "Peter Levi",
            "version": "0.1",
        }

    def get_source_type(self):
        return "bing"

    def get_description(self):
        return BingDownloader.DESCRIPTION

    def get_source_name(self):
        return "Bing"

    def get_source_location(self):
        return "https://www.bing.com/gallery/"

    def get_local_filename(self, url):
        return parse_qs(urlparse(url).query)["id"][0]

    def fill_queue(self):
        queue = []
        s = Util.fetch_json(BingDownloader.BING_JSON_URL)
        for item in s["images"]:
            try:
                if not item["wp"]:
                    # not marked as a wallpaper
                    continue

                image_url = "https://www.bing.com" + item["url"]
                filename = item["url"].split("/")[-1]
                name = filename[0 : filename.find("_EN")]
                src_url = "https://www.bing.com/gallery/#images/%s" % name
                try:
                    date = datetime.strptime(item["startdate"], "%Y%m%d").strftime("%Y-%m-%d")
                except:
                    date = item["startdate"]
                extra_metadata = {
                    "sourceType": "bing",
                    "sfwRating": 100,
                    "headline": "Bing Photo of the Day, %s" % date,
                    "description": item["copyright"],
                }
                queue.append((src_url, image_url, extra_metadata))
            except:
                logger.exception(lambda: "Could not process an item in the Bing json result")

        random.shuffle(queue)
        return queue
Пример #13
0
 def get_info(cls):
     return {
         "name": "LDSInspiration",
         "description": _("Fetches quotes from lds.org quotes RSS feed.\n"
                          "Does not support searching by tags, authors, or topics...yet."),
         "author": "Andrew Payne",
         "version": "0.2"
     }
Пример #14
0
 def get_info(cls):
     return {
         "name": "QuotesDaddy",
         "description": _("Fetches quotes from QuotesDaddy's daily quotes RSS feed.\n"
                          "Does not support searching by tags or authors."),
         "author": "Peter Levi",
         "version": "0.1"
     }
Пример #15
0
 def get_info(cls):
     return {
         "name": "QuotesDaddy",
         "description": _("Fetches quotes from QuotesDaddy's daily quotes RSS feed.\n"
                          "Does not support searching by tags or authors."),
         "author": "Peter Levi",
         "version": "0.1"
     }
Пример #16
0
    def create_rating_menu(file, main_window):
        def _set_rating_maker(rating):
            def _set_rating(widget, rating=rating):
                try:
                    Util.set_rating(file, rating)
                    main_window.on_rating_changed(file)
                except Exception:
                    logger.exception(lambda: "Could not set EXIF rating")
                    main_window.show_notification(
                        _("Could not set EXIF rating"))

            return _set_rating

        try:
            actual_rating = Util.get_rating(file)
        except Exception:
            actual_rating = None

        rating_menu = Gtk.Menu()
        for rating in range(5, 0, -1):
            item = Gtk.CheckMenuItem("\u2605" * rating)
            item.set_draw_as_radio(True)
            item.set_active(actual_rating == rating)
            item.set_sensitive(not item.get_active())
            item.connect("activate", _set_rating_maker(rating))
            rating_menu.append(item)

        rating_menu.append(Gtk.SeparatorMenuItem.new())

        unrated_item = Gtk.CheckMenuItem(_("Unrated"))
        unrated_item.set_draw_as_radio(True)
        unrated_item.set_active(actual_rating is None or actual_rating == 0)
        unrated_item.set_sensitive(not unrated_item.get_active())
        unrated_item.connect("activate", _set_rating_maker(None))
        rating_menu.append(unrated_item)

        rejected_item = Gtk.CheckMenuItem(_("Rejected"))
        rejected_item.set_draw_as_radio(True)
        rejected_item.set_active(actual_rating is not None
                                 and actual_rating < 0)
        rejected_item.set_sensitive(not rejected_item.get_active())
        rejected_item.connect("activate", _set_rating_maker(-1))
        rating_menu.append(rejected_item)

        rating_menu.show_all()
        return rating_menu
Пример #17
0
 def _set_rating(widget, rating=rating):
     try:
         Util.set_rating(file, rating)
         main_window.on_rating_changed(file)
     except Exception:
         logger.exception(lambda: "Could not set EXIF rating")
         main_window.show_notification(
             _("Could not set EXIF rating"))
Пример #18
0
    def ok_thread(self):
        search = ""

        if len(self.ui.tags.get_text().strip()):
            search +=  "tags:" + ','.join([urllib.quote_plus(t.strip()) for t in self.ui.tags.get_text().split(',')]) + ";"

        if len(self.ui.text.get_text().strip()):
            search +=  "text:" + urllib.quote_plus(self.ui.text.get_text().strip()) +";"

        self.error = ""

        user_url = self.ui.user_url.get_text().strip()
        if len(user_url) > 0:
            self.show_spinner()
            u = FlickrDownloader.obtain_userid(user_url)
            if u[0]:
                search += "user:"******"http://", "").replace("https://", "") + ";"
                search += "user_id:" + u[2] + ";"
            else:
                self.error = self.error + "\n" + u[1]

        group_url = self.ui.group_url.get_text().strip()
        if len(group_url) > 0:
            self.show_spinner()
            g = FlickrDownloader.obtain_groupid(group_url)
            if g[0]:
                search += "group:" + self.ui.group_url.get_text().replace("http://", "").replace("https://", "") + ";"
                search += "group_id:" + g[2]
            else:
                self.error = self.error + "\n" + g[1]

        if not len(self.error) and len(search) > 0:
            self.show_spinner()
            if FlickrDownloader.count_search_results(search) <= 0:
                self.error = _("No images found")

        try:
            Gdk.threads_enter()

            self.ui.buttonbox.set_sensitive(True)
            self.ui.spinner.stop()
            self.ui.spinner.set_visible(False)
            self.ui.message.set_visible(False)

            if len(self.error) > 0:
                self.ui.error.set_label(self.error)
                for entry in (self.ui.text, self.ui.tags, self.ui.user_url, self.ui.group_url):
                    if entry.get_text().strip():
                        entry.grab_focus()
                        break
            else:
                if len(search):
                    self.parent.on_add_dialog_okay(Options.SourceType.FLICKR, search, self.edited_row)
                self.destroy()

        finally:
            Gdk.threads_leave()
Пример #19
0
 def get_info(cls):
     return {
         "name": "Local text files",
         "description": _("Displays quotes, defined in local text files.\n"
                          "Put your own txt files in: ~/.config/variety/pluginconfig/quotes/.\n"
                          "The file format is:\n\nquote -- author\n.\nsecond quote -- another author\n.\netc...\n\n"
                          "Example: http://rvelthuis.de/zips/quotes.txt"),
         "author": "Peter Levi",
         "version": "0.1"
     }
Пример #20
0
    def create_rating_menu(file, main_window):
        def _set_rating_maker(rating):
            def _set_rating(widget, rating=rating):
                try:
                    Util.set_rating(file, rating)
                    main_window.on_rating_changed(file)
                except Exception:
                    logger.exception(lambda: "Could not set EXIF rating")
                    main_window.show_notification(_("Could not set EXIF rating"))
            return _set_rating

        try:
            actual_rating = Util.get_rating(file)
        except Exception:
            actual_rating = None

        rating_menu = Gtk.Menu()
        for rating in xrange(5, 0, -1):
            item = Gtk.CheckMenuItem(u"\u2605" * rating)
            item.set_draw_as_radio(True)
            item.set_active(actual_rating == rating)
            item.set_sensitive(not item.get_active())
            item.connect("activate", _set_rating_maker(rating))
            rating_menu.append(item)

        rating_menu.append(Gtk.SeparatorMenuItem.new())

        unrated_item = Gtk.CheckMenuItem(_("Unrated"))
        unrated_item.set_draw_as_radio(True)
        unrated_item.set_active(actual_rating is None or actual_rating == 0)
        unrated_item.set_sensitive(not unrated_item.get_active())
        unrated_item.connect("activate", _set_rating_maker(None))
        rating_menu.append(unrated_item)

        rejected_item = Gtk.CheckMenuItem(_("Rejected"))
        rejected_item.set_draw_as_radio(True)
        rejected_item.set_active(actual_rating is not None and actual_rating < 0)
        rejected_item.set_sensitive(not rejected_item.get_active())
        rejected_item.connect("activate", _set_rating_maker(-1))
        rating_menu.append(rejected_item)

        rating_menu.show_all()
        return rating_menu
Пример #21
0
 def get_info(cls):
     return {
         "name": "Local text files",
         "description": _("Displays quotes, defined in local text files.\n"
                          "Put your own txt files in: ~/.config/variety/pluginconfig/quotes/.\n"
                          "The file format is:\n\nquote -- author\n.\nsecond quote -- another author\n.\netc...\n\n"
                          "Example: http://rvelthuis.de/zips/quotes.txt"),
         "author": "Peter Levi",
         "version": "0.1"
     }
Пример #22
0
    def on_facebook_auth(self, params):
        try:
            if self.hash != params["hash"][0]:
                return  # user has reloaded an old redirect page, ignore it

            self.token = params['access_token'][0]
            self.token_expire = params['expires_in'][0]  # Should be equal to 0, don't expire

            # Save token to file
            with open(self.token_file, 'w') as token_file:
                token_file.write(self.token)
                token_file.close()

            if self.on_success:
                self.parent.show_notification(_("Authorization successful"), _("Publishing..."))
                self.on_success(self, self.token)
        except Exception:
            logger.exception(lambda: "Facebook auth failed")
            if self.on_failure:
                self.on_failure(self, "authorize", _("Authorization failed"))
Пример #23
0
class EarthDownloader(SimpleDownloader):
    DESCRIPTION = _("World Sunlight Map - live wallpaper from Die.net")

    @classmethod
    def get_info(cls):
        return {
            "name": "EarthDownloader",
            "description": EarthDownloader.DESCRIPTION,
            "author": "Peter Levi",
            "version": "0.1"
        }

    def get_source_type(self):
        return "earth"

    def get_description(self):
        return EarthDownloader.DESCRIPTION

    def get_source_name(self):
        return "Die.net"

    def get_folder_name(self):
        return "Earth"

    def get_source_location(self):
        return EARTH_ORIGIN_URL

    def get_refresh_interval_seconds(self):
        return 15 * 60

    def download_one(self):
        logger.info(
            lambda: "Downloading world sunlight map from " + EARTH_ORIGIN_URL)
        downloaded = self.save_locally(
            EARTH_ORIGIN_URL,
            EARTH_IMAGE_URL,
            force_download=True,
            extra_metadata={'headline': 'World Sunlight Map'},
        )
        final_path = os.path.join(self.target_folder, EARTH_FILENAME)
        shutil.move(downloaded, final_path)
        for f in os.listdir(self.target_folder):
            if f != EARTH_FILENAME and f.lower().endswith(".jpg"):
                os.unlink(os.path.join(self.target_folder, f))
        return final_path

    def fill_queue(self):
        """ Not needed here """
        return []

    def on_variety_start_complete(self):
        if not os.path.exists(os.path.join(self.target_folder,
                                           EARTH_FILENAME)):
            self.download_one()
Пример #24
0
    def browse(self, widget=None):
        try:
            self.chooser = Gtk.FileChooserDialog(
                _("Choose a folder"), parent=self.button.get_toplevel(), action=Gtk.FileChooserAction.SELECT_FOLDER,
                buttons=[_("Cancel"), Gtk.ResponseType.CANCEL, _("OK"), Gtk.ResponseType.OK])
            self.chooser.set_filename(self.folder)
            self.chooser.set_select_multiple(False)
            self.chooser.set_local_only(False)

            if self.chooser.run() == Gtk.ResponseType.OK:
                self.set_folder(_u(self.chooser.get_filename()))
                try:
                    if self.on_change:
                        self.on_change()
                except Exception:
                    logger.exception(lambda: "Exception during FolderChooser on_change:")
        finally:
            if self.chooser:
                try:
                    self.chooser.destroy()
                    self.chooser = None
                except Exception:
                    logger.exception(lambda: "Exception during FolderChooser destroying:")
Пример #25
0
class ChromeOSWallpapersDownloader(SimpleDownloader):
    DESCRIPTION = _("Chrome OS Wallpapers")

    @classmethod
    def get_info(cls):
        return {
            "name": "ChromeOsWallpapersDownloader",
            "description": ChromeOSWallpapersDownloader.DESCRIPTION,
            "author": "Peter Levi",
            "version": "0.1",
        }

    def get_description(self):
        return ChromeOSWallpapersDownloader.DESCRIPTION

    def get_source_type(self):
        return "chromeos"

    def get_source_name(self):
        return "Chrome OS Wallpapers"

    def get_source_location(self):
        return self.get_source_name()

    def fill_queue(self):
        manifest = Util.fetch_json(MANIFEST_URL)
        queue = manifest["wallpaper_list"]
        self.tags = manifest["tags"]
        random.shuffle(queue)
        return queue

    def download_queue_item(self, item):
        image_url = item["base_url"] + "_high_resolution.jpg"
        origin_url = item["dynamic_url"]
        extra_metadata = {}
        if "tags" in item:
            extra_metadata["keywords"] = [
                self.tags[str(tag)] for tag in item["tags"]
                if str(tag) in self.tags
            ]
        if "author" in item:
            extra_metadata["author"] = item["author"]
        if "author_website" in item:
            extra_metadata["authorURL"] = item["author_website"]

        return self.save_locally(origin_url,
                                 image_url,
                                 extra_metadata=extra_metadata)
Пример #26
0
class EarthviewDownloader(SimpleDownloader):
    DESCRIPTION = _("Google Earth View Wallpapers")
    ROOT_URL = "https://earthview.withgoogle.com/"

    @classmethod
    def get_info(cls):
        return {
            "name": "EarthviewDownloader",
            "description": EarthviewDownloader.DESCRIPTION,
            "author": "Peter Levi",
            "version": "0.1",
        }

    def get_description(self):
        return EarthviewDownloader.DESCRIPTION

    def get_source_type(self):
        return "earthview"

    def get_source_name(self):
        return "Earth View"

    def get_source_location(self):
        return self.ROOT_URL

    def fill_queue(self):
        queue = Util.fetch_json(DATA_URL)
        random.shuffle(queue)
        return queue

    def get_default_throttling(self):
        # throttle this source, as otherwise maps "overpower" all other types of images
        # with Variety's default settings, and we have no other way to control source "weights"
        return Throttling(min_download_interval=600, min_fill_queue_interval=0)

    def download_queue_item(self, item):
        region = item["Region"]
        filename = "{}{} (ID-{}).jpg".format(
            region + ", " if region and region != "-" else "", item["Country"],
            item["ID"])
        origin_url = EarthviewDownloader.ROOT_URL + str(item["ID"])
        image_url = item["Image URL"]
        if not image_url.startswith("http"):
            image_url = "https://" + image_url
        return self.save_locally(origin_url,
                                 image_url,
                                 local_filename=filename)
Пример #27
0
                    def _add_menuitem(rating):
                        menuitem = Gtk.ImageMenuItem(_(rating['label_long']))
                        menuitem.set_visible(True)

                        def _rate(*args, **kwargs):
                            self.parent.report_sfw_rating(file=None, rating=rating['rating'])

                        menuitem.connect("activate", _rate)
                        try:
                            menuitem.set_always_show_image(True)
                            image = Gtk.Image()
                            image.set_from_file(varietyconfig.get_data_file("media", "sfw-%s.svg" % rating['rating']))
                            menuitem.set_image(image)
                        except:
                            logger.exception(lambda: "Could not set image to NSFW menuitem:")
                        self.sfw_menu.append(menuitem)
                        self.rating_items.append(menuitem)
Пример #28
0
                    def _add_menuitem(rating):
                        menuitem = Gtk.ImageMenuItem(_(rating['label_long']))
                        menuitem.set_visible(True)

                        def _rate(*args, **kwargs):
                            self.parent.report_sfw_rating(file=None, rating=rating['rating'])

                        menuitem.connect("activate", _rate)
                        try:
                            menuitem.set_always_show_image(True)
                            image = Gtk.Image()
                            image.set_from_file(varietyconfig.get_data_file("media", "sfw-%s.svg" % rating['rating']))
                            menuitem.set_image(image)
                        except:
                            logger.exception(lambda: "Could not set image to NSFW menuitem:")
                        self.sfw_menu.append(menuitem)
                        self.rating_items.append(menuitem)
Пример #29
0
            def _gui_update(sfw_ratings):
                try:
                    def _add_menuitem(rating):
                        menuitem = Gtk.ImageMenuItem(_(rating['label_long']))
                        menuitem.set_visible(True)

                        def _rate(*args, **kwargs):
                            self.parent.report_sfw_rating(file=None, rating=rating['rating'])

                        menuitem.connect("activate", _rate)
                        try:
                            menuitem.set_always_show_image(True)
                            image = Gtk.Image()
                            image.set_from_file(varietyconfig.get_data_file("media", "sfw-%s.svg" % rating['rating']))
                            menuitem.set_image(image)
                        except:
                            logger.exception(lambda: "Could not set image to NSFW menuitem:")
                        self.sfw_menu.append(menuitem)
                        self.rating_items.append(menuitem)

                    map(_add_menuitem, reversed(sfw_ratings))

                    separator = Gtk.SeparatorMenuItem.new()
                    separator.set_visible(True)
                    self.sfw_menu.append(separator)

                    self.safe_mode = Gtk.CheckMenuItem(_("_Safe mode"))
                    self.safe_mode.set_visible(True)
                    self.safe_mode.set_active(self.parent.options.safe_mode)
                    self.safe_mode.set_use_underline(True)
                    self.safe_mode_handler_id = self.safe_mode.connect("toggled", self.parent.on_safe_mode_toggled)
                    self.sfw_menu.append(self.safe_mode)

                    self.sfw_menu_item.set_sensitive(True)

                    self.parent.update_indicator()
                except Exception:
                    logger.exception(lambda: 'Oops, could not populate NSFW menu:')
Пример #30
0
            def _gui_update(sfw_ratings):
                try:
                    def _add_menuitem(rating):
                        menuitem = Gtk.ImageMenuItem(_(rating['label_long']))
                        menuitem.set_visible(True)

                        def _rate(*args, **kwargs):
                            self.parent.report_sfw_rating(file=None, rating=rating['rating'])

                        menuitem.connect("activate", _rate)
                        try:
                            menuitem.set_always_show_image(True)
                            image = Gtk.Image()
                            image.set_from_file(varietyconfig.get_data_file("media", "sfw-%s.svg" % rating['rating']))
                            menuitem.set_image(image)
                        except:
                            logger.exception(lambda: "Could not set image to NSFW menuitem:")
                        self.sfw_menu.append(menuitem)
                        self.rating_items.append(menuitem)

                    map(_add_menuitem, reversed(sfw_ratings))

                    separator = Gtk.SeparatorMenuItem.new()
                    separator.set_visible(True)
                    self.sfw_menu.append(separator)

                    self.safe_mode = Gtk.CheckMenuItem(_("_Safe mode"))
                    self.safe_mode.set_visible(True)
                    self.safe_mode.set_active(self.parent.options.safe_mode)
                    self.safe_mode.set_use_underline(True)
                    self.safe_mode_handler_id = self.safe_mode.connect("toggled", self.parent.on_safe_mode_toggled)
                    self.sfw_menu.append(self.safe_mode)

                    self.sfw_menu_item.set_sensitive(True)

                    self.parent.update_indicator()
                except Exception:
                    logger.exception(lambda: 'Oops, could not populate NSFW menu:')
Пример #31
0
class DesktopprDownloader(SimpleDownloader):
    DESCRIPTION = _("Random wallpapers from Desktoppr.co")

    @classmethod
    def get_info(cls):
        return {
            "name": "DesktopprDownloader",
            "description": DesktopprDownloader.DESCRIPTION,
            "author": "Peter Levi",
            "version": "0.1",
        }

    def get_source_type(self):
        return "desktoppr"

    def get_description(self):
        return DesktopprDownloader.DESCRIPTION

    def get_source_name(self):
        return "Desktoppr.co"

    def get_folder_name(self):
        return "Desktoppr"

    def fill_queue(self):
        response = Util.fetch_json(
            "https://api.desktoppr.co/1/wallpapers/random")

        if response["response"]["review_state"] != "safe":
            logger.info(
                lambda: "Non-safe image returned by Desktoppr, skipping")
            return None

        origin_url = response["response"]["url"]
        image_url = response["response"]["image"]["url"]
        return [QueueItem(origin_url, image_url, {})]
Пример #32
0
    def fetch(
        url,
        to_folder,
        origin_url=None,
        source_type=None,
        source_location=None,
        source_name=None,
        extra_metadata=None,
        progress_reporter=lambda a, b: None,
        verbose=True,
    ):
        reported = verbose
        try:
            logger.info(lambda: "Trying to fetch URL %s to %s " % (url, to_folder))
            if verbose:
                progress_reporter(_("Fetching"), url)

            if url.startswith("javascript:"):
                if verbose:
                    progress_reporter(_("Not an image"), url)
                return None

            if url.find("://") < 0:
                url = "file://" + url

            r = Util.request(url, stream=True)
            if not "content-type" in r.headers:
                logger.info(lambda: "Unknown content-type for url " + url)
                if verbose:
                    progress_reporter(_("Not an image"), url)
                return None

            ct = r.headers["content-type"]
            if not ct.startswith("image/"):
                logger.info(lambda: "Unsupported content-type for url " + url + ": " + ct)
                if verbose:
                    progress_reporter(_("Not an image"), url)
                return None

            local_name = Util.get_local_name(r.url)
            if "content-disposition" in r.headers:
                cd = r.headers["content-disposition"]
                cd_name = ImageFetcher.extract_filename_from_content_disposition(cd)
                if cd_name:
                    local_name = cd_name

            filename = os.path.join(to_folder, local_name)
            if os.path.exists(filename):
                m = Util.read_metadata(filename)
                if m and m.get("imageURL") == url:
                    logger.info(lambda: "Local file already exists (%s)" % filename)
                    return filename
                else:
                    logger.info(
                        lambda: "File with same name already exists, but from different imageURL; renaming new download"
                    )
                    filename = Util.find_unique_name(filename)

            logger.info(lambda: "Fetching to " + filename)
            if not reported:
                reported = True
                progress_reporter(_("Fetching"), url)

            local_filepath_partial = filename + ".partial"
            with open(local_filepath_partial, "wb") as f:
                Util.request_write_to(r, f)

            try:
                img = Image.open(local_filepath_partial)
            except Exception:
                progress_reporter(_("Not an image"), url)
                Util.safe_unlink(local_filepath_partial)
                return None

            if img.size[0] < 400 or img.size[1] < 400:
                # too small - delete and do not use
                progress_reporter(_("Image too small, ignoring it"), url)
                Util.safe_unlink(local_filepath_partial)
                return None

            metadata = {
                "sourceType": source_type or "fetched",
                "sourceName": source_name or "Fetched",
                "sourceURL": origin_url or url,
                "imageURL": url,
            }
            if source_location:
                metadata["sourceLocation"] = source_location
            metadata.update(extra_metadata or {})
            Util.write_metadata(local_filepath_partial, metadata)

            os.rename(local_filepath_partial, filename)
            logger.info(lambda: "Fetched %s to %s." % (url, filename))
            return filename

        except Exception as e:
            # pylint: disable=no-member
            logger.exception(lambda: "Fetch failed for URL " + url)
            if reported:
                if isinstance(e, HTTPError) and e.response.status_code in (403, 404):
                    progress_reporter(
                        _("Sorry, got %s error...") % str(e.response.status_code),
                        _("This means the link is no longer valid"),
                    )
                else:
                    progress_reporter(
                        _("Fetch failed for some reason"),
                        _(
                            "To get more information, please run Variety from terminal with -v option and retry the action"
                        ),
                    )
            return None
Пример #33
0
    def get_one_quote(self):
        keywords = []
        if self.parent.options.quotes_tags.strip():
            keywords = self.parent.options.quotes_tags.split(",")
        authors = []
        if self.parent.options.quotes_authors.strip():
            authors = self.parent.options.quotes_authors.split(",")

        category, search = ("random", "")
        if keywords or authors:
            category, search = random.choice(
                [("keyword", k) for k in keywords] + [("author", a) for a in authors]
            )

        plugins = list(self.plugins)
        if not plugins:
            self.parent.show_notification(
                _("No quote plugins"), _("There are no quote plugins installed")
            )
            raise Exception("No quote plugins")
        if keywords or authors:
            plugins = [p for p in self.plugins if p["plugin"].supports_search()]
            if not plugins:
                self.parent.show_notification(
                    _("No suitable quote plugins"),
                    _("You have no quote plugins which support searching by keywords and authors"),
                )
                raise Exception("No quote plugins")

        error_plugins = []
        count_plugins = len(plugins)
        while self.running and self.parent.options.quotes_enabled:
            if not plugins:
                if (
                    time.time() - self.last_error_notification_time > 3600
                    and len(self.prepared) + len(self.used) < 5
                ):
                    self.last_error_notification_time = time.time()
                    if len(error_plugins) == count_plugins:
                        self.parent.show_notification(
                            _("Could not fetch quotes"),
                            _("Quotes services may be down, we will continue trying"),
                        )
                    else:
                        self.parent.show_notification(
                            _("Could not find quotes"),
                            _("Maybe you are searching for something very obscure?"),
                        )
                return None

            plugin = random.choice(plugins)
            plugin_name = plugin["info"]["name"]
            self.cache.setdefault(plugin_name, {"random": {}, "keyword": {}, "author": {}})
            self.cache[plugin_name][category].setdefault(search, {})
            cached = self.cache[plugin_name][category][search]

            if not cached:
                try:
                    if category == "random":
                        quotes = plugin["plugin"].get_random()
                    elif category == "keyword":
                        quotes = plugin["plugin"].get_for_keyword(search)
                    elif category == "author":
                        quotes = plugin["plugin"].get_for_author(search)
                    else:
                        raise RuntimeError("Unknown category")

                    if quotes:
                        for q in quotes:
                            if len(q["quote"]) < self.parent.options.quotes_max_length:
                                cached[q["quote"]] = q

                except Exception:
                    logger.exception(lambda: "Exception in quote plugin")
                    plugins.remove(plugin)
                    error_plugins.append(plugin)
                    continue

            if not cached:
                logger.warning(lambda: "No quotes for '%s' for plugin %s" % (search, plugin_name))
                plugins.remove(plugin)
                continue

            quote = random.choice(list(cached.values()))
            del cached[quote["quote"]]
            if not cached:
                del cached

            return quote
Пример #34
0
    def get_one_quote(self):
        keywords = []
        if self.parent.options.quotes_tags.strip():
            keywords = self.parent.options.quotes_tags.split(",")
        authors = []
        if self.parent.options.quotes_authors.strip():
            authors = self.parent.options.quotes_authors.split(",")

        category, search = ("random", "")
        if keywords or authors:
            category, search = random.choice(
                map(lambda k: ("keyword", k), keywords) + map(lambda a: ("author", a), authors))

        plugins = list(self.plugins)
        if not plugins:
            self.parent.show_notification(_("No quote plugins"), _("There are no quote plugins installed"))
            raise Exception("No quote plugins")
        if keywords or authors:
            plugins = [p for p in self.plugins if p["plugin"].supports_search()]
            if not plugins:
                self.parent.show_notification(
                    _("No suitable quote plugins"),
                    _("You have no quote plugins which support searching by keywords and authors"))
                raise Exception("No quote plugins")

        error_plugins = []
        count_plugins = len(plugins)
        while self.running and self.parent.options.quotes_enabled:
            if not plugins:
                if time.time() - self.last_error_notification_time > 3600 and len(self.prepared) + len(
                        self.used) < 5:
                    self.last_error_notification_time = time.time()
                    if len(error_plugins) == count_plugins:
                        self.parent.show_notification(
                            _("Could not fetch quotes"),
                            _("Quotes services may be down, we will continue trying"))
                    else:
                        self.parent.show_notification(
                            _("Could not find quotes"),
                            _("Maybe you are searching for something very obscure?"))
                return None

            plugin = random.choice(plugins)
            plugin_name = plugin["info"]["name"]
            self.cache.setdefault(plugin_name, {"random": {}, "keyword": {}, "author": {}})
            self.cache[plugin_name][category].setdefault(search, {})
            cached = self.cache[plugin_name][category][search]

            if not cached:
                try:
                    if category == "random":
                        quotes = plugin["plugin"].get_random()
                    elif category == "keyword":
                        quotes = plugin["plugin"].get_for_keyword(search)
                    elif category == "author":
                        quotes = plugin["plugin"].get_for_author(search)
                    else:
                        raise RuntimeError("Unknown category")

                    for q in quotes:
                        if len(q["quote"]) < 250:
                            cached[q["quote"]] = q

                except Exception:
                    logger.exception(lambda: "Exception in quote plugin")
                    plugins.remove(plugin)
                    error_plugins.append(plugin)
                    continue

            if not cached:
                logger.warning(lambda: "No quotes for '%s' for plugin %s" % (search, plugin_name))
                plugins.remove(plugin)
                continue

            quote = random.choice(cached.values())
            del cached[quote["quote"]]
            if not cached:
                del cached

            return quote
Пример #35
0
 def validate(self, query):
     valid = WallhavenDownloader.validate(query)
     return query, None if valid else _("No images found")
Пример #36
0
 def validate(self, query):
     valid = WallhavenDownloader.validate(query)
     return query, None if valid else _("No images found")
Пример #37
0
 def validate(self, url):
     if not url.startswith("http://") and not url.startswith("https://"):
         url = "https://" + url
     valid = MediaRssDownloader.validate(url)
     return url, None if valid else _("This does not seem to be a valid Media RSS feed URL or there is no content there.")
Пример #38
0
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranties of
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
# PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see <http://www.gnu.org/licenses/>.
### END LICENSE

from variety import _

FILTERS = {
    "Keep original": _("Keep original"),
    "Grayscale": _("Grayscale"),
    "Heavy blur": _("Heavy blur"),
    "Soft blur": _("Soft blur"),
    "Oil painting": _("Oil painting"),
    "Pointilism": _("Pointilism"),
    "Pixellate": _("Pixellate"),
}

SOURCES = {
    "favorites": ("The Favorites folder", _("The Favorites folder")),
    "fetched": ("The Fetched folder", _("The Fetched folder")),
    "recommended": (
        "Recommended by Variety. Adapts to your taste as you mark images as favorite or trash.",
        _("Recommended by Variety. Adapts to your taste as you mark images as favorite or trash."
          ),
Пример #39
0
    def fetch(url, to_folder, origin_url=None,
              source_type=None, source_location=None, source_name=None,
              extra_metadata={},
              progress_reporter=lambda a, b: None, verbose=True):
        reported = verbose
        try:
            logger.info(lambda: "Trying to fetch URL %s to %s " % (url, to_folder))
            if verbose:
                progress_reporter(_("Fetching"), url)

            if url.startswith('javascript:'):
                if verbose:
                    progress_reporter(_("Not an image"), url)
                return None

            if url.find('://') < 0:
                url = "file://" + url

            r = Util.request(url, stream=True)
            if not "content-type" in r.headers:
                logger.info(lambda: "Unknown content-type for url " + url)
                if verbose:
                    progress_reporter(_("Not an image"), url)
                return None

            ct = r.headers["content-type"]
            if not ct.startswith("image/"):
                logger.info(lambda: "Unsupported content-type for url " + url + ": " + ct)
                if verbose:
                    progress_reporter(_("Not an image"), url)
                return None

            local_name = Util.get_local_name(r.url)
            if "content-disposition" in r.headers:
                cd = r.headers["content-disposition"]
                cd_name = ImageFetcher.extract_filename_from_content_disposition(cd)
                if cd_name:
                    local_name = cd_name

            filename = os.path.join(to_folder, local_name)
            if os.path.exists(filename):
                m = Util.read_metadata(filename)
                if m and m.get("imageURL") == url:
                    logger.info(lambda: "Local file already exists (%s)" % filename)
                    return filename
                else:
                    logger.info(lambda:
                        "File with same name already exists, but from different imageURL; renaming new download")
                    filename = Util.find_unique_name(filename)
                    local_name = os.path.basename(filename)

            logger.info(lambda: "Fetching to " + filename)
            if not reported:
                reported = True
                progress_reporter(_("Fetching"), url)

            with open(filename, 'wb') as f:
                Util.request_write_to(r, f)

            try:
                img = Image.open(filename)
            except Exception:
                progress_reporter(_("Not an image"), url)
                os.unlink(filename)
                return None

            if img.size[0] < 400 or img.size[1] < 400:
                # too small - delete and do not use
                progress_reporter(_("Image too small, ignoring it"), url)
                os.unlink(filename)
                return None

            metadata = {"sourceType": source_type or 'fetched',
                        "sourceName": source_name or "Fetched",
                        "sourceURL": origin_url or url,
                        "imageURL": url}
            if source_location:
                metadata["sourceLocation"] = source_location
            metadata.update(extra_metadata)
            Util.write_metadata(filename, metadata)

            logger.info(lambda: "Fetched %s to %s." % (url, filename))

            return filename

        except Exception, e:
            logger.exception(lambda: "Fetch failed for URL " + url)
            if reported:
                if isinstance(e, HTTPError) and e.response.status_code in (403, 404):
                    progress_reporter(
                        _("Sorry, got %s error...") % str(e.response.status_code),
                        _("This means the link is no longer valid"))
                else:
                    progress_reporter(
                        _("Fetch failed for some reason"),
                        _("To get more information, please run Variety from terminal with -v option and retry the action"))
            return None
Пример #40
0
class APODDownloader(SimpleDownloader):
    DESCRIPTION = _("NASA Astro Pic of the Day")
    ROOT_URL = "http://apod.nasa.gov/apod/"

    @classmethod
    def get_info(cls):
        return {
            "name": "APODDownloader",
            "description": APODDownloader.DESCRIPTION,
            "author": "Peter Levi",
            "version": "0.1"
        }

    def get_description(self):
        return APODDownloader.DESCRIPTION

    def get_source_type(self):
        return "apod"

    def get_source_name(self):
        return "NASA Astro Pic of the Day"

    def get_folder_name(self):
        return "nasa_apod"

    def get_source_location(self):
        return self.ROOT_URL

    def fill_queue(self):
        logger.info(lambda: "Filling APOD queue from Archive")

        s = Util.html_soup(self.ROOT_URL + "archivepix.html")
        urls = [
            self.ROOT_URL + x["href"] for x in s.findAll("a")
            if x["href"].startswith("ap") and x["href"].endswith(".html")
        ]
        urls = urls[:730]  # leave only last 2 years' pics
        urls = [x for x in urls if not self.is_in_banned(x)]

        queue = urls[:3]  # always put the latest 3 first
        urls = urls[3:]
        random.shuffle(urls)  # shuffle the rest
        queue.extend(urls)
        return queue

    def download_queue_item(self, queue_item):
        origin_url = queue_item
        logger.info(lambda: "APOD URL: " + origin_url)

        s = Util.html_soup(origin_url)
        img_url = None
        try:
            link = s.find("img").parent["href"]
            if link.startswith("image/"):
                img_url = self.ROOT_URL + link
                logger.info(lambda: "Image URL: " + img_url)
        except Exception:
            pass

        if img_url:
            return self.save_locally(origin_url,
                                     img_url,
                                     source_location=self.ROOT_URL)
        else:
            logger.info(lambda: "No image url found for this APOD URL")
            return None
Пример #41
0
    def create_menu(self, window):
        self.menu = Gtk.Menu()

        if not Util.is_unity():
            self.next_main = Gtk.MenuItem(_("_Next"))
            self.next_main.set_use_underline(True)
            self.next_main.connect("activate", window.next_wallpaper)
            self.menu.append(self.next_main)

            self.prev_main = Gtk.MenuItem(_("_Previous"))
            self.prev_main.set_use_underline(True)
            self.prev_main.connect("activate", window.prev_wallpaper)
            self.menu.append(self.prev_main)

            self.menu.append(Gtk.SeparatorMenuItem.new())

        self.file_label = Gtk.MenuItem(_("Current desktop wallpaper"))
        self.file_label.connect("activate", window.open_file)
        self.menu.append(self.file_label)

        self.show_origin = Gtk.MenuItem(_("Show origin"))
        self.show_origin.connect("activate", window.on_show_origin)
        self.show_origin.set_sensitive(False)
        self.menu.append(self.show_origin)

        self.show_author = Gtk.MenuItem("Show author")
        self.show_author.connect("activate", window.on_show_author)
        self.show_author.set_sensitive(False)
        self.show_author.set_visible(False)
        self.menu.append(self.show_author)

        self.copy_to_favorites = Gtk.MenuItem(_("Copy to _Favorites"))
        self.copy_to_favorites.set_use_underline(True)
        self.copy_to_favorites.connect("activate", window.copy_to_favorites)
        self.menu.append(self.copy_to_favorites)

        self.move_to_favorites = Gtk.MenuItem(_("Move to Favorites"))
        self.move_to_favorites.set_use_underline(True)
        self.move_to_favorites.connect("activate", window.move_to_favorites)
        self.move_to_favorites.set_visible(False)
        self.menu.append(self.move_to_favorites)

        self.trash = Gtk.MenuItem(_("Delete to _Trash"))
        self.trash.set_use_underline(True)
        self.trash.connect("activate", window.move_to_trash)
        self.menu.append(self.trash)

        self.menu.append(Gtk.SeparatorMenuItem.new())

        self.image_menu = Gtk.Menu()

        self.next = Gtk.MenuItem(_("_Next"))
        self.next.set_use_underline(True)
        self.next.connect("activate", window.next_wallpaper)
        self.image_menu.append(self.next)

        self.prev = Gtk.MenuItem(_("_Previous"))
        self.prev.set_use_underline(True)
        self.prev.connect("activate", window.prev_wallpaper)
        self.image_menu.append(self.prev)

        self.fast_forward = Gtk.MenuItem(_("_Next, skipping forward history"))
        self.fast_forward.set_use_underline(True)
        def _fast_forward(widget):
            window.next_wallpaper(widget, bypass_history=True)
        self.fast_forward.connect("activate", _fast_forward)
        self.image_menu.append(self.fast_forward)

        self.image_menu.append(Gtk.SeparatorMenuItem.new())
        self.scroll_tip = Gtk.MenuItem(_("Tip: Scroll wheel over icon\nfor Next and Previous"))
        self.scroll_tip.set_sensitive(False)
        self.image_menu.append(self.scroll_tip)

        self.image_menu.append(Gtk.SeparatorMenuItem.new())

        self.pause_resume = Gtk.MenuItem(_("Pause on current"))
        self.pause_resume.connect("activate", window.on_pause_resume)
        self.image_menu.append(self.pause_resume)

        self.image_item = Gtk.MenuItem(_("_Image"))
        self.image_item.set_use_underline(True)
        self.image_item.set_submenu(self.image_menu)
        self.menu.append(self.image_item)

        self.image_menu.append(Gtk.SeparatorMenuItem.new())

        self.focus = Gtk.MenuItem(_("Where is it from?"))
        self.focus.connect("activate", window.focus_in_preferences)
        self.image_menu.append(self.focus)

        self.no_effects = Gtk.CheckMenuItem(_("Show without effects"))
        self.no_effects.set_active(False)
        self.no_effects.set_use_underline(True)
        def _toggle_no_effects(widget=None):
            window.toggle_no_effects(self.no_effects.get_active())
        self.no_effects_handler_id = self.no_effects.connect("toggled", _toggle_no_effects)
        self.image_menu.append(self.no_effects)

        self.google_image = Gtk.MenuItem(_("Google Image Search"))
        self.google_image.connect("activate", window.google_image_search)
        self.image_menu.append(self.google_image)

        self.image_menu.append(Gtk.SeparatorMenuItem.new())

        self.publish_fb = Gtk.MenuItem(_("Share on Facebook"))
        self.publish_fb.connect("activate", window.publish_on_facebook)
        self.image_menu.append(self.publish_fb)

        self.rating_separator = Gtk.SeparatorMenuItem.new()
        self.image_menu.append(self.rating_separator)

        self.rating = Gtk.MenuItem(_("Set EXIF Rating"))
        self.image_menu.append(self.rating)

        # self.image_item = Gtk.MenuItem(_("_Image"))
        # self.image_item.set_use_underline(True)
        # self.image_item.set_submenu(self.image_menu)
        # self.menu.append(self.image_item)
        #
        self.sfw_menu = Gtk.Menu()
        threading.Timer(2, self.populate_sfw_menu).start()

        self.sfw_menu_item = Gtk.MenuItem(_("Report NSFW image"))
        self.sfw_menu_item.set_sensitive(False)
        self.sfw_menu_item.set_use_underline(True)
        self.sfw_menu_item.set_submenu(self.sfw_menu)
        self.menu.append(self.sfw_menu_item)

        self.quotes_menu = Gtk.Menu()

        self.next_quote = Gtk.MenuItem(_("_Next"))
        self.next_quote.set_use_underline(True)
        self.next_quote.connect("activate", window.next_quote)
        self.quotes_menu.append(self.next_quote)

        self.prev_quote = Gtk.MenuItem(_("_Previous"))
        self.prev_quote.set_use_underline(True)
        self.prev_quote.connect("activate", window.prev_quote)
        self.quotes_menu.append(self.prev_quote)

        self.fast_forward_quote = Gtk.MenuItem(_("_Next, skipping forward history"))
        self.fast_forward_quote.set_use_underline(True)
        def _fast_forward_quote(widget):
            window.next_quote(widget, bypass_history=True)
        self.fast_forward_quote.connect("activate", _fast_forward_quote)
        self.quotes_menu.append(self.fast_forward_quote)

        self.quotes_menu.append(Gtk.SeparatorMenuItem.new())

        self.quotes_pause_resume = Gtk.MenuItem(_("Pause on current"))
        self.quotes_pause_resume.connect("activate", window.on_quotes_pause_resume)
        self.quotes_menu.append(self.quotes_pause_resume)

        self.quotes_menu.append(Gtk.SeparatorMenuItem.new())

        self.quote_favorite = Gtk.MenuItem(_("Save to Favorites"))
        self.quote_favorite.set_use_underline(True)
        self.quote_favorite.connect("activate", window.quote_save_to_favorites)
        self.quotes_menu.append(self.quote_favorite)

        self.quote_view_favs = Gtk.MenuItem(_("View Favorites..."))
        self.quote_view_favs.set_use_underline(True)
        self.quote_view_favs.connect("activate", window.quote_view_favorites)
        self.quotes_menu.append(self.quote_view_favs)

        self.quotes_menu.append(Gtk.SeparatorMenuItem.new())

        self.quote_clipboard = Gtk.MenuItem(_("Copy to Clipboard"))
        self.quote_clipboard.set_use_underline(True)
        self.quote_clipboard.connect("activate", window.quote_copy_to_clipboard)
        self.quotes_menu.append(self.quote_clipboard)

        self.view_quote = Gtk.MenuItem()
        self.view_quote.set_use_underline(True)
        self.view_quote.connect("activate", window.view_quote)
        self.quotes_menu.append(self.view_quote)

        self.google_quote_text = Gtk.MenuItem(_("Google Quote"))
        self.google_quote_text.set_use_underline(True)
        self.google_quote_text.connect("activate", window.google_quote_text)
        self.quotes_menu.append(self.google_quote_text)

        self.google_quote_author = Gtk.MenuItem(_("Google Author"))
        self.google_quote_author.set_use_underline(True)
        self.google_quote_author.connect("activate", window.google_quote_author)
        self.quotes_menu.append(self.google_quote_author)

        self.quote_fb = Gtk.MenuItem(_("Share on Facebook"))
        self.quote_fb.set_use_underline(True)
        self.quote_fb.connect("activate", window.publish_quote_on_facebook)
        self.quotes_menu.append(self.quote_fb)

        self.quotes_menu.append(Gtk.SeparatorMenuItem.new())

        self.quotes_preferences = Gtk.MenuItem(_("Preferences..."))
        self.quotes_preferences.set_use_underline(True)
        def _quotes_prefs(widget=None):
            window.preferences_dialog.ui.notebook.set_current_page(1)
            window.on_mnu_preferences_activate()
        self.quotes_preferences.connect("activate", _quotes_prefs)
        self.quotes_menu.append(self.quotes_preferences)

        self.quotes_disable = Gtk.MenuItem(_("Turn off"))
        self.quotes_disable.set_use_underline(True)
        self.quotes_disable.connect("activate", window.disable_quotes)
        self.quotes_menu.append(self.quotes_disable)


        self.quotes = Gtk.MenuItem(_("_Quote"))
        self.quotes.set_use_underline(True)
        self.quotes.set_submenu(self.quotes_menu)
        self.menu.append(self.quotes)

        self.menu.append(Gtk.SeparatorMenuItem.new())

        self.history = Gtk.CheckMenuItem(_("_History"))
        self.history.set_active(False)
        self.history.set_use_underline(True)
        self.history_handler_id = self.history.connect("toggled", window.show_hide_history)
        self.menu.append(self.history)

        self.selector = Gtk.CheckMenuItem(_("_Wallpaper Selector"))
        self.selector.set_active(False)
        self.selector.set_use_underline(True)
        self.selector_handler_id = self.selector.connect("toggled", window.show_hide_wallpaper_selector)
        self.menu.append(self.selector)

        self.downloads = Gtk.CheckMenuItem(_("Recent _Downloads"))
        self.downloads.set_active(False)
        self.downloads.set_use_underline(True)
        self.downloads_handler_id = self.downloads.connect("toggled", window.show_hide_downloads)
        self.menu.append(self.downloads)

        try:
            from varietyslideshow import varietyslideshow
        except:
            logger.warning('Variety Slideshow is not installed. '
                           'Install it with "sudo apt-get install variety-slideshow", '
                           'read more here: http://peterlevi.com/variety/slideshow/')
        else:
            self.menu.append(Gtk.SeparatorMenuItem.new())

            self.slideshow = Gtk.MenuItem(_("Start Slideshow"))
            self.slideshow.connect("activate", window.on_start_slideshow)
            self.menu.append(self.slideshow)

        self.menu.append(Gtk.SeparatorMenuItem.new())

        self.preferences = Gtk.MenuItem(_("Preferences..."))
        self.preferences.connect("activate", window.on_mnu_preferences_activate)
        self.menu.append(self.preferences)

        self.about = Gtk.MenuItem(_("About"))
        self.about.connect("activate", window.on_mnu_about_activate)
        self.menu.append(self.about)

        self.donate = Gtk.MenuItem(_("Donate"))
        self.donate.connect("activate", window.on_mnu_donate_activate)
        self.menu.append(self.donate)

        self.quit = Gtk.MenuItem(_("Quit"))
        self.quit.connect("activate",window.on_quit)
        self.menu.append(self.quit)

        self.menu.show_all()
Пример #42
0
class UnsplashDownloader(SimpleDownloader):
    DESCRIPTION = _("High-resolution photos from Unsplash.com")

    CLIENT_ID = "072e5048dfcb73a8d9ad59fcf402471518ff8df725df462b0c4fa665f466515a"
    UTM_PARAMS = "?utm_source=Variety+Wallpaper+Changer&utm_medium=referral"

    rate_limiting_started_time = 0

    @classmethod
    def get_info(cls):
        return {
            "name": "UnsplashDownloader",
            "description": UnsplashDownloader.DESCRIPTION,
            "author": "Peter Levi",
            "version": "0.1",
        }

    def get_source_type(self):
        return "unsplash"

    def get_description(self):
        return UnsplashDownloader.DESCRIPTION

    def get_source_name(self):
        return "Unsplash.com"

    def get_source_location(self):
        return "https://unsplash.com"

    def get_folder_name(self):
        return "Unsplash"

    def get_server_options_key(self):
        return "unsplash_v2"

    def get_default_throttling(self):
        return Throttling(min_download_interval=600,
                          min_fill_queue_interval=1800)

    def fill_queue(self):
        if time.time() - UnsplashDownloader.rate_limiting_started_time < 3600:
            logger.info(
                lambda:
                "Unsplash queue empty, but rate limit reached, will try again later"
            )
            return []

        page = random.randint(1, 250)
        url = "https://api.unsplash.com/photos/?page=%d&per_page=30&client_id=%s" % (
            page,
            UnsplashDownloader.CLIENT_ID,
        )
        logger.info(lambda: "Filling Unsplash queue from " + url)

        r = Util.request(url)
        if int(r.headers.get("X-Ratelimit-Remaining", 1000000)) < 100:
            UnsplashDownloader.rate_limiting_started_time = time.time()

        queue = []
        for item in r.json():
            try:
                width = item["width"]
                height = item["height"]
                if self.is_size_inadequate(width, height):
                    continue

                image_url = item["urls"]["full"]
                origin_url = item["links"][
                    "html"] + UnsplashDownloader.UTM_PARAMS

                extra_metadata = {
                    "sourceType":
                    "unsplash",
                    "sfwRating":
                    100,
                    "author":
                    item["user"]["name"],
                    "authorURL":
                    item["user"]["links"]["html"] +
                    UnsplashDownloader.UTM_PARAMS,
                    "keywords": [
                        cat["title"].lower().strip()
                        for cat in item["categories"]
                    ],
                    "extraData": {
                        "unsplashDownloadLocation":
                        item["links"]["download_location"],
                        "unsplashDownloadReported":
                        False,
                    },
                }

                queue.append((origin_url, image_url, extra_metadata))
            except:
                logger.exception(
                    lambda: "Could not process an item from Unsplash")
                raise

        random.shuffle(queue)
        return queue

    def on_image_set_as_wallpaper(self, img, meta):
        extraData = meta.get("extraData", None)
        if not extraData:
            return

        download_loc = extraData.get("unsplashDownloadLocation")
        reported = extraData.get("unsplashDownloadReported")
        if download_loc and not reported:
            url = "{}?client_id={}".format(download_loc,
                                           UnsplashDownloader.CLIENT_ID)
            Util.fetch(url)
            meta["extraData"]["unsplashDownloadReported"] = True
            Util.write_metadata(img, meta)
Пример #43
0
    def create_menu(self, file):
        options = self.load_options()

        menu = Gtk.Menu()

        position_menu = Gtk.Menu()
        for p, v in ThumbsManager.POSITIONS.items():
            item = Gtk.CheckMenuItem(ThumbsManager.POSITION_NAMES[p])
            item.set_draw_as_radio(True)
            item.set_active(options.position == v)
            def _set_position(widget, pos=p): self.set_position(pos)
            item.connect("activate", _set_position)
            position_menu.append(item)

        size_menu = Gtk.Menu()
        for size in ThumbsManager.SIZES:
            item = Gtk.CheckMenuItem(str(size))
            item.set_draw_as_radio(True)
            item.set_active(options.breadth == size)
            def _set_size(widget, size=size): self.set_size(size)
            item.connect("activate", _set_size)
            size_menu.append(item)

        position_item = Gtk.MenuItem(_("Position"))
        position_item.set_submenu(position_menu)
        menu.append(position_item)

        size_item = Gtk.MenuItem(_("Size"))
        size_item.set_submenu(size_menu)
        menu.append(size_item)

        menu.append(Gtk.SeparatorMenuItem.new())

        open_file = Gtk.MenuItem(os.path.basename(file).replace('_', '__'))
        def _open_file(widget): self.parent.open_file(widget, file)
        open_file.connect("activate", _open_file)
        menu.append(open_file)

        open_folder = Gtk.MenuItem(_("Show Containing Folder"))
        def _open_folder(widget): self.parent.open_folder(widget, file)
        open_folder.connect("activate", _open_folder)
        menu.append(open_folder)

        info = Util.read_metadata(file)
        if info and "sourceURL" in info and "sourceName" in info:
            url = info["sourceURL"]
            source_name = info["sourceName"]
            if "Fetched" in source_name:
                label = _("Fetched: Show Origin")
            else:
                label = _("View at %s") % source_name

            if len(label) > 50:
                label = label[:50] + "..."

            show_origin = Gtk.MenuItem(label)

            def _show_origin(widget=None):
                logger.info(lambda: "Opening url: " + url)
                webbrowser.open_new_tab(url)

            show_origin.connect("activate", _show_origin)
            menu.append(show_origin)

        menu.append(Gtk.SeparatorMenuItem.new())
        rating_item  = Gtk.MenuItem(_("Set EXIF Rating"))
        rating_item.set_submenu(ThumbsManager.create_rating_menu(file, self.parent))
        if not os.access(file, os.W_OK):
            rating_item.set_sensitive(False)
        menu.append(rating_item)

        menu.append(Gtk.SeparatorMenuItem.new())

        self.copy_to_favorites = Gtk.MenuItem(_("Copy to _Favorites"))
        self.copy_to_favorites.set_use_underline(True)
        def _copy_to_favorites(widget):
            self.parent.copy_to_favorites(widget, file)
        self.copy_to_favorites.connect("activate", _copy_to_favorites)
        menu.append(self.copy_to_favorites)

        self.move_to_favorites = Gtk.MenuItem(_("Move to _Favorites"))
        self.move_to_favorites.set_use_underline(True)
        def _move_to_favorites(widget):
            self.parent.move_to_favorites(widget, file)
            self.remove_image(file)
        self.move_to_favorites.connect("activate", _move_to_favorites)
        self.move_to_favorites.set_visible(False)
        menu.append(self.move_to_favorites)

        trash_item = Gtk.MenuItem(_("Delete to _Trash"))
        trash_item.set_use_underline(True)
        def _trash(widget):
            self.parent.move_to_trash(widget, file)
        trash_item.connect("activate", _trash)
        menu.append(trash_item)

        focus = Gtk.MenuItem(_("Where is it from?"))
        focus.set_sensitive(self.parent.get_source(file) is not None)
        def _focus(widget):
            self.parent.focus_in_preferences(widget, file)
        focus.connect("activate", _focus)
        menu.append(focus)

        menu.append(Gtk.SeparatorMenuItem.new())

        def close(widget):
            self.hide(gdk_thread=True, force=True)
        close_item = Gtk.MenuItem(_("Close"))
        close_item.connect("activate", close)
        menu.append(close_item)

        menu.show_all()

        favs_op = self.parent.determine_favorites_operation(file)
        self.parent.update_favorites_menuitems(self, False, favs_op)

        return menu
Пример #44
0
class ThumbsManager:
    POSITIONS = {
        "bottom": ThumbsWindow.BOTTOM,
        "top": ThumbsWindow.TOP,
        "left": ThumbsWindow.LEFT,
        "right": ThumbsWindow.RIGHT,
    }

    POSITION_NAMES = {
        "bottom": _("Bottom"),
        "top": _("Top"),
        "left": _("Left"),
        "right": _("Right"),
    }

    R_POSITIONS = {v: k for (k, v) in POSITIONS.items()}

    SIZES = [x * 30 for x in range(2, 11)]

    UNLIMITED = "Unlimited"

    LIMITS = [10, 50, 100, 200, 500, 1000, 2000, UNLIMITED]

    class Options:
        def __init__(self):
            self.position = ThumbsWindow.BOTTOM
            self.breadth = 120
            self.limit = 200

    def __init__(self, parent):
        self.parent = parent
        self.thumbs_window = None
        self.show_thumbs_lock = threading.Lock()

        self.pinned = False
        self.images = []
        self.screen = None

        self.type = None
        self.folders = None

        self.active_file = None
        self.active_position = None

    def create_menu(self, file):
        options = self.load_options()

        menu = Gtk.Menu()

        position_menu = Gtk.Menu()
        for p, v in ThumbsManager.POSITIONS.items():
            item = Gtk.CheckMenuItem(ThumbsManager.POSITION_NAMES[p])
            item.set_draw_as_radio(True)
            item.set_active(options.position == v)

            def _set_position(widget, pos=p):
                self.set_position(pos)

            item.connect("activate", _set_position)
            position_menu.append(item)

        size_menu = Gtk.Menu()
        for size in ThumbsManager.SIZES:
            item = Gtk.CheckMenuItem(str(size))
            item.set_draw_as_radio(True)
            item.set_active(options.breadth == size)

            def _set_size(widget, size=size):
                self.set_size(size)

            item.connect("activate", _set_size)
            size_menu.append(item)

        limit_menu = Gtk.Menu()
        for limit in ThumbsManager.LIMITS:
            item = Gtk.CheckMenuItem(str(limit))
            item.set_draw_as_radio(True)
            item.set_active(options.limit == limit)

            def _set_limit(widget, limit=limit):
                self.set_limit(limit)

            item.connect("activate", _set_limit)
            limit_menu.append(item)

        position_item = Gtk.MenuItem(_("Position"))
        position_item.set_submenu(position_menu)
        menu.append(position_item)

        size_item = Gtk.MenuItem(_("Size"))
        size_item.set_submenu(size_menu)
        menu.append(size_item)

        limit_item = Gtk.MenuItem(_("Maximum Shown Images"))
        limit_item.set_submenu(limit_menu)
        menu.append(limit_item)

        menu.append(Gtk.SeparatorMenuItem.new())

        open_file = Gtk.MenuItem(os.path.basename(file).replace("_", "__"))

        def _open_file(widget):
            self.parent.open_file(widget, file)

        open_file.connect("activate", _open_file)
        menu.append(open_file)

        open_folder = Gtk.MenuItem(_("Show Containing Folder"))

        def _open_folder(widget):
            self.parent.open_folder(widget, file)

        open_folder.connect("activate", _open_folder)
        menu.append(open_folder)

        info = Util.read_metadata(file)
        if info and "sourceURL" in info and "sourceName" in info:
            url = info["sourceURL"]
            source_name = info["sourceName"]
            if "Fetched" in source_name:
                label = _("Fetched: Show Origin")
            else:
                label = _("View at %s") % source_name

            if len(label) > 50:
                label = label[:50] + "..."

            show_origin = Gtk.MenuItem(label)

            def _show_origin(widget=None):
                logger.info(lambda: "Opening url: " + url)
                webbrowser.open_new_tab(url)

            show_origin.connect("activate", _show_origin)
            menu.append(show_origin)

        menu.append(Gtk.SeparatorMenuItem.new())
        rating_item = Gtk.MenuItem(_("Set EXIF Rating"))
        rating_item.set_submenu(
            ThumbsManager.create_rating_menu(file, self.parent))
        if not os.access(file, os.W_OK):
            rating_item.set_sensitive(False)
        menu.append(rating_item)

        menu.append(Gtk.SeparatorMenuItem.new())

        self.copy_to_favorites = Gtk.MenuItem(_("Copy to _Favorites"))
        self.copy_to_favorites.set_use_underline(True)

        def _copy_to_favorites(widget):
            self.parent.copy_to_favorites(widget, file)

        self.copy_to_favorites.connect("activate", _copy_to_favorites)
        menu.append(self.copy_to_favorites)

        self.move_to_favorites = Gtk.MenuItem(_("Move to _Favorites"))
        self.move_to_favorites.set_use_underline(True)

        def _move_to_favorites(widget):
            self.parent.move_to_favorites(widget, file)
            self.remove_image(file)

        self.move_to_favorites.connect("activate", _move_to_favorites)
        self.move_to_favorites.set_visible(False)
        menu.append(self.move_to_favorites)

        trash_item = Gtk.MenuItem(_("Delete to _Trash"))
        trash_item.set_use_underline(True)

        def _trash(widget):
            self.parent.move_to_trash(widget, file)

        trash_item.connect("activate", _trash)
        menu.append(trash_item)

        focus = Gtk.MenuItem(_("Where is it from?"))
        focus.set_sensitive(self.parent.get_source(file) is not None)

        def _focus(widget):
            self.parent.focus_in_preferences(widget, file)

        focus.connect("activate", _focus)
        menu.append(focus)

        menu.append(Gtk.SeparatorMenuItem.new())

        def close(widget):
            self.hide(force=True)

        close_item = Gtk.MenuItem(_("Close"))
        close_item.connect("activate", close)
        menu.append(close_item)

        menu.show_all()

        favs_op = self.parent.determine_favorites_operation(file)
        self.parent.update_favorites_menuitems(self, False, favs_op)

        return menu

    @staticmethod
    def create_rating_menu(file, main_window):
        def _set_rating_maker(rating):
            def _set_rating(widget, rating=rating):
                try:
                    Util.set_rating(file, rating)
                    main_window.on_rating_changed(file)
                except Exception:
                    logger.exception(lambda: "Could not set EXIF rating")
                    main_window.show_notification(
                        _("Could not set EXIF rating"))

            return _set_rating

        try:
            actual_rating = Util.get_rating(file)
        except Exception:
            actual_rating = None

        rating_menu = Gtk.Menu()
        for rating in range(5, 0, -1):
            item = Gtk.CheckMenuItem("\u2605" * rating)
            item.set_draw_as_radio(True)
            item.set_active(actual_rating == rating)
            item.set_sensitive(not item.get_active())
            item.connect("activate", _set_rating_maker(rating))
            rating_menu.append(item)

        rating_menu.append(Gtk.SeparatorMenuItem.new())

        unrated_item = Gtk.CheckMenuItem(_("Unrated"))
        unrated_item.set_draw_as_radio(True)
        unrated_item.set_active(actual_rating is None or actual_rating == 0)
        unrated_item.set_sensitive(not unrated_item.get_active())
        unrated_item.connect("activate", _set_rating_maker(None))
        rating_menu.append(unrated_item)

        rejected_item = Gtk.CheckMenuItem(_("Rejected"))
        rejected_item.set_draw_as_radio(True)
        rejected_item.set_active(actual_rating is not None
                                 and actual_rating < 0)
        rejected_item.set_sensitive(not rejected_item.get_active())
        rejected_item.connect("activate", _set_rating_maker(-1))
        rating_menu.append(rejected_item)

        rating_menu.show_all()
        return rating_menu

    def repaint(self):
        self.hide(keep_settings=True)
        if self.images:
            self.show(self.unlimited_images,
                      screen=self.screen,
                      type=self.type,
                      folders=self.folders)

    def set_position(self, position):
        logger.info(lambda: "Setting thumbs position " + str(position))
        options = self.load_options()
        options.position = ThumbsManager.POSITIONS[position]
        self.save_options(options)
        self.repaint()

    def set_size(self, size):
        logger.info(lambda: "Setting thumbs size " + str(size))
        options = self.load_options()
        options.breadth = size
        self.save_options(options)
        self.repaint()

    def set_limit(self, limit):
        logger.info(lambda: "Setting thumbs limit " + str(limit))
        options = self.load_options()
        options.limit = limit
        self.save_options(options)
        self.repaint()

    def pin(self, widget=None):
        self.pinned = True

    def on_click(self, thumbs_window, file, widget, event):
        file = file
        self.pin()

        def _resume_scrolling(menu=None):
            thumbs_window.resume_scrolling()

        thumbs_window.pause_scrolling()
        if event.button == 1:
            if self.is_showing("history"):
                index = [info["eventbox"]
                         for info in thumbs_window.all].index(widget)
                self.parent.move_to_history_position(index)
            else:
                self.parent.set_wallpaper(file)
            _resume_scrolling()
        else:
            menu = self.create_menu(file)

            def _compute_position(*args, **kwargs):
                x, y = event.get_root_coords()[0], event.get_root_coords()[1]
                h = menu.get_preferred_height()[1]
                return x, y - h if y - h >= 40 else y, True

            menu.connect("deactivate", _resume_scrolling)
            menu.popup(None, None, _compute_position, None, 0, event.time)

    def mark_active(self, file=None, position=None):
        self.active_file = file
        self.active_position = position
        if self.thumbs_window:
            if self.is_showing("history"):
                self.thumbs_window.mark_active(position=position)
            else:
                self.thumbs_window.mark_active(file=file)

    def show(self, images, screen=None, type=None, folders=None):
        options = self.load_options()
        with self.show_thumbs_lock:
            self.unlimited_images = images
            self.type = type
            limit = len(self.unlimited_images
                        ) if options.limit == self.UNLIMITED else options.limit
            self.images = self.unlimited_images[:limit]
            self.screen = screen
            self.folders = folders

            def _go():
                try:
                    if self.thumbs_window:
                        self.thumbs_window.destroy()
                        self.thumbs_window = None

                    if len(self.images) > 0:
                        self.initialize_thumbs_window()
                except Exception:
                    logger.exception(lambda: "Could not create thumbs window:")

            Util.add_mainloop_task(_go)

    def initialize_thumbs_window(self):
        options = self.load_options()

        def _go():
            self.thumbs_window = ThumbsWindow(screen=self.screen,
                                              position=options.position,
                                              breadth=options.breadth)
            try:
                icon = varietyconfig.get_data_file("media", "variety.svg")
                self.thumbs_window.set_icon_from_file(icon)
            except Exception:
                logger.exception(lambda: "Could not set thumbs window icon")

            if self.type == "history":
                title = _("Variety History")
            elif self.type == "downloads":
                title = _("Variety Recent Downloads")
            else:
                title = _("Variety Images")

            self.thumbs_window.set_title(title)
            self.thumbs_window.connect("clicked", self.on_click)

            def _on_close(window, event):
                self.hide(force=True)

            self.thumbs_window.connect("delete-event", _on_close)

            self.mark_active(self.active_file, self.active_position)

            self.thumbs_window.start(self.images)

        Util.add_mainloop_task(_go)

    def load_options(self):
        options = ThumbsManager.Options()
        try:
            config = ConfigObj(
                os.path.join(self.parent.config_folder, "ui.conf"))
            try:
                s = config["thumbs_position"].lower()
                options.position = ThumbsManager.POSITIONS[s]
            except Exception:
                logger.exception(
                    lambda: "Missing or bad thumbs_position option in ui.conf")

            try:
                options.breadth = int(config["thumbs_size"])
            except Exception:
                logger.exception(
                    lambda: "Missing or bad thumbs_size option in ui.conf")

            try:
                options.limit = (int(config["thumbs_limit"])
                                 if config["thumbs_limit"] != self.UNLIMITED
                                 else self.UNLIMITED)
            except Exception:
                logger.exception(
                    lambda: "Missing or bad thumbs_limit option in ui.conf")
        except Exception:
            logger.exception(lambda: "Could not read ui.conf")

        self.save_options(options)
        return options

    def save_options(self, options):
        try:
            config = ConfigObj(
                os.path.join(self.parent.config_folder, "ui.conf"))
            try:
                config["thumbs_position"] = ThumbsManager.R_POSITIONS[
                    options.position]
                config["thumbs_size"] = options.breadth
                config["thumbs_limit"] = str(options.limit)
                config.write()
            except Exception:
                logger.exception(
                    lambda: "Missing or bad thumbs_position option in ui.conf")
        except Exception:
            logger.exception(lambda: "Could not save ui.conf")

    def hide(self, force=True, keep_settings=False):
        if force:
            self.pinned = False

        if self.pinned:
            return

        if not keep_settings:
            self.type = None
            self.images = []
            self.screen = None
            self.folders = None

        if self.thumbs_window:

            def _go():
                self.thumbs_window.destroy()
                self.thumbs_window = None

            Util.add_mainloop_task(_go)
            self.parent.update_indicator(auto_changed=False)

    def remove_image(self, file):
        self.images = [f for f in self.images if f != file]
        if self.thumbs_window:
            if self.thumbs_window.fits_in_screen(+1000):
                self.repaint()
            else:
                self.thumbs_window.remove_image(file)

    def add_image(self, file):
        self.images.insert(0, file)
        if not self.thumbs_window:
            self.initialize_thumbs_window()
        else:
            self.thumbs_window.add_image(file, at_front=True)

    def is_showing(self, type):
        return self.type == type

    def get_folders(self):
        return self.folders
Пример #45
0
    def create_menu(self, window):
        self.menu = Gtk.Menu()

        if not Util.is_unity():
            self.next_main = Gtk.MenuItem(_("_Next"))
            self.next_main.set_use_underline(True)
            self.next_main.connect("activate", window.next_wallpaper)
            self.menu.append(self.next_main)

            self.prev_main = Gtk.MenuItem(_("_Previous"))
            self.prev_main.set_use_underline(True)
            self.prev_main.connect("activate", window.prev_wallpaper)
            self.menu.append(self.prev_main)

            self.menu.append(Gtk.SeparatorMenuItem.new())

        self.file_label = Gtk.MenuItem(_("Current desktop wallpaper"))
        self.file_label.connect("activate", window.open_file)
        self.menu.append(self.file_label)

        self.show_origin = Gtk.MenuItem(_("Show origin"))
        self.show_origin.connect("activate", window.on_show_origin)
        self.show_origin.set_sensitive(False)
        self.menu.append(self.show_origin)

        self.show_author = Gtk.MenuItem("Show author")
        self.show_author.connect("activate", window.on_show_author)
        self.show_author.set_sensitive(False)
        self.show_author.set_visible(False)
        self.menu.append(self.show_author)

        self.copy_to_favorites = Gtk.MenuItem(_("Copy to _Favorites"))
        self.copy_to_favorites.set_use_underline(True)
        self.copy_to_favorites.connect("activate", window.copy_to_favorites)
        self.menu.append(self.copy_to_favorites)

        self.move_to_favorites = Gtk.MenuItem(_("Move to Favorites"))
        self.move_to_favorites.set_use_underline(True)
        self.move_to_favorites.connect("activate", window.move_to_favorites)
        self.move_to_favorites.set_visible(False)
        self.menu.append(self.move_to_favorites)

        self.trash = Gtk.MenuItem(_("Delete to _Trash"))
        self.trash.set_use_underline(True)
        self.trash.connect("activate", window.move_to_trash)
        self.menu.append(self.trash)

        self.menu.append(Gtk.SeparatorMenuItem.new())

        self.image_menu = Gtk.Menu()

        self.next = Gtk.MenuItem(_("_Next"))
        self.next.set_use_underline(True)
        self.next.connect("activate", window.next_wallpaper)
        self.image_menu.append(self.next)

        self.prev = Gtk.MenuItem(_("_Previous"))
        self.prev.set_use_underline(True)
        self.prev.connect("activate", window.prev_wallpaper)
        self.image_menu.append(self.prev)

        self.fast_forward = Gtk.MenuItem(_("_Next, skipping forward history"))
        self.fast_forward.set_use_underline(True)

        def _fast_forward(widget):
            window.next_wallpaper(widget, bypass_history=True)

        self.fast_forward.connect("activate", _fast_forward)
        self.image_menu.append(self.fast_forward)

        self.image_menu.append(Gtk.SeparatorMenuItem.new())
        self.scroll_tip = Gtk.MenuItem(
            _("Tip: Scroll wheel over icon\nfor Next and Previous"))
        self.scroll_tip.set_sensitive(False)
        self.image_menu.append(self.scroll_tip)

        self.image_menu.append(Gtk.SeparatorMenuItem.new())

        self.pause_resume = Gtk.MenuItem(_("Pause on current"))
        self.pause_resume.connect("activate", window.on_pause_resume)
        self.image_menu.append(self.pause_resume)

        self.image_item = Gtk.MenuItem(_("_Image"))
        self.image_item.set_use_underline(True)
        self.image_item.set_submenu(self.image_menu)
        self.menu.append(self.image_item)

        self.image_menu.append(Gtk.SeparatorMenuItem.new())

        self.focus = Gtk.MenuItem(_("Where is it from?"))
        self.focus.connect("activate", window.focus_in_preferences)
        self.image_menu.append(self.focus)

        self.no_effects = Gtk.CheckMenuItem(_("Show without effects"))
        self.no_effects.set_active(False)
        self.no_effects.set_use_underline(True)

        def _toggle_no_effects(widget=None):
            window.toggle_no_effects(self.no_effects.get_active())

        self.no_effects_handler_id = self.no_effects.connect(
            "toggled", _toggle_no_effects)
        self.image_menu.append(self.no_effects)

        self.google_image = Gtk.MenuItem(_("Google Image Search"))
        self.google_image.connect("activate", window.google_image_search)
        self.image_menu.append(self.google_image)

        self.rating_separator = Gtk.SeparatorMenuItem.new()
        self.image_menu.append(self.rating_separator)

        self.rating = Gtk.MenuItem(_("Set EXIF Rating"))
        self.image_menu.append(self.rating)

        # self.image_item = Gtk.MenuItem(_("_Image"))
        # self.image_item.set_use_underline(True)
        # self.image_item.set_submenu(self.image_menu)
        # self.menu.append(self.image_item)
        #

        self.quotes_menu = Gtk.Menu()

        self.next_quote = Gtk.MenuItem(_("_Next"))
        self.next_quote.set_use_underline(True)
        self.next_quote.connect("activate", window.next_quote)
        self.quotes_menu.append(self.next_quote)

        self.prev_quote = Gtk.MenuItem(_("_Previous"))
        self.prev_quote.set_use_underline(True)
        self.prev_quote.connect("activate", window.prev_quote)
        self.quotes_menu.append(self.prev_quote)

        self.fast_forward_quote = Gtk.MenuItem(
            _("_Next, skipping forward history"))
        self.fast_forward_quote.set_use_underline(True)

        def _fast_forward_quote(widget):
            window.next_quote(widget, bypass_history=True)

        self.fast_forward_quote.connect("activate", _fast_forward_quote)
        self.quotes_menu.append(self.fast_forward_quote)

        self.quotes_menu.append(Gtk.SeparatorMenuItem.new())

        self.quotes_pause_resume = Gtk.MenuItem(_("Pause on current"))
        self.quotes_pause_resume.connect("activate",
                                         window.on_quotes_pause_resume)
        self.quotes_menu.append(self.quotes_pause_resume)

        self.quotes_menu.append(Gtk.SeparatorMenuItem.new())

        self.quote_favorite = Gtk.MenuItem(_("Save to Favorites"))
        self.quote_favorite.set_use_underline(True)
        self.quote_favorite.connect("activate", window.quote_save_to_favorites)
        self.quotes_menu.append(self.quote_favorite)

        self.quote_view_favs = Gtk.MenuItem(_("View Favorites..."))
        self.quote_view_favs.set_use_underline(True)
        self.quote_view_favs.connect("activate", window.quote_view_favorites)
        self.quotes_menu.append(self.quote_view_favs)

        self.quotes_menu.append(Gtk.SeparatorMenuItem.new())

        self.quote_clipboard = Gtk.MenuItem(_("Copy to Clipboard"))
        self.quote_clipboard.set_use_underline(True)
        self.quote_clipboard.connect("activate",
                                     window.quote_copy_to_clipboard)
        self.quotes_menu.append(self.quote_clipboard)

        self.view_quote = Gtk.MenuItem()
        self.view_quote.set_use_underline(True)
        self.view_quote.connect("activate", window.view_quote)
        self.quotes_menu.append(self.view_quote)

        self.google_quote_text = Gtk.MenuItem(_("Google Quote"))
        self.google_quote_text.set_use_underline(True)
        self.google_quote_text.connect("activate", window.google_quote_text)
        self.quotes_menu.append(self.google_quote_text)

        self.google_quote_author = Gtk.MenuItem(_("Google Author"))
        self.google_quote_author.set_use_underline(True)
        self.google_quote_author.connect("activate",
                                         window.google_quote_author)
        self.quotes_menu.append(self.google_quote_author)

        self.quotes_menu.append(Gtk.SeparatorMenuItem.new())

        self.quotes_preferences = Gtk.MenuItem(_("Preferences..."))
        self.quotes_preferences.set_use_underline(True)

        def _quotes_prefs(widget=None):
            window.preferences_dialog.ui.notebook.set_current_page(1)
            window.on_mnu_preferences_activate()

        self.quotes_preferences.connect("activate", _quotes_prefs)
        self.quotes_menu.append(self.quotes_preferences)

        self.quotes_disable = Gtk.MenuItem(_("Turn off"))
        self.quotes_disable.set_use_underline(True)
        self.quotes_disable.connect("activate", window.disable_quotes)
        self.quotes_menu.append(self.quotes_disable)

        self.quotes = Gtk.MenuItem(_("_Quote"))
        self.quotes.set_use_underline(True)
        self.quotes.set_submenu(self.quotes_menu)
        self.menu.append(self.quotes)

        self.menu.append(Gtk.SeparatorMenuItem.new())

        self.history = Gtk.CheckMenuItem(_("_History"))
        self.history.set_active(False)
        self.history.set_use_underline(True)
        self.history_handler_id = self.history.connect(
            "toggled", window.show_hide_history)
        self.menu.append(self.history)

        self.selector = Gtk.CheckMenuItem(_("_Wallpaper Selector"))
        self.selector.set_active(False)
        self.selector.set_use_underline(True)
        self.selector_handler_id = self.selector.connect(
            "toggled", window.show_hide_wallpaper_selector)
        self.menu.append(self.selector)

        self.downloads = Gtk.CheckMenuItem(_("Recent _Downloads"))
        self.downloads.set_active(False)
        self.downloads.set_use_underline(True)
        self.downloads_handler_id = self.downloads.connect(
            "toggled", window.show_hide_downloads)
        self.menu.append(self.downloads)

        if Util.check_variety_slideshow_present():
            self.menu.append(Gtk.SeparatorMenuItem.new())
            self.slideshow = Gtk.MenuItem(_("Start Slideshow"))
            self.slideshow.connect("activate", window.on_start_slideshow)
            self.menu.append(self.slideshow)
        else:
            logger.warning(
                "Variety Slideshow is not installed. This is an optional extension "
                "adding pan-and-zoom slideshows to Variety: see "
                "https://github.com/peterlevi/variety-slideshow for details")

        self.menu.append(Gtk.SeparatorMenuItem.new())

        self.preferences = Gtk.MenuItem(_("Preferences..."))
        self.preferences.connect("activate",
                                 window.on_mnu_preferences_activate)
        self.menu.append(self.preferences)

        self.about = Gtk.MenuItem(_("About"))
        self.about.connect("activate", window.on_mnu_about_activate)
        self.menu.append(self.about)

        self.donate = Gtk.MenuItem(_("Donate"))
        self.donate.connect("activate", window.on_mnu_donate_activate)
        self.menu.append(self.donate)

        self.quit = Gtk.MenuItem(_("Quit"))
        self.quit.connect("activate", window.on_quit)
        self.menu.append(self.quit)

        self.menu.show_all()
Пример #46
0
    def create_menu(self, file):
        options = self.load_options()

        menu = Gtk.Menu()

        position_menu = Gtk.Menu()
        for p, v in ThumbsManager.POSITIONS.items():
            item = Gtk.CheckMenuItem(ThumbsManager.POSITION_NAMES[p])
            item.set_draw_as_radio(True)
            item.set_active(options.position == v)

            def _set_position(widget, pos=p):
                self.set_position(pos)

            item.connect("activate", _set_position)
            position_menu.append(item)

        size_menu = Gtk.Menu()
        for size in ThumbsManager.SIZES:
            item = Gtk.CheckMenuItem(str(size))
            item.set_draw_as_radio(True)
            item.set_active(options.breadth == size)

            def _set_size(widget, size=size):
                self.set_size(size)

            item.connect("activate", _set_size)
            size_menu.append(item)

        limit_menu = Gtk.Menu()
        for limit in ThumbsManager.LIMITS:
            item = Gtk.CheckMenuItem(str(limit))
            item.set_draw_as_radio(True)
            item.set_active(options.limit == limit)

            def _set_limit(widget, limit=limit):
                self.set_limit(limit)

            item.connect("activate", _set_limit)
            limit_menu.append(item)

        position_item = Gtk.MenuItem(_("Position"))
        position_item.set_submenu(position_menu)
        menu.append(position_item)

        size_item = Gtk.MenuItem(_("Size"))
        size_item.set_submenu(size_menu)
        menu.append(size_item)

        limit_item = Gtk.MenuItem(_("Maximum Shown Images"))
        limit_item.set_submenu(limit_menu)
        menu.append(limit_item)

        menu.append(Gtk.SeparatorMenuItem.new())

        open_file = Gtk.MenuItem(os.path.basename(file).replace("_", "__"))

        def _open_file(widget):
            self.parent.open_file(widget, file)

        open_file.connect("activate", _open_file)
        menu.append(open_file)

        open_folder = Gtk.MenuItem(_("Show Containing Folder"))

        def _open_folder(widget):
            self.parent.open_folder(widget, file)

        open_folder.connect("activate", _open_folder)
        menu.append(open_folder)

        info = Util.read_metadata(file)
        if info and "sourceURL" in info and "sourceName" in info:
            url = info["sourceURL"]
            source_name = info["sourceName"]
            if "Fetched" in source_name:
                label = _("Fetched: Show Origin")
            else:
                label = _("View at %s") % source_name

            if len(label) > 50:
                label = label[:50] + "..."

            show_origin = Gtk.MenuItem(label)

            def _show_origin(widget=None):
                logger.info(lambda: "Opening url: " + url)
                webbrowser.open_new_tab(url)

            show_origin.connect("activate", _show_origin)
            menu.append(show_origin)

        menu.append(Gtk.SeparatorMenuItem.new())
        rating_item = Gtk.MenuItem(_("Set EXIF Rating"))
        rating_item.set_submenu(
            ThumbsManager.create_rating_menu(file, self.parent))
        if not os.access(file, os.W_OK):
            rating_item.set_sensitive(False)
        menu.append(rating_item)

        menu.append(Gtk.SeparatorMenuItem.new())

        self.copy_to_favorites = Gtk.MenuItem(_("Copy to _Favorites"))
        self.copy_to_favorites.set_use_underline(True)

        def _copy_to_favorites(widget):
            self.parent.copy_to_favorites(widget, file)

        self.copy_to_favorites.connect("activate", _copy_to_favorites)
        menu.append(self.copy_to_favorites)

        self.move_to_favorites = Gtk.MenuItem(_("Move to _Favorites"))
        self.move_to_favorites.set_use_underline(True)

        def _move_to_favorites(widget):
            self.parent.move_to_favorites(widget, file)
            self.remove_image(file)

        self.move_to_favorites.connect("activate", _move_to_favorites)
        self.move_to_favorites.set_visible(False)
        menu.append(self.move_to_favorites)

        trash_item = Gtk.MenuItem(_("Delete to _Trash"))
        trash_item.set_use_underline(True)

        def _trash(widget):
            self.parent.move_to_trash(widget, file)

        trash_item.connect("activate", _trash)
        menu.append(trash_item)

        focus = Gtk.MenuItem(_("Where is it from?"))
        focus.set_sensitive(self.parent.get_source(file) is not None)

        def _focus(widget):
            self.parent.focus_in_preferences(widget, file)

        focus.connect("activate", _focus)
        menu.append(focus)

        menu.append(Gtk.SeparatorMenuItem.new())

        def close(widget):
            self.hide(force=True)

        close_item = Gtk.MenuItem(_("Close"))
        close_item.connect("activate", close)
        menu.append(close_item)

        menu.show_all()

        favs_op = self.parent.determine_favorites_operation(file)
        self.parent.update_favorites_menuitems(self, False, favs_op)

        return menu
Пример #47
0
# under the terms of the GNU General Public License version 3, as published 
# by the Free Software Foundation.
# 
# This program is distributed in the hope that it will be useful, but 
# WITHOUT ANY WARRANTY; without even the implied warranties of 
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
# PURPOSE.  See the GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along 
# with this program.  If not, see <http://www.gnu.org/licenses/>.
### END LICENSE

from variety import _, _u

FILTERS = {
    "Keep original": _("Keep original"),
    "Grayscale": _("Grayscale"),
    "Heavy blur": _("Heavy blur"),
    "Soft blur": _("Soft blur"),
    "Oil painting": _("Oil painting"),
    "Pencil sketch": _("Pencil sketch"),
    "Pointilism": _("Pointilism"),
    "Pixellate": _("Pixellate")
}

SOURCES = {
    "favorites": ("The Favorites folder", _("The Favorites folder")),
    "fetched": ("The Fetched folder", _("The Fetched folder")),
    "recommended":
        ("Recommended by Variety. Adapts to your taste as you mark images as favorite or trash.",
        _("Recommended by Variety. Adapts to your taste as you mark images as favorite or trash.")),
Пример #48
0
 def get_description(self):
     return _("Images from Wallhaven.cc")