[gnome-clocks/wip/cityimages] Add a flickr client and integrate it into flickr provider



commit 28eb2bb870495dbdf599cc4d23068893ec0d3bb6
Author: Evgeny Bobkin <evgen ibqn gmail com>
Date:   Mon Sep 16 22:45:55 2013 +0200

    Add a flickr client and integrate it into flickr provider

 Makefile.am        |    3 +
 configure.ac       |    2 +
 src/providers.vala |  191 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/world.vala     |   18 +++---
 4 files changed, 205 insertions(+), 9 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index b27d647..355f826 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -95,6 +95,9 @@ AM_VALAFLAGS = \
        --pkg libnotify \
        --pkg gio-2.0 \
        --pkg geocode-glib-1.0 \
+       --pkg libsoup-2.4 \
+       --pkg json-glib-1.0 \
+       --thread \
        --gresources  $(top_srcdir)/data/gnome-clocks.gresource.xml
 
 bin_PROGRAMS = gnome-clocks
diff --git a/configure.ac b/configure.ac
index 0648f33..7c7d584 100644
--- a/configure.ac
+++ b/configure.ac
@@ -58,6 +58,8 @@ PKG_CHECK_MODULES(CLOCKS, [
     libnotify >= 0.7.0
     geocode-glib-1.0 >= 0.99.3
     geoclue-2.0 >= 1.99.3
+    json-glib-1.0
+    libsoup-2.4
 ])
 
 AC_CONFIG_FILES([
diff --git a/src/providers.vala b/src/providers.vala
index 508a5ad..7275c84 100644
--- a/src/providers.vala
+++ b/src/providers.vala
@@ -58,6 +58,15 @@ public class LocalImageProvider : GLib.Object, ImageProvider {
 
         File folder = File.new_for_path (folder_path);
 
+        if (!folder.query_exists ()) {
+            stdout.printf( "creating a flickr directory\n");
+            try {
+                folder.make_directory_with_parents ();
+            } catch (Error e) {
+                warning ("Could not create a city-images directory: %s", e.message);
+            }
+        }
+
         try {
             monitor = folder.monitor_directory (FileMonitorFlags.NONE, null);
             stdout.printf ("Monitoring: %s\n", folder.get_path ());
@@ -93,9 +102,134 @@ public class LocalImageProvider : GLib.Object, ImageProvider {
     }
 }
 
+private class FlickrClient : GLib.Object {
+    private static const string api_key = "8fe23980339fd51887815d106d3d3498";
+    private static const string url = "http://www.flickr.com/groups/gnome-clocks/";;
+
+    private Soup.SessionAsync session;
+    private string query_message;
+
+    public string server { get; set; }
+    public string group_id { get; set; default = null; }
+
+    public FlickrClient () {
+        server = "http://api.flickr.com/services/rest/?format=json&nojsoncallback=1";;
+        query_message = @"$server&api_key=$api_key";
+
+        session = new Soup.SessionAsync ();
+        session.use_thread_context = true;
+    }
+
+    private async Json.Object? get_root_object (string message) {
+        GLib.InputStream stream;
+
+        string msg = query_message + message; // stdout.printf (@"$msg\n");
+        var query = new Soup.Message ("GET", msg);
+
+        try {
+            stream = yield session.send_async (query);
+        } catch (Error e) {
+            warning ("Unable to sent message: %s", e.message);
+            return null;
+        }
+
+        var parser = new Json.Parser ();
+
+        try {
+            yield parser.load_from_stream_async (stream);
+        } catch (Error e) {
+            warning ("Failed to load data from stream: %s", e.message);
+            return null;
+        }
+
+        var root_object = parser.get_root ().get_object ();
+
+        if (root_object.has_member ("stat")) {
+            string stat = root_object.get_string_member ("stat");
+
+            if (stat != "ok") {
+                warning ("Response from the server contains an error");
+                return null;
+            }
+        }
+
+        return root_object;
+    }
+
+    public async void seek_group_id () {
+        string msg = @"&method=flickr.urls.lookupGroup&url=$url";
+
+        var object = yield get_root_object (msg);
+
+        if (object == null) {
+            return;
+        }
+
+        if (object.has_member ("group")) {
+            var group = object.get_object_member ("group");
+            if (group.has_member ("id")) {
+                group_id = group.get_string_member ("id");
+            }
+        }
+    }
+
+    public async string? seek_image_id (string name) {
+        string msg = @"&method=flickr.groups.pools.getPhotos&group_id=$group_id";
+
+        var object = yield get_root_object (msg);
+
+        if (object == null) {
+            return null;
+        }
+
+        if (object.has_member ("photos")) {
+            var photos = object.get_object_member ("photos");
+            var node_list = photos.get_array_member ("photo").get_elements ();
+
+            foreach (var node in node_list) {
+                var photo = node.get_object ();
+                string title = photo.get_string_member ("title");
+                stdout.printf (@"$title\n");
+                if (name == title) {
+                    string image_id = photo.get_string_member ("id");
+                    return image_id;
+                }
+            }
+        }
+        return null;
+    }
+
+    public async string? get_image_uri (string image_id) {
+        string msg = @"&method=flickr.photos.getSizes&photo_id=$image_id";
+
+        var object = yield get_root_object (msg);
+
+        if (object == null) {
+            return null;
+        }
+
+        if (object.has_member ("sizes")) {
+            var sizes = object.get_object_member ("sizes");
+            var node_list = sizes.get_array_member ("size").get_elements ();
+
+            foreach (var node in node_list) {
+                var image = node.get_object ();
+                string label = image.get_string_member ("label");
+                stdout.printf (@"$label\n");
+                if (label == "Original") {
+                    string image_url = image.get_string_member ("source");
+                    return image_url;
+                }
+            }
+        }
+        return null;
+    }
+}
+
 public class FlickrImageProvider : GLib.Object, ImageProvider {
     private string folder_path;
     private FileMonitor monitor;
+    private FlickrClient flickr_client;
 
     public FlickrImageProvider () {
         folder_path = GLib.Path.build_path (GLib.Path.DIR_SEPARATOR_S,
@@ -104,6 +238,15 @@ public class FlickrImageProvider : GLib.Object, ImageProvider {
 
         File folder = File.new_for_path (folder_path);
 
+        if (!folder.query_exists ()) {
+            stdout.printf( "creating a flickr directory\n");
+            try {
+                folder.make_directory_with_parents ();
+            } catch (Error e) {
+                warning ("Could not create a flickr directory: %s", e.message);
+            }
+        }
+
         try {
             monitor = folder.monitor_directory (FileMonitorFlags.NONE, null);
             stdout.printf ("Monitoring: %s\n", folder.get_path ());
@@ -121,6 +264,8 @@ public class FlickrImageProvider : GLib.Object, ImageProvider {
         } catch (Error err) {
             warning ("Monitoring flickr image files: %s\n", err.message);
         }
+
+        flickr_client = new FlickrClient ();
     }
 
     public Gdk.Pixbuf? get_image (string name) {
@@ -132,10 +277,56 @@ public class FlickrImageProvider : GLib.Object, ImageProvider {
             image = new Gdk.Pixbuf.from_file (path);
         } catch (Error e) {
             image = null;
+
+            fetch_image (name);
         }
 
         return image;
     }
+
+    private void fetch_image (string name) {
+        if (flickr_client.group_id != null) {
+            receive_image.begin ((obj, res) = > {
+                    receive_image.end (res);
+            });
+        } else {
+            flickr_client.notify["group-id"].connect (receve_image, name);
+            flickr_client.get_group_id.begin ();
+        }
+    }
+
+    private async void receive_image (string name) {
+        string? image_id = yield flickr_client.seek_image_id (name);
+
+        if (image_id == null) {
+            warning (@"Could not get image id for $name.");
+            return;
+        }
+
+        string? image_uri = yield flickr_client.seek_image_uri (image_id);
+
+        if (image_uri == null) {
+            warning (@"Could not get image uri for $name.");
+            return;
+        }
+
+        yield download_image (image_uri, string name);
+    }
+
+    private async void download_image (string uri, string name) {
+        var target_path = GLib.Path.build_path (GLib.Path.DIR_SEPARATOR_S,
+                                                folder_path,
+                                                name + ".jpg");
+        var source = File.new_for_uri (uri);
+        var target = File.new_for_path (target_path);
+
+        try {
+            yield source.copy_async (target, FileCopyFlags.OVERWRITE);
+        } catch (Error e) {
+            warning ("Copying an image has failed: %s", e.message);
+            return;
+        }
+    }
 }
 
 public class AutomaticImageProvider : GLib.Object, ImageProvider {
diff --git a/src/world.vala b/src/world.vala
index a4b4546..8dc8ee8 100644
--- a/src/world.vala
+++ b/src/world.vala
@@ -271,14 +271,15 @@ private class StandalonePanel : Gtk.EventBox {
 
         var overlay = new Gtk.Overlay ();
         var scrolled_window = new Gtk.ScrolledWindow (null, null);
+        scrolled_window.set_policy (Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER);
         city_image = new Gtk.Image ();
-        //city_image.halign = Gtk.Align.FILL;
-        //city_image.valign = Gtk.Align.FILL;
+        city_image.halign = Gtk.Align.FILL;
+        city_image.valign = Gtk.Align.FILL;
         scrolled_window.add (city_image);
         overlay.add (scrolled_window);
         overlay.add_overlay (grid);
-    fuck
-        //city_image.size_allocate.connect (on_size_allocate);
+
+        city_image.size_allocate.connect (on_size_allocate);
 
         add (overlay);
     }
@@ -290,7 +291,6 @@ private class StandalonePanel : Gtk.EventBox {
             sunrise_label.label = location.sunrise_label;
             sunset_label.label = location.sunset_label;
 
-            return;
             if (location.is_daytime) {
                 city_image.set_from_pixbuf (day_pixbuf);
             } else {
@@ -300,13 +300,13 @@ private class StandalonePanel : Gtk.EventBox {
     }
 
     public void on_size_allocate (Gtk.Allocation rectangle) {
-        //day_pixbuf = location.day_pixbuf.scale_simple (rectangle.width, rectangle.height, 
Gdk.InterpType.BILINEAR);
-        //night_pixbuf = location.night_pixbuf.scale_simple (rectangle.width, rectangle.height, 
Gdk.InterpType.BILINEAR);
+        day_pixbuf = location.day_pixbuf.scale_simple (rectangle.width, rectangle.height, 
Gdk.InterpType.BILINEAR);
+        night_pixbuf = location.night_pixbuf.scale_simple (rectangle.width, rectangle.height, 
Gdk.InterpType.BILINEAR);
 
         if (location.is_daytime) {
-            //city_image.set_from_pixbuf (day_pixbuf);
+            city_image.set_from_pixbuf (day_pixbuf);
         } else {
-            //city_image.set_from_pixbuf (night_pixbuf);
+            city_image.set_from_pixbuf (night_pixbuf);
         }
     }
 }


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