/* 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);
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 && download_posters) {
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);
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");
}
}