[polari/wip/kunaljain/image-paste-service] Initial support for imgur paste service



commit 984c21104b4bb6eec7e5e6c81f6457a28e9bb8a7
Author: Kunaal Jain <kunaalus gmail com>
Date:   Sat Jan 2 18:49:55 2016 +0530

    Initial support for imgur paste service

 src/application.js  |   12 ++++++------
 src/entryArea.js    |   28 +++++++++++++++++++++++++---
 src/pasteManager.js |   15 ++++++++++-----
 src/utils.js        |   51 ++++++++++++++++++++++++++++++++++++++++++++-------
 4 files changed, 85 insertions(+), 21 deletions(-)
---
diff --git a/src/application.js b/src/application.js
index 3d67ad7..55deb42 100644
--- a/src/application.js
+++ b/src/application.js
@@ -70,9 +70,9 @@ const Application = new Lang.Class({
           { name: 'message-user',
             activate: Lang.bind(this, this._onMessageUser),
             parameter_type: GLib.VariantType.new('(ssu)') },
-          { name: 'paste-text',
-            activate: Lang.bind(this, this._onPasteText),
-            parameter_type: GLib.VariantType.new('s') },
+          { name: 'paste-content',
+            activate: Lang.bind(this, this._onPasteContent),
+            parameter_type: GLib.VariantType.new('(si)') },
           { name: 'leave-room',
             activate: Lang.bind(this, this._onLeaveRoom),
             parameter_type: GLib.VariantType.new('(ss)') },
@@ -354,9 +354,9 @@ const Application = new Lang.Class({
                              contactName, time);
     },
 
-    _onPasteText: function(action, parameter) {
-        let text = parameter.deep_unpack();
-        this.pasteManager.pasteText(text);
+    _onPasteContent: function(action, parameter) {
+        let [data, type] = parameter.deep_unpack();
+        this.pasteManager.pasteContent(data, type);
     },
 
     _onLeaveRoom: function(action, parameter) {
diff --git a/src/entryArea.js b/src/entryArea.js
index 95892d1..e8b39e4 100644
--- a/src/entryArea.js
+++ b/src/entryArea.js
@@ -18,7 +18,8 @@ const ChatEntry = new Lang.Class({
     Name: 'ChatEntry',
     Extends: Gtk.Entry,
     Signals: { 'text-pasted': { param_types: [GObject.TYPE_STRING,
-                                              GObject.TYPE_INT] } },
+                                              GObject.TYPE_INT] },
+               'image-pasted': { param_types: [GObject.TYPE_OBJECT] } },
 
     _init: function(params) {
         this.parent(params);
@@ -35,6 +36,7 @@ const ChatEntry = new Lang.Class({
         let clipboard = Gtk.Clipboard.get_default(this.get_display());
         clipboard.request_text(Lang.bind(this,
             function(clipboard, text) {
+                if(text==null) return;
                 let nLines = text.split('\n').length;
                 if (nLines >= MAX_LINES) {
                     this.emit('text-pasted', text, nLines);
@@ -45,6 +47,12 @@ const ChatEntry = new Lang.Class({
                 this.emit('paste-clipboard');
                 this._useDefaultHandler = false;
             }));
+
+        clipboard.request_image(Lang.bind(this,
+            function(clipboard, pixbuf) {
+                if(pixbuf==null) return;
+                this.emit('image-pasted', pixbuf);
+            }));
     },
 });
 
@@ -119,6 +127,7 @@ const EntryArea = new Lang.Class({
 
         this._entry = new ChatEntry({ hexpand: true, activates_default: true });
         this._entry.connect('text-pasted', Lang.bind(this, this._onTextPasted));
+        this._entry.connect('image-pasted', Lang.bind(this, this._onImagePasted));
         this._entry.connect('changed', Lang.bind(this, this._onEntryChanged));
         chatBox.add(this._entry);
 
@@ -148,7 +157,7 @@ const EntryArea = new Lang.Class({
 
         this._pasteButton = new Gtk.Button({ label: _("_Paste"),
                                              use_underline: true,
-                                             action_name: 'app.paste-text' });
+                                             action_name: 'app.paste-content' });
         this._pasteButton.get_style_context().add_class('suggested-action');
         this._pasteButton.connect('clicked',
                                   Lang.bind(this, this._onButtonClicked));
@@ -228,7 +237,20 @@ const EntryArea = new Lang.Class({
             ngettext("Paste %s line of text to public paste service?",
                      "Paste %s lines of text to public paste service?",
                      nLines).format(nLines);
-        this._pasteButton.action_target = new GLib.Variant('s', text);
+        this._pasteButton.action_target = new GLib.Variant('(si)', [text, 0]);
+        this.widget.visible_child_name = 'multiline';
+        this._pasteButton.grab_focus();
+    },
+
+    _onImagePasted: function(entry, data) {
+        this._multiLinelabel.label = "Paste image to imgur paste service?";
+
+        let [success, buffer] = data.save_to_bufferv('png',[],[]);
+        if (!success)
+            return;
+        let encoded_buffer = GLib.base64_encode(buffer);
+
+        this._pasteButton.action_target = new GLib.Variant('(si)', [encoded_buffer, 1]);
         this.widget.visible_child_name = 'multiline';
         this._pasteButton.grab_focus();
     },
diff --git a/src/pasteManager.js b/src/pasteManager.js
index 2207751..9f8e1a8 100644
--- a/src/pasteManager.js
+++ b/src/pasteManager.js
@@ -73,15 +73,20 @@ const PasteManager = new Lang.Class({
         this._widgets.push(widget);
     },
 
-    pasteText: function(text) {
+    pasteContent: function(data, type) {
         let app = Gio.Application.get_default();
-        let n = new UploadNotification("text");
+        let n;
+        if (type==0)
+            n = new UploadNotification("text");
+        else
+            n = new UploadNotification("image");
+
         app.notificationQueue.addNotification(n);
 
-        this._pasteText(text, n);
+        this._pasteContent(data, type, n);
     },
 
-    _pasteText: function(text, notification) {
+    _pasteContent: function(data, datatype, notification) {
         let room = this._roomManager.getActiveRoom();
         if (!room) {
             notification.close();
@@ -99,7 +104,7 @@ const PasteManager = new Lang.Class({
         if (title.length > MAX_PASTE_TITLE_LENGTH)
             title = title.substr(0, MAX_PASTE_TITLE_LENGTH - 1) + '…';
 
-        Utils.gpaste(text, title, Lang.bind(this,
+        Utils.gpaste(data, datatype, title, Lang.bind(this,
             function(url) {
                 if (!url) {
                     notification.close();
diff --git a/src/utils.js b/src/utils.js
index 3961b01..bb716f3 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -30,7 +30,9 @@ const Tp = imports.gi.TelepathyGLib;
 const AppNotifications = imports.appNotifications;
 const Signals = imports.signals;
 
-const GPASTE_BASEURL = 'https://paste.gnome.org/'
+const GPASTE_TEXT_BASEURL = 'https://paste.gnome.org/';
+
+const IMGUR_CLIENT_ID = '4109e59177ec95e';
 
 // http://daringfireball.net/2010/07/improved_regex_for_matching_urls
 const _balancedParens = '\\((?:[^\\s()<>]+|(?:\\(?:[^\\s()<>]+\\)))*\\)';
@@ -137,7 +139,12 @@ function openURL(url, timestamp) {
     }
 }
 
-function gpaste(text, title, callback) {
+function gpaste(data, datatype, title, callback) {
+    if (datatype==0) pasteText(data, title, callback);
+    else pasteImage(data, title, callback);
+}
+
+function pasteText(text, title, callback) {
     let params = {
         title: title,
         data: text,
@@ -145,14 +152,43 @@ function gpaste(text, title, callback) {
     };
 
     let session = new Soup.Session();
-    let createUrl = GPASTE_BASEURL + 'api/json/create';
+    let createUrl = GPASTE_TEXT_BASEURL + 'api/json/create';
     let message = Soup.form_request_new_from_hash('POST', createUrl, params);
     session.queue_message(message,
         function(session, message) {
-            if (message.status_code != Soup.KnownStatusCode.OK) {
+            if (message.status_code != Soup.KnownStatusCode.OK)
                 callback(null);
-                return;
+
+            let info = {};
+            try {
+                info = JSON.parse(message.response_body.data);
+            } catch(e) {
+                log(e.message);
+            }
+            if (info.result && info.result.id) {
+                callback(GPASTE_TEXT_BASEURL + info.result.id);
             }
+            else
+                callback(null);
+        });
+}
+
+function pasteImage(data, title, callback) {
+    let params = {
+        title: title,
+        image: data
+    };
+
+    let session = new Soup.Session();
+    let createUrl = 'https://api.imgur.com/3/image';
+    let message = Soup.form_request_new_from_hash('POST', createUrl, params);
+
+    let requestHeaders = message.request_headers;
+    requestHeaders.append('Authorization', 'Client-ID ' + IMGUR_CLIENT_ID);
+    session.queue_message(message,
+        function(session, message) {
+            if (message.status_code != Soup.KnownStatusCode.OK)
+                callback(null);
 
             let info = {};
             try {
@@ -160,8 +196,9 @@ function gpaste(text, title, callback) {
             } catch(e) {
                 log(e.message);
             }
-            if (info.result && info.result.id)
-                callback(GPASTE_BASEURL + info.result.id);
+            if (info.success) {
+                callback(info.data.link);
+            }
             else
                 callback(null);
         });


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