[gnome-shell] extensionSystem: Split off the extension downloader into a separate file



commit 3ff51da529f9350c293a61e5f2160bda1df21a78
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri May 25 19:07:31 2012 -0400

    extensionSystem: Split off the extension downloader into a separate file
    
    This keeps all UI out of the extension system, leaving it strictly for
    loading and unloading extensions.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=677586

 js/Makefile.am               |    1 +
 js/ui/extensionDownloader.js |  171 ++++++++++++++++++++++++++++++++++++++++++
 js/ui/extensionSystem.js     |  159 ---------------------------------------
 js/ui/main.js                |    2 +
 js/ui/shellDBus.js           |    7 +-
 5 files changed, 177 insertions(+), 163 deletions(-)
---
diff --git a/js/Makefile.am b/js/Makefile.am
index ea66c3e..82efd21 100644
--- a/js/Makefile.am
+++ b/js/Makefile.am
@@ -52,6 +52,7 @@ nobase_dist_js_DATA = 	\
 	ui/endSessionDialog.js	\
 	ui/environment.js	\
 	ui/extensionSystem.js	\
+	ui/extensionDownloader.js \
 	ui/flashspot.js		\
 	ui/iconGrid.js		\
 	ui/keyboard.js		\
diff --git a/js/ui/extensionDownloader.js b/js/ui/extensionDownloader.js
new file mode 100644
index 0000000..507fc2c
--- /dev/null
+++ b/js/ui/extensionDownloader.js
@@ -0,0 +1,171 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+const Lang = imports.lang;
+
+const Clutter = imports.gi.Clutter;
+const GLib = imports.gi.GLib;
+const Gio = imports.gi.Gio;
+const Soup = imports.gi.Soup;
+const St = imports.gi.St;
+
+const Config = imports.misc.config;
+const ExtensionUtils = imports.misc.extensionUtils;
+const ExtensionSystem = imports.ui.extensionSystem;
+const FileUtils = imports.misc.fileUtils;
+const ModalDialog = imports.ui.modalDialog;
+
+const _signals = ExtensionSystem._signals;
+
+const REPOSITORY_URL_BASE = 'https://extensions.gnome.org';
+const REPOSITORY_URL_DOWNLOAD = REPOSITORY_URL_BASE + '/download-extension/%s.shell-extension.zip';
+const REPOSITORY_URL_INFO =     REPOSITORY_URL_BASE + '/extension-info/';
+
+let _httpSession;
+
+function installExtensionFromUUID(uuid) {
+    let params = { uuid: uuid,
+                   shell_version: Config.PACKAGE_VERSION };
+
+    let message = Soup.form_request_new_from_hash('GET', REPOSITORY_URL_INFO, params);
+
+    _httpSession.queue_message(message,
+                               function(session, message) {
+                                   let info = JSON.parse(message.response_body.data);
+                                   let dialog = new InstallExtensionDialog(uuid, info);
+                                   dialog.open(global.get_current_time());
+                               });
+}
+
+function uninstallExtensionFromUUID(uuid) {
+    let extension = ExtensionUtils.extensions[uuid];
+    if (!extension)
+        return false;
+
+    // Try to disable it -- if it's ERROR'd, we can't guarantee that,
+    // but it will be removed on next reboot, and hopefully nothing
+    // broke too much.
+    ExtensionSystem.disableExtension(uuid);
+
+    // Don't try to uninstall system extensions
+    if (extension.type != ExtensionUtils.ExtensionType.PER_USER)
+        return false;
+
+    extension.state = ExtensionSystem.ExtensionState.UNINSTALLED;
+    _signals.emit('extension-state-changed', extension);
+
+    delete ExtensionUtils.extensions[uuid];
+
+    FileUtils.recursivelyDeleteDir(Gio.file_new_for_path(extension.path));
+
+    return true;
+}
+
+function gotExtensionZipFile(session, message, uuid) {
+    if (message.status_code != Soup.KnownStatusCode.OK) {
+        logExtensionError(uuid, 'downloading extension: ' + message.status_code);
+        return;
+    }
+
+    let [file, stream] = Gio.File.new_tmp('XXXXXX.shell-extension.zip');
+    let dir = ExtensionUtils.userExtensionsDir.get_child(uuid);
+    let contents = message.response_body.flatten().as_bytes();
+    stream.output_stream.write_bytes(contents, null);
+    stream.close(null);
+    let [success, pid] = GLib.spawn_async(null,
+                                          ['unzip', '-uod', dir.get_path(), '--', file.get_path()],
+                                          null,
+                                          GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
+                                          null);
+
+    if (!success) {
+        logExtensionError(uuid, 'extract: could not extract');
+        return;
+    }
+
+    GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function(pid, status) {
+        GLib.spawn_close_pid(pid);
+
+        // Add extension to 'enabled-extensions' for the user, always...
+        let enabledExtensions = global.settings.get_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY);
+        if (enabledExtensions.indexOf(uuid) == -1) {
+            enabledExtensions.push(uuid);
+            global.settings.set_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY, enabledExtensions);
+        }
+
+        ExtensionSystem.loadExtension(dir, ExtensionUtils.ExtensionType.PER_USER, true);
+    });
+}
+
+const InstallExtensionDialog = new Lang.Class({
+    Name: 'InstallExtensionDialog',
+    Extends: ModalDialog.ModalDialog,
+
+    _init: function(uuid, info) {
+        this.parent({ styleClass: 'extension-dialog' });
+
+        this._uuid = uuid;
+        this._info = info;
+
+        this.setButtons([{ label: _("Cancel"),
+                           action: Lang.bind(this, this._onCancelButtonPressed),
+                           key:    Clutter.Escape
+                         },
+                         { label:  _("Install"),
+                           action: Lang.bind(this, this._onInstallButtonPressed)
+                         }]);
+
+        let message = _("Download and install '%s' from extensions.gnome.org?").format(info.name);
+
+        let box = new St.BoxLayout();
+        this.contentLayout.add(box);
+
+        let gicon = new Gio.FileIcon({ file: Gio.File.new_for_uri(REPOSITORY_URL_BASE + info.icon) })
+        let icon = new St.Icon({ gicon: gicon });
+        box.add(icon);
+
+        let label = new St.Label({ text: message });
+        box.add(label);
+    },
+
+    _onCancelButtonPressed: function(button, event) {
+        this.close(global.get_current_time());
+
+        // Even though the extension is already "uninstalled", send through
+        // a state-changed signal for any users who want to know if the install
+        // went through correctly -- using proper async DBus would block more
+        // traditional clients like the plugin
+        let meta = { uuid: this._uuid,
+                     state: ExtensionSystem.ExtensionState.UNINSTALLED,
+                     error: '' };
+
+        _signals.emit('extension-state-changed', meta);
+    },
+
+    _onInstallButtonPressed: function(button, event) {
+        let state = { uuid: this._uuid,
+                      state: ExtensionSystem.ExtensionState.DOWNLOADING,
+                      error: '' };
+
+        _signals.emit('extension-state-changed', state);
+
+        let params = { shell_version: Config.PACKAGE_VERSION };
+
+        let url = REPOSITORY_URL_DOWNLOAD.format(this._uuid);
+        let message = Soup.form_request_new_from_hash('GET', url, params);
+
+        _httpSession.queue_message(message,
+                                   Lang.bind(this, function(session, message) {
+                                       gotExtensionZipFile(session, message, this._uuid);
+                                   }));
+
+        this.close(global.get_current_time());
+    }
+});
+
+function init() {
+    _httpSession = new Soup.SessionAsync({ ssl_use_system_ca_file: true });
+
+    // See: https://bugzilla.gnome.org/show_bug.cgi?id=655189 for context.
+    // _httpSession.add_feature(new Soup.ProxyResolverDefault());
+    Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault());
+}
diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js
index efc79ae..fa2983a 100644
--- a/js/ui/extensionSystem.js
+++ b/js/ui/extensionSystem.js
@@ -3,19 +3,11 @@
 const Lang = imports.lang;
 const Signals = imports.signals;
 
-const Clutter = imports.gi.Clutter;
 const GLib = imports.gi.GLib;
 const Gio = imports.gi.Gio;
 const St = imports.gi.St;
-const Shell = imports.gi.Shell;
-const Soup = imports.gi.Soup;
 
-const Config = imports.misc.config;
 const ExtensionUtils = imports.misc.extensionUtils;
-const FileUtils = imports.misc.fileUtils;
-const ModalDialog = imports.ui.modalDialog;
-
-const API_VERSION = 1;
 
 const ExtensionState = {
     ENABLED: 1,
@@ -30,12 +22,6 @@ const ExtensionState = {
     UNINSTALLED: 99
 };
 
-const REPOSITORY_URL_BASE = 'https://extensions.gnome.org';
-const REPOSITORY_URL_DOWNLOAD = REPOSITORY_URL_BASE + '/download-extension/%s.shell-extension.zip';
-const REPOSITORY_URL_INFO =     REPOSITORY_URL_BASE + '/extension-info/';
-
-let _httpSession;
-
 // Arrays of uuids
 var enabledExtensions;
 // Contains the order that extensions were enabled in.
@@ -52,80 +38,6 @@ const disconnect = Lang.bind(_signals, _signals.disconnect);
 
 const ENABLED_EXTENSIONS_KEY = 'enabled-extensions';
 
-function installExtensionFromUUID(uuid) {
-    let params = { uuid: uuid,
-                   shell_version: Config.PACKAGE_VERSION };
-
-    let message = Soup.form_request_new_from_hash('GET', REPOSITORY_URL_INFO, params);
-
-    _httpSession.queue_message(message,
-                               function(session, message) {
-                                   let info = JSON.parse(message.response_body.data);
-                                   let dialog = new InstallExtensionDialog(uuid, info);
-                                   dialog.open(global.get_current_time());
-                               });
-}
-
-function uninstallExtensionFromUUID(uuid) {
-    let extension = ExtensionUtils.extensions[uuid];
-    if (!extension)
-        return false;
-
-    // Try to disable it -- if it's ERROR'd, we can't guarantee that,
-    // but it will be removed on next reboot, and hopefully nothing
-    // broke too much.
-    disableExtension(uuid);
-
-    // Don't try to uninstall system extensions
-    if (extension.type != ExtensionUtils.ExtensionType.PER_USER)
-        return false;
-
-    extension.state = ExtensionState.UNINSTALLED;
-    _signals.emit('extension-state-changed', extension);
-
-    delete ExtensionUtils.extensions[uuid];
-
-    FileUtils.recursivelyDeleteDir(Gio.file_new_for_path(extension.path));
-
-    return true;
-}
-
-function gotExtensionZipFile(session, message, uuid) {
-    if (message.status_code != Soup.KnownStatusCode.OK) {
-        logExtensionError(uuid, 'downloading extension: ' + message.status_code);
-        return;
-    }
-
-    let [file, stream] = Gio.File.new_tmp('XXXXXX.shell-extension.zip');
-    let dir = ExtensionUtils.userExtensionsDir.get_child(uuid);
-    let contents = message.response_body.flatten().as_bytes();
-    stream.output_stream.write_bytes(contents, null);
-    stream.close(null);
-    let [success, pid] = GLib.spawn_async(null,
-                                          ['unzip', '-uod', dir.get_path(), '--', file.get_path()],
-                                          null,
-                                          GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
-                                          null);
-
-    if (!success) {
-        logExtensionError(uuid, 'extract: could not extract');
-        return;
-    }
-
-    GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function(pid, status) {
-        GLib.spawn_close_pid(pid);
-
-        // Add extension to 'enabled-extensions' for the user, always...
-        let enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
-        if (enabledExtensions.indexOf(uuid) == -1) {
-            enabledExtensions.push(uuid);
-            global.settings.set_strv(ENABLED_EXTENSIONS_KEY, enabledExtensions);
-        }
-
-        loadExtension(dir, ExtensionUtils.ExtensionType.PER_USER, true);
-    });
-}
-
 function disableExtension(uuid) {
     let extension = ExtensionUtils.extensions[uuid];
     if (!extension)
@@ -347,11 +259,6 @@ function onEnabledExtensionsChanged() {
 function init() {
     ExtensionUtils.init();
 
-    _httpSession = new Soup.SessionAsync({ ssl_use_system_ca_file: true });
-    // See: https://bugzilla.gnome.org/show_bug.cgi?id=655189 for context.
-    // _httpSession.add_feature(new Soup.ProxyResolverDefault());
-    Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault());
-
     global.settings.connect('changed::' + ENABLED_EXTENSIONS_KEY, onEnabledExtensionsChanged);
     enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
 }
@@ -362,69 +269,3 @@ function loadExtensions() {
         loadExtension(dir, type, enabled);
     });
 }
-
-const InstallExtensionDialog = new Lang.Class({
-    Name: 'InstallExtensionDialog',
-    Extends: ModalDialog.ModalDialog,
-
-    _init: function(uuid, info) {
-        this.parent({ styleClass: 'extension-dialog' });
-
-        this._uuid = uuid;
-        this._info = info;
-
-        this.setButtons([{ label: _("Cancel"),
-                           action: Lang.bind(this, this._onCancelButtonPressed),
-                           key:    Clutter.Escape
-                         },
-                         { label:  _("Install"),
-                           action: Lang.bind(this, this._onInstallButtonPressed)
-                         }]);
-
-        let message = _("Download and install '%s' from extensions.gnome.org?").format(info.name);
-
-        let box = new St.BoxLayout();
-        this.contentLayout.add(box);
-
-        let gicon = new Gio.FileIcon({ file: Gio.File.new_for_uri(REPOSITORY_URL_BASE + info.icon) })
-        let icon = new St.Icon({ gicon: gicon });
-        box.add(icon);
-
-        let label = new St.Label({ text: message });
-        box.add(label);
-    },
-
-    _onCancelButtonPressed: function(button, event) {
-        this.close(global.get_current_time());
-
-        // Even though the extension is already "uninstalled", send through
-        // a state-changed signal for any users who want to know if the install
-        // went through correctly -- using proper async DBus would block more
-        // traditional clients like the plugin
-        let meta = { uuid: this._uuid,
-                     state: ExtensionState.UNINSTALLED,
-                     error: '' };
-
-        _signals.emit('extension-state-changed', meta);
-    },
-
-    _onInstallButtonPressed: function(button, event) {
-        let state = { uuid: this._uuid,
-                      state: ExtensionState.DOWNLOADING,
-                      error: '' };
-
-        _signals.emit('extension-state-changed', state);
-
-        let params = { shell_version: Config.PACKAGE_VERSION };
-
-        let url = REPOSITORY_URL_DOWNLOAD.format(this._uuid);
-        let message = Soup.form_request_new_from_hash('GET', url, params);
-
-        _httpSession.queue_message(message,
-                                   Lang.bind(this, function(session, message) {
-                                       gotExtensionZipFile(session, message, this._uuid);
-                                   }));
-
-        this.close(global.get_current_time());
-    }
-});
diff --git a/js/ui/main.js b/js/ui/main.js
index 81232ff..35c47de 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -18,6 +18,7 @@ const PolkitAuthenticationAgent = imports.ui.polkitAuthenticationAgent;
 const KeyringPrompt = imports.ui.keyringPrompt;
 const Environment = imports.ui.environment;
 const ExtensionSystem = imports.ui.extensionSystem;
+const ExtensionDownloader = imports.ui.extensionDownloader;
 const Keyboard = imports.ui.keyboard;
 const MessageTray = imports.ui.messageTray;
 const Overview = imports.ui.overview;
@@ -221,6 +222,7 @@ function start() {
 
     if (sessionMode.allowExtensions) {
         ExtensionSystem.init();
+        ExtensionDownloader.init();
         ExtensionSystem.loadExtensions();
     }
 
diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js
index 66e5dfb..7a62577 100644
--- a/js/ui/shellDBus.js
+++ b/js/ui/shellDBus.js
@@ -7,6 +7,7 @@ const Shell = imports.gi.Shell;
 
 const Config = imports.misc.config;
 const ExtensionSystem = imports.ui.extensionSystem;
+const ExtensionDownloader = imports.ui.extensionDownloader;
 const ExtensionUtils = imports.misc.extensionUtils;
 const Flashspot = imports.ui.flashspot;
 const Main = imports.ui.main;
@@ -254,11 +255,11 @@ const GnomeShell = new Lang.Class({
     },
 
     InstallRemoteExtension: function(uuid) {
-        ExtensionSystem.installExtensionFromUUID(uuid);
+        ExtensionDownloader.installExtensionFromUUID(uuid);
     },
 
     UninstallExtension: function(uuid) {
-        return ExtensionSystem.uninstallExtensionFromUUID(uuid);
+        return ExtensionDownloader.uninstallExtensionFromUUID(uuid);
     },
 
     LaunchExtensionPrefs: function(uuid) {
@@ -279,8 +280,6 @@ const GnomeShell = new Lang.Class({
             Main.overview.hide();
     },
 
-    ApiVersion: ExtensionSystem.API_VERSION,
-
     ShellVersion: Config.PACKAGE_VERSION,
 
     _extensionStateChanged: function(_, newState) {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]