[polari/wip/kunaljain/image-paste-service: 2/2] Add support for pasting image to public image service



commit 93fb5a64851d7b17b4a747dc9d124e054e8a1eec
Author: Kunaal Jain <kunaalus gmail com>
Date:   Wed Feb 10 16:46:35 2016 +0530

    Add support for pasting image to public image service

 src/entryArea.js    |   25 ++++++++++++++++++++++++-
 src/pasteManager.js |   40 ++++++++++++++++++++++++++++++++++++++++
 src/utils.js        |   36 +++++++++++++++++++++++++++++++++++-
 3 files changed, 99 insertions(+), 2 deletions(-)
---
diff --git a/src/entryArea.js b/src/entryArea.js
index e15dcb0..a341852 100644
--- a/src/entryArea.js
+++ b/src/entryArea.js
@@ -1,4 +1,5 @@
 const Gdk = imports.gi.Gdk;
+const GdkPixbuf = imports.gi.GdkPixbuf;
 const GLib = imports.gi.GLib;
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
@@ -19,7 +20,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: [GdkPixbuf.Pixbuf.$gtype] } },
 
     _init: function(params) {
         this.parent(params);
@@ -50,6 +52,13 @@ 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);
+            }));
     },
 });
 
@@ -105,6 +114,7 @@ const EntryArea = new Lang.Class({
         this._nickPopover.set_default_widget(this._changeButton);
 
         this._chatEntry.connect('text-pasted', Lang.bind(this, this._onTextPasted));
+        this._chatEntry.connect('image-pasted', Lang.bind(this, this._onImagePasted));
         this._chatEntry.connect('changed', Lang.bind(this, this._onEntryChanged));
 
         this._chatEntry.connect('activate', Lang.bind(this,
@@ -216,6 +226,19 @@ const EntryArea = new Lang.Class({
         this._pasteButton.grab_focus();
     },
 
+    _onImagePasted: function(entry, data) {
+        this._multiLineLabel.label = _("Upload image to public 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, 
PasteManager.DndTargetType.IMAGE]);
+        this.visible_child_name = 'multiline';
+        this._pasteButton.grab_focus();
+    },
+
     _onButtonClicked: function() {
             this._chatEntry.text = '';
             this.visible_child_name = 'default';
diff --git a/src/pasteManager.js b/src/pasteManager.js
index 2aeb419..7a6043f 100644
--- a/src/pasteManager.js
+++ b/src/pasteManager.js
@@ -80,6 +80,10 @@ const PasteManager = new Lang.Class({
             let n = new UploadNotification("text");
             app.notificationQueue.addNotification(n);
             this._pasteText(data, n);
+        } else if (type == DndTargetType.IMAGE) {
+            let n = new UploadNotification("image");
+            app.notificationQueue.addNotification(n);
+            this._pasteImage(data, n);
         }
     },
 
@@ -122,6 +126,42 @@ const PasteManager = new Lang.Class({
             }));
     },
 
+    _pasteImage: function(data, notification) {
+        let room = this._roomManager.getActiveRoom();
+        if (!room) {
+            notification.close();
+            return;
+        }
+
+        let title;
+        let nick = room.channel.connection.self_contact.alias;
+        if (room.type == Tp.HandleType.ROOM)
+            /* translators: %s is a nick, #%s a channel */
+            title = _("%s in #%s").format(nick, room.display_name);
+        else
+            title = _("Paste from %s").format(nick);
+
+        Utils.imgurPaste(data, title, Lang.bind(this,
+            function(url) {
+                if (!url) {
+                    notification.close();
+                    return;
+                }
+
+                let type = Tp.ChannelTextMessageType.NORMAL;
+                let message = Tp.ClientMessage.new_text(type, url);
+                room.channel.send_message_async(message, 0, Lang.bind(this,
+                    function(c, res) {
+                        try {
+                             c.send_message_finish(res);
+                        } catch(e) {
+                             logError(e, 'Failed to send message')
+                        }
+                        notification.close();
+                    }));
+            }));
+    },
+
     _onDragDrop: function(widget, context, x, y, time) {
         if (!Polari.drag_dest_supports_target(widget, context, null))
             return Gdk.EVENT_PROPAGATE;
diff --git a/src/utils.js b/src/utils.js
index 3961b01..d58d340 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_BASEURL = 'https://paste.gnome.org/';
+
+const IMGUR_CLIENT_ID = '4109e59177ec95e';
 
 // http://daringfireball.net/2010/07/improved_regex_for_matching_urls
 const _balancedParens = '\\((?:[^\\s()<>]+|(?:\\(?:[^\\s()<>]+\\)))*\\)';
@@ -166,3 +168,35 @@ function gpaste(text, title, callback) {
                 callback(null);
         });
 }
+
+function imgurPaste(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);
+                return;
+            }
+
+            let info = {};
+            try {
+                info = JSON.parse(message.response_body.data);
+            } catch(e) {
+                log(e.message);
+            }
+            if (info.success)
+                callback(info.data.link);
+            else
+                callback(null);
+        });
+}


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