[polari] app: Handle links that dont match existing networks



commit 23d68c5acaafcf5e7c1f0e4b8c7a29dc2f285bfd
Author: Bastian Ilsø <hougaard junior gmail com>
Date:   Thu Feb 11 21:00:22 2016 +0100

    app: Handle links that dont match existing networks
    
    IRC URLs may point to networks which the user haven't
    connected to yet. Add support for matching IRC URLs
    against the list of predefined networks. If a match
    can't be found, create a custom connection pointing
    directly to the URL which the IRC link specifies.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=728593

 src/application.js     |   68 +++++++++++++++++++++++++++++++++++++++++------
 src/networksManager.js |    7 +++++
 2 files changed, 66 insertions(+), 9 deletions(-)
---
diff --git a/src/application.js b/src/application.js
index d01315e..b6fa847 100644
--- a/src/application.js
+++ b/src/application.js
@@ -12,6 +12,7 @@ const Lang = imports.lang;
 const MainWindow = imports.mainWindow;
 const PasteManager = imports.pasteManager;
 const Utils = imports.utils;
+const NetworksManager = imports.networksManager;
 
 const MAX_RETRIES = 3;
 
@@ -42,6 +43,7 @@ const Application = new Lang.Class({
         this._chatroomManager = ChatroomManager.getDefault();
         this._accountsMonitor = AccountsMonitor.getDefault();
         this._networkMonitor = Gio.NetworkMonitor.get_default();
+        this._networksManager = NetworksManager.getDefault();
 
         this._accountsMonitor.connect('account-removed', Lang.bind(this,
             function(am, account) {
@@ -173,7 +175,10 @@ const Application = new Lang.Class({
                 return;
 
             let params = a.dup_parameters_vardict().deep_unpack();
-            map[a.get_object_path()] = params.server.deep_unpack();
+            map[a.get_object_path()] = {
+                server: params.server.deep_unpack(),
+                service: a.service
+            };
         });
 
         let joinAction = this.lookup_action('join-room');
@@ -182,17 +187,27 @@ const Application = new Lang.Class({
             if (!success)
                 return;
 
+            // When launching Polari via a URL, there is a potential race
+            // condition between networksManager and AccountsManager here. If
+            // AccountsManager finishes first, networksManager's list of
+            // servers would be empty and hence no matches would be found.
+            let matchedId = this._networksManager.findByServer(server);
             let matches = Object.keys(map).filter(function(a) {
-                return GLib.ascii_strcasecmp(map[a], server) == 0;
+                return GLib.ascii_strcasecmp(map[a].server, server) == 0 ||
+                       map[a].service == matchedId;
             });
 
-            if (!matches.length) {
-                log("No matching account");
-                return;
-            }
-
-            joinAction.activate(new GLib.Variant('(ssu)',
-                            [matches[0], '#' + room, time]));
+            if (matches.length)
+                joinAction.activate(new GLib.Variant('(ssu)',
+                                [matches[0], '#' + room, time]));
+            else
+                this._createAccount(matchedId, server, port,
+                    function(a) {
+                        if (a)
+                            joinAction.activate(new GLib.Variant('(ssu)',
+                                            [a.get_object_path(),
+                                             '#' + room, time]));
+                    });
         }));
     },
 
@@ -212,6 +227,41 @@ const Application = new Lang.Class({
         return [success, server, port, room];
     },
 
+    _createAccount: function(id, server, port, callback) {
+        let params, name;
+
+        if (id) {
+            params = this._networksManager.getNetworkDetails(id);
+            name = this._networksManager.getNetworkName(id);
+        } else {
+            params = {
+                'account': new GLib.Variant('s', GLib.get_user_name()),
+                'server': new GLib.Variant('s', server),
+                'port': new GLib.Variant('u', port ? port : 6667),
+                'use-ssl': new GLib.Variant('b', (port == 6697)),
+            };
+            name = server;
+        }
+
+        let req = new Tp.AccountRequest({ account_manager: Tp.AccountManager.dup(),
+                                          connection_manager: 'idle',
+                                          protocol: 'irc',
+                                          display_name: name });
+        req.set_enabled(true);
+
+        if (id)
+            req.set_service(id);
+
+        for (let prop in params)
+            req.set_parameter(prop, params[prop]);
+
+        req.create_account_async(Lang.bind(this,
+            function(r, res) {
+                let account = req.create_account_finish(res);
+                callback(account);
+            }));
+    },
+
     _updateAccountAction: function(action) {
         action.enabled = this._accountsMonitor.dupAccounts().filter(
             function(a) {
diff --git a/src/networksManager.js b/src/networksManager.js
index 489f4b6..6b04261 100644
--- a/src/networksManager.js
+++ b/src/networksManager.js
@@ -91,6 +91,13 @@ const NetworksManager = new Lang.Class({
         });
         return [network.name.toLowerCase(),
                 network.id.toLowerCase()].concat(servers);
+    },
+
+    findByServer: function(server) {
+        for (let n of this._networks)
+           if (n.servers.some(s => s.address == server))
+               return n.id;
+        return null;
     }
 });
 Signals.addSignalMethods(NetworksManager.prototype);


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