[rygel] core: Do not bail out on missing thumbnail dir



commit 2e5abd330b298f71218ba8e3c3c8ac1c81a28b73
Author: Jens Georg <mail jensge org>
Date:   Mon Jul 9 14:03:52 2012 +0200

    core: Do not bail out on missing thumbnail dir
    
    This fixed the situation where you not yet have a ".thumbnails"
    directory in your $HOME but have tumbler available. To do this, the code
    now uses ListActivateableServices on D-Bus to check for the Thumbnailer1
    interface and keeps on queuing incoming thumbnail requests until the
    thumbnailer is either ready or not found. The queue will be passed on to
    tumbler in the first case or flushed in the latter, marking the
    thumbnailer not available then.
    
    Unfortunately we cannot rely on Bus.get_proxy_sync to fail if it is not
    available because it simply doesn't, looking at the gdbus code.
    
    We stop handling the thumbnail directory ourselves and use GLib's
    FileInfo for that

 src/librygel-core/rygel-dbus-thumbnailer.vala |   33 ++++++++-
 src/librygel-core/rygel-thumbnailer.vala      |   93 +++++++++++--------------
 2 files changed, 70 insertions(+), 56 deletions(-)
---
diff --git a/src/librygel-core/rygel-dbus-thumbnailer.vala b/src/librygel-core/rygel-dbus-thumbnailer.vala
index 0de15ef..64b9c0e 100644
--- a/src/librygel-core/rygel-dbus-thumbnailer.vala
+++ b/src/librygel-core/rygel-dbus-thumbnailer.vala
@@ -37,6 +37,7 @@ internal class Rygel.DbusThumbnailer : GLib.Object {
     private ArrayList<string> mimes;
     private uint timeout_id;
     private string flavor;
+    FreeDesktop.DBusObject fdo;
 
     private const string THUMBNAILER_IFACE =
                                 "org.freedesktop.thumbnails.Thumbnailer1";
@@ -45,6 +46,8 @@ internal class Rygel.DbusThumbnailer : GLib.Object {
 
     private const uint THUMBNAIL_MAX_QUEUE_SIZE = 50;
 
+    public signal void ready (bool available);
+
     public DbusThumbnailer (string flavor = "normal") throws GLib.IOError,
                                                              GLib.DBusError {
         this.uris = new ArrayList<string> ();
@@ -52,9 +55,11 @@ internal class Rygel.DbusThumbnailer : GLib.Object {
         this.timeout_id = 0;
         this.flavor = flavor;
 
-        this.tumbler = GLib.Bus.get_proxy_sync (BusType.SESSION,
-                                                THUMBNAILER_IFACE,
-                                                THUMBNAILER_SERVICE);
+        this.fdo = Bus.get_proxy_sync (BusType.SESSION,
+                                       FreeDesktop.DBUS_SERVICE,
+                                       FreeDesktop.DBUS_OBJECT_PATH);
+
+        this.fdo.list_activatable_names.begin (this.on_activatable_names);
     }
 
     public void queue_thumbnail_task (string uri, string mime) {
@@ -79,6 +84,11 @@ internal class Rygel.DbusThumbnailer : GLib.Object {
     }
 
     private bool on_timeout () {
+        if (this.tumbler == null) {
+            // D-Bus service is not ready yet, keep on queuing
+            return true;
+        }
+
         debug ("Queueing thumbnail creation for %d files",
                this.uris.size);
 
@@ -94,4 +104,21 @@ internal class Rygel.DbusThumbnailer : GLib.Object {
 
         return false;
     }
+
+    private void on_activatable_names (Object? source, AsyncResult res) {
+        try {
+            var names = this.fdo.list_activatable_names.end (res);
+            if (THUMBNAILER_IFACE in names) {
+                this.tumbler = GLib.Bus.get_proxy_sync (BusType.SESSION,
+                                                        THUMBNAILER_IFACE,
+                                                        THUMBNAILER_SERVICE);
+            } else {
+                debug (_("No D-Bus thumbnailer service available"));
+            }
+        } catch (DBusError error) {
+        } catch (IOError io_error) {
+        }
+
+        this.ready (this.tumbler != null);
+    }
 }
diff --git a/src/librygel-core/rygel-thumbnailer.vala b/src/librygel-core/rygel-thumbnailer.vala
index db6ea20..e4f13da 100644
--- a/src/librygel-core/rygel-thumbnailer.vala
+++ b/src/librygel-core/rygel-thumbnailer.vala
@@ -34,52 +34,22 @@ internal class Rygel.Thumbnailer : GLib.Object {
     private static Thumbnailer thumbnailer; // Our singleton object
     private static bool first_time = true;
 
-    public string directory;
-
     private Thumbnail template;
     private string extension;
 
     private DbusThumbnailer thumbler = null;
 
     private Thumbnailer () throws ThumbnailerError {
-        var dir = Path.build_filename (Environment.get_home_dir (),
-                                       ".thumbnails",
-                                       "cropped");
-        var file = File.new_for_path (dir);
-        this.template = new Thumbnail ();
-
-        if (!file.query_exists (null)) {
-            dir = Path.build_filename (Environment.get_home_dir (),
-                                       ".thumbnails",
-                                       "normal");
-            file = File.new_for_path (dir);
-
-            if (!file.query_exists (null)) {
-                var message = _("Failed to find thumbnails folder.");
-
-                throw new ThumbnailerError.NO_DIR (message);
-            } else {
-                this.template.mime_type = "image/png";
-                this.template.dlna_profile = "PNG_TN";
-                this.template.file_extension = "png";
-                this.template.width = 128;
-                this.template.height = 128;
-                this.template.depth = 32;
-                this.extension = "." + this.template.file_extension;
-            }
-        } else {
-            this.template.width = 124;
-            this.template.height = 124;
-            this.template.depth = 24;
-            this.extension = ".jpeg";
-        }
-
-        this.directory = dir;
+        this.template = new Thumbnail ("image/png", "PNG_TN", "png");
+        this.template.width = 128;
+        this.template.height = 128;
+        this.template.depth = 32;
+        this.extension = "." + this.template.file_extension;
 
         try {
             this.thumbler = new DbusThumbnailer ();
-       } catch (GLib.Error error) { }
-
+            this.thumbler.ready.connect (this.on_dbus_thumbnailer_ready);
+        } catch (Error error) {}
     }
 
     public static Thumbnailer? get_default () {
@@ -97,41 +67,58 @@ internal class Rygel.Thumbnailer : GLib.Object {
     }
 
     public Thumbnail get_thumbnail (string uri, string mime_type) throws Error {
-        Thumbnail thumbnail = null;
-
-        var path = Checksum.compute_for_string (ChecksumType.MD5, uri) +
-                   this.extension;
-        var full_path = Path.build_filename (this.directory, path);
-        var file = File.new_for_path (full_path);
+        var file = File.new_for_uri (uri);
+        var info = file.query_info (FileAttribute.THUMBNAIL_PATH + "," +
+                                    FileAttribute.THUMBNAILING_FAILED,
+                                    FileQueryInfoFlags.NONE);
+        var path = info.get_attribute_as_string (FileAttribute.THUMBNAIL_PATH);
+        var failed = info.get_attribute_boolean
+                                        (FileAttribute.THUMBNAILING_FAILED);
+
+        if (failed) {
+            // Thumbnailing failed previously, so there's no current thumbnail
+            // and it doesn't make any sense to request one.
+            throw new ThumbnailerError.NO_THUMBNAIL
+                                        (_("No thumbnail available"));
+        }
 
-        // send a request to create thumbnail if it does not exist
-        if ((this.thumbler != null) && (!file.query_exists ())) {
+        // Send a request to create thumbnail if it does not exist, signalize
+        // that there's no thumbnail available now.
+        if (this.thumbler != null && path == null) {
             this.thumbler.queue_thumbnail_task (uri, mime_type);
 
             throw new ThumbnailerError.NO_THUMBNAIL
                                         (_("No thumbnail available"));
         }
 
-        var info = file.query_info (FileAttribute.ACCESS_CAN_READ + "," +
-                                    FileAttribute.STANDARD_SIZE,
-                                    FileQueryInfoFlags.NONE,
-                                    null);
+        file = File.new_for_path (path);
+        info = file.query_info (FileAttribute.ACCESS_CAN_READ + "," +
+                                FileAttribute.STANDARD_SIZE,
+                                FileQueryInfoFlags.NONE,
+                                null);
 
         if (!info.get_attribute_boolean (FileAttribute.ACCESS_CAN_READ)) {
             throw new ThumbnailerError.NO_THUMBNAIL
                                         (_("No thumbnail available"));
         }
 
-        thumbnail = new Thumbnail (this.template.mime_type,
-                                   this.template.dlna_profile,
-                                   this.template.file_extension);
+        var thumbnail = new Thumbnail (this.template.mime_type,
+                                       this.template.dlna_profile,
+                                       this.template.file_extension);
         thumbnail.width = this.template.width;
         thumbnail.height = this.template.height;
         thumbnail.depth = this.template.depth;
-        thumbnail.uri = Filename.to_uri (full_path, null);
+        thumbnail.uri = Filename.to_uri (path, null);
         thumbnail.size = (int64) info.get_attribute_uint64
                                         (FileAttribute.STANDARD_SIZE);
 
         return thumbnail;
     }
+
+    private void on_dbus_thumbnailer_ready (bool available) {
+        if (!available) {
+            this.thumbler = null;
+            message (_("No D-Bus thumbnailer available"));
+        }
+    }
 }



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