cinaest
libexec_PROGRAMS = \
+ google-poster-downloader \
imdb-plaintext-downloader
pkglib_LTLIBRARIES = \
dbusservice_DATA = \
data/org.maemo.cinaest.service \
- data/org.maemo.cinaest.IMDb.service
+ data/org.maemo.cinaest.IMDb.service \
+ data/org.maemo.movieposter.GoogleImages.service
desktopentry_DATA = \
data/cinaest.desktop
${imdb_plaintext_downloader_SOURCES}: ${imdb_plaintext_downloader_VALASOURCES}
${VALAC} -C ${imdb_plaintext_downloader_VALASOURCES} ${imdb_plaintext_downloader_VALAFLAGS}
+google_poster_downloader_SOURCES = \
+ src/poster/google-poster-downloader.c
+
+google_poster_downloader_VALASOURCES = \
+ src/poster/google-poster-downloader.vala
+
+google_poster_downloader_VALAFLAGS = --vapidir ./vapi --pkg dbus-glib-1 --pkg gio-2.0
+google_poster_downloader_CFLAGS = ${DBUS_CFLAGS} ${GIO_CFLAGS}
+google_poster_downloader_LDADD = ${DBUS_LIBS} ${GIO_LIBS}
+
+${google_poster_downloader_SOURCES}: ${google_poster_downloader_VALASOURCES}
+ ${VALAC} -C ${google_poster_downloader_VALASOURCES} ${google_poster_downloader_VALAFLAGS}
+
BUILT_SOURCES = \
${cinaest_SOURCES} \
${libimdb_plugin_la_SOURCES} \
--- /dev/null
+using GLib;
+
+[DBus (name = "org.maemo.movieposter.Provider", signals = "fetched")]
+public interface Provider {
+ public abstract int Fetch (string title, string year, string kind) throws DBus.Error;
+ public abstract int FetchThumbnail (string title, string year, string kind) throws DBus.Error;
+ public signal void fetched (int handle, string path);
+}
+
+// http://live.gnome.org/MediaArtStorageSpec
+
+// Sample implementation of org.maemo.movieposter.Provider that uses Google
+// images's first result as movie poster. There is of course no certainty
+// that the first result on Google images is indeed the movie's poster - there
+// are quite a few false positives, especially for non-mainstream movies.
+
+public class GoogleImages : Object, Provider {
+ int fetch_handle;
+
+ public int Fetch (string title, string year, string kind) throws DBus.Error {
+ int handle = fetch_handle++;
+
+ _fetch_async.begin (title, year, kind, false, handle);
+ return handle;
+ }
+
+ public int FetchThumbnail (string title, string year, string kind) throws DBus.Error {
+ int handle = fetch_handle++;
+
+ _fetch_async.begin (title, year, kind, true, handle);
+ return handle;
+ }
+
+ private async void _fetch_async (string title, string year, string kind, bool thumbnail, int handle) {
+ uint u = 0;
+ size_t hread = 0;
+ string [] pieces = title.split (" ", -1);
+ string stitched = "";
+ bool first = true;
+
+ stdout.printf ("Fetching %s \"%s (%s)\" ...\n", kind, title, year);
+
+ if (title == null || title == "")
+ title = " ";
+
+ if (year == null || year == "")
+ year = " ";
+
+ // Convert the title and year into something that will work for Google images
+
+ while (pieces[u] != null) {
+ if (!first)
+ stitched += "+";
+ stitched += pieces[u];
+ u++;
+ first = false;
+ }
+
+ stitched += "+";
+
+ u = 0;
+ first = true;
+ pieces = year.split (" ", -1);
+
+ while (pieces[u] != null) {
+ if (!first)
+ stitched += "+";
+ stitched += pieces[u];
+ u++;
+ first = false;
+ }
+
+ stitched += "+movie+poster";
+
+ // Start the query on Google images
+
+ stdout.printf("GET http://images.google.com/images?q=" + Uri.escape_string (stitched, "+", false) + "\n");
+
+ File google_search = File.new_for_uri ("http://images.google.com/images?q=" + Uri.escape_string (stitched, "+", false));
+
+ try {
+ char [] buffer = new char [40000];
+ string asstring;
+ size_t total = 0;
+
+ // Fetch the first page
+
+ InputStream stream = google_search.read (null);
+
+ while (total < 40000) {
+ hread = yield stream.read_async ((char *)buffer + total, 40000 - total, Priority.DEFAULT_IDLE, null);
+ total += hread;
+ if (hread == 0)
+ break;
+ }
+ buffer[total] = 0;
+
+ asstring = (string) buffer;
+
+ // Find the first result
+
+ string found = null;
+ int i;
+ char end;
+ if (thumbnail) {
+ do {
+ found = asstring.str ("http://t");
+ } while (found != null && !found.offset (9).has_prefix (".gstatic.com/images?q=tbn"));
+ i = 0;
+ end = ' ';
+ } else {
+ found = asstring.str ("href=/imgres?imgurl=");
+ i = 20;
+ end = '&';
+ }
+
+ if (found != null) {
+
+ StringBuilder url = new StringBuilder ();
+ long y = found.len();
+
+ while (found[i] != end && i < y) {
+ url.append_unichar (found[i]);
+ i++;
+ }
+
+ string cache_path;
+
+ string cache_dir;
+ if (thumbnail) {
+ // FIXME
+ cache_dir = Path.build_filename (Environment.get_tmp_dir(), "cinaest-thumbnails");
+ } else {
+ cache_dir = Path.build_filename (Environment.get_user_cache_dir(), "media-art");
+ }
+
+ // Define cache path = ~/.album_art/MD5 (down (albumartist)).jpeg
+
+ cache_path = Path.build_filename (cache_dir, kind + "-" +
+ Checksum.compute_for_string (
+ ChecksumType.MD5,
+ (title).down (),
+ -1) + "-" +
+ Checksum.compute_for_string (
+ ChecksumType.MD5,
+ (year).down (),
+ -1) +
+ ".jpeg", null);
+
+ // Make sure the directory .album_arts is available
+ DirUtils.create_with_parents (cache_dir, 0770);
+
+ stdout.printf ("GET %s --> %s\n", url.str, cache_path);
+
+ File online_image = File.new_for_uri (url.str);
+ File cache_image = File.new_for_path (cache_path + ".part");
+
+ // Copy from Google images to local cache
+
+ yield online_image.copy_async (cache_image,
+ FileCopyFlags.NONE,
+ Priority.DEFAULT_IDLE,
+ null,
+ null);
+
+ FileUtils.rename (cache_path + ".part", cache_path);
+
+ fetched (handle, cache_path);
+
+ stdout.printf ("DONE\n");
+ } else {
+ stdout.printf ("NOT FOUND\n");
+ // stdout.printf ("%s\n", asstring);
+ }
+
+ } catch (GLib.Error error) {
+ stderr.printf ("Error: %s\n", error.message);
+ }
+ }
+}
+
+void main () {
+ var loop = new MainLoop (null, false);
+
+ try {
+ var conn = DBus.Bus.get (DBus.BusType.SESSION);
+
+ dynamic DBus.Object bus = conn.get_object ("org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus");
+
+ // Try to register service in session bus
+ uint request_name_result = bus.request_name ("org.maemo.movieposter.GoogleImages", (uint) 0);
+
+ if (request_name_result == DBus.RequestNameReply.PRIMARY_OWNER) {
+ // Start server
+ var server = new GoogleImages ();
+ conn.register_object ("/org/maemo/movieposter/GoogleImages", server);
+
+ loop.run ();
+ }
+ } catch (Error e) {
+ error ("Oops: %s\n", e.message);
+ }
+}