[polari/wip/bastianilso/irc-url-handling: 2/2] app: Handle links that dont match users existing connections



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

    app: Handle links that dont match users existing connections
    
    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.

 src/application.js     |   90 ++++++++++++++++++++++++++++++++++++++++++------
 src/networksManager.js |    7 ++++
 2 files changed, 86 insertions(+), 11 deletions(-)
---
diff --git a/src/application.js b/src/application.js
index 8401b30..8ff3497 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;
 
@@ -40,6 +41,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) {
@@ -166,13 +168,24 @@ const Application = new Lang.Class({
     _openURIs: function(uris, time) {
         let map = {};
 
-        this._accountsMonitor.dupAccounts().forEach(function(a) {
+        this._accountsMonitor.dupAccounts().forEach(Lang.bind(this, function(a) {
             if (!a.enabled)
                 return;
 
-            let params = a.dup_parameters_vardict().deep_unpack();
-            map[a.get_object_path()] = params.server.deep_unpack();
-        });
+            let servers = [];
+
+            let predefined = this._networksManager.getAccountIsPredefined(a);
+            if (predefined) {
+                this._networksManager.getServers(a).forEach(function(s) {
+                    servers.push(s.address);
+                });
+            } else {
+                let params = a.dup_parameters_vardict().deep_unpack();
+                servers = [params.server.deep_unpack()];
+            }
+
+            map[a.get_object_path()] = servers;
+        }));
 
         let action = this.lookup_action('join-room');
         uris.forEach(Lang.bind(this, function(uri) {
@@ -191,16 +204,71 @@ const Application = new Lang.Class({
             }
 
             let matches = Object.keys(map).filter(function(a) {
-                return map[a] == server;
+                let result = false;
+                map[a].forEach(function(s) {
+                    if (s == server)
+                        result = true;
+                        return;
+                });
+                return result;
             });
 
-            if (!matches.length) {
-                log("No matching account");
-                return;
+            if (matches.length) {
+                action.activate(new GLib.Variant('(ssu)',
+                                [matches[0], '#' + room, time]));
+            } else {
+                let networks = this._networksManager.networks;
+                let id, name, params;
+                for (let n of networks) {
+                    for (let s of n.servers) {
+                        log("checking " + s.address + " vs. " + server);
+                        if (s.address == server) {
+                            id = n.id;
+                            break;
+                        }
+                    }
+                    if (id) {
+                        name = n.name;
+                        params = this._networksManager.getNetworkDetails(id);
+                        break;
+                    }
+                }
+
+                if (!id) {
+                    let ssl = (port == 6697);
+                    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', ssl),
+                    };
+                    name = server;
+                }
+
+                let req = new Tp.AccountRequest({ account_manager: Tp.AccountManager.dup(),
+                                                  connection_manager: 'idle',
+                                                  protocol: 'irc',
+                                                  display_name: name });
+                req.set_enabled(true);
+
+                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);
+
+                        if (!account)
+                            return;
+                            // TODO: Handle errors
+
+                        let action = this.lookup_action('join-room');
+                        action.activate(GLib.Variant.new('(ssu)',
+                                                         [ account.get_object_path(),
+                                                           '#' + room,
+                                                           Utils.getTpEventTime() ]));
+                    }));
             }
-
-            action.activate(new GLib.Variant('(ssu)',
-                            [matches[0], '#' + room, time]));
         }));
     },
 
diff --git a/src/networksManager.js b/src/networksManager.js
index 489f4b6..962d619 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);
+    },
+
+    getServers: function(account) {
+        if (!account)
+            throw new Error('Missing account argument');
+        return this._lookupNetwork(account.service).servers;
     }
+
 });
 Signals.addSignalMethods(NetworksManager.prototype);


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