Movie poster factory: fix the clear_queue method
[cinaest] / src / poster / movie-poster-factory.vala
1 /* This file is part of Cinaest.
2  *
3  * Copyright (C) 2009 Philipp Zabel
4  *
5  * Cinaest is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Cinaest is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with Cinaest. If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 using GLib;
20
21 namespace MoviePoster {
22
23         public delegate void RequestCallback (Gdk.Pixbuf movieposter, Movie movie);
24
25         public class Factory : Object {
26                 private static Factory the_factory = null;
27                 internal List<Request> requests;
28                 internal dynamic DBus.Object server;
29                 internal bool download_posters;
30                 private GConf.Client gc;
31                 private uint cxnid;
32
33                 construct {
34                         try {
35                                 var conn = DBus.Bus.get (DBus.BusType.SESSION);
36                                 server = conn.get_object ("org.maemo.movieposter.GoogleImages",
37                                                           "/org/maemo/movieposter/GoogleImages",
38                                                           "org.maemo.movieposter.Provider");
39                                 server.Fetched += this.on_poster_fetched;
40                         } catch (Error e) {
41                                 warning ("Couldn't connect to Google image downloader: %s\n", e.message);
42                         }
43                         gc = GConf.Client.get_default ();
44
45                         download_posters = gc.get_bool ("/apps/cinaest/download_posters");
46                         gc.add_dir ("/apps/cinaest", GConf.ClientPreloadType.ONELEVEL);
47                         cxnid = gc.notify_add ("/apps/cinaest/download_posters", on_download_posters_changed);
48                 }
49
50                 private static void on_download_posters_changed (GConf.Client gc, uint cxnid, GConf.Entry entry) {
51                         the_factory.download_posters = entry.get_value ().get_bool ();
52                 }
53
54                 public static Factory get_instance () {
55                         if (the_factory == null)
56                                 the_factory = new MoviePoster.Factory ();
57                         return the_factory;
58                 }
59
60                 public int queue (Movie movie, RequestCallback callback) throws Error {
61                         string path = get_path (movie);
62
63                         if (FileUtils.test (path, FileTest.IS_REGULAR)) {
64                                 // TODO: make this async?
65                                 var pixbuf = new Gdk.Pixbuf.from_file_at_size (path, 268, 424);
66                                 callback (pixbuf, movie);
67                         } else if (server != null && download_posters) {
68                                 var request = new Request ();
69
70                                 request.handle = server.fetch (movie.title.down (), movie.year.to_string (), "movie");
71                                 request.movie = movie;
72                                 request.callback = callback;
73                                 request.width = 268;
74                                 request.height = 424;
75                                 requests.append (request);
76                         }
77                         return 0;
78                 }
79
80                 public int queue_thumbnail (Movie movie, uint width, uint height, bool cropped, RequestCallback callback) throws Error {
81                         string path = get_path_thumbnail (movie);
82
83                         if (FileUtils.test (path, FileTest.IS_REGULAR)) {
84                                 // TODO: make this async?
85                                 var pixbuf = new Gdk.Pixbuf.from_file_at_size (path, (int) width, (int) height);
86                                 callback (pixbuf, movie);
87                         } else if (server != null && download_posters) {
88                                 var request = new Request ();
89
90                                 request.handle = server.fetch_thumbnail (movie.title.down (), movie.year.to_string (), "movie");
91                                 request.movie = movie;
92                                 request.callback = callback;
93                                 request.width = (int) width;
94                                 request.height = (int) height;
95                                 requests.append (request);
96                         }
97                         return 0;
98                 }
99
100                 private void on_poster_fetched (dynamic DBus.Object server, int handle, string path) {
101                         Request request = null;
102                         foreach (Request r in requests) {
103                                 if (r.handle == handle) {
104                                         request = r;
105                                         break;
106                                 }
107                         }
108                         if (request == null)
109                                 return;
110                         try {
111                                 var pixbuf = new Gdk.Pixbuf.from_file_at_size (path, request.width, request.height);
112
113                                 requests.remove (request);
114                                 request.callback (pixbuf, request.movie);
115                                 return;
116                         } catch (Error e) {
117                                 warning ("Failed to open poster: %s\n", e.message);
118                         }
119                 }
120
121                 public void join () {
122                 }
123
124                 public static void factory_remove (Movie movie) {
125                 }
126
127                 public static void factory_clean_cache (int max_size, time_t min_mtime) {
128                 }
129
130                 public void clear_queue () {
131                         if (server != null) {
132                                 foreach (Request r in requests)
133                                         server.unqueue (r.handle);
134                         }
135                         requests = null;
136                 }
137         }
138
139         public class Request {
140                 public int handle;
141                 public Movie movie;
142                 public RequestCallback callback;
143                 public int width;
144                 public int height;
145
146                 public void unqueue () {
147                         if (Factory.get_instance ().server != null)
148                                 Factory.get_instance ().server.unqueue (this.handle);
149
150                         Factory.get_instance ().requests.remove (this);
151                 }
152
153                 public void join () {
154                 }
155         }
156
157         public static bool is_cached (Movie movie) {
158                 string filename = get_path (movie);
159                 if (FileUtils.test (filename, FileTest.IS_REGULAR))
160                         return true;
161                 else
162                         return false;
163         }
164
165         public static string get_path (Movie movie) {
166                 return Path.build_filename (Environment.get_user_cache_dir (), "media-art", "movie-" +
167                                             Checksum.compute_for_string (ChecksumType.MD5, movie.title.down ()) + "-" +
168                                             Checksum.compute_for_string (ChecksumType.MD5, movie.year.to_string ()) + ".jpeg");
169         }
170
171         public static string get_path_thumbnail (Movie movie) {
172                 return Path.build_filename (Environment.get_tmp_dir (), "cinaest-thumbnails", "movie-" +
173                                             Checksum.compute_for_string (ChecksumType.MD5, movie.title.down ()) + "-" +
174                                             Checksum.compute_for_string (ChecksumType.MD5, movie.year.to_string ()) + ".jpeg");
175         }
176 }
177