[polari/wip/bastianilso/irc-url-parsing] Register and support opening irc URL schemes



commit 32d7ef0bad97c3431f7ab2af54a75714156455cc
Author: Bastian Ilsø <bastianilso src gnome org>
Date:   Fri Jul 3 21:13:32 2015 +0200

    Register and support opening irc URL schemes
    
    The irc URL scheme can refer to either a server, channel
    or individual person. This patch register Polari as
    handler of the x-scheme-handler/irc mimetype. If Polari
    is the default handler, browsers can activate Polari
    via xdg-open/d-bus activation. Polari will attempt to
    parse any number of links passed to it.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=728593

 data/org.gnome.Polari.desktop.in |    1 +
 src/application.js               |   90 +++++++++++++++++++++++++++++++++++++-
 src/connections.js               |   34 ++++++++++++++-
 3 files changed, 122 insertions(+), 3 deletions(-)
---
diff --git a/data/org.gnome.Polari.desktop.in b/data/org.gnome.Polari.desktop.in
index 8aab491..f401f4c 100644
--- a/data/org.gnome.Polari.desktop.in
+++ b/data/org.gnome.Polari.desktop.in
@@ -5,6 +5,7 @@ Exec=polari
 TryExec=polari
 Icon=polari
 Type=Application
+MimeType=x-scheme-handler/irc;
 StartupNotify=true
 DBusActivatable=true
 Actions=connections;
diff --git a/src/application.js b/src/application.js
index 7262bfd..cfd7bb2 100644
--- a/src/application.js
+++ b/src/application.js
@@ -13,6 +13,7 @@ const MainWindow = imports.mainWindow;
 const PasteManager = imports.pasteManager;
 const Utils = imports.utils;
 
+const TP_CURRENT_TIME = GLib.MAXUINT32;
 
 const MAX_RETRIES = 3;
 
@@ -27,8 +28,7 @@ const Application = new Lang.Class({
 
     _init: function() {
         this.parent({ application_id: 'org.gnome.Polari' });
-
-        GLib.set_application_name('Polari');
+        this.set_flags(Gio.ApplicationFlags.HANDLES_OPEN);
         this._window = null;
         this._pendingRequests = {};
     },
@@ -47,11 +47,15 @@ const Application = new Lang.Class({
                 this._removeSavedChannelsForAccount(account);
             }));
 
+        this._accountsMonitor.connect('account-manager-prepared',
+                Lang.bind(this, this._parseArgs));
+
         this._settings = new Gio.Settings({ schema_id: 'org.gnome.Polari' });
 
         this.pasteManager = new PasteManager.PasteManager();
         this.notificationQueue = new AppNotifications.NotificationQueue();
         this.commandOutputQueue = new AppNotifications.CommandOutputQueue();
+        this._accountsMonitor = AccountsMonitor.getDefault();
 
         let actionEntries = [
           { name: 'room-menu',
@@ -143,6 +147,88 @@ const Application = new Lang.Class({
         this._window.window.present();
     },
 
+    vfunc_open: function(args) {
+
+        if (!this._window) {
+            this._window = new MainWindow.MainWindow(this);
+            this._window.window.connect('destroy', Lang.bind(this,
+                function() {
+                    for (let id in this._pendingRequests)
+                        this._pendingRequests[id].cancellable.cancel();
+                    this.emitJS('prepare-shutdown');
+            }));
+            this._window.window.show_all();
+
+            this._chatroomManager.lateInit();
+
+        }
+        this._window.window.present()
+
+        this._args = args;
+        this._parseArgs();
+    },
+
+    _parseArgs: function() {
+        let args =  this._args;
+        let accounts = this._accountsMonitor.dupAccounts();
+        if (accounts.length == 0) {
+            log('didnt pass check! ' + ' accounts: ' + accounts);
+            return;
+        }
+        log('accounts available: ' + accounts.length);
+        if (args.length == 0) {
+            log('didnt pass check! ' + ' args: ' + args);
+            return;
+        }
+        log('args available: ' + args.length);
+        this._args = null;
+        for (let i = 0; i < args.length; i++) {
+            let uriRegEx = /^(irc?:\/\/)([\da-z\.-:]+)\/(?:%23)?([\w \. \+-]*)/;
+            let [, , server, room] = args[i].get_uri().match(uriRegEx);
+            log('server: ' + server);
+            log('room: ' + room);
+            if (server && room)
+                this._onJoinUri(server.toLowerCase(), room.toLowerCase(), accounts);
+        }
+    },
+
+    _onJoinUri: function(server, room, accounts) {
+        let account = null;
+        log('looking through accounts..');
+        for (let i = 0; i < accounts.length; i++) {
+            let params = accounts[i].dup_parameters_vardict().deep_unpack();
+            for (let p in params)
+                params[p] = params[p].deep_unpack();
+            log('checking ' + server + ' vs ' + params.server);
+            if (server == params.server) {
+                log('match!');
+                account = accounts[i];
+                break;
+            }
+        }
+
+        if (account) {
+            log('got an account, joining ' + room);
+            let action = this.lookup_action('join-room');
+            action.activate(GLib.Variant.new('(ssu)',
+                                             [ account.get_object_path(),
+                                               '#' + room,
+                                               TP_CURRENT_TIME ]));
+            return;
+        }
+        log('no account match, opening details dialog..');
+        let detailsDialog = new Connections.ConnectionDetailsDialog(null);
+        detailsDialog.server_entry = server;
+        detailsDialog.room = room;
+        detailsDialog.widget.transient_for = this._window.window;
+        detailsDialog.nick_entry.grab_focus();
+        detailsDialog.widget.show();
+        detailsDialog.widget.connect('response',
+            Lang.bind(this, function(widget) {
+                widget.destroy();
+            }));
+    },
+
     _updateAccountAction: function(action) {
         action.enabled = this._accountsMonitor.dupAccounts().filter(
             function(a) {
diff --git a/src/connections.js b/src/connections.js
index b7fc45c..e17d4e9 100644
--- a/src/connections.js
+++ b/src/connections.js
@@ -9,6 +9,8 @@ const AccountsMonitor = imports.accountsMonitor;
 const Lang = imports.lang;
 const Signals = imports.signals;
 
+const TP_CURRENT_TIME = GLib.MAXUINT32;
+
 const ConnectionsDialog = new Lang.Class({
     Name: 'ConnectionsDialog',
 
@@ -254,6 +256,14 @@ const ConnectionDetails = new Lang.Class({
                this._nickEntry.get_text_length() > 0;
     },
 
+    get server_entry() {
+        return this._serverEntry;
+    },
+
+    get nick_entry() {
+        return this._nickEntry;
+    },
+
     save: function() {
         if (!this.can_confirm)
             return;
@@ -280,7 +290,16 @@ const ConnectionDetails = new Lang.Class({
 
         req.create_account_async(Lang.bind(this,
             function(r, res) {
-                req.create_account_finish(res); // TODO: Check for errors
+                let account = req.create_account_finish(res); // TODO: Check for errors
+                if (this.room) {
+                    log('room assigned, joining..');
+                    let app = Gio.Application.get_default();
+                    let action = app.lookup_action('join-room');
+                    action.activate(GLib.Variant.new('(ssu)',
+                                                     [ account.get_object_path(),
+                                                       '#' + this.room,
+                                                       TP_CURRENT_TIME ]));
+                }
             }));
     },
 
@@ -349,5 +368,18 @@ const ConnectionDetailsDialog = new Lang.Class({
                                     this._confirmButton, 'sensitive',
                                     GObject.BindingFlags.SYNC_CREATE);
         this.widget.get_content_area().add(this._details);
+    },
+    
+    set server_entry(server) {
+        let entry = this._details.server_entry;
+        entry.text = server;
+    },
+
+    set room(room) {
+        this._details.room = room;
+    },
+
+    get nick_entry() {
+        return this._details.nick_entry;
     }
 });


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