[gnome-documents/rhel-7.4: 11/16] documents: Thumbnail SkydriveDocuments once they are loaded



commit aa507bc55aef99815308fe7865f016d40ed6f76d
Author: Debarshi Ray <debarshir gnome org>
Date:   Mon Mar 27 16:08:57 2017 +0200

    documents: Thumbnail SkydriveDocuments once they are loaded
    
    Historically, unlike GoogleDocuments, we were unable to fetch
    server-side thumbnails for SkydriveDocuments due to limitations of
    OneDrive's REST API. Newer versions of the REST API do support it [1],
    but it is not implemented in libzapojit.
    
    Some ways to work around these limitations:
      - Create the thumbnail from the EvDocument when it is loaded for
        previewing
      - Use a cached copy of the document as source for the thumbnail
    
    Even if we can fetch thumbnails from the server in future, these would
    still be nice optimizations to have — reduces network consumption and
    offers a cheap way to jump ahead in the thumbnailing queue.
    
    [1] https://dev.onedrive.com/items/thumbnails.htm

 src/documents.js |  111 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 109 insertions(+), 2 deletions(-)
---
diff --git a/src/documents.js b/src/documents.js
index 3bed18c..27518b2 100644
--- a/src/documents.js
+++ b/src/documents.js
@@ -1150,7 +1150,7 @@ const SkydriveDocument = new Lang.Class({
     Extends: DocCommon,
 
     _init: function(cursor) {
-        this._failedThumbnailing = true;
+        this._failedThumbnailing = false;
 
         this.parent(cursor);
 
@@ -1174,6 +1174,54 @@ const SkydriveDocument = new Lang.Class({
         this.uriToLoad = localFile.get_uri();
     },
 
+    _createThumbnailFromEvDocument: function(evDoc, cancellable, callback) {
+        let thumbnailPath = GnomeDesktop.desktop_thumbnail_path_for_uri (this.uri,
+                                                                         
GnomeDesktop.DesktopThumbnailSize.LARGE);
+        let thumbnailFile = Gio.File.new_for_path(thumbnailPath);
+
+        let thumbnailDir = GLib.path_get_dirname(thumbnailPath);
+        GLib.mkdir_with_parents(thumbnailDir, 448);
+
+        thumbnailFile.replace_async(null,
+                                    false,
+                                    Gio.FileCreateFlags.PRIVATE,
+                                    GLib.PRIORITY_DEFAULT,
+                                    cancellable,
+                                    Lang.bind(this,
+            function(source, res) {
+                let outputStream;
+
+                try {
+                    outputStream = thumbnailFile.replace_finish(res);
+                } catch (e) {
+                    callback(e);
+                    return;
+                }
+
+                let [width, height] = evDoc.get_page_size(0);
+                let maxDimension = Math.max(width, height);
+                let scale = Application.application.getScaleFactor();
+                let size = 128 * scale;
+                let zoom = size / maxDimension;
+
+                let page = evDoc.get_page(0);
+
+                let rc = EvDocument.RenderContext.new(page, 0, zoom);
+                let pixbuf = evDoc.get_thumbnail(rc);
+                pixbuf.save_to_streamv_async(outputStream, "png", [], [], cancellable, Lang.bind(this,
+                    function(source, res) {
+                        try {
+                            GdkPixbuf.Pixbuf.save_to_stream_finish(res);
+                        } catch (e) {
+                            callback(e);
+                            return;
+                        }
+
+                        callback(null);
+                    }));
+            }));
+    },
+
     _createZpjEntry: function(cancellable, callback) {
         let source = Application.sourceManager.getItemById(this.resourceUrn);
 
@@ -1276,7 +1324,16 @@ const SkydriveDocument = new Lang.Class({
                                             return;
                                         }
 
-                                        this.loadLocal(passwd, cancellable, callback);
+                                        this.loadLocal(passwd, cancellable, Lang.bind(this,
+                                            function(doc, docModel, error) {
+                                                if (error) {
+                                                    callback(this, null, error);
+                                                    return;
+                                                }
+
+                                                callback(this, docModel, null);
+                                                this._postLoad(docModel);
+                                            }));
                                     }));
                             } else {
                                 callback(this, null, error);
@@ -1286,6 +1343,56 @@ const SkydriveDocument = new Lang.Class({
                         }
 
                         callback(this, docModel, null);
+                        this._postLoad(docModel);
+                    }));
+            }));
+    },
+
+    _postLoad: function(docModel) {
+        if (this._thumbPath)
+            return;
+
+        if (!docModel)
+            return;
+
+        this._createThumbnailFromEvDocument(docModel.document, null, Lang.bind(this,
+            function(error) {
+                if (error) {
+                    logError(error, 'Unable to create thumbnail from EvDocument');
+                    return;
+                }
+
+                this._failedThumbnailing = false;
+                this.refreshIcon();
+            }));
+    },
+
+    createThumbnail: function(callback) {
+        // try loading from the most recent cache, if any
+        this.loadLocal(null, null, Lang.bind(this,
+            function(doc, docModel, error) {
+                if (error) {
+                    if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND) &&
+                        !error.matches(EvDocument.DocumentError, EvDocument.DocumentError.ENCRYPTED)) {
+                        logError(error, 'Unable to load document from the cache');
+                        callback(false);
+                        return;
+                    }
+                }
+
+                if (!docModel) {
+                    callback(false);
+                    return;
+                }
+
+                this._createThumbnailFromEvDocument(docModel.document, null, Lang.bind(this,
+                    function(error) {
+                        if (error) {
+                            logError(error, 'Unable to create thumbnail from EvDocument');
+                            return;
+                        }
+
+                        callback(true);
                     }));
             }));
     },


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