Ejemplo n.º 1
0
 def get_userinfo(self):
     dict = {}
     dict['username'] = GLib.get_user_name()
     dict['homedir'] = GLib.get_home_dir()
     dict['shell'] = GLib.getenv('SHELL')
     dict['lang'] =  GLib.getenv('LANG')
     return dict['username'], dict['homedir'],dict['shell'],dict['lang']
Ejemplo n.º 2
0
Archivo: misc.py Proyecto: GNOME/meld
def get_base_style_scheme() -> GtkSource.StyleScheme:

    global base_style_scheme

    if base_style_scheme:
        return base_style_scheme

    env_theme = GLib.getenv('GTK_THEME')
    if env_theme:
        use_dark = env_theme.endswith(':dark')
    else:
        gtk_settings = Gtk.Settings.get_default()
        use_dark = gtk_settings.props.gtk_application_prefer_dark_theme

    # As of 3.28, the global dark theme switch is going away.
    if not use_dark:
        from meld.sourceview import MeldSourceView
        stylecontext = MeldSourceView().get_style_context()
        background_set, rgba = (
            stylecontext.lookup_color('theme_bg_color'))

        # This heuristic is absolutely dire. I made it up. There's
        # literally no basis to this.
        if background_set and rgba.red + rgba.green + rgba.blue < 1.0:
            use_dark = True

    base_scheme_name = (
        MELD_STYLE_SCHEME_DARK if use_dark else MELD_STYLE_SCHEME)

    manager = GtkSource.StyleSchemeManager.get_default()
    base_style_scheme = manager.get_scheme(base_scheme_name)

    return base_style_scheme
Ejemplo n.º 3
0
    def __init__ (self, bus, engine, datadir, gettext_package):
        self.__config = Config(bus, engine, self.on_value_changed)

        ui_file = GLib.build_filenamev([datadir, "setup.ui"])
        self.__builder = Gtk.Builder()
        self.__builder.set_translation_domain(gettext_package)
        self.__builder.add_from_file(ui_file)

        for option in options:
            prepare_func = getattr(self, "prepare_%s" % option["widget"])
            prepare_func(option)

        self.__window = self.__builder.get_object("setup_dialog")
        self.__window.set_title(titles[engine])

        try:
            # Pretend to be a GNOME Control Center dialog if appropriate
            self.gnome_cc_xid = int(GLib.getenv('GNOME_CONTROL_CENTER_XID'))
            self.__window.set_wmclass('gnome-control-center',
                                      'Gnome-control-center')
            self.__window.set_modal(True)
            self.__window.connect('notify::window', self.set_transient)
            self.__window.set_type_hint(Gdk.WindowTypeHint.DIALOG)

        except:
            # No problem here, we're just a normal dialog
            pass

        self.__window.show()
    def __init__(
            self,
            connmgr,
            datadir=GLib.getenv("HOME") + "/.config/chromium",
            namespace="org.chromium.Policies"):

        logging.debug(
            "Initializing chromium logger with namespace %s at %s" % (
                namespace, datadir))

        self.connmgr = connmgr
        self.datadir = datadir
        self.namespace = namespace
        self.local_state_path = self.datadir + "/Local State";
        self.monitored_preferences = {}
        self.initial_bookmarks = {}
        self.monitored_bookmarks = {}
        self.bookmarks_paths = []
        self.file_monitors = {}

        # Load policy map
        self.policy_map = self.load_policy_map()
        if self.policy_map is None:
            logging.error(
                "WARNING: ChromiumLogger can't locate policies file. Chromium/Chrome disabled.")
            return

        # Setup file monitoring for local state
        self._setup_local_state_file_monitor()
Ejemplo n.º 5
0
    def __init__(self):
        Clip.__init__(self)

        self.table = EasyTable(items=(
                        (Gtk.Label(label=_('Current user:'******'Home directory:')),
                         Gtk.Label(label=GLib.get_home_dir())),
                        (Gtk.Label(label=_('Shell:')),
                         Gtk.Label(label=GLib.getenv('SHELL'))),
                        (Gtk.Label(label=_('Language:')),
                         Gtk.Label(label=GLib.getenv('LANG')))),
                        xpadding=12, ypadding=2)

        self.add_content(self.table)

        self.show_all()
Ejemplo n.º 6
0
    def __init__ (self, engine, datadir, gettext_package):
        self.settings = Gio.Settings("org.cangjians.ibus.%s" % engine)
        self.settings.connect("changed", self.on_value_changed)

        ui_file = GLib.build_filenamev([datadir, "setup.ui"])
        self.__builder = Gtk.Builder()
        self.__builder.set_translation_domain(gettext_package)
        self.__builder.add_from_file(ui_file)

        for key in ("version", ):
            combo = self.__builder.get_object(key)
            active = self.__get_active_combo_index(combo.get_model(),
                                                   self.settings.get_int(key))
            combo.set_active(active)
            combo.connect("changed", self.on_combo_changed, key)
            setattr(self, "widget_%s" % key, combo)

        for key in ("include-allzh", "include-jp",
                    "include-zhuyin", "include-symbols"):
            switch = self.__builder.get_object(key)
            switch.set_active(self.settings.get_boolean(key))
            switch.connect("notify::active", self.on_switch_toggled, key)
            setattr(self, "widget_%s" % key, switch)

        self.__window = self.__builder.get_object("setup_dialog")

        if engine == "cangjie":
            title = dgettext(gettext_package, "Cangjie Preferences")
        elif engine == "quick":
            title = dgettext(gettext_package, "Quick Preferences")

        self.__window.set_title(title)

        try:
            # Pretend to be a GNOME Control Center dialog if appropriate
            self.gnome_cc_xid = int(GLib.getenv('GNOME_CONTROL_CENTER_XID'))
            self.__window.set_wmclass('gnome-control-center',
                                      'Gnome-control-center')
            self.__window.set_modal(True)
            self.__window.connect('notify::window', self.set_transient)
            self.__window.set_type_hint(Gdk.WindowTypeHint.DIALOG)

        except:
            # No problem here, we're just a normal dialog
            pass

        self.__window.show()
Ejemplo n.º 7
0
    def __init__(self):
        super(BinFileMonitor, self).__init__()

        self.changed_id = 0

        env = GLib.getenv("PATH")

        if env == None:
            env = "/bin:/usr/bin:."

        self.paths = env.split(":")

        self.monitors = []

        for path in self.paths:
            file = Gio.File.new_for_path(path)
            mon = file.monitor_directory(Gio.FileMonitorFlags.SEND_MOVED, None)
            mon.connect("changed", self.queue_emit_changed)
            self.monitors.append(mon)
Ejemplo n.º 8
0
    def __init__(self):
        super(BinFileMonitor, self).__init__()

        self.changed_id = 0

        env = GLib.getenv("PATH")

        if env == None:
            env = "/bin:/usr/bin:."

        self.paths = env.split(":")

        self.monitors = []

        for path in self.paths:
            file = Gio.File.new_for_path(path)
            mon = file.monitor_directory(Gio.FileMonitorFlags.SEND_MOVED, None)
            mon.connect("changed", self.queue_emit_changed)
            self.monitors.append(mon)
Ejemplo n.º 9
0
def get_base_style_scheme():

    global base_style_scheme

    if base_style_scheme:
        return base_style_scheme

    env_theme = GLib.getenv('GTK_THEME')
    if env_theme:
        use_dark = env_theme.endswith(':dark')
    else:
        gtk_settings = Gtk.Settings.get_default()
        use_dark = gtk_settings.props.gtk_application_prefer_dark_theme

    try:
        from Foundation import NSUserDefaults
        standardUserDefaults = NSUserDefaults.standardUserDefaults()
        if standardUserDefaults.stringForKey_("AppleInterfaceStyle") == 'Dark':
            use_dark = True
    except:
        pass

    # As of 3.28, the global dark theme switch is going away.
    if not use_dark:
        from meld.sourceview import MeldSourceView
        stylecontext = MeldSourceView().get_style_context()
        background_set, rgba = (
            stylecontext.lookup_color('theme_bg_color'))

        # This heuristic is absolutely dire. I made it up. There's
        # literally no basis to this.
        if background_set and rgba.red + rgba.green + rgba.blue < 1.0:
            use_dark = True

    base_scheme_name = (
        MELD_STYLE_SCHEME_DARK if use_dark else MELD_STYLE_SCHEME)

    manager = GtkSource.StyleSchemeManager.get_default()
    base_style_scheme = manager.get_scheme(base_scheme_name)

    return base_style_scheme
Ejemplo n.º 10
0
def get_base_style_scheme():
    MELD_STYLE_SCHEME = "meld-base"
    MELD_STYLE_SCHEME_DARK = "meld-dark"

    global base_style_scheme

    if base_style_scheme:
        return base_style_scheme

    env_theme = GLib.getenv('GTK_THEME')
    if env_theme:
        use_dark = env_theme.endswith(':dark')
    else:
        gtk_settings = Gtk.Settings.get_default()
        use_dark = gtk_settings.props.gtk_application_prefer_dark_theme
    base_scheme_name = (
        MELD_STYLE_SCHEME_DARK if use_dark else MELD_STYLE_SCHEME)

    manager = GtkSource.StyleSchemeManager.get_default()
    base_style_scheme = manager.get_scheme(base_scheme_name)

    return base_style_scheme
Ejemplo n.º 11
0
def get_base_style_scheme():
    MELD_STYLE_SCHEME = "meld-base"
    MELD_STYLE_SCHEME_DARK = "meld-dark"

    global base_style_scheme

    if base_style_scheme:
        return base_style_scheme

    env_theme = GLib.getenv('GTK_THEME')
    if env_theme:
        use_dark = env_theme.endswith(':dark')
    else:
        gtk_settings = Gtk.Settings.get_default()
        use_dark = gtk_settings.props.gtk_application_prefer_dark_theme
    base_scheme_name = (MELD_STYLE_SCHEME_DARK
                        if use_dark else MELD_STYLE_SCHEME)

    manager = GtkSource.StyleSchemeManager.get_default()
    base_style_scheme = manager.get_scheme(base_scheme_name)

    return base_style_scheme
Ejemplo n.º 12
0
 def __on_button_press(self, widget, event):
     """
         Popup menu for track relative to track row
         @param widget as Gtk.Widget
         @param event as Gdk.Event
     """
     if self.__context is not None:
         self.__on_button_clicked(self.__menu_button)
     if event.button == 3:
         if GLib.getenv("WAYLAND_DISPLAY") != "" and\
                 self.get_ancestor(Gtk.Popover) is not None:
             print("https://bugzilla.gnome.org/show_bug.cgi?id=774148")
         window = widget.get_window()
         if window == event.window:
             self.__popup_menu(widget, event.x, event.y)
         # Happens when pressing button over menu btn
         else:
             self.__on_button_clicked(self.__menu_button)
         return True
     elif event.button == 2:
         if self._track.id in Lp().player.get_queue():
             Lp().player.del_from_queue(self._track.id)
         else:
             Lp().player.append_to_queue(self._track.id)
Ejemplo n.º 13
0
def main(args=None):
    '''Entry point function.

    Since we're often running from within flatpak, make sure to override
    XDG_DATA_DIRS to include the flatpak exports too, since they don't get
    included by default.

    We use GLib.setenv here, since os.environ is only visible to
    Python code, but setting a variable in os.environ does not actually
    update the 'environ' global variable on the C side.
    '''
    flatpak_export_share_dirs = [
        os.path.join(d, 'exports', 'share')
        for d in EosCompanionAppService.flatpak_install_dirs()
    ]
    GLib.setenv(
        'XDG_DATA_DIRS',
        os.pathsep.join([GLib.getenv('XDG_DATA_DIRS') or ''] +
                        flatpak_export_share_dirs), True)

    logging.basicConfig(
        format='CompanionAppService %(levelname)s: %(message)s',
        level=get_log_level())
    CompanionAppApplication().run(args or sys.argv)
Ejemplo n.º 14
0
 def __on_button_press(self, widget, event):
     """
         Popup menu for track relative to track row
         @param widget as Gtk.Widget
         @param event as Gdk.Event
     """
     if self.__context is not None:
         self.__on_button_clicked(self.__menu_button)
     if event.button == 3:
         if GLib.getenv("WAYLAND_DISPLAY") != "" and\
                 self.get_ancestor(Gtk.Popover) is not None:
             print("https://bugzilla.gnome.org/show_bug.cgi?id=774148")
         window = widget.get_window()
         if window == event.window:
             self.__popup_menu(widget, event.x, event.y)
         # Happens when pressing button over menu btn
         else:
             self.__on_button_clicked(self.__menu_button)
         return True
     elif event.button == 2:
         if self._track.id in Lp().player.queue:
             Lp().player.del_from_queue(self._track.id)
         else:
             Lp().player.append_to_queue(self._track.id)
Ejemplo n.º 15
0
class Application(Gtk.Application):
    """
        Eolie application:
    """

    if GLib.getenv("XDG_DATA_HOME") is None:
        LOCAL_PATH = GLib.get_home_dir() + "/.local/share/eolie"
    else:
        LOCAL_PATH = GLib.getenv("XDG_DATA_HOME") + "/eolie"
    __COOKIES_PATH = "%s/cookies.db" % LOCAL_PATH
    __FAVICONS_PATH = "%s/favicons" % LOCAL_PATH

    def __init__(self, extension_dir):
        """
            Create application
            @param extension_dir as str
        """
        # First check WebKit2 version
        if WebKit2.MINOR_VERSION < 16:
            exit("You need WebKit2GTK >= 2.16")
        Gtk.Application.__init__(
            self,
            application_id='org.gnome.Eolie',
            flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
        self.set_property('register-session', True)
        # Ideally, we will be able to delete this once Flatpak has a solution
        # for SSL certificate management inside of applications.
        if GLib.file_test("/app", GLib.FileTest.EXISTS):
            paths = [
                "/etc/ssl/certs/ca-certificates.crt", "/etc/pki/tls/cert.pem",
                "/etc/ssl/cert.pem"
            ]
            for path in paths:
                if GLib.file_test(path, GLib.FileTest.EXISTS):
                    GLib.setenv('SSL_CERT_FILE', path, True)
                    break
        self.__extension_dir = extension_dir
        self.__windows = []
        self.__pages_menu = PagesMenu(self)
        self.debug = False
        try:
            self.zoom_levels = load(
                open(self.LOCAL_PATH + "/zoom_levels.bin", "rb"))
        except:
            self.zoom_levels = {}
        self.cursors = {}
        GLib.set_application_name('Eolie')
        GLib.set_prgname('eolie')
        self.add_main_option("debug", b'd', GLib.OptionFlags.NONE,
                             GLib.OptionArg.NONE, "Debug Eolie", None)
        self.add_main_option("private", b'p', GLib.OptionFlags.NONE,
                             GLib.OptionArg.NONE, "Add a private page", None)
        self.connect('activate', self.__on_activate)
        self.connect('command-line', self.__on_command_line)
        self.register(None)
        if self.get_is_remote():
            Gdk.notify_startup_complete()

    def init(self):
        """
            Init main application
        """
        self.__is_fs = False
        self.__setup_app_menu()
        self.set_app_menu(self.__menu)
        cssProviderFile = Gio.File.new_for_uri(
            'resource:///org/gnome/Eolie/application.css')
        cssProvider = Gtk.CssProvider()
        cssProvider.load_from_file(cssProviderFile)
        screen = Gdk.Screen.get_default()
        styleContext = Gtk.StyleContext()
        styleContext.add_provider_for_screen(screen, cssProvider,
                                             Gtk.STYLE_PROVIDER_PRIORITY_USER)
        self.settings = Settings.new()
        self.history = DatabaseHistory()
        self.bookmarks = DatabaseBookmarks()
        # We store cursors for main thread
        SqlCursor.add(self.history)
        SqlCursor.add(self.bookmarks)
        try:
            from eolie.mozilla_sync import SyncWorker
            self.sync_worker = SyncWorker()
            self.sync_worker.sync()
            GLib.timeout_add_seconds(3600, self.sync_worker.sync)
        except Exception as e:
            print("Application::init():", e)
            self.sync_worker = None
        self.adblock = DatabaseAdblock()
        self.adblock.update()
        self.art = Art()
        self.search = Search()
        self.download_manager = DownloadManager()

        shortcut_action = Gio.SimpleAction.new('shortcut',
                                               GLib.VariantType.new('s'))
        shortcut_action.connect('activate', self.__on_shortcut_action)
        self.add_action(shortcut_action)
        self.set_accels_for_action("win.shortcut::uri", ["<Control>l"])
        self.set_accels_for_action("win.shortcut::new_page", ["<Control>t"])
        self.set_accels_for_action("app.shortcut::new_window", ["<Control>n"])
        self.set_accels_for_action("win.shortcut::private",
                                   ["<Control><Shift>p"])
        self.set_accels_for_action("win.shortcut::close_page", ["<Control>w"])
        self.set_accels_for_action("win.shortcut::save", ["<Control>s"])
        self.set_accels_for_action("win.shortcut::filter", ["<Control>i"])
        self.set_accels_for_action("win.shortcut::reload", ["<Control>r"])
        self.set_accels_for_action("win.shortcut::find", ["<Control>f"])
        self.set_accels_for_action("win.shortcut::print", ["<Control>p"])
        self.set_accels_for_action("win.shortcut::settings", ["<Control>e"])
        self.set_accels_for_action("win.shortcut::backward", ["<Alt>Left"])
        self.set_accels_for_action("win.shortcut::forward", ["<Alt>Right"])
        self.set_accels_for_action("win.shortcut::next", ["<Control>Tab"])
        self.set_accels_for_action("win.shortcut::previous",
                                   ["<Control><Shift>Tab"])

        # Set some WebKit defaults
        context = WebKit2.WebContext.get_default()
        GLib.setenv('PYTHONPATH', self.__extension_dir, True)
        context.set_web_extensions_directory(self.__extension_dir)

        data_manager = WebKit2.WebsiteDataManager()
        context.new_with_website_data_manager(data_manager)
        context.set_process_model(
            WebKit2.ProcessModel.MULTIPLE_SECONDARY_PROCESSES)
        context.set_cache_model(WebKit2.CacheModel.WEB_BROWSER)
        d = Gio.File.new_for_path(self.__FAVICONS_PATH)
        if not d.query_exists():
            d.make_directory_with_parents()
        context.set_favicon_database_directory(self.__FAVICONS_PATH)
        cookie_manager = context.get_cookie_manager()
        cookie_manager.set_accept_policy(
            self.settings.get_enum("cookie-storage"))
        cookie_manager.set_persistent_storage(
            self.__COOKIES_PATH, WebKit2.CookiePersistentStorage.SQLITE)
        helper = DBusHelper()
        helper.connect(self.__on_extension_signal, None)

    def do_startup(self):
        """
            Init application
        """
        Gtk.Application.do_startup(self)

        if not self.__windows:
            self.init()
            self.__get_new_window()

    def set_setting(self, key, value):
        """
            Set setting for all view
            @param key as str
            @param value as GLib.Variant
        """
        for window in self.__windows:
            for view in window.container.views:
                view.webview.set_setting(key, value)

    @property
    def pages_menu(self):
        """
            Get pages menu
            @return PagesMenu
        """
        return self.__pages_menu

    @property
    def start_page(self):
        """
            Get start page
            @return uri as str
        """
        value = self.settings.get_value("start-page").get_string()
        if value == "search":
            value = self.search.uri
        elif value == "popular":
            value = "populars://"
        return value

    @property
    def active_window(self):
        """
            Get active window
            @return Window
        """
        for window in self.__windows:
            if window.is_active():
                return window
        # Fallback
        if self.__windows:
            return self.__windows[0]
        return None

    @property
    def windows(self):
        """
            Get windows
            @return [Window]
        """
        return self.__windows

    @property
    def cookies_path(self):
        """
            Cookies sqlite db path
        """
        return self.__COOKIES_PATH

    @property
    def favicons_path(self):
        """
            Cookies sqlite db path
        """
        return self.__FAVICONS_PATH + "/WebpageIcons.db"

#######################
# PRIVATE             #
#######################

    def __save_state(self):
        """
            Save window position and view
        """
        self.download_manager.cancel()
        self.adblock.stop()
        if self.sync_worker is not None:
            self.sync_worker.stop()
        try:
            remember_session = self.settings.get_value("remember-session")
            session_states = []
            for window in self.__windows:
                window.container.stop()
                if not remember_session:
                    continue
                for view in window.container.views:
                    uri = view.webview.get_uri()
                    private = view.webview.private
                    state = view.webview.get_session_state().serialize()
                    session_states.append((uri, private, state.get_data()))
            if remember_session:
                dump(session_states,
                     open(self.LOCAL_PATH + "/session_states.bin", "wb"))
                dump(self.zoom_levels,
                     open(self.LOCAL_PATH + "/zoom_levels.bin", "wb"))
        except Exception as e:
            print("Application::save_state()", e)

    def __get_new_window(self):
        """
            Return a new window
            @return Window
        """
        window = Window(self)
        window.connect('delete-event', self.__on_delete_event)
        window.show()
        self.__windows.append(window)
        return window

    def __show_plugins(self):
        """
            Show available plugins on stdout
        """
        if self.debug:
            self.active_window.container.current.webview.get_context(
            ).get_plugins(None, self.__on_get_plugins, None)

    def __restore_state(self):
        """
            Restore saved state
            @return restored pages count as int
        """
        count = 0
        try:
            session_states = load(
                open(self.LOCAL_PATH + "/session_states.bin", "rb"))
            for (uri, private, state) in session_states:
                webkit_state = WebKit2.WebViewSessionState(
                    GLib.Bytes.new(state))
                GLib.idle_add(self.active_window.container.add_web_view, uri,
                              count == 0, private, None, None, webkit_state)
                count += 1
        except Exception as e:
            print("Application::restore_state()", e)
        return count

    def __on_command_line(self, app, app_cmd_line):
        """
            Handle command line
            @param app as Gio.Application
            @param options as Gio.ApplicationCommandLine
        """
        self.__externals_count = 0
        args = app_cmd_line.get_arguments()
        options = app_cmd_line.get_options_dict()
        if options.contains("debug"):
            GLib.setenv("LIBGL_DEBUG", "verbose", True)
            GLib.setenv("WEBKIT_DEBUG", "network", True)
            GLib.setenv("GST_DEBUG", "webkit*:5", True)
            self.debug = True
        private_browsing = options.contains("private")
        if self.settings.get_value("remember-session"):
            count = self.__restore_state()
        else:
            count = 0
        active_window = self.active_window
        if len(args) > 1:
            for uri in args[1:]:
                active_window.container.add_web_view(uri, True,
                                                     private_browsing)
            active_window.present()
        elif count == 0:
            # We already have a window, open a new one
            if active_window.container.current:
                window = self.__get_new_window()
                window.container.add_web_view(self.start_page, True,
                                              private_browsing)
            else:
                active_window.container.add_web_view(self.start_page, True,
                                                     private_browsing)
        GLib.idle_add(self.__show_plugins)
        return 0

    def __on_get_plugins(self, source, result, data):
        """
            Print plugins on command line
            @param source as GObject.Object
            @param result as Gio.AsyncResult
            @param data as None
        """
        plugins = source.get_plugins_finish(result)
        for plugin in plugins:
            print(plugin.get_name(), plugin.get_description(),
                  plugin.get_path())

    def __on_delete_event(self, window, event):
        """
            Exit application
            @param window as Window
            @param event as Gdk.Event
        """
        self.__save_state()
        self.__windows.remove(window)
        window.destroy()
        if not self.__windows:
            self.quit()

    def __on_settings_activate(self, action, param):
        """
            Show settings dialog
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        dialog = SettingsDialog(self.active_window)
        dialog.show()

    def __on_about_activate(self, action, param):
        """
            Setup about dialog
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Eolie/AboutDialog.ui')
        about = builder.get_object('about_dialog')
        window = self.active_window
        if window is not None:
            about.set_transient_for(window)
        about.connect("response", self.__on_about_activate_response)
        about.show()

    def __on_shortcuts_activate(self, action, param):
        """
            Show help in yelp
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        try:
            builder = Gtk.Builder()
            builder.add_from_resource('/org/gnome/Eolie/Shortcuts.ui')
            shortcuts = builder.get_object('shortcuts')
            window = self.active_window
            if window is not None:
                shortcuts.set_transient_for(window)
            shortcuts.show()
        except:  # GTK < 3.20
            self.__on_help_activate(action, param)

    def __on_help_activate(self, action, param):
        """
            Show help in yelp
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        try:
            Gtk.show_uri(None, "help:eolie", Gtk.get_current_event_time())
        except:
            print(_("Eolie: You need to install yelp."))

    def __on_about_activate_response(self, dialog, response_id):
        """
            Destroy about dialog when closed
            @param dialog as Gtk.Dialog
            @param response id as int
        """
        dialog.destroy()

    def __setup_app_menu(self):
        """
            Setup application menu
            @return menu as Gio.Menu
        """
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Eolie/Appmenu.ui')
        self.__menu = builder.get_object('app-menu')

        settings_action = Gio.SimpleAction.new('settings', None)
        settings_action.connect('activate', self.__on_settings_activate)
        self.add_action(settings_action)

        about_action = Gio.SimpleAction.new('about', None)
        about_action.connect('activate', self.__on_about_activate)
        self.add_action(about_action)

        shortcuts_action = Gio.SimpleAction.new('shortcuts', None)
        shortcuts_action.connect('activate', self.__on_shortcuts_activate)
        self.add_action(shortcuts_action)

        help_action = Gio.SimpleAction.new('help', None)
        help_action.connect('activate', self.__on_help_activate)
        self.add_action(help_action)

        quit_action = Gio.SimpleAction.new('quit', None)
        quit_action.connect('activate', lambda x, y: self.__save_state())
        self.add_action(quit_action)

    def __on_activate(self, application):
        """
            Call default handler, raise last window
            @param application as Gio.Application
        """
        if self.__windows:
            self.__windows[-1].present()

    def __on_shortcut_action(self, action, param):
        """
            Global shortcuts handler
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        string = param.get_string()
        if string == "new_window":
            window = self.__get_new_window()
            window.container.add_web_view(self.start_page, True)

    def __on_extension_signal(self, connection, sender, path, interface,
                              signal, params, data):
        """
            Show message on wanted window
            @param connection as Gio.DBusConnection
            @param sender as str
            @param path as str
            @param interface as str
            @param signal as str
            @param parameters as GLib.Variant
            @param data
        """
        webview = self.active_window.container.current.webview
        self.active_window.toolbar.title.show_input_warning(webview)
Ejemplo n.º 16
0
class RadioArt(BaseArt):
    """
        Manage radio artwork
    """
    if GLib.getenv("XDG_DATA_HOME") is None:
        _RADIOS_PATH = GLib.get_home_dir() + "/.local/share/lollypop/radios"
    else:
        _RADIOS_PATH = GLib.getenv("XDG_DATA_HOME") + "/lollypop/radios"

    def __init__(self):
        """
            Init radio art
        """
        BaseArt.__init__(self)
        d = Gio.File.new_for_path(self._RADIOS_PATH)
        if not d.query_exists():
            try:
                d.make_directory_with_parents()
            except Exception as e:
                print("RadioArt.__init__(): %s" % e)

    def get_radio_cache_path(self, name, size):
        """
            get cover cache path for radio
            @param name as string
            @return cover path as string or None if no cover
        """
        filename = ""
        try:
            filename = self.__get_radio_cache_name(name)
            cache_path_png = "%s/%s_%s.png" % (self._CACHE_PATH,
                                               filename,
                                               size)
            f = Gio.File.new_for_path(cache_path_png)
            if f.query_exists():
                return cache_path_png
            else:
                self.get_radio_artwork(name, size, 1)
                if f.query_exists():
                    return cache_path_png
                else:
                    return self._get_default_icon_path(
                                           size,
                                           "audio-input-microphone-symbolic")
        except Exception as e:
            print("Art::get_radio_cache_path(): %s" % e, ascii(filename))
            return None

    def get_radio_artwork(self, name, size, scale):
        """
            Return a cairo surface for radio name
            @param radio name as string
            @param pixbuf size as int
            @param scale factor as int
            @return cairo surface
        """
        size *= scale
        filename = self.__get_radio_cache_name(name)
        cache_path_png = "%s/%s_%s.png" % (self._CACHE_PATH, filename, size)
        pixbuf = None

        try:
            # Look in cache
            f = Gio.File.new_for_path(cache_path_png)
            if f.query_exists():
                pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(cache_path_png,
                                                                size,
                                                                size)
            else:
                path = self.__get_radio_art_path(name)
                if path is not None:
                    pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(path,
                                                                    size,
                                                                    size)
            if pixbuf is None:
                return self.get_default_icon(
                                             "audio-input-microphone-symbolic",
                                             size,
                                             scale)
            pixbuf.savev(cache_path_png, "png", [None], [None])
            surface = Gdk.cairo_surface_create_from_pixbuf(pixbuf, scale, None)
            return surface

        except Exception as e:
            print(e)
            return self.get_default_icon("audio-input-microphone-symbolic",
                                         size,
                                         scale)

    def copy_uri_to_cache(self, params):
        """
            Copy uri to cache at size
            @param params as (str, str, int)
            @thread safe
        """
        uri, name, size = params
        filename = self.__get_radio_cache_name(name)
        cache_path_png = "%s/%s_%s.png" % (self._CACHE_PATH, filename, size)
        s = Gio.File.new_for_uri(uri)
        d = Gio.File.new_for_path(cache_path_png)
        s.copy(d, Gio.FileCopyFlags.OVERWRITE, None, None)
        GLib.idle_add(self.emit, "radio-artwork-changed", name)

    def rename_radio(self, old_name, new_name):
        """
            Rename artwork
            @param old name as str
            @param new name as str
        """
        old = "%s/%s.png" % (self._RADIOS_PATH, old_name)
        new = "%s/%s.png" % (self._RADIOS_PATH, new_name)
        try:
            src = Gio.File.new_for_path(old)
            dst = Gio.File.new_for_path(new)
            src.move(dst, Gio.FileCopyFlags.OVERWRITE, None, None)
        except Exception as e:
            print("RadioArt::rename_radio(): %s" % e)

    def save_radio_artwork(self, pixbuf, radio):
        """
            Save pixbuf for radio
            @param pixbuf as Gdk.Pixbuf
            @param radio name as string
        """
        try:
            artpath = self._RADIOS_PATH + "/" +\
                      radio.replace("/", "-") + ".png"
            pixbuf.savev(artpath, "png", [None], [None])
        except Exception as e:
            print("RadioArt::save_radio_artwork(): %s" % e)

    def radio_artwork_update(self, name):
        """
            Announce radio logo update
            @param radio name as string
        """
        self.emit("radio-artwork-changed", name)

    def clean_radio_cache(self, name):
        """
            Remove logo from cache for radio
            @param radio name as string
        """
        cache_name = self.__get_radio_cache_name(name)
        try:
            f = Gio.File.new_for_path(self._CACHE_PATH)
            infos = f.enumerate_children(
                "standard::name",
                Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
                None)
            for info in infos:
                f = infos.get_child(info)
                basename = f.get_basename()
                if re.search("%s_.*\.png" % re.escape(cache_name), basename):
                    f.delete()
        except Exception as e:
            print("RadioArt::clean_radio_cache(): ", e, cache_name)

#######################
# PRIVATE             #
#######################
    def __get_radio_art_path(self, name):
        """
            Look for radio covers
            @param radio name as string
            @return cover file path as string
        """
        try:
            name = name.replace("/", "-")
            f = Gio.File.new_for_path(self._RADIOS_PATH + "/" + name + ".png")
            if f.query_exists():
                return self._RADIOS_PATH + "/" + name + ".png"
            return None
        except Exception as e:
            print("Art::__get_radio_art_path(): %s" % e)

    def __get_radio_cache_name(self, name):
        """
            Get a uniq string for radio
            @param album id as int
            @param sql as sqlite cursor
        """
        return "@@"+name.replace("/", "-")+"@@radio@@"
Ejemplo n.º 17
0
class DatabaseBookmarks:
    """
        Eolie bookmarks db
    """
    if GLib.getenv("XDG_DATA_HOME") is None:
        __LOCAL_PATH = GLib.get_home_dir() + "/.local/share/eolie"
    else:
        __LOCAL_PATH = GLib.getenv("XDG_DATA_HOME") + "/eolie"
    DB_PATH = "%s/bookmarks.db" % __LOCAL_PATH

    # SQLite documentation:
    # In SQLite, a column with type INTEGER PRIMARY KEY
    # is an alias for the ROWID.
    # Here, we define an id INT PRIMARY KEY but never feed it,
    # this make VACUUM not destroy rowids...
    __create_bookmarks = '''CREATE TABLE bookmarks (
                                               id INTEGER PRIMARY KEY,
                                               title TEXT NOT NULL,
                                               uri TEXT NOT NULL
                                               )'''
    __create_tags = '''CREATE TABLE tags (id INTEGER PRIMARY KEY,
                                          title TEXT NOT NULL)'''
    __create_bookmarks_tags = '''CREATE TABLE bookmarks_tags (
                                                    id INTEGER PRIMARY KEY,
                                                    bookmark_id INT NOT NULL,
                                                    tag_id INT NOT NULL)'''

    def __init__(self):
        """
            Create database tables or manage update if needed
        """
        f = Gio.File.new_for_path(self.DB_PATH)
        if not f.query_exists():
            try:
                d = Gio.File.new_for_path(self.__LOCAL_PATH)
                if not d.query_exists():
                    d.make_directory_with_parents()
                # Create db schema
                with SqlCursor(self) as sql:
                    sql.execute(self.__create_bookmarks)
                    sql.execute(self.__create_tags)
                    sql.execute(self.__create_bookmarks_tags)
                    sql.commit()
            except Exception as e:
                print("DatabaseBookmarks::__init__(): %s" % e)

    def add(self, title, uri, tags):
        """
            Add a new bookmark
            @param title as str
            @param uri as str
            @param tags as [str]
        """
        if not uri or not title:
            return
        with SqlCursor(self) as sql:
            result = sql.execute(
                "INSERT INTO bookmarks\
                                  (title, uri)\
                                  VALUES (?, ?)", (title, uri))
            bookmarks_id = result.lastrowid
            for tag in tags:
                if not tag:
                    continue
                tag_id = self.get_tag_id(tag)
                if tag_id is None:
                    result = sql.execute(
                        "INSERT INTO tags\
                                          (title) VALUES (?)", (tag, ))
                    tag_id = result.lastrowid
                sql.execute(
                    "INSERT INTO bookmarks_tags\
                             (bookmark_id, tag_id) VALUES (?, ?)",
                    (bookmarks_id, tag_id))
            sql.commit()
            # We need this as current db is attached to history
            El().history.add(title, uri, 0)

    def get_id(self, uri):
        """
            Get id for uri
            @param uri as str
        """
        with SqlCursor(self) as sql:
            result = sql.execute(
                "SELECT rowid\
                                  FROM bookmarks\
                                  WHERE uri=?", (uri, ))
            v = result.fetchone()
            if v is not None:
                return v[0]
            return None

    def get_tag_id(self, title):
        """
            Get tag id
            @param title as str
        """
        with SqlCursor(self) as sql:
            result = sql.execute(
                "SELECT rowid\
                                  FROM tags\
                                  WHERE title=?", (title, ))
            v = result.fetchone()
            if v is not None:
                return v[0]
            return None

    def get_tags(self):
        """
            Get all tags
            @return [rowid, str]
        """
        with SqlCursor(self) as sql:
            result = sql.execute("SELECT rowid, title\
                                  FROM tags\
                                  ORDER BY title COLLATE LOCALIZED")
            return list(result)

    def get_bookmarks(self, tag_id):
        """
            Get all bookmarks
            @param tag id as int
            @return [(id, title, uri)]
        """
        with SqlCursor(self) as sql:
            result = sql.execute(
                "\
                            SELECT bookmarks.rowid,\
                                   bookmarks.title,\
                                   bookmarks.uri\
                            FROM bookmarks, bookmarks_tags, history.history\
                            WHERE bookmarks.rowid=bookmarks_tags.bookmark_id\
                            AND bookmarks_tags.tag_id=?\
                            AND history.uri=bookmarks.uri\
                            ORDER BY history.popularity DESC", (tag_id, ))
            return list(result)

    def get_populars(self):
        """
            Get popular bookmarks
        """
        with SqlCursor(self) as sql:
            result = sql.execute("\
                            SELECT bookmarks.rowid,\
                                   bookmarks.title,\
                                   bookmarks.uri\
                            FROM bookmarks, history.history\
                            WHERE history.uri=bookmarks.uri\
                            AND history.popularity!=0\
                            ORDER BY history.popularity DESC")
            return list(result)

    def get_recents(self):
        """
            Get recents bookmarks
        """
        with SqlCursor(self) as sql:
            result = sql.execute("\
                            SELECT bookmarks.rowid,\
                                   bookmarks.title,\
                                   bookmarks.uri\
                            FROM bookmarks, history.history\
                            WHERE history.uri=bookmarks.uri\
                            AND history.mtime != 0\
                            ORDER BY history.mtime DESC")
            return list(result)

    def import_firefox(self):
        """
            Mozilla Firefox importer
        """
        firefox_path = GLib.get_home_dir() + "/.mozilla/firefox/"
        d = Gio.File.new_for_path(firefox_path)
        infos = d.enumerate_children('standard::name,standard::type',
                                     Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
                                     None)
        sqlite_path = None
        for info in infos:
            if info.get_file_type() == Gio.FileType.DIRECTORY:
                f = Gio.File.new_for_path(firefox_path + info.get_name() +
                                          "/places.sqlite")
                if f.query_exists():
                    sqlite_path = f.get_path()
                    break
        if sqlite_path is not None:
            c = sqlite3.connect(sqlite_path, 600.0)
            result = c.execute("SELECT bookmarks.title,\
                                       moz_places.url,\
                                       tag.title\
                                FROM moz_bookmarks AS bookmarks,\
                                     moz_bookmarks AS tag,\
                                     moz_places\
                                WHERE bookmarks.fk=moz_places.id\
                                AND bookmarks.type=1\
                                AND tag.id=bookmarks.parent")
            for (title, uri, tag) in list(result):
                rowid = self.get_id(uri)
                if rowid is None:
                    self.add(title, uri, [tag])

    def search(self, search):
        """
            Search string in db (uri and title)
            @param search as str
        """
        with SqlCursor(self) as sql:
            filter = '%' + search + '%'
            result = sql.execute(
                "SELECT title, uri\
                                  FROM bookmarks\
                                  WHERE title LIKE ?\
                                   OR uri LIKE ?\
                                  ORDER BY popularity DESC, mtime DESC",
                (filter, filter))
            return list(result)

    def get_cursor(self):
        """
            Return a new sqlite cursor
        """
        try:
            c = sqlite3.connect(self.DB_PATH, 600.0)
            c.create_collation('LOCALIZED', LocalizedCollation())
            c.execute("ATTACH DATABASE '%s' AS history" %
                      DatabaseHistory.DB_PATH)
            c.create_function("noaccents", 1, noaccents)
            return c
        except:
            exit(-1)

    def drop_db(self):
        """
            Drop database
        """
        try:
            f = Gio.File.new_for_path(self.DB_PATH)
            f.trash()
        except Exception as e:
            print("DatabaseBookmarks::drop_db():", e)
Ejemplo n.º 18
0
from datetime import datetime
from gi._gi import variant_type_from_string
from gi.repository import GLib
from gi.repository import Gio

gettext.bindtextdomain("{{UUID}}", os.path.expanduser("~") + "/.local/share/locale")
gettext.textdomain("{{UUID}}")
_ = gettext.gettext

# The application ID is also used as the daemon name.
APPLICATION_ID = "org.cinnamon.Applets.WallpaperChangerApplet.Daemon"
SCHEMA_NAME = "org.cinnamon.applets.{{UUID}}"
SCHEMA_PATH = "/org/cinnamon/applets/{{UUID}}/"

CINNAMON_VERSION = GLib.getenv("CINNAMON_VERSION")
XLET_DIR = os.path.dirname(os.path.abspath(__file__))

__daemon_path__ = XLET_DIR
__version__ = "2.2.0"


WallChangerDaemonDBusInterface = Gio.DBusNodeInfo.new_for_xml("""<node>\
    <interface name="%s">\
        <method name="LoadProfile">\
            <arg direction="in" name="profile" type="s" />\
        </method>\
        <method name="Next">\
            <arg direction="out" name="uri" type="s" />\
        </method>\
        <method name="Prev">\
Ejemplo n.º 19
0
 def __init__(
         self,
         connmgr,
         datadir=GLib.getenv("HOME") + "/.config/google-chrome",
         namespace="com.google.chrome.Policies"):
     super(ChromeLogger, self).__init__(connmgr, datadir, namespace)
Ejemplo n.º 20
0
def is_gnome():
    """
        Return True if desktop is Gnome
    """
    return GLib.getenv("XDG_CURRENT_DESKTOP") == "GNOME"
Ejemplo n.º 21
0
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY 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/>.

from gi.repository import Gio, GLib

El = Gio.Application.get_default

PROXY_BUS = 'org.gnome.Eolie.Proxy.Page%s'
PROXY_PATH = '/org/gnome/EolieProxy'
PROXY_INTERFACE = 'org.gnome.Eolie.Proxy'

# Setup common paths
if GLib.getenv("XDG_DATA_HOME") is None:
    LOCAL_PATH = GLib.get_home_dir() + "/.local/share"
else:
    LOCAL_PATH = GLib.getenv("XDG_DATA_HOME")

EOLIE_LOCAL_PATH = LOCAL_PATH + "/eolie"
ADBLOCK_JS = "%s/adblock_js" % EOLIE_LOCAL_PATH

if GLib.getenv("XDG_CONFIG_HOME") is None:
    CONFIG_PATH = GLib.get_home_dir() + "/.config"
else:
    CONFIG_PATH = GLib.getenv("XDG_CONFIG_HOME")

if GLib.getenv("XDG_CACHE_HOME") is None:
    CACHE_PATH = GLib.get_home_dir() + "/.cache/eolie"
else:
Ejemplo n.º 22
0
def session_is_cinnamon():
    if "cinnamon" in GLib.getenv("DESKTOP_SESSION"):
        if GLib.find_program_in_path("cinnamon-session-quit"):
            return True

    return False
Ejemplo n.º 23
0
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY 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/>.

from gi.repository import Gio, GLib

El = Gio.Application.get_default

PROXY_BUS = 'org.gnome.Eolie.Proxy'
PROXY_PATH = '/org/gnome/EolieProxy'


# Setup common paths
if GLib.getenv("XDG_DATA_HOME") is None:
    LOCAL_PATH = GLib.get_home_dir() + "/.local/share"
else:
    LOCAL_PATH = GLib.getenv("XDG_DATA_HOME")

EOLIE_LOCAL_PATH = LOCAL_PATH + "/eolie"

if GLib.getenv("XDG_CONFIG_HOME") is None:
    CONFIG_PATH = GLib.get_home_dir() + "/.config"
else:
    CONFIG_PATH = GLib.getenv("XDG_CONFIG_HOME")


class TimeSpan:
    HOUR = "0"
    DAY = "1"
Ejemplo n.º 24
0
def is_gnome():
    """
        Return True if desktop is Gnome
    """
    return GLib.getenv("XDG_CURRENT_DESKTOP") == "GNOME"
Ejemplo n.º 25
0
    def __init__(self, window):
        """
            Init dialog
            @param window as Window
        """
        builder = Gtk.Builder()
        builder.add_from_resource("/org/gnome/Eolie/SettingsDialog.ui")

        self.__settings_dialog = builder.get_object("settings_dialog")
        self.__settings_dialog.set_transient_for(window)
        # self.__settings_dialog.connect("destroy", self.__on_destroy)

        if False:
            self.__settings_dialog.set_title(_("Preferences"))
        else:
            headerbar = builder.get_object("header_bar")
            headerbar.set_title(_("Preferences"))
            self.__settings_dialog.set_titlebar(headerbar)

        download_chooser = builder.get_object("download_chooser")
        dir_uri = El().settings.get_value("download-uri").get_string()
        if not dir_uri:
            directory = GLib.get_user_special_dir(
                GLib.UserDirectory.DIRECTORY_DOWNLOAD)
            if directory is not None:
                dir_uri = GLib.filename_to_uri(directory, None)
        if dir_uri:
            download_chooser.set_uri(dir_uri)
        else:
            download_chooser.set_uri("file://" + GLib.getenv("HOME"))

        open_downloads = builder.get_object("open_downloads_check")
        open_downloads.set_active(El().settings.get_value("open-downloads"))

        self.__start_page_uri = builder.get_object("start_page_uri")
        combo_start = builder.get_object("combo_start")
        start_page = El().settings.get_value("start-page").get_string()
        if start_page.startswith("http"):
            combo_start.set_active_id("address")
            self.__start_page_uri.set_text(start_page)
            self.__start_page_uri.show()
        else:
            combo_start.set_active_id(start_page)

        combo_engine = builder.get_object("combo_engine")
        combo_engine.set_active_id(
            El().settings.get_value("search-engine").get_string())

        remember_session = builder.get_object("remember_sessions_check")
        remember_session.set_active(
            El().settings.get_value("remember-session"))

        enable_plugins = builder.get_object("plugins_check")
        enable_plugins.set_active(El().settings.get_value("enable-plugins"))

        self.__fonts_grid = builder.get_object("fonts_grid")
        use_system_fonts = builder.get_object("system_fonts_check")
        use_system_fonts.set_active(
            El().settings.get_value("use-system-fonts"))
        self.__fonts_grid.set_sensitive(
            not El().settings.get_value("use-system-fonts"))

        sans_serif_button = builder.get_object("sans_serif_button")
        sans_serif_button.set_font_name(
            El().settings.get_value("font-sans-serif").get_string())
        serif_button = builder.get_object("serif_button")
        serif_button.set_font_name(
            El().settings.get_value("font-serif").get_string())
        monospace_button = builder.get_object("monospace_button")
        monospace_button.set_font_name(
            El().settings.get_value("font-monospace").get_string())

        min_font_size_spin = builder.get_object("min_font_size_spin")
        min_font_size_spin.set_value(
            El().settings.get_value("min-font-size").get_int32())

        monitor_model = get_current_monitor_model(window)
        zoom_levels = El().settings.get_value("default-zoom-level")
        wanted_zoom_level = 1.0
        try:
            for zoom_level in zoom_levels:
                zoom_splited = zoom_level.split('@')
                if zoom_splited[0] == monitor_model:
                    wanted_zoom_level = float(zoom_splited[1])
        except:
            pass
        default_zoom_level = builder.get_object("default_zoom_level")
        default_zoom_level.set_value(float(wanted_zoom_level))

        cookies_combo = builder.get_object("cookies_combo")
        storage = El().settings.get_enum("cookie-storage")
        cookies_combo.set_active_id(str(storage))

        if GLib.find_program_in_path("seahorse") is None:
            button = builder.get_object("manage_passwords_button")
            button.set_sensitive(False)
            button.set_label(
                _("Installing seahorse will allow you\n"
                  "managing your passwords"))

        remember_passwords = builder.get_object("remember_passwords_check")
        remember_passwords.set_active(
            El().settings.get_value("remember-passwords"))

        tracking_check = builder.get_object("tracking_check")
        tracking_check.set_active(El().settings.get_value("do-not-track"))
        label = builder.get_object("result_label")
        sync_button = builder.get_object("sync_button")
        if El().sync_worker is not None:
            login_entry = builder.get_object("login_entry")
            login_entry.set_text(El().sync_worker.username)
            password_entry = builder.get_object("password_entry")
            image = builder.get_object("result_image")
            if El().sync_worker.status:
                label.set_text(_("Synchronization is working"))
                image.set_from_icon_name("network-transmit-receive-symbolic",
                                         Gtk.IconSize.MENU)
            sync_button.connect("clicked", self.__on_sync_button_clicked,
                                login_entry, password_entry, label, image)
        else:
            try:
                from eolie.mozilla_sync import SyncWorker
                SyncWorker  # Just make PEP8 happy
            except Exception as e:
                label.set_text(
                    _("Synchronization is not available"
                      " on your computer:\n %s") % e)
                sync_button.set_sensitive(False)

        builder.connect_signals(self)
Ejemplo n.º 26
0
class Application(Gtk.Application):
    """
        Eolie application:
    """

    if GLib.getenv("XDG_DATA_HOME") is None:
        __LOCAL_PATH = GLib.get_home_dir() + "/.local/share/eolie"
    else:
        __LOCAL_PATH = GLib.getenv("XDG_DATA_HOME") + "/eolie"
    __COOKIES_PATH = "%s/cookies.db" % __LOCAL_PATH
    __FAVICONS_PATH = "%s/favicons" % __LOCAL_PATH

    def __init__(self, extension_dir):
        """
            Create application
            @param extension_dir as str
        """
        Gtk.Application.__init__(
            self,
            application_id='org.gnome.Eolie',
            flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
        self.set_property('register-session', True)
        # Ideally, we will be able to delete this once Flatpak has a solution
        # for SSL certificate management inside of applications.
        if GLib.file_test("/app", GLib.FileTest.EXISTS):
            paths = [
                "/etc/ssl/certs/ca-certificates.crt", "/etc/pki/tls/cert.pem",
                "/etc/ssl/cert.pem"
            ]
            for path in paths:
                if GLib.file_test(path, GLib.FileTest.EXISTS):
                    GLib.setenv('SSL_CERT_FILE', path, True)
                    break
        self.__extension_dir = extension_dir
        self.__windows = []
        self.debug = False
        self.cursors = {}
        GLib.set_application_name('Eolie')
        GLib.set_prgname('eolie')
        self.connect('activate', self.__on_activate)
        self.connect('command-line', self.__on_command_line)
        self.register(None)
        if self.get_is_remote():
            Gdk.notify_startup_complete()

    def init(self):
        """
            Init main application
        """
        self.__is_fs = False
        if Gtk.get_minor_version() > 18:
            cssProviderFile = Gio.File.new_for_uri(
                'resource:///org/gnome/Eolie/application.css')
        else:
            cssProviderFile = Gio.File.new_for_uri(
                'resource:///org/gnome/Eolie/application-legacy.css')
        cssProvider = Gtk.CssProvider()
        cssProvider.load_from_file(cssProviderFile)
        screen = Gdk.Screen.get_default()
        styleContext = Gtk.StyleContext()
        styleContext.add_provider_for_screen(screen, cssProvider,
                                             Gtk.STYLE_PROVIDER_PRIORITY_USER)
        self.settings = Settings.new()
        self.history = DatabaseHistory()
        self.bookmarks = DatabaseBookmarks()
        # We store cursors for main thread
        SqlCursor.add(self.history)
        SqlCursor.add(self.bookmarks)
        self.bookmarks.import_firefox()
        adblock = DatabaseAdblock()
        adblock.update()
        self.art = Art()
        self.search = Search()
        self.downloads_manager = DownloadsManager()

        shortcut_action = Gio.SimpleAction.new('shortcut',
                                               GLib.VariantType.new('s'))
        shortcut_action.connect('activate', self.__on_shortcut_action)
        self.add_action(shortcut_action)
        self.set_accels_for_action("app.shortcut::uri", ["<Control>l"])
        self.set_accels_for_action("app.shortcut::new_page", ["<Control>t"])
        self.set_accels_for_action("app.shortcut::close_page", ["<Control>w"])

        # Set some WebKit defaults
        context = WebKit2.WebContext.get_default()
        GLib.setenv('PYTHONPATH', self.__extension_dir, True)
        context.set_web_extensions_directory(self.__extension_dir)

        data_manager = WebKit2.WebsiteDataManager()
        context.new_with_website_data_manager(data_manager)
        context.set_process_model(
            WebKit2.ProcessModel.MULTIPLE_SECONDARY_PROCESSES)
        context.set_cache_model(WebKit2.CacheModel.WEB_BROWSER)
        d = Gio.File.new_for_path(self.__FAVICONS_PATH)
        if not d.query_exists():
            d.make_directory_with_parents()
        context.set_favicon_database_directory(self.__FAVICONS_PATH)
        cookie_manager = context.get_cookie_manager()
        cookie_manager.set_accept_policy(
            WebKit2.CookieAcceptPolicy.NO_THIRD_PARTY)
        cookie_manager.set_persistent_storage(
            self.__COOKIES_PATH, WebKit2.CookiePersistentStorage.SQLITE)

    def do_startup(self):
        """
            Init application
        """
        Gtk.Application.do_startup(self)

        if not self.__windows:
            self.init()
            menu = self.__setup_app_menu()
            if self.prefers_app_menu():
                self.set_app_menu(menu)
                window = Window()
            else:
                window = Window()
                window.setup_menu(menu)
            window.connect('delete-event', self.__on_delete_event)
            window.show()
            self.__windows.append(window)

    def prepare_to_exit(self, action=None, param=None, exit=True):
        """
            Save window position and view
        """
        self.downloads_manager.cancel()
        if exit:
            self.quit()

    def quit(self):
        """
            Quit Eolie
        """
        for window in self.__windows:
            window.destroy()

    @property
    def active_window(self):
        """
            Get active window
            @return Window
        """
        for window in self.__windows:
            if window.is_active():
                return window
        # Fallback
        if self.__windows:
            return self.__windows[0]
        return None

    @property
    def windows(self):
        """
            Get windows
            @return [Window]
        """
        return self.__windows

#######################
# PRIVATE             #
#######################

    def __on_command_line(self, app, app_cmd_line):
        """
            Handle command line
            @param app as Gio.Application
            @param options as Gio.ApplicationCommandLine
        """
        self.__externals_count = 0
        args = app_cmd_line.get_arguments()
        options = app_cmd_line.get_options_dict()
        if options.contains('debug'):
            pass
        else:
            active_window = self.active_window
            if len(args) > 1:
                for uri in args[1:]:
                    active_window.container.add_web_view(uri, True)
                active_window.present()
            else:
                active_window.container.add_web_view("google.fr", True)
        return 0

    def __on_delete_event(self, widget, event):
        """
            Exit application
            @param widget as Gtk.Widget
            @param event as Gdk.Event
        """
        self.prepare_to_exit()

    def __on_settings_activate(self, action, param):
        """
            Show settings dialog
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        dialog = SettingsDialog()
        dialog.show()

    def __on_about_activate(self, action, param):
        """
            Setup about dialog
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Eolie/AboutDialog.ui')
        about = builder.get_object('about_dialog')
        window = self.active_window
        if window is not None:
            about.set_transient_for(window)
        about.connect("response", self.__on_about_activate_response)
        about.show()

    def __on_shortcuts_activate(self, action, param):
        """
            Show help in yelp
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        try:
            builder = Gtk.Builder()
            builder.add_from_resource('/org/gnome/Eolie/Shortcuts.ui')
            shortcuts = builder.get_object('shortcuts')
            window = self.active_window
            if window is not None:
                shortcuts.set_transient_for(window)
            shortcuts.show()
        except:  # GTK < 3.20
            self.__on_help_activate(action, param)

    def __on_help_activate(self, action, param):
        """
            Show help in yelp
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        try:
            Gtk.show_uri(None, "help:eolie", Gtk.get_current_event_time())
        except:
            print(_("Eolie: You need to install yelp."))

    def __on_about_activate_response(self, dialog, response_id):
        """
            Destroy about dialog when closed
            @param dialog as Gtk.Dialog
            @param response id as int
        """
        dialog.destroy()

    def __setup_app_menu(self):
        """
            Setup application menu
            @return menu as Gio.Menu
        """
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Eolie/Appmenu.ui')
        menu = builder.get_object('app-menu')

        settings_action = Gio.SimpleAction.new('settings', None)
        settings_action.connect('activate', self.__on_settings_activate)
        self.add_action(settings_action)

        about_action = Gio.SimpleAction.new('about', None)
        about_action.connect('activate', self.__on_about_activate)
        self.add_action(about_action)

        shortcuts_action = Gio.SimpleAction.new('shortcuts', None)
        shortcuts_action.connect('activate', self.__on_shortcuts_activate)
        self.add_action(shortcuts_action)

        help_action = Gio.SimpleAction.new('help', None)
        help_action.connect('activate', self.__on_help_activate)
        self.add_action(help_action)

        quit_action = Gio.SimpleAction.new('quit', None)
        quit_action.connect('activate', self.prepare_to_exit)
        self.add_action(quit_action)

        return menu

    def __on_activate(self, application):
        """
            Call default handler, raise last window
            @param application as Gio.Application
        """
        if self.__windows:
            self.__windows[-1].present()

    def __on_shortcut_action(self, action, param):
        """
            Global shortcuts handler
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        window = self.active_window
        if window is None:
            return
        string = param.get_string()
        if string == "uri":
            window.toolbar.title.focus_entry()
        elif string == "new_page":
            window.container.add_web_view("google.fr", True)
        elif string == "close_page":
            window.container.sidebar.current.destroy()
Ejemplo n.º 27
0
def is_unity():
    """
        Return True if desktop is Gnome
    """
    return GLib.getenv("XDG_CURRENT_DESKTOP") == "ubuntu:GNOME"
Ejemplo n.º 28
0
class History:
    """
        Playlists manager
    """
    if GLib.getenv("XDG_DATA_HOME") is None:
        __LOCAL_PATH = GLib.get_home_dir() + "/.local/share/lollypop"
    else:
        __LOCAL_PATH = GLib.getenv("XDG_DATA_HOME") + "/lollypop"
    __DB_PATH = "%s/history.db" % __LOCAL_PATH
    __LIMIT = 1000000  # Delete when limit is reached
    __DELETE = 100     # How many elements to delete
    __create_history = """CREATE TABLE history (
                            id INTEGER PRIMARY KEY,
                            name TEXT NOT NULL,
                            duration INT NOT NULL,
                            ltime INT NOT NULL,
                            popularity INT NOT NULL,
                            rate INT NOT NULL,
                            mtime INT NOT NULL,
                            album_rate INT NOT NULL,
                            loved_album INT NOT NULL,
                            album_popularity INT NOT NULL)"""

    def __init__(self):
        """
            Init playlists manager
        """
        # Create db schema
        try:
            with SqlCursor(self) as sql:
                sql.execute(self.__create_history)
                sql.commit()
        except:
            pass
        with SqlCursor(self) as sql:
            result = sql.execute("SELECT COUNT(*)\
                                  FROM history")
            v = result.fetchone()
            if v is not None and v[0] > self.__LIMIT:
                sql.execute("DELETE FROM history\
                             WHERE rowid IN (SELECT rowid\
                                             FROM history\
                                             LIMIT %s)" % self.__DELETE)
                sql.commit()
                sql.execute("VACUUM")

    def add(self, name, duration, popularity, rate,
            ltime, mtime, loved_album, album_popularity, album_rate):
        """
            Add a radio, update url if radio already exists in db
            @param name as str
            @param duration as int
            @param popularity as int
            @param rate as int
            @param ltime as int
            @param mtime as int
            @param loved album as bool
            @param album_popularity as int
            @param album_rate as int
            @thread safe
        """
        with SqlCursor(self) as sql:
            if self.exists(name, duration):
                sql.execute("UPDATE history\
                             SET popularity=?,rate=?,ltime=?,mtime=?,\
                             loved_album=?,album_popularity=?,album_rate=?\
                             WHERE name=? AND duration=?",
                            (popularity, rate, ltime, mtime, loved_album,
                             album_popularity, album_rate, name, duration))
            else:
                sql.execute("INSERT INTO history\
                             (name, duration, popularity, rate, ltime, mtime,\
                             loved_album, album_popularity, album_rate)\
                             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
                            (name, duration, popularity, rate, ltime, mtime,
                             loved_album, album_popularity, album_rate))
            sql.commit()

    def get(self, name, duration):
        """
            Get stats for track with filename and duration
            @param path as str
            @param duration as int
            @return (popularity, ltime, mtime,
                     loved album, album_popularity)
             as (int, int, int, int, int, int)
        """
        with SqlCursor(self) as sql:
            result = sql.execute("SELECT popularity, rate, ltime, mtime,\
                                  loved_album, album_popularity, album_rate\
                                  FROM history\
                                  WHERE name=?\
                                  AND duration=?",
                                 (name, duration))
            v = result.fetchone()
            if v is not None:
                return v
            return (0, 0, 0, 0, 0, 0, 0)

    def exists(self, name, duration):
        """
            Return True if entry exists
            @param name as str
            @parma duration as int
            @return bool
        """
        with SqlCursor(self) as sql:
            result = sql.execute("SELECT rowid\
                                  FROM history\
                                  WHERE name=?\
                                  AND duration=?",
                                 (name, duration))
            v = result.fetchone()
            if v is not None:
                return True
            else:
                return False

    def get_cursor(self):
        """
            Return a new sqlite cursor
        """
        try:
            return sqlite3.connect(self.__DB_PATH, 600.0)
        except:
            exit(-1)
Ejemplo n.º 29
0
class DatabaseAdblock:
    """
        Eolie adblock db
    """
    if GLib.getenv("XDG_DATA_HOME") is None:
        __LOCAL_PATH = GLib.get_home_dir() + "/.local/share/eolie"
    else:
        __LOCAL_PATH = GLib.getenv("XDG_DATA_HOME") + "/eolie"
    DB_PATH = "%s/adblock.db" % __LOCAL_PATH

    __URIS = [
        "https://adaway.org/hosts.txt",
        "http://winhelp2002.mvps.org/hosts.txt",
        "http://hosts-file.net/ad_servers.txt",
        "https://pgl.yoyo.org/adservers/serverlist.php?"
        "hostformat=hosts&showintro=0&mimetype=plaintext"
    ]

    # SQLite documentation:
    # In SQLite, a column with type INTEGER PRIMARY KEY
    # is an alias for the ROWID.
    # Here, we define an id INT PRIMARY KEY but never feed it,
    # this make VACUUM not destroy rowids...
    __create_adblock = '''CREATE TABLE adblock (
                                               id INTEGER PRIMARY KEY,
                                               dns TEXT NOT NULL,
                                               mtime INT NOT NULL
                                               )'''

    def __init__(self):
        """
            Create database tables or manage update if needed
        """
        self.__exceptions = DatabaseExceptions()
        self.__cancellable = Gio.Cancellable.new()
        f = Gio.File.new_for_path(self.DB_PATH)
        # Lazy loading if not empty
        if not f.query_exists():
            try:
                d = Gio.File.new_for_path(self.__LOCAL_PATH)
                if not d.query_exists():
                    d.make_directory_with_parents()
                # Create db schema
                with SqlCursor(self) as sql:
                    sql.execute(self.__create_adblock)
                    sql.commit()
            except Exception as e:
                print("DatabaseAdblock::__init__(): %s" % e)

    def add_exception(self, uri):
        """
            Add an exception
            @param uri as str
        """
        try:
            with SqlCursor(self.__exceptions) as sql:
                sql.execute("INSERT INTO exceptions (uri) VALUES (?)", (uri, ))
                sql.commit()
        except:
            pass

    def remove_exception(self, uri):
        """
            Remove an exception
            @param uri as str
        """
        try:
            with SqlCursor(self.__exceptions) as sql:
                sql.execute("DELETE FROM exceptions WHERE uri=?", (uri, ))
                sql.commit()
        except:
            pass

    def is_an_exception(self, uri):
        """
            True if uri not in exceptions
            @param uri as str
            @return bool
        """
        with SqlCursor(self.__exceptions) as sql:
            result = sql.execute(
                "SELECT rowid FROM exceptions\
                                  WHERE uri=?", (uri, ))
            v = result.fetchone()
            return v is not None

    def update(self):
        """
            Update database
        """
        # Get in db mtime
        # Only update if filters older than one week
        mtime = 0
        with SqlCursor(self) as sql:
            result = sql.execute("SELECT mtime FROM adblock LIMIT 1")
            v = result.fetchone()
            if v is not None:
                mtime = v[0]
        self.__mtime = int(time())
        if self.__mtime - mtime < 604800:
            return
        self.__stop = False
        if Gio.NetworkMonitor.get_default().get_network_available():
            thread = Thread(target=self.__update)
            thread.daemon = True
            thread.start()

    def stop(self):
        """
            Stop update
        """
        self.__cancellable.cancel()
        self.__cancellable.reset()
        self.__stop = True

    def is_blocked(self, uri):
        """
            Return True if uri is blocked
            @param uri as str
            @return bool
        """
        try:
            parse = urlparse(uri)
            with SqlCursor(self) as sql:
                result = sql.execute(
                    "SELECT mtime FROM adblock\
                                      WHERE dns=?", (parse.netloc, ))
                v = result.fetchone()
                return v is not None
        except Exception as e:
            print("DatabaseAdblock::is_blocked():", e)
            return False

    def get_cursor(self):
        """
            Return a new sqlite cursor
        """
        try:
            c = sqlite3.connect(self.DB_PATH, 600.0)
            return c
        except Exception as e:
            print(e)
            exit(-1)

#######################
# PRIVATE             #
#######################

    def __update(self):
        """
            Update database
        """
        SqlCursor.add(self)
        result = ""
        try:
            for uri in self.__URIS:
                session = Soup.Session.new()
                request = session.request(uri)
                stream = request.send(self.__cancellable)
                bytes = bytearray(0)
                buf = stream.read_bytes(1024, self.__cancellable).get_data()
                while buf:
                    bytes += buf
                    buf = stream.read_bytes(1024,
                                            self.__cancellable).get_data()
                result = bytes.decode('utf-8')
                count = 0
                for line in result.split('\n'):
                    if self.__cancellable.is_cancelled() or self.__stop:
                        raise IOError("Cancelled")
                    if line.startswith('#'):
                        continue
                    array = line.replace(' ', '\t', 1).replace('\t', '@',
                                                               1).split('@')
                    if len(array) <= 1:
                        continue
                    dns = array[1].replace(' ', '').replace('\r',
                                                            '').split('#')[0]
                    # Update entry if exists, create else
                    with SqlCursor(self) as sql:
                        sql.execute(
                            "INSERT INTO adblock\
                                          (dns, mtime)\
                                          VALUES (?, ?)", (dns, self.__mtime))
                        count += 1
                        if count == 1000:
                            sql.commit()
                            count = 0
            # Delete removed entries
            with SqlCursor(self) as sql:
                sql.execute(
                    "DELETE FROM adblock\
                             WHERE mtime!=?", (self.__mtime, ))
        except Exception as e:
            print("DatabaseAdlbock:__update():", e)
        with SqlCursor(self) as sql:
            sql.commit()
        SqlCursor.remove(self)
Ejemplo n.º 30
0
class InfoCache:
    """
        Generic class to cache text and images
    """
    if GLib.getenv("XDG_DATA_HOME") is None:
        _INFO_PATH = GLib.get_home_dir() + "/.local/share/lollypop/info"
    else:
        _INFO_PATH = GLib.getenv("XDG_DATA_HOME") + "/lollypop/info"
    if GLib.getenv("XDG_CACHE_HOME") is None:
        _CACHE_PATH = GLib.get_home_dir() + "/.cache/lollypop_info"
    else:
        _CACHE_PATH = GLib.getenv("XDG_CACHE_HOME") + "/lollypop_info"

    WEBSERVICES = [
        ("lastfm", "_get_lastfm_artist_info", "_get_lastfm_album_artwork"),
        ("spotify", "_get_spotify_artist_info", "_get_spotify_album_artwork"),
        ("deezer", "_get_deezer_artist_info", "_get_deezer_album_artwork"),
        ("wikipedia", "_get_wp_artist_info", None)
    ]

    def init():
        """
            Init cache
        """
        if not path.exists(InfoCache._INFO_PATH):
            try:
                mkdir(InfoCache._INFO_PATH)
            except:
                print("Can't create %s" % InfoCache._INFO_PATH)
        if not path.exists(InfoCache._CACHE_PATH):
            try:
                mkdir(InfoCache._CACHE_PATH)
            except:
                print("Can't create %s" % InfoCache._CACHE_PATH)

    def exists(prefix):
        """
            Return True if an info is cached
            @param prefix as string
        """
        exists = False
        for (suffix, helper1, helper2) in InfoCache.WEBSERVICES:
            filepath = "%s/%s_%s.jpg" % (InfoCache._INFO_PATH, escape(prefix),
                                         suffix)
            if path.exists(filepath):
                exists = True
        return exists

    def get_artwork(prefix, suffix, size):
        """
            Return path for artwork
            @param prefix as string
            @param suffix as string
            @param size as int
            @return path as string/None
        """
        try:
            for (suffix, helper1, helper2) in InfoCache.WEBSERVICES:
                extract = None
                filepath = "%s/%s_%s.jpg" % (InfoCache._INFO_PATH,
                                             escape(prefix), suffix)
                filepath_at_size = "%s/%s_%s_%s.jpg" % (
                    InfoCache._CACHE_PATH, escape(prefix), suffix, size)
                if not path.exists(filepath) or path.getsize(filepath) == 0:
                    filepath_at_size = None
                    continue
                # Make cache for this size
                if not path.exists(filepath_at_size):
                    pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
                        filepath, size, size)
                    if pixbuf.get_height() > pixbuf.get_width():
                        vertical = True
                    elif pixbuf.get_height() < pixbuf.get_width():
                        vertical = False
                    else:
                        extract = pixbuf
                    if extract is None:
                        extract = GdkPixbuf.Pixbuf.new(
                            GdkPixbuf.Colorspace.RGB, True, 8, size, size)
                        if vertical:
                            pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
                                filepath, size, -1, True)
                            diff = pixbuf.get_height() - size
                            pixbuf.copy_area(0, diff / 2, pixbuf.get_width(),
                                             size, extract, 0, 0)
                        else:
                            pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
                                filepath, -1, size, True)
                            diff = pixbuf.get_width() - size
                            pixbuf.copy_area(diff / 2, 0, size,
                                             pixbuf.get_height(), extract, 0,
                                             0)
                    extract.savev(filepath_at_size, "jpeg", ["quality"], [
                        str(Lp().settings.get_value(
                            "cover-quality").get_int32())
                    ])
                return filepath_at_size
        except Exception as e:
            print("InfoCache::get_artwork():", e)
            return None

    def get(prefix, suffix):
        """
            Get content from cache
            @param prefix as str
            @param suffix as str
            @return (content as string, data as bytes)
        """
        filepath = "%s/%s_%s" % (InfoCache._INFO_PATH, escape(prefix), suffix)
        content = None
        data = None
        if path.exists(filepath + ".txt"):
            f = Gio.File.new_for_path(filepath + ".txt")
            (status, content, tag) = f.load_contents()
            if not status:
                content = None
            image_path = filepath + ".jpg"
            if path.exists(image_path):
                f = Gio.File.new_for_path(image_path)
                (status, data, tag) = f.load_contents()
                if not status:
                    data = None
        return (content, data)

    def add(prefix, content, data, suffix):
        """
            Add info to store
            @param prefix as str
            @param content as str
            @param data as bytes
            @param suffix as str
        """
        filepath = "%s/%s_%s" % (InfoCache._INFO_PATH, escape(prefix), suffix)
        if content is not None:
            f = Gio.File.new_for_path(filepath + ".txt")
            fstream = f.replace(None, False,
                                Gio.FileCreateFlags.REPLACE_DESTINATION, None)
            if fstream is not None:
                fstream.write(content, None)
                fstream.close()
        if data is None:
            f = Gio.File.new_for_path(filepath + ".jpg")
            fstream = f.replace(None, False,
                                Gio.FileCreateFlags.REPLACE_DESTINATION, None)
            fstream.close()
        else:
            bytes = GLib.Bytes(data)
            stream = Gio.MemoryInputStream.new_from_bytes(bytes)
            bytes.unref()
            pixbuf = GdkPixbuf.Pixbuf.new_from_stream_at_scale(
                stream, ArtSize.ARTIST, -1, True, None)
            stream.close()
            pixbuf.savev(
                filepath + ".jpg", "jpeg", ["quality"],
                [str(Lp().settings.get_value("cover-quality").get_int32())])

    def remove(prefix, suffix):
        """
            Remove info from store
            @param prefix as str
            @param suffix as str
        """
        filepath = "%s/%s_%s.txt" % (InfoCache._INFO_PATH, escape(prefix),
                                     suffix)
        f = Gio.File.new_for_path(filepath)
        try:
            f.delete(None)
        except:
            pass
        filepath = "%s/%s_%s.jpg" % (InfoCache._INFO_PATH, escape(prefix),
                                     suffix)
        f = Gio.File.new_for_path(filepath)
        try:
            f.delete(None)
        except:
            pass

    def uncache_artwork(prefix, suffix, scale):
        """
            Remove artwork from cache
            @param prefix as str
            @param suffix as str
            @param scale factor as int
        """
        for i in [1, 2]:
            filepath = "%s/%s_%s_%s.jpg" % (InfoCache._CACHE_PATH,
                                            escape(prefix), suffix,
                                            ArtSize.ARTIST_SMALL * scale * i)
            f = Gio.File.new_for_path(filepath)
            try:
                f.delete(None)
            except:
                pass
Ejemplo n.º 31
0
def is_unity():
    """
        Return True if desktop is Unity
    """
    return GLib.getenv("XDG_CURRENT_DESKTOP") == "Unity"
Ejemplo n.º 32
0
class Art:
    """
        Base art manager
    """
    if GLib.getenv("XDG_CACHE_HOME") is None:
        __CACHE_PATH = GLib.get_home_dir() + "/.cache/eolie"
    else:
        __CACHE_PATH = GLib.getenv("XDG_CACHE_HOME") + "/eolie"

    def __init__(self):
        """
            Init base art
        """
        self.__create_cache()

    def save_artwork(self, uri, surface, suffix):
        """
            Save artwork for uri with suffix
            @param uri as str
            @param surface as cairo.surface
            @param suffix as str
        """
        encoded = sha256(self.__strip_uri(uri)).hexdigest()
        filepath = "%s/%s_%s.png" % (self.__CACHE_PATH, encoded, suffix)
        pixbuf = Gdk.pixbuf_get_from_surface(surface, 0, 0,
                                             surface.get_width(),
                                             surface.get_height())
        pixbuf.savev(filepath, "png", [None], [None])
        del pixbuf

    def get_artwork(self, uri, suffix, scale_factor, width, heigth):
        """
            @param uri as str
            @param suffix as str
            @param scale factor as int
            @param width as int
            @param height as int
            @return cairo.surface
        """
        encoded = sha256(self.__strip_uri(uri)).hexdigest()
        filepath = "%s/%s_%s.png" % (self.__CACHE_PATH, encoded, suffix)
        f = Gio.File.new_for_path(filepath)
        if f.query_exists():
            pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(filepath,
                                                             width,
                                                             heigth,
                                                             True)
            surface = Gdk.cairo_surface_create_from_pixbuf(pixbuf,
                                                           scale_factor, None)
            del pixbuf
            return surface
        return None

#######################
# PROTECTED           #
#######################

#######################
# PRIVATE             #
#######################
    def __strip_uri(self, uri):
        """
            Remove prefix from uri
            @param uri as str
            @return bytes
        """
        parsed = urlparse(uri)
        scheme = "%s://" % parsed.scheme
        return parsed.geturl().replace(scheme, '', 1).encode("utf-8")

    def __create_cache(self):
        """
            Create cache dir
        """
        d = Gio.File.new_for_path(self.__CACHE_PATH)
        if not d.query_exists():
            try:
                d.make_directory_with_parents()
            except:
                print("Can't create %s" % self.__CACHE_PATH)
Ejemplo n.º 33
0
class BaseArt(GObject.GObject):
    """
        Base art manager
    """
    if GLib.getenv("XDG_CACHE_HOME") is None:
        _CACHE_PATH = GLib.get_home_dir() + "/.cache/lollypop"
    else:
        _CACHE_PATH = GLib.getenv("XDG_CACHE_HOME") + "/lollypop"
    # Fallback when album dir is readonly
    if GLib.getenv("XDG_DATA_HOME") is None:
        _STORE_PATH = GLib.get_home_dir() + "/.local/share/lollypop/store"
    else:
        _STORE_PATH = GLib.getenv("XDG_DATA_HOME") + "/lollypop/store"
    __gsignals__ = {
        "album-artwork-changed":
        (GObject.SignalFlags.RUN_FIRST, None, (int, )),
        "artist-artwork-changed":
        (GObject.SignalFlags.RUN_FIRST, None, (str, )),
        "radio-artwork-changed": (GObject.SignalFlags.RUN_FIRST, None, (str, ))
    }

    def __init__(self):
        """
            Init base art
        """
        GObject.GObject.__init__(self)

    def update_art_size(self):
        """
            Update value with some check
        """
        value = Lp().settings.get_value("cover-size").get_int32()
        # Check value as user can enter bad value via dconf
        if value < ArtSize.SMALL or value > ArtSize.MAX:
            value = 200
        ArtSize.BIG = value
        # For a 200 album artwork, we want a 60 artist artwork
        ArtSize.ARTIST_SMALL = ArtSize.BIG * 60 / 200

    def clean_store(self, filename):
        """
            @param filename as str
        """
        try:
            filepath = self._STORE_PATH + "/" + filename + ".jpg"
            f = Lio.File.new_for_path(filepath)
            if f.query_exists():
                f.delete()
        except Exception as e:
            print("Art::clean_store()", e)

    def get_default_icon(self, icon_name, size, scale):
        """
            Construct an empty cover album,
            code forked Gnome Music, see copyright header
            @param icon_name as str
            @param size as int
            @param scale factor as int
            @return pixbuf as cairo.Surface
        """
        try:
            # First look in cache
            cache_path_jpg = self._get_default_icon_path(size, icon_name)
            f = Lio.File.new_for_path(cache_path_jpg)
            if f.query_exists():
                pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
                    cache_path_jpg, size, size, False)
            else:
                # get a small pixbuf with the given path
                icon_size = size / 4
                icon = Gtk.IconTheme.get_default().load_icon(
                    icon_name, icon_size, 0)
                # create an empty pixbuf with the requested size
                pixbuf = GdkPixbuf.Pixbuf.new(icon.get_colorspace(), True,
                                              icon.get_bits_per_sample(), size,
                                              size)
                pixbuf.fill(0xffffffff)
                icon.composite(pixbuf, icon_size * 3 / 2, icon_size * 3 / 2,
                               icon_size, icon_size, icon_size * 3 / 2,
                               icon_size * 3 / 2, 1, 1,
                               GdkPixbuf.InterpType.NEAREST, 255)
                # Gdk < 3.15 was missing save method
                # > 3.15 is missing savev method
                try:
                    pixbuf.save(cache_path_jpg, "jpeg", ["quality"], [
                        str(Lp().settings.get_value(
                            "cover-quality").get_int32())
                    ])
                except:
                    pixbuf.savev(cache_path_jpg, "jpeg", ["quality"], [
                        str(Lp().settings.get_value(
                            "cover-quality").get_int32())
                    ])
            surface = Gdk.cairo_surface_create_from_pixbuf(pixbuf, scale, None)
            return surface
        except:
            return self.get_default_icon("computer-fail-symbolic",
                                         ArtSize.MEDIUM, scale)

#######################
# PROTECTED           #
#######################

    def _respect_ratio(self, uri):
        """
            Check for aspect ratio based on size
            @param uri as str
            @return respect aspect ratio as bool
        """
        f = Lio.File.new_for_uri(uri)
        (status, data, tag) = f.load_contents(None)
        bytes = GLib.Bytes(data)
        stream = Gio.MemoryInputStream.new_from_bytes(bytes)
        bytes.unref()
        cover = GdkPixbuf.Pixbuf.new_from_stream(stream, None)
        stream.close()
        cover_width = cover.get_width()
        cover_height = cover.get_height()
        del cover
        if cover_width == cover_height:
            return True
        elif cover_width < cover_height:
            cut = cover_height / 5
            return cover_width < cover_height - cut
        else:
            cut = cover_width / 5
            return cover_height < cover_width - cut

    def _create_store(self):
        """
            Create store dir
        """
        d = Lio.File.new_for_path(self._STORE_PATH)
        if not d.query_exists():
            try:
                d.make_directory_with_parents()
            except:
                print("Can't create %s" % self._STORE_PATH)

    def _create_cache(self):
        """
            Create cache dir
        """
        d = Lio.File.new_for_path(self._CACHE_PATH)
        if not d.query_exists():
            try:
                d.make_directory_with_parents()
            except:
                print("Can't create %s" % self._CACHE_PATH)

    def _get_default_icon_path(self, size, icon_name):
        """
            Return default icon path
            @return path as string
        """
        return "%s/%s_%s.jpg" % (self._CACHE_PATH, icon_name, size)
Ejemplo n.º 34
0
def is_unity():
    """
        Return True if desktop is Unity
    """
    return GLib.getenv("XDG_CURRENT_DESKTOP") == "Unity"
Ejemplo n.º 35
0
class Art:
    """
        Base art manager
    """
    if GLib.getenv("XDG_CACHE_HOME") is None:
        __CACHE_PATH = GLib.get_home_dir() + "/.cache/eolie"
    else:
        __CACHE_PATH = GLib.getenv("XDG_CACHE_HOME") + "/eolie"

    def __init__(self):
        """
            Init base art
        """
        self.__create_cache()

    def save_artwork(self, uri, surface, suffix):
        """
            Save artwork for uri with suffix
            @param uri as str
            @param surface as cairo.surface
            @param suffix as str
        """
        filepath = self.get_path(uri, suffix)
        pixbuf = Gdk.pixbuf_get_from_surface(surface, 0, 0,
                                             surface.get_width(),
                                             surface.get_height())
        pixbuf.savev(filepath, "png", [None], [None])
        del pixbuf

    def get_artwork(self, uri, suffix, scale_factor, width, heigth):
        """
            @param uri as str
            @param suffix as str
            @param scale factor as int
            @param width as int
            @param height as int
            @return cairo.surface
        """
        filepath = self.get_path(uri, suffix)
        f = Gio.File.new_for_path(filepath)
        if f.query_exists():
            pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
                filepath, width, heigth, True)
            surface = Gdk.cairo_surface_create_from_pixbuf(
                pixbuf, scale_factor, None)
            del pixbuf
            return surface
        return None

    def get_path(self, uri, suffix):
        """
            Return cache image path
            @return str
        """
        strip = strip_uri(uri, False, True)
        strip = strip.replace("www.", "")
        encoded = sha256(strip.encode("utf-8")).hexdigest()
        filepath = "%s/%s_%s.png" % (self.__CACHE_PATH, encoded, suffix)
        return filepath

    def exists(self, uri, suffix):
        """
            True if exists in cache and not older than one day
            @return bool
        """
        f = Gio.File.new_for_path(self.get_path(uri, suffix))
        exists = f.query_exists()
        if exists:
            info = f.query_info('time::modified', Gio.FileQueryInfoFlags.NONE,
                                None)
            mtime = int(info.get_attribute_as_string('time::modified'))
            if time() - mtime > 86400:
                exists = False
        return exists

    @property
    def base_uri(self):
        """
            Get cache base uri
            @return str
        """
        return GLib.filename_to_uri(self.__CACHE_PATH)

#######################
# PROTECTED           #
#######################

#######################
# PRIVATE             #
#######################

    def __create_cache(self):
        """
            Create cache dir
        """
        d = Gio.File.new_for_path(self.__CACHE_PATH)
        if not d.query_exists():
            try:
                d.make_directory_with_parents()
            except:
                print("Can't create %s" % self.__CACHE_PATH)
Ejemplo n.º 36
0
def is_gnome():
    """
        Return True if desktop is Gnome
    """
    return GLib.getenv("XDG_CURRENT_DESKTOP") in ["ubuntu:GNOME", "GNOME"]
 def __init__(
         self,
         connmgr,
         datadir=GLib.getenv("HOME") + "/.config/google-chrome",
         namespace="com.google.chrome.Policies"):
     super(ChromeLogger, self).__init__(connmgr, datadir, namespace)
Ejemplo n.º 38
0
import os
import argparse
import gettext
import gi
import re
import json
import sys
gi.require_version("Gtk", "3.0")
from gi.repository import Gio, Gtk, GLib

home = os.path.expanduser("~")
APPLICATION_ID = "org.cinnamon.applets.odyseus.extensions-manager-debugger"
SETTING_TYPE_NONE = 0
SETTING_TYPE_INTERNAL = 1
SETTING_TYPE_EXTERNAL = 2
curr_ver = GLib.getenv("CINNAMON_VERSION")
debug = False
translations = {}
XLET_DIR = os.path.dirname(os.path.abspath(__file__))
XLET_UUID = str(os.path.basename(XLET_DIR))


def cmp(x, y):
    """
    cmp(x, y) -> integer

    Return negative if x<y, zero if x==y, positive if x>y.
    """
    return (x > y) - (x < y)

Ejemplo n.º 39
0
import sys
import gettext
import gi

gi.require_version("Gio", "2.0")

from datetime import datetime
from gi.repository import GLib, Gio
from gi._gi import variant_type_from_string

# The application ID is also used as the daemon name.
APPLICATION_ID = "org.cinnamon.Applets.WallpaperChangerApplet.Daemon"
SCHEMA_NAME = "org.cinnamon.applets.0dyseus@WallpaperChangerApplet"
SCHEMA_PATH = "/org/cinnamon/applets/0dyseus@WallpaperChangerApplet/"

CINNAMON_VERSION = GLib.getenv("CINNAMON_VERSION")
HOME = os.path.expanduser("~")
EXTENSION_DIR = os.path.dirname(os.path.abspath(__file__))
EXTENSION_UUID = str(os.path.basename(EXTENSION_DIR))
TRANSLATIONS = {}

__daemon_path__ = EXTENSION_DIR
__version__ = "2.2.0"


def _(string):
    # check for a translation for this xlet
    if EXTENSION_UUID not in TRANSLATIONS:
        try:
            TRANSLATIONS[EXTENSION_UUID] = gettext.translation(
                EXTENSION_UUID, HOME + "/.local/share/locale").gettext
Ejemplo n.º 40
0
    def __init__(self, window):
        """
            Init dialog
            @param window as Window
        """
        self.__helper = PasswordsHelper()
        builder = Gtk.Builder()
        builder.add_from_resource("/org/gnome/Eolie/SettingsDialog.ui")

        self.__settings_dialog = builder.get_object("settings_dialog")
        self.__settings_dialog.set_transient_for(window)
        # self.__settings_dialog.connect("destroy", self.__on_destroy)

        if False:
            self.__settings_dialog.set_title(_("Preferences"))
        else:
            headerbar = builder.get_object("header_bar")
            headerbar.set_title(_("Preferences"))
            self.__settings_dialog.set_titlebar(headerbar)

        download_chooser = builder.get_object("download_chooser")
        dir_uri = El().settings.get_value("download-uri").get_string()
        if not dir_uri:
            directory = GLib.get_user_special_dir(
                                         GLib.UserDirectory.DIRECTORY_DOWNLOAD)
            if directory is not None:
                dir_uri = GLib.filename_to_uri(directory, None)
        if dir_uri:
            download_chooser.set_uri(dir_uri)
        else:
            download_chooser.set_uri("file://" + GLib.getenv("HOME"))

        open_downloads = builder.get_object("open_downloads_check")
        open_downloads.set_active(
                                El().settings.get_value("open-downloads"))

        self.__start_page_uri = builder.get_object("start_page_uri")
        combo_start = builder.get_object("combo_start")
        start_page = El().settings.get_value("start-page").get_string()
        if start_page.startswith("http"):
            combo_start.set_active_id("address")
            self.__start_page_uri.set_text(start_page)
            self.__start_page_uri.show()
        else:
            combo_start.set_active_id(start_page)

        remember_session = builder.get_object("remember_sessions_check")
        remember_session.set_active(
                                El().settings.get_value("remember-session"))

        enable_plugins = builder.get_object("plugins_check")
        enable_plugins.set_active(
                                El().settings.get_value("enable-plugins"))

        self.__fonts_grid = builder.get_object("fonts_grid")
        use_system_fonts = builder.get_object("system_fonts_check")
        use_system_fonts.set_active(
                                El().settings.get_value("use-system-fonts"))
        self.__fonts_grid.set_sensitive(
                            not El().settings.get_value("use-system-fonts"))

        sans_serif_button = builder.get_object("sans_serif_button")
        sans_serif_button.set_font_name(
                       El().settings.get_value("font-sans-serif").get_string())
        serif_button = builder.get_object("serif_button")
        serif_button.set_font_name(
                       El().settings.get_value("font-serif").get_string())
        monospace_button = builder.get_object("monospace_button")
        monospace_button.set_font_name(
                       El().settings.get_value("font-monospace").get_string())

        min_font_size_spin = builder.get_object("min_font_size_spin")
        min_font_size_spin.set_value(
                       El().settings.get_value("min-font-size").get_int32())

        monitor_model = get_current_monitor_model(window)
        zoom_levels = El().settings.get_value("default-zoom-level")
        wanted_zoom_level = 1.0
        try:
            for zoom_level in zoom_levels:
                zoom_splited = zoom_level.split('@')
                if zoom_splited[0] == monitor_model:
                    wanted_zoom_level = float(zoom_splited[1])
        except:
            pass
        default_zoom_level = builder.get_object("default_zoom_level")
        default_zoom_level.set_value(float(wanted_zoom_level))

        cookies_combo = builder.get_object("cookies_combo")
        storage = El().settings.get_enum("cookie-storage")
        cookies_combo.set_active_id(str(storage))

        history_combo = builder.get_object("history_combo")
        storage = El().settings.get_enum("history-storage")
        history_combo.set_active_id(str(storage))

        self.__populars_count = builder.get_object("populars_count")
        if start_page == "popular":
            self.__populars_count.show()
        max_popular_items = El().settings.get_value(
                                              "max-popular-items").get_int32()
        builder.get_object("popular_spin_button").set_value(max_popular_items)
        remember_passwords = builder.get_object("remember_passwords_check")
        remember_passwords.set_active(
                                El().settings.get_value("remember-passwords"))

        tracking_check = builder.get_object("tracking_check")
        tracking_check.set_active(
                                El().settings.get_value("do-not-track"))
        self.__result_label = builder.get_object("result_label")
        self.__sync_button = builder.get_object("sync_button")
        self.__login_entry = builder.get_object("login_entry")
        self.__password_entry = builder.get_object("password_entry")
        self.__result_image = builder.get_object("result_image")
        builder.connect_signals(self)
        self.__helper.get_sync(self.__on_get_sync)

        thread = Thread(target=self.__get_sync_status)
        thread.daemon = True
        thread.start()
Ejemplo n.º 41
0
class Playlists(GObject.GObject):
    """
        Playlists manager
    """
    if GLib.getenv("XDG_DATA_HOME") is None:
        __LOCAL_PATH = GLib.get_home_dir() + "/.local/share/lollypop"
    else:
        __LOCAL_PATH = GLib.getenv("XDG_DATA_HOME") + "/lollypop"
    _DB_PATH = "%s/playlists.db" % __LOCAL_PATH
    __gsignals__ = {
        # Add or remove a playlist
        'playlists-changed': (GObject.SignalFlags.RUN_FIRST, None, (int,)),
        # Objects added/removed to/from playlist
        'playlist-add': (GObject.SignalFlags.RUN_FIRST, None, (int, int, int)),
        'playlist-del': (GObject.SignalFlags.RUN_FIRST, None, (int, int))
    }
    __create_playlists = '''CREATE TABLE playlists (
                            id INTEGER PRIMARY KEY,
                            name TEXT NOT NULL,
                            mtime BIGINT NOT NULL)'''

    __create_tracks = '''CREATE TABLE tracks (
                        playlist_id INT NOT NULL,
                        uri TEXT NOT NULL)'''

    def __init__(self):
        """
            Init playlists manager
        """
        GObject.GObject.__init__(self)
        self.LOVED = _("Loved tracks")
        # Create db schema
        try:
            with SqlCursor(self) as sql:
                sql.execute(self.__create_playlists)
                sql.execute(self.__create_tracks)
                sql.commit()
        except:
            pass

    def add(self, name):
        """
            Add a playlist
            @param playlist name as str
            @thread safe
        """
        with SqlCursor(self) as sql:
            result = sql.execute("INSERT INTO playlists (name, mtime)"
                                 " VALUES (?, ?)",
                                 (name, datetime.now().strftime('%s')))
            sql.commit()
            GLib.idle_add(self.emit, 'playlists-changed', result.lastrowid)

    def exists(self, playlist_id):
        """
            Return True if playlist exists
            @param playlist id as int
            @param bool
        """
        with SqlCursor(self) as sql:
            result = sql.execute("SELECT rowid\
                                  FROM playlists\
                                  WHERE rowid=?",
                                 (playlist_id,))
            v = result.fetchone()
            if v is not None:
                return True
            else:
                return False

    def rename(self, new_name, old_name):
        """
            Rename playlist
            @param new playlist name as str
            @param old playlist name as str
        """
        with SqlCursor(self) as sql:
            playlist_id = self.get_id(old_name)
            sql.execute("UPDATE playlists\
                        SET name=?\
                        WHERE name=?",
                        (new_name, old_name))
            sql.commit()
            GLib.idle_add(self.emit, 'playlists-changed', playlist_id)

    def delete(self, name):
        """
            delete playlist
            @param playlist name as str
        """
        with SqlCursor(self) as sql:
            playlist_id = self.get_id(name)
            sql.execute("DELETE FROM playlists\
                        WHERE name=?",
                        (name,))
            sql.execute("DELETE FROM tracks\
                        WHERE playlist_id=?",
                        (playlist_id,))
            sql.commit()
            GLib.idle_add(self.emit, 'playlists-changed', playlist_id)

    def remove(self, uri):
        """
            Remove track from playlists
            @param uri as str
        """
        with SqlCursor(self) as sql:
            sql.execute("DELETE FROM tracks\
                        WHERE uri=?",
                        (uri,))
            sql.commit()

    def get(self):
        """
            Return availables playlists
            @return array of (id, string)
        """
        with SqlCursor(self) as sql:
            result = sql.execute("SELECT rowid, name\
                                  FROM playlists\
                                  ORDER BY name\
                                  COLLATE NOCASE COLLATE LOCALIZED")
            return list(result)

    def get_last(self):
        """
            Return 6 last modified playlist
            @return [string]
        """
        with SqlCursor(self) as sql:
            result = sql.execute("SELECT rowid, name\
                                  FROM playlists\
                                  ORDER BY mtime DESC\
                                  LIMIT 6")
            return list(result)

    def get_tracks(self, playlist_id):
        """
            Return availables tracks for playlist
            If playlist name == Type.ALL, then return all tracks from db
            @param playlist name as str
            @return array of paths as [str]
        """
        with SqlCursor(self) as sql:
            result = sql.execute("SELECT uri\
                                  FROM tracks\
                                  WHERE playlist_id=?", (playlist_id,))
            return list(itertools.chain(*result))

    def get_track_ids(self, playlist_id):
        """
            Return availables track ids for playlist
            If playlist name == Type.ALL, then return all tracks from db
            @param playlist id as int
            @return array of track id as int
        """
        with SqlCursor(self) as sql:
            result = sql.execute("SELECT music.tracks.rowid\
                                  FROM tracks, music.tracks\
                                  WHERE tracks.playlist_id=?\
                                  AND music.tracks.uri=\
                                  main.tracks.uri",
                                 (playlist_id,))
            return list(itertools.chain(*result))

    def get_track_ids_sorted(self, playlist_id):
        """
            Return availables track ids for playlist sorted by artist/album
            If playlist name == Type.ALL, then return all tracks from db
            @param playlist id as int
            @return array of track id as int
        """
        with SqlCursor(self) as sql:
            result = sql.execute("SELECT music.tracks.rowid\
                                  FROM tracks, music.tracks,\
                                  music.track_artists, music.artists\
                                  WHERE tracks.playlist_id=?\
                                  AND music.track_artists.track_id=\
                                  music.tracks.rowid\
                                  AND music.artists.id=\
                                  music.track_artists.artist_id\
                                  AND music.tracks.uri=\
                                  main.tracks.uri\
                                  ORDER BY\
                                  music.artists.sortname, album_id",
                                 (playlist_id,))
            return list(itertools.chain(*result))

    def get_id(self, playlist_name):
        """
            Get playlist id
            @param playlist name as str
            @return playlst id as int
        """
        if playlist_name == self.LOVED:
            return Type.LOVED

        with SqlCursor(self) as sql:
            result = sql.execute("SELECT rowid\
                                 FROM playlists\
                                 WHERE name=?", (playlist_name,))
            v = result.fetchone()
            if v is not None:
                return v[0]
            return Type.NONE

    def get_name(self, playlist_id):
        """
            Get playlist name
            @param playlist id as int
            @return playlist name as str
        """
        if playlist_id == Type.LOVED:
            return self.LOVED

        with SqlCursor(self) as sql:
            result = sql.execute("SELECT name\
                                 FROM playlists\
                                 WHERE rowid=?", (playlist_id,))
            v = result.fetchone()
            if v is not None:
                return v[0]
            return ''

    def get_names(self, playlist_ids):
        """
            Return playlist names
            @param playlist_ids as [int]
            @return names as [str]
        """
        names = []
        for playlist_id in playlist_ids:
            if playlist_id == Type.POPULARS:
                names.append(_("Popular tracks"))
            elif playlist_id == Type.RECENTS:
                names.append(_("Recently played"))
            elif playlist_id == Type.NEVER:
                names.append(_("Never played"))
            elif playlist_id == Type.RANDOMS:
                names.append(_("Random tracks"))
            elif playlist_id == Type.SEARCH:
                names.append(_("Search"))
            else:
                names.append(self.get_name(playlist_id))
        return names

    def clear(self, playlist_id, notify=True):
        """
            Clear playlsit
            @param playlist id as int
            @param notify as bool
        """
        with SqlCursor(self) as sql:
            sql.execute("DELETE FROM tracks\
                         WHERE playlist_id=?", (playlist_id,))
            sql.commit()
            if notify:
                GLib.idle_add(self.emit, 'playlist-del', playlist_id, None)

    def add_tracks(self, playlist_id, tracks, notify=True):
        """
            Add tracks to playlist if not already present
            @param playlist id as int
            @param tracks as [Track]
            @param notify as bool
        """
        with SqlCursor(self) as sql:
            changed = False
            for track in tracks:
                if not self.exists_track(playlist_id, track.id):
                    changed = True
                    sql.execute("INSERT INTO tracks"
                                " VALUES (?, ?)",
                                (playlist_id, track.uri))
                if notify:
                    GLib.idle_add(self.emit, 'playlist-add',
                                  playlist_id, track.id, -1)
            if changed:
                sql.execute("UPDATE playlists SET mtime=?\
                             WHERE rowid=?", (datetime.now().strftime('%s'),
                                              playlist_id))
                sql.commit()

    def remove_tracks(self, playlist_id, tracks, notify=True):
        """
            Remove tracks from playlist
            @param playlist id as int
            @param tracks as [Track]
        """
        with SqlCursor(self) as sql:
            for track in tracks:
                sql.execute("DELETE FROM tracks\
                             WHERE uri=?\
                             AND playlist_id=?", (track.uri, playlist_id))
                if notify:
                    GLib.idle_add(self.emit, 'playlist-del',
                                  playlist_id, track.id)
            sql.commit()

    def import_uri(self, playlist_id, uri, start=None, up=False):
        """
            Import uri in playlist
            @param playlist id as int
            @param uri as str
            @param start track id as int
            @param up as bool
        """
        try:
            uri = uri.strip('\n\r')
            f = Lio.File.new_for_uri(uri)
            if f.query_exists():
                if f.query_file_type(Gio.FileQueryInfoFlags.NONE,
                                     None) == Gio.FileType.DIRECTORY:
                    walk_uris = [uri]
                    track_ids = []
                    while walk_uris:
                        uri = walk_uris.pop(0)
                        try:
                            d = Lio.File.new_for_uri(uri)
                            infos = d.enumerate_children(
                                'standard::name,standard::type',
                                Gio.FileQueryInfoFlags.NONE,
                                None)
                        except Exception as e:
                            print("Playlists::import_uri():", e)
                            continue
                        for info in infos:
                            f = infos.get_child(info)
                            if info.get_file_type() == Gio.FileType.DIRECTORY:
                                walk_uris.append(f.get_uri())
                            else:
                                track_id = Lp().tracks.get_id_by_uri(
                                                                   f.get_uri())
                                if track_id is not None:
                                    track_ids.append(track_id)
                else:
                    track_id = Lp().tracks.get_id_by_uri(uri)
                    track_ids = [track_id]
                tracks = []
                if start is None:
                    for track_id in track_ids:
                        tracks.append(Track(track_id))
                    self.add_tracks(playlist_id, tracks)
                else:
                    # Insert at wanted position
                    playlist_track_ids = self.get_track_ids(playlist_id)
                    start_idx = playlist_track_ids.index(start)
                    if not up:
                        start_idx += 1
                    for track_id in track_ids:
                        playlist_track_ids.insert(start_idx, track_id)
                        GLib.idle_add(self.emit, 'playlist-add',
                                      playlist_id, track_id, start_idx)
                        start_idx += 1
                    self.clear(playlist_id, False)
                    tracks = []
                    for track_id in playlist_track_ids:
                        tracks.append(Track(track_id))
                    self.add_tracks(playlist_id, tracks, False)
        except:
            pass

    def get_position(self, playlist_id, track_id):
        """
            Get track position in playlist
            @param playlist id as int
            @param track id as int
            @return position as int
        """
        i = 0
        for tid in self.get_track_ids(playlist_id):
            if track_id == tid:
                break
            i += 1
        return i

    def exists_track(self, playlist_id, track_id):
        """
            Check if track id exist in playlist
            @param playlist id as int
            @param track as Track
            @return bool
        """
        with SqlCursor(self) as sql:
            result = sql.execute("SELECT main.tracks.uri\
                                  FROM tracks, music.tracks\
                                  WHERE music.tracks.rowid=?\
                                  AND playlist_id=?\
                                  AND music.tracks.uri=\
                                  main.tracks.uri",
                                 (track_id, playlist_id))
            v = result.fetchone()
            if v is not None:
                return True
            return False

    def exists_album(self, playlist_id, album_id, genre_ids, artist_ids):
        """
            Return True if object_id is already present in playlist
            @param playlist id as int
            @param album id as int
            @param genre ids as [int]
            @param artist ids as [int]
            @param sql as sqlite cursor
            @return bool
        """
        # We do not use Album object for performance reasons
        playlist_uris = self.get_tracks(playlist_id)
        track_uris = Lp().albums.get_track_uris(album_id,
                                                genre_ids,
                                                artist_ids)
        return len(set(playlist_uris) & set(track_uris)) == len(track_uris)

    def get_cursor(self):
        """
            Return a new sqlite cursor
        """
        try:
            sql = sqlite3.connect(self._DB_PATH, 600.0)
            sql.execute("ATTACH DATABASE '%s' AS music" % Database.DB_PATH)
            sql.create_collation('LOCALIZED', LocalizedCollation())
            return sql
        except:
            exit(-1)
Ejemplo n.º 42
0
def is_gnome():
    """
        Check if the current desktop env is gnome
    """
    return GLib.getenv("XDG_CURRENT_DESKTOP").lower() == "gnome"
Ejemplo n.º 43
0
def session_is_cinnamon():
    if "cinnamon" in GLib.getenv("DESKTOP_SESSION"):
        if GLib.find_program_in_path("cinnamon-session-quit"):
            return True

    return False
Ejemplo n.º 44
0
class Database:
    """
        Base database object
    """
    if GLib.getenv("XDG_DATA_HOME") is None:
        __LOCAL_PATH = GLib.get_home_dir() + "/.local/share/lollypop"
    else:
        __LOCAL_PATH = GLib.getenv("XDG_DATA_HOME") + "/lollypop"
    DB_PATH = "%s/lollypop.db" % __LOCAL_PATH

    # SQLite documentation:
    # In SQLite, a column with type INTEGER PRIMARY KEY
    # is an alias for the ROWID.
    # Here, we define an id INT PRIMARY KEY but never feed it,
    # this make VACUUM not destroy rowids...
    __create_albums = '''CREATE TABLE albums (id INTEGER PRIMARY KEY,
                                              name TEXT NOT NULL,
                                              no_album_artist BOOLEAN NOT NULL,
                                              year INT,
                                              uri TEXT NOT NULL,
                                              popularity INT NOT NULL,
                                              rate INT NOT NULL,
                                              loved INT NOT NULL,
                                              synced INT NOT NULL,
                                              mtime INT NOT NULL)'''
    __create_artists = '''CREATE TABLE artists (id INTEGER PRIMARY KEY,
                                               name TEXT NOT NULL,
                                               sortname TEXT NOT NULL)'''
    __create_genres = '''CREATE TABLE genres (id INTEGER PRIMARY KEY,
                                            name TEXT NOT NULL)'''
    __create_album_artists = '''CREATE TABLE album_artists (
                                                album_id INT NOT NULL,
                                                artist_id INT NOT NULL)'''
    __create_album_genres = '''CREATE TABLE album_genres (
                                                album_id INT NOT NULL,
                                                genre_id INT NOT NULL)'''
    __create_tracks = '''CREATE TABLE tracks (id INTEGER PRIMARY KEY,
                                              name TEXT NOT NULL,
                                              uri TEXT NOT NULL,
                                              duration INT,
                                              tracknumber INT,
                                              discnumber INT,
                                              discname TEXT,
                                              album_id INT NOT NULL,
                                              year INT,
                                              popularity INT NOT NULL,
                                              rate INT NOT NULL,
                                              ltime INT NOT NULL,
                                              mtime INT NOT NULL,
                                              persistent INT NOT NULL
                                              DEFAULT 1)'''
    __create_track_artists = '''CREATE TABLE track_artists (
                                                track_id INT NOT NULL,
                                                artist_id INT NOT NULL)'''
    __create_track_genres = '''CREATE TABLE track_genres (
                                                track_id INT NOT NULL,
                                                genre_id INT NOT NULL)'''
    __create_album_artists_idx = '''CREATE index idx_aa ON album_artists(
                                                album_id)'''
    __create_track_artists_idx = '''CREATE index idx_ta ON track_artists(
                                                track_id)'''
    __create_album_genres_idx = '''CREATE index idx_ag ON album_genres(
                                                album_id)'''
    __create_track_genres_idx = '''CREATE index idx_tg ON track_genres(
                                                track_id)'''

    def __init__(self):
        """
            Create database tables or manage update if needed
        """
        f = Lio.File.new_for_path(self.DB_PATH)
        if not f.query_exists():
            db_version = Lp().settings.get_value('db-version').get_int32()
            upgrade = DatabaseUpgrade(db_version)
            try:
                d = Lio.File.new_for_path(self.__LOCAL_PATH)
                if not d.query_exists():
                    d.make_directory_with_parents()
                # Create db schema
                with SqlCursor(self) as sql:
                    sql.execute(self.__create_albums)
                    sql.execute(self.__create_artists)
                    sql.execute(self.__create_genres)
                    sql.execute(self.__create_album_genres)
                    sql.execute(self.__create_album_artists)
                    sql.execute(self.__create_tracks)
                    sql.execute(self.__create_track_artists)
                    sql.execute(self.__create_track_genres)
                    sql.execute(self.__create_album_artists_idx)
                    sql.execute(self.__create_track_artists_idx)
                    sql.execute(self.__create_album_genres_idx)
                    sql.execute(self.__create_track_genres_idx)
                    sql.commit()
                    Lp().settings.set_value('db-version',
                                            GLib.Variant('i', upgrade.count()))
            except Exception as e:
                print("Database::__init__(): %s" % e)

    def upgrade(self):
        """
            Upgrade database
        """
        db_version = Lp().settings.get_value('db-version').get_int32()
        upgrade = DatabaseUpgrade(db_version)
        f = Lio.File.new_for_path(self.DB_PATH)
        if f.query_exists():
            upgrade.do_db_upgrade()
            Lp().settings.set_value('db-version',
                                    GLib.Variant('i', upgrade.count()))

    def get_cursor(self):
        """
            Return a new sqlite cursor
        """
        try:
            c = sqlite3.connect(self.DB_PATH, 600.0)
            c.create_collation('LOCALIZED', LocalizedCollation())
            c.create_function("noaccents", 1, noaccents)
            return c
        except:
            exit(-1)

    def drop_db(self):
        """
            Drop database
        """
        try:
            f = Gio.File.new_for_path(self.DB_PATH)
            f.trash()
        except Exception as e:
            print("Database::drop_db():", e)

    def del_tracks(self, track_ids):
        """
            Delete tracks from db
            @param track_ids as [int]
        """
        with SqlCursor(self) as sql:
            all_album_ids = []
            all_artist_ids = []
            all_genre_ids = []
            for track_id in track_ids:
                album_id = Lp().tracks.get_album_id(track_id)
                art_file = Lp().art.get_album_cache_name(Album(album_id))
                genre_ids = Lp().tracks.get_genre_ids(track_id)
                album_artist_ids = Lp().albums.get_artist_ids(album_id)
                artist_ids = Lp().tracks.get_artist_ids(track_id)
                uri = Lp().tracks.get_uri(track_id)
                Lp().playlists.remove(uri)
                Lp().tracks.remove(track_id)
                Lp().tracks.clean(track_id)
                all_album_ids.append(album_id)
                all_artist_ids += album_artist_ids + artist_ids
                all_genre_ids += genre_ids
            for album_id in list(set(all_album_ids)):
                if Lp().albums.clean(album_id):
                    Lp().art.clean_store(art_file)
            for artist_id in list(set(all_artist_ids)):
                Lp().artists.clean(artist_id)
            for genre_id in list(set(all_genre_ids)):
                Lp().genres.clean(genre_id)
            sql.commit()