def __missing_fxa(self): """ Show a message about missing fxa module """ from eolie.mozilla_sync import SyncWorker if not SyncWorker.check_modules(): cmd = "<b>$ pip3 install requests-hawk\n"\ "PyFxA pycrypto cryptography</b>" self.__result_label.set_markup( _("Synchronization is not available" " on your computer:\n %s") % cmd) self.__sync_button.set_sensitive(False)
def __init(self): """ Init main application """ self.settings = Settings.new() # Init extensions GLib.setenv('PYTHONPATH', self.__extension_dir, True) # Create favicon path d = Gio.File.new_for_path(self.__FAVICONS_PATH) if not d.query_exists(): d.make_directory_with_parents() # Setup default context context = WebKit2.WebContext.get_default() Context(context) # Setup ephemeral context self.__ephemeral_context = WebKit2.WebContext.new_ephemeral() Context(self.__ephemeral_context) # Add a global DBus helper self.helper = DBusHelper() # First init sync worker try: from eolie.mozilla_sync import SyncWorker self.sync_worker = SyncWorker() # Run a first sync in 10 seconds, speed up app start GLib.timeout_add_seconds(10, self.sync_worker.sync, False) # Then run a sync every hour GLib.timeout_add_seconds(3600, self.sync_worker.sync, True) except Exception as e: print("Application::init():", e) self.sync_worker = None if self.prefers_app_menu(): menu = self.get_app_menu() self.set_app_menu(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.history = DatabaseHistory() self.bookmarks = DatabaseBookmarks() # We store cursors for main thread SqlCursor.add(self.history) SqlCursor.add(self.bookmarks) self.websettings = DatabaseSettings() self.adblock = DatabaseAdblock() self.adblock.update() self.phishing = DatabasePhishing() self.adblock_exceptions = DatabaseExceptions("adblock") self.popup_exceptions = DatabaseExceptions("popup") self.image_exceptions = DatabaseExceptions("image") if self.settings.get_user_value("jsblock") is not None: self.js_exceptions = DatabaseExceptions("js") else: self.js_exceptions = None self.phishing.update() self.art = Art() self.search = Search() self.download_manager = DownloadManager() self.pages_menu = PagesMenu() 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::expose", ["<Alt>e"]) self.set_accels_for_action("win.exceptions::site", ["<Control>e"]) self.set_accels_for_action("win.shortcut::show_left_panel", ["F9"]) self.set_accels_for_action("win.shortcut::uri", ["<Control>l", "<Control>b"]) self.set_accels_for_action("win.shortcut::new_page", ["<Control>t"]) self.set_accels_for_action("win.shortcut::last_page", ["<Control><Shift>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::quit", ["<Control>q"]) 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", "F5"]) 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::source", ["<Control><Shift>c"]) self.set_accels_for_action("win.shortcut::history", ["<Control>h"]) self.set_accels_for_action("win.shortcut::search", ["<Control>k"]) self.set_accels_for_action("win.shortcut::fullscreen", ["F11"]) self.set_accels_for_action("app.settings", ["<Control><Shift>s"]) self.set_accels_for_action("win.shortcut::backward", ["<Alt>Left", "XF86Back"]) self.set_accels_for_action("win.shortcut::forward", ["<Alt>Right", "XF86Forward"]) self.set_accels_for_action("win.shortcut::next", ["<Control>Tab", "<Control>Page_Down"]) self.set_accels_for_action("win.shortcut::previous", ["<Control><Shift>Tab", "<Control>Page_Up"]) self.set_accels_for_action("win.shortcut::zoom_in", ["<Control>KP_Add", "<Control>plus", "<Control>equal"]) self.set_accels_for_action("win.shortcut::zoom_out", ["<Control>KP_Subtract", "<Control>minus"]) self.set_accels_for_action("win.shortcut::zoom_default", ["<Control>KP_0", "<Control>0"])
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)
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)
class Application(Gtk.Application): """ Eolie application: """ __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.sync_worker = None # Not initialised self.__extension_dir = extension_dir self.__windows = [] self.debug = False self.show_tls = False try: self.zoom_levels = load(open(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.add_main_option("new", b'n', GLib.OptionFlags.NONE, GLib.OptionArg.NONE, "Add a new window", None) self.add_main_option("show-tls", b's', GLib.OptionFlags.NONE, GLib.OptionArg.NONE, "Show TLS info", 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() self.__listen_to_gnome_sm() def get_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', lambda x, y: self.quit()) self.add_action(quit_action) return menu def do_startup(self): """ Init application """ Gtk.Application.do_startup(self) if not self.__windows: self.__init() self.get_new_window() 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 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) def quit(self, vacuum=False): """ Quit application @param vacuum as bool """ # Save webpage state self.__save_state() # Stop pending tasks self.download_manager.cancel() self.adblock.stop() # If sync is running, to avoid db lock, we do not vacuum if self.sync_worker is not None and self.sync_worker.syncing: self.sync_worker.stop() Gio.Application.quit(self) elif vacuum: thread = Thread(target=self.__vacuum) thread.daemon = True thread.start() else: Gio.Application.quit(self) @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://" elif value == "blank": value = "about:blank" 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 __init(self): """ Init main application """ # First init sync worker 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 if self.prefers_app_menu(): menu = self.get_app_menu() self.set_app_menu(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) self.adblock = DatabaseAdblock() self.adblock.update() self.phishing = DatabasePhishing() self.adblock_exceptions = DatabaseExceptions("adblock") self.popup_exceptions = DatabaseExceptions("popup") self.image_exceptions = DatabaseExceptions("image") self.phishing.update() self.art = Art() self.search = Search() self.download_manager = DownloadManager() self.pages_menu = PagesMenu(self) # Db upgrade db_version = self.settings.get_value("db-version").get_int32() upgrade = DatabaseUpgrade(db_version) db_version = upgrade.do_db_upgrade() self.settings.set_value("db-version", GLib.Variant("i", db_version)) 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.exceptions::site", ["<Control>e"]) 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("win.shortcut::last_page", ["<Control><Shift>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::quit", ["<Control>q"]) 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::source", ["<Control><Shift>c"]) self.set_accels_for_action("win.shortcut::fullscreen", ["F11"]) self.set_accels_for_action("app.settings", ["<Control><Shift>s"]) self.set_accels_for_action("win.shortcut::backward", ["<Alt>Left", "XF86Back"]) self.set_accels_for_action("win.shortcut::forward", ["<Alt>Right", "XF86Forward"]) self.set_accels_for_action("win.shortcut::next", ["<Control>Tab"]) self.set_accels_for_action("win.shortcut::previous", ["<Control><Shift>Tab"]) self.set_accels_for_action("win.shortcut::zoom_in", ["<Control>KP_Add", "<Control>plus"]) self.set_accels_for_action("win.shortcut::zoom_out", ["<Control>KP_Subtract", "<Control>minus"]) self.set_accels_for_action("win.panel_mode(0)", ["<Control><Alt>0", "<Control><Alt>KP_0"]) self.set_accels_for_action("win.panel_mode(1)", ["<Control><Alt>1", "<Control><Alt>KP_1"]) self.set_accels_for_action("win.panel_mode(2)", ["<Control><Alt>2", "<Control><Alt>KP_2"]) # Set some WebKit defaults context = WebKit2.WebContext.get_default() Context(context) 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("UnsecureFormFocused", self.__on_extension_signal) def __listen_to_gnome_sm(self): """ Save state on EndSession signal """ try: bus = self.get_dbus_connection() bus.signal_subscribe(None, "org.gnome.SessionManager.EndSessionDialog", "ConfirmedLogout", "/org/gnome/SessionManager/EndSessionDialog", None, Gio.DBusSignalFlags.NONE, lambda a, b, c, d, e, f: self.__save_state()) except Exception as e: print("Application::__listen_to_gnome_sm():", e) def __vacuum(self): """ VACUUM DB @thread safe """ try: with SqlCursor(self.bookmarks) as sql: sql.isolation_level = None sql.execute("VACUUM") sql.isolation_level = "" with SqlCursor(self.history) as sql: sql.isolation_level = None sql.execute("VACUUM") sql.isolation_level = "" with SqlCursor(self.adblock) as sql: sql.isolation_level = None sql.execute("VACUUM") sql.isolation_level = "" with SqlCursor(self.phishing) as sql: sql.isolation_level = None sql.execute("VACUUM") sql.isolation_level = "" except Exception as e: print("Application::__vacuum(): ", e) self.art.vacuum() GLib.idle_add(Gio.Application.quit, self) def __save_state(self): """ Save window position and view """ 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() parsed = urlparse(uri) if parsed.scheme not in ["http", "https"]: continue ephemeral = view.webview.ephemeral state = view.webview.get_session_state().serialize() session_states.append((uri, ephemeral, state.get_data())) if remember_session: dump(session_states, open(LOCAL_PATH + "/session_states.bin", "wb")) dump(self.zoom_levels, open(LOCAL_PATH + "/zoom_levels.bin", "wb")) except Exception as e: print("Application::save_state()", e) 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 True as bool if restored """ window_type = Gdk.WindowType.CHILD try: session_states = load( open(LOCAL_PATH + "/session_states.bin", "rb")) for (uri, ephemeral, state) in session_states: webkit_state = WebKit2.WebViewSessionState( GLib.Bytes.new(state)) GLib.idle_add(self.active_window.container.add_webview, uri, window_type, ephemeral, None, webkit_state, window_type == Gdk.WindowType.CHILD) window_type = Gdk.WindowType.OFFSCREEN except Exception as e: print("Application::restore_state()", e) return window_type != Gdk.WindowType.CHILD 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("WEBKIT_DEBUG", "network", True) self.debug = True if options.contains("show-tls"): self.show_tls = True ephemeral = options.contains("private") restored = False if self.settings.get_value("remember-session"): restored = self.__restore_state() if options.contains("new"): active_window = self.get_new_window() else: active_window = self.active_window # Open command line args if len(args) > 1: for uri in args[1:]: # Transform path to uri f = Gio.File.new_for_path(uri) if f.query_exists(): uri = f.get_uri() active_window.container.add_webview(uri, Gdk.WindowType.CHILD, ephemeral) active_window.present_with_time(Gtk.get_current_event_time()) # We already have a window, open a new one elif active_window.container.current: window = self.get_new_window() window.container.add_webview(self.start_page, Gdk.WindowType.CHILD, ephemeral) # Add default start page elif not restored: active_window.container.add_webview(self.start_page, Gdk.WindowType.CHILD, ephemeral) thread = Thread(target=self.__show_plugins) thread.daemon = True thread.start() 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 """ if len(self.__windows) > 1: self.__windows.remove(window) window.destroy() else: window.hide() self.quit(True) return True 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 __on_activate(self, application): """ Call default handler, raise last window @param application as Gio.Application """ if self.__windows: self.__windows[-1].present_with_time(Gtk.get_current_event_time()) 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_webview(self.start_page, Gdk.WindowType.CHILD) 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)
def __init(self): """ Init main application """ # First init sync worker 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 if self.prefers_app_menu(): menu = self.get_app_menu() self.set_app_menu(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) self.adblock = DatabaseAdblock() self.adblock.update() self.phishing = DatabasePhishing() self.adblock_exceptions = DatabaseExceptions("adblock") self.popup_exceptions = DatabaseExceptions("popup") self.image_exceptions = DatabaseExceptions("image") self.phishing.update() self.art = Art() self.search = Search() self.download_manager = DownloadManager() self.pages_menu = PagesMenu(self) # Db upgrade db_version = self.settings.get_value("db-version").get_int32() upgrade = DatabaseUpgrade(db_version) db_version = upgrade.do_db_upgrade() self.settings.set_value("db-version", GLib.Variant("i", db_version)) 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.exceptions::site", ["<Control>e"]) 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("win.shortcut::last_page", ["<Control><Shift>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::quit", ["<Control>q"]) 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::source", ["<Control><Shift>c"]) self.set_accels_for_action("win.shortcut::fullscreen", ["F11"]) self.set_accels_for_action("app.settings", ["<Control><Shift>s"]) self.set_accels_for_action("win.shortcut::backward", ["<Alt>Left", "XF86Back"]) self.set_accels_for_action("win.shortcut::forward", ["<Alt>Right", "XF86Forward"]) self.set_accels_for_action("win.shortcut::next", ["<Control>Tab"]) self.set_accels_for_action("win.shortcut::previous", ["<Control><Shift>Tab"]) self.set_accels_for_action("win.shortcut::zoom_in", ["<Control>KP_Add", "<Control>plus"]) self.set_accels_for_action("win.shortcut::zoom_out", ["<Control>KP_Subtract", "<Control>minus"]) self.set_accels_for_action("win.panel_mode(0)", ["<Control><Alt>0", "<Control><Alt>KP_0"]) self.set_accels_for_action("win.panel_mode(1)", ["<Control><Alt>1", "<Control><Alt>KP_1"]) self.set_accels_for_action("win.panel_mode(2)", ["<Control><Alt>2", "<Control><Alt>KP_2"]) # Set some WebKit defaults context = WebKit2.WebContext.get_default() Context(context) 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("UnsecureFormFocused", self.__on_extension_signal)
def __init(self): """ Init main application """ self.settings = Settings.new() # Init extensions GLib.setenv("PYTHONPATH", self.__extension_dir, True) # Create favicon path if not GLib.file_test(self.__FAVICONS_PATH, GLib.FileTest.IS_DIR): GLib.mkdir_with_parents(self.__FAVICONS_PATH, 0o0750) # Add a global DBus helper self.helper = DBusHelper() # First init sync worker from eolie.mozilla_sync import SyncWorker if SyncWorker.check_modules(): self.sync_worker = SyncWorker() # Run a first sync in 10 seconds, speed up app start GLib.timeout_add_seconds(10, self.sync_worker.sync, False) # Then run a sync every hour GLib.timeout_add_seconds(3600, self.sync_worker.sync, True) else: self.sync_worker = None if self.prefers_app_menu(): menu = self.get_app_menu() self.set_app_menu(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.history = DatabaseHistory() self.bookmarks = DatabaseBookmarks() # We store cursors for main thread SqlCursor.add(self.history) SqlCursor.add(self.bookmarks) self.websettings = DatabaseSettings() self.adblock = DatabaseAdblock() self.adblock.update() self.phishing = DatabasePhishing() self.adblock_exceptions = DatabaseExceptions("adblock") # Do not remove this! self.update_default_style_sheet() self.popup_exceptions = DatabaseExceptions("popups") self.image_exceptions = DatabaseExceptions("images") if self.settings.get_user_value("jsblock") is not None: self.js_exceptions = DatabaseExceptions("js") else: self.js_exceptions = None self.phishing.update() self.art = Art() self.search = Search() self.download_manager = DownloadManager() self.pages_menu = PagesMenu() # Check MOZ_PLUGIN_PATH if self.settings.get_value('enable-plugins') and\ not GLib.getenv("MOZ_PLUGIN_PATH"): print("You need to set MOZ_PLUGIN_PATH to use plugins") # https://wiki.ubuntu.com/Unity/LauncherAPI self.__unity = None if is_unity(): try: gi.require_version('Unity', '7.0') from gi.repository import Unity self.__unity = Unity.LauncherEntry.get_for_desktop_id( "org.gnome.Eolie.desktop") except: pass # Init profiles self.set_profiles() 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::expose", ["<Alt>e"]) self.set_accels_for_action("win.exceptions::site", ["<Control>e"]) self.set_accels_for_action("win.shortcut::show_left_panel", ["F9"]) self.set_accels_for_action("win.shortcut::uri", ["<Control>l", "<Control>b"]) self.set_accels_for_action("win.shortcut::new_page", ["<Control>t"]) self.set_accels_for_action("win.shortcut::last_page", ["<Control><Shift>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::quit", ["<Control>q"]) self.set_accels_for_action("win.shortcut::save", ["<Control><Shift>s"]) self.set_accels_for_action("win.shortcut::filter", ["<Control>i"]) self.set_accels_for_action("win.shortcut::reload", ["<Control>r", "F5"]) self.set_accels_for_action("win.shortcut::home", ["<Control>Home"]) 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::source", ["<Control><Shift>c"]) self.set_accels_for_action("win.shortcut::history", ["<Control>h"]) self.set_accels_for_action("win.shortcut::search", ["<Control>k"]) self.set_accels_for_action("win.shortcut::fullscreen", ["F11"]) self.set_accels_for_action("app.settings", ["<Control>s"]) self.set_accels_for_action("win.shortcut::backward", ["<Alt>Left", "XF86Back"]) self.set_accels_for_action("win.shortcut::forward", ["<Alt>Right", "XF86Forward"]) self.set_accels_for_action("win.shortcut::next", ["<Control>Tab", "<Control>Page_Down"]) self.set_accels_for_action("win.shortcut::previous", ["<Control><Shift>Tab", "<Control>Page_Up"]) self.set_accels_for_action("win.shortcut::next_site", ["<Control>twosuperior"]) self.set_accels_for_action("win.shortcut::previous_site", ["<Control><Shift>twosuperior"]) self.set_accels_for_action( "win.shortcut::zoom_in", ["<Control>KP_Add", "<Control>plus", "<Control>equal"]) self.set_accels_for_action("win.shortcut::zoom_out", ["<Control>KP_Subtract", "<Control>minus"]) self.set_accels_for_action("win.shortcut::zoom_default", ["<Control>KP_0", "<Control>0"])