Add movie poster factory
authorPhilipp Zabel <philipp.zabel@gmail.com>
Fri, 16 Oct 2009 11:41:21 +0000 (13:41 +0200)
committerPhilipp Zabel <philipp.zabel@gmail.com>
Thu, 12 Nov 2009 18:23:24 +0000 (19:23 +0100)
Downloads movie poster images using the google-poster-downloader D-Bus service.
In the future, additional services (IMDb downloader, IMPawards downloader) might
be added.

Makefile.am
src/poster/movie-poster-factory.vala [new file with mode: 0644]

index aabbb5b..59b6ec1 100644 (file)
@@ -38,6 +38,7 @@ cinaest_SOURCES = \
         src/movie-list-window.c \
         src/plugin-interface.c \
        src/plugin-registrar.c \
+       src/poster/movie-poster-factory.c \
        src/settings-dialog.c \
        src/source-dialog.c
 
@@ -53,16 +54,18 @@ cinaest_VALASOURCES = \
         src/movie-list-window.vala \
         src/plugin-interface.vala \
        src/plugin-registrar.vala \
+       src/poster/movie-poster-factory.vala \
        src/settings-dialog.vala \
        src/source-dialog.vala
 
 ${cinaest_SOURCES}: ${cinaest_VALASOURCES}
        ${VALAC} -C ${cinaest_VALASOURCES} ${cinaest_VALAFLAGS}
 
-cinaest_VALAFLAGS = --vapidir ./vapi --pkg config --pkg hildon-1 --pkg libosso --pkg gmodule-2.0
-cinaest_CFLAGS = ${HILDON_CFLAGS} ${OSSO_CFLAGS} ${GMODULE_CFLAGS} \
+cinaest_VALAFLAGS = --vapidir ./vapi --pkg config \
+       --pkg dbus-glib-1 --pkg hildon-1 --pkg libosso --pkg gmodule-2.0
+cinaest_CFLAGS = ${DBUS_CFLAGS} ${HILDON_CFLAGS} ${OSSO_CFLAGS} ${GMODULE_CFLAGS} \
        -DGETTEXT_PACKAGE=\"@GETTEXT_PACKAGE@\"
-cinaest_LDADD = ${HILDON_LIBS} ${OSSO_LIBS} ${GMODULE_LIBS}
+cinaest_LDADD = ${DBUS_LIBS} ${HILDON_LIBS} ${OSSO_LIBS} ${GMODULE_LIBS}
 
 libgoogle_plugin_la_SOURCES = \
        src/plugins/google-plugin.c \
diff --git a/src/poster/movie-poster-factory.vala b/src/poster/movie-poster-factory.vala
new file mode 100644 (file)
index 0000000..e3224ba
--- /dev/null
@@ -0,0 +1,130 @@
+using GLib;
+
+namespace MoviePoster {
+
+       public delegate void RequestCallback (Gdk.Pixbuf movieposter, Movie movie);
+
+       public class Factory : Object {
+               private static Factory the_factory = null;
+               private List<Request> requests;
+               dynamic DBus.Object server;
+
+               construct {
+                       try {
+                               var conn = DBus.Bus.get (DBus.BusType.SESSION);
+                               server = conn.get_object ("org.maemo.movieposter.GoogleImages",
+                                                         "/org/maemo/movieposter/GoogleImages",
+                                                         "org.maemo.movieposter.Provider");
+                               server.Fetched += this.on_poster_fetched;
+                       } catch (Error e) {
+                               warning ("Couldn't connect to Google image downloader: %s\n", e.message);
+                       }
+               }
+
+               public static Factory get_instance () {
+                       if (the_factory == null)
+                               the_factory = new MoviePoster.Factory ();
+                       return the_factory;
+               }
+
+               public int queue (Movie movie, RequestCallback callback) throws Error {
+                       string path = get_path (movie);
+
+                       if (FileUtils.test (path, FileTest.IS_REGULAR)) {
+                               // TODO: make this async?
+                               var pixbuf = new Gdk.Pixbuf.from_file_at_size (path, 268, 424);
+                               callback (pixbuf, movie);
+                       } else if (server != null) {
+                               var request = new Request ();
+
+                               request.handle = server.fetch (movie.title.down (), movie.year.to_string (), "movie");
+                               request.movie = movie;
+                               request.callback = callback;
+                               request.width = 268;
+                               request.height = 424;
+                               requests.append (request);
+                       }
+                       return 0;
+               }
+
+               public int queue_thumbnail (Movie movie, uint width, uint height, bool cropped, RequestCallback callback) throws Error {
+                       string path = get_path_thumbnail (movie);
+
+                       if (FileUtils.test (path, FileTest.IS_REGULAR)) {
+                               // TODO: make this async?
+                               var pixbuf = new Gdk.Pixbuf.from_file_at_size (path, (int) width, (int) height);
+                               callback (pixbuf, movie);
+                       } else if (server != null) {
+                               var request = new Request ();
+
+                               request.handle = server.fetch_thumbnail (movie.title.down (), movie.year.to_string (), "movie");
+                               request.movie = movie;
+                               request.callback = callback;
+                               request.width = (int) width;
+                               request.height = (int) height;
+                               requests.append (request);
+                       }
+                       return 0;
+               }
+
+               private void on_poster_fetched (dynamic DBus.Object server, int handle, string path) {
+                       foreach (Request request in requests) {
+                               if (request.handle != handle)
+                                       continue;
+                               try {
+                                       var pixbuf = new Gdk.Pixbuf.from_file_at_size (path, request.width, request.height);
+
+                                       requests.remove (request);
+                                       request.callback (pixbuf, request.movie);
+                                       return;
+                               } catch (Error e) {
+                                       warning ("Failed to open poster: %s\n", e.message);
+                               }
+                       }
+               }
+
+               public void join () {
+               }
+
+               public static void factory_remove (Movie movie) {
+               }
+
+               public static void factory_clean_cache (int max_size, time_t min_mtime) {
+               }
+       }
+
+       public class Request {
+               public int handle;
+               public Movie movie;
+               public RequestCallback callback;
+               public int width;
+               public int height;
+
+               public void unqueue () {
+               }
+
+               public void join () {
+               }
+       }
+
+       public static bool is_cached (Movie movie) {
+               string filename = get_path (movie);
+               if (FileUtils.test (filename, FileTest.IS_REGULAR))
+                       return true;
+               else
+                       return false;
+       }
+
+       public static string get_path (Movie movie) {
+               return Path.build_filename (Environment.get_user_cache_dir (), "media-art", "movie-" +
+                                           Checksum.compute_for_string (ChecksumType.MD5, movie.title.down ()) + "-" +
+                                           Checksum.compute_for_string (ChecksumType.MD5, movie.year.to_string ()) + ".jpeg");
+       }
+
+       public static string get_path_thumbnail (Movie movie) {
+               return Path.build_filename (Environment.get_tmp_dir (), "cinaest-thumbnails", "movie-" +
+                                           Checksum.compute_for_string (ChecksumType.MD5, movie.title.down ()) + "-" +
+                                           Checksum.compute_for_string (ChecksumType.MD5, movie.year.to_string ()) + ".jpeg");
+       }
+}
+