[polari] app: open IRC links



commit 44c75c33d6a3e496972fef4996249a19633eacd3
Author: Bastian Ilsø <hougaard junior gmail com>
Date:   Thu Feb 11 17:18:16 2016 +0100

    app: open IRC links
    
    Register Polari as handler of IRC URLs and add
    support for opening IRC URLs pointing to rooms on
    the networks the user have added.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=728593

 data/org.gnome.Polari.desktop.in |    1 +
 src/application.js               |   68 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 68 insertions(+), 1 deletions(-)
---
diff --git a/data/org.gnome.Polari.desktop.in b/data/org.gnome.Polari.desktop.in
index b8fce56..56095dd 100644
--- a/data/org.gnome.Polari.desktop.in
+++ b/data/org.gnome.Polari.desktop.in
@@ -4,6 +4,7 @@ _Comment=An Internet Relay Chat Client for GNOME
 Exec=gapplication launch org.gnome.Polari
 Icon=org.gnome.Polari
 Type=Application
+MimeType=x-scheme-handler/irc;
 StartupNotify=true
 DBusActivatable=true
 X-GNOME-UsesNotifications=true
diff --git a/src/application.js b/src/application.js
index 2cb8fcb..d01315e 100644
--- a/src/application.js
+++ b/src/application.js
@@ -15,6 +15,8 @@ const Utils = imports.utils;
 
 const MAX_RETRIES = 3;
 
+const IRC_SCHEMA_REGEX = /^(irc?:\/\/)([\da-z\.-]+):?(\d+)?\/(?:%23)?([\w\.\+-]+)/i;
+
 const ConnectionError = {
     CANCELLED: Tp.error_get_dbus_name(Tp.Error.CANCELLED),
     ALREADY_CONNECTED: Tp.error_get_dbus_name(Tp.Error.ALREADY_CONNECTED)
@@ -26,7 +28,8 @@ const Application = new Lang.Class({
     Signals: { 'prepare-shutdown': {} },
 
     _init: function() {
-        this.parent({ application_id: 'org.gnome.Polari' });
+        this.parent({ application_id: 'org.gnome.Polari',
+                      flags: Gio.ApplicationFlags.HANDLES_OPEN });
 
         GLib.set_application_name('Polari');
         this._window = null;
@@ -146,6 +149,69 @@ const Application = new Lang.Class({
         this._window.present();
     },
 
+    vfunc_open: function(files) {
+        this.activate();
+
+        let time = Utils.getTpEventTime();
+        let uris = files.map(function(f) { return f.get_uri(); });
+
+        let quark = Tp.AccountManager.get_feature_quark_core();
+        if (this._accountsMonitor.accountManager.is_prepared(quark))
+            this._openURIs(uris, time);
+        else
+            this._accountsMonitor.connect('account-manager-prepared', Lang.bind(this,
+                function(mon) {
+                    this._openURIs(uris, time);
+                }));
+    },
+
+    _openURIs: function(uris, time) {
+        let map = {};
+
+        this._accountsMonitor.dupAccounts().forEach(function(a) {
+            if (!a.enabled)
+                return;
+
+            let params = a.dup_parameters_vardict().deep_unpack();
+            map[a.get_object_path()] = params.server.deep_unpack();
+        });
+
+        let joinAction = this.lookup_action('join-room');
+        uris.forEach(Lang.bind(this, function(uri) {
+            let [success, server, port, room] = this._parseURI(uri);
+            if (!success)
+                return;
+
+            let matches = Object.keys(map).filter(function(a) {
+                return GLib.ascii_strcasecmp(map[a], server) == 0;
+            });
+
+            if (!matches.length) {
+                log("No matching account");
+                return;
+            }
+
+            joinAction.activate(new GLib.Variant('(ssu)',
+                            [matches[0], '#' + room, time]));
+        }));
+    },
+
+    _parseURI: function(uri) {
+        let server, port, room;
+        let success = false;
+        try {
+            [,, server, port, room] = uri.match(IRC_SCHEMA_REGEX);
+            success = true;
+        } catch(e) {
+            let label = _("Failed to open link");
+            let n = new AppNotifications.MessageNotification(label,
+                                                             'dialog-error-symbolic');
+            this.notificationQueue.addNotification(n);
+        }
+
+        return [success, server, port, room];
+    },
+
     _updateAccountAction: function(action) {
         action.enabled = this._accountsMonitor.dupAccounts().filter(
             function(a) {


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