/* This file is part of Cinaest. * * Copyright (C) 2009 Philipp Zabel * * Cinaest is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Cinaest is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Cinaest. If not, see . */ using GLib; namespace MoviePoster { public delegate void RequestCallback (Gdk.Pixbuf movieposter, Movie movie); public class Factory : Object { private static Factory the_factory = null; internal List requests; internal dynamic DBus.Object server; internal bool download_posters; private GConf.Client gc; private uint cxnid; construct { try { var conn = DBus.Bus.get (DBus.BusType.SESSION); server = conn.get_object ("org.maemo.movieposter.IMDb", "/org/maemo/movieposter/IMDb", "org.maemo.movieposter.Provider"); server.Fetched.connect (this.on_poster_fetched); server.Failed.connect (this.on_poster_failed); } catch (Error e) { warning ("Couldn't connect to IMDb poster downloader: %s\n", e.message); } gc = GConf.Client.get_default (); try { download_posters = gc.get_bool ("/apps/cinaest/download_posters"); gc.add_dir ("/apps/cinaest", GConf.ClientPreloadType.ONELEVEL); cxnid = gc.notify_add ("/apps/cinaest/download_posters", on_download_posters_changed); } catch (Error e) { stdout.printf ("Error installing GConf notification: %s\n", e.message); } } private static void on_download_posters_changed (GConf.Client gc, uint cxnid, GConf.Entry entry) { the_factory.download_posters = entry.get_value ().get_bool (); } 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); foreach (Request request in requests) if (request.movie == movie) return 0; if (FileUtils.test (path, FileTest.IS_REGULAR)) { // TODO: make this async? var pixbuf = new Gdk.Pixbuf.from_file_at_scale (path, 288, 400, true); callback (pixbuf, movie); } else if (server != null && download_posters) { var request = new Request (); request.handle = server.Fetch (movie.title, movie.year.to_string (), "movie"); request.movie = movie; request.callback = callback; request.width = 288; request.height = 400; 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); foreach (Request request in requests) if (request.movie == movie) return 0; if (FileUtils.test (path, FileTest.IS_REGULAR)) { // TODO: make this async? var pixbuf = new Gdk.Pixbuf.from_file_at_scale (path, (int) width, (int) height, true); callback (pixbuf, movie); } else if (server != null && download_posters) { var request = new Request (); request.handle = server.FetchThumbnail (movie.title, 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) { Request request = null; foreach (Request r in requests) { if (r.handle == handle) { request = r; break; } } if (request == null) return; 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); } } private void on_poster_failed (dynamic DBus.Object server, int handle) { Request request = null; foreach (Request r in requests) { if (r.handle == handle) { request = r; break; } } if (request == null) return; requests.remove (request); // request.callback (pixbuf, request.movie); } public void join () { } public static void factory_remove (Movie movie) { } public static void factory_clean_cache (int max_size, time_t min_mtime) { } public void clear_queue () { if (server != null) { foreach (Request r in requests) server.Unqueue (r.handle); } requests = null; } } public class Request { public int handle; public Movie movie; public RequestCallback callback; public int width; public int height; public void unqueue () { if (Factory.get_instance ().server != null) Factory.get_instance ().server.Unqueue (this.handle); Factory.get_instance ().requests.remove (this); } 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"); } }