Movie poster factory: add unqueue support
[cinaest] / src / poster / movie-poster-factory.vala
1 using GLib;
2
3 namespace MoviePoster {
4
5         public delegate void RequestCallback (Gdk.Pixbuf movieposter, Movie movie);
6
7         public class Factory : Object {
8                 private static Factory the_factory = null;
9                 internal List<Request> requests;
10                 internal dynamic DBus.Object server;
11                 internal bool download_posters;
12                 private GConf.Client gc;
13                 private uint cxnid;
14
15                 construct {
16                         try {
17                                 var conn = DBus.Bus.get (DBus.BusType.SESSION);
18                                 server = conn.get_object ("org.maemo.movieposter.GoogleImages",
19                                                           "/org/maemo/movieposter/GoogleImages",
20                                                           "org.maemo.movieposter.Provider");
21                                 server.Fetched += this.on_poster_fetched;
22                         } catch (Error e) {
23                                 warning ("Couldn't connect to Google image downloader: %s\n", e.message);
24                         }
25                         gc = GConf.Client.get_default ();
26
27                         download_posters = gc.get_bool ("/apps/cinaest/download_posters");
28                         gc.add_dir ("/apps/cinaest", GConf.ClientPreloadType.ONELEVEL);
29                         cxnid = gc.notify_add ("/apps/cinaest/download_posters", on_download_posters_changed);
30                 }
31
32                 private static void on_download_posters_changed (GConf.Client gc, uint cxnid, GConf.Entry entry) {
33                         the_factory.download_posters = entry.get_value ().get_bool ();
34                 }
35
36                 public static Factory get_instance () {
37                         if (the_factory == null)
38                                 the_factory = new MoviePoster.Factory ();
39                         return the_factory;
40                 }
41
42                 public int queue (Movie movie, RequestCallback callback) throws Error {
43                         string path = get_path (movie);
44
45                         if (FileUtils.test (path, FileTest.IS_REGULAR)) {
46                                 // TODO: make this async?
47                                 var pixbuf = new Gdk.Pixbuf.from_file_at_size (path, 268, 424);
48                                 callback (pixbuf, movie);
49                         } else if (server != null && download_posters) {
50                                 var request = new Request ();
51
52                                 request.handle = server.fetch (movie.title.down (), movie.year.to_string (), "movie");
53                                 request.movie = movie;
54                                 request.callback = callback;
55                                 request.width = 268;
56                                 request.height = 424;
57                                 requests.append (request);
58                         }
59                         return 0;
60                 }
61
62                 public int queue_thumbnail (Movie movie, uint width, uint height, bool cropped, RequestCallback callback) throws Error {
63                         string path = get_path_thumbnail (movie);
64
65                         if (FileUtils.test (path, FileTest.IS_REGULAR)) {
66                                 // TODO: make this async?
67                                 var pixbuf = new Gdk.Pixbuf.from_file_at_size (path, (int) width, (int) height);
68                                 callback (pixbuf, movie);
69                         } else if (server != null && download_posters) {
70                                 var request = new Request ();
71
72                                 request.handle = server.fetch_thumbnail (movie.title.down (), movie.year.to_string (), "movie");
73                                 request.movie = movie;
74                                 request.callback = callback;
75                                 request.width = (int) width;
76                                 request.height = (int) height;
77                                 requests.append (request);
78                         }
79                         return 0;
80                 }
81
82                 private void on_poster_fetched (dynamic DBus.Object server, int handle, string path) {
83                         Request request = null;
84                         foreach (Request r in requests) {
85                                 if (r.handle == handle) {
86                                         request = r;
87                                         break;
88                                 }
89                         }
90                         if (request == null)
91                                 return;
92                         try {
93                                 var pixbuf = new Gdk.Pixbuf.from_file_at_size (path, request.width, request.height);
94
95                                 requests.remove (request);
96                                 request.callback (pixbuf, request.movie);
97                                 return;
98                         } catch (Error e) {
99                                 warning ("Failed to open poster: %s\n", e.message);
100                         }
101                 }
102
103                 public void join () {
104                 }
105
106                 public static void factory_remove (Movie movie) {
107                 }
108
109                 public static void factory_clean_cache (int max_size, time_t min_mtime) {
110                 }
111
112                 public void clear_queue () {
113
114                         // FIXME
115                         if (server != null)
116                                 server.unqueue (0);
117
118                         requests = null;
119                 }
120         }
121
122         public class Request {
123                 public int handle;
124                 public Movie movie;
125                 public RequestCallback callback;
126                 public int width;
127                 public int height;
128
129                 public void unqueue () {
130                         if (Factory.get_instance ().server != null)
131                                 Factory.get_instance ().server.unqueue (this.handle);
132
133                         Factory.get_instance ().requests.remove (this);
134                 }
135
136                 public void join () {
137                 }
138         }
139
140         public static bool is_cached (Movie movie) {
141                 string filename = get_path (movie);
142                 if (FileUtils.test (filename, FileTest.IS_REGULAR))
143                         return true;
144                 else
145                         return false;
146         }
147
148         public static string get_path (Movie movie) {
149                 return Path.build_filename (Environment.get_user_cache_dir (), "media-art", "movie-" +
150                                             Checksum.compute_for_string (ChecksumType.MD5, movie.title.down ()) + "-" +
151                                             Checksum.compute_for_string (ChecksumType.MD5, movie.year.to_string ()) + ".jpeg");
152         }
153
154         public static string get_path_thumbnail (Movie movie) {
155                 return Path.build_filename (Environment.get_tmp_dir (), "cinaest-thumbnails", "movie-" +
156                                             Checksum.compute_for_string (ChecksumType.MD5, movie.title.down ()) + "-" +
157                                             Checksum.compute_for_string (ChecksumType.MD5, movie.year.to_string ()) + ".jpeg");
158         }
159 }
160