Google plugin: report D-Bus errors
[cinaest] / src / plugins / google-plugin.vala
index 060dd1b..600c407 100644 (file)
 using Gtk;
 using Hildon;
 
+public class GoogleMovie : Movie {
+       public string cinema_name;
+       public string cinema_phone;
+       public int runtime;
+       public string showtimes;
+}
+
 class GooglePlugin : Plugin {
        List<MovieSource> sources;
-       List<string> locations;
+       SList<string> locations;
        string last_location;
+       GConf.Client gconf;
 
        public override void hello (Gtk.Window window, Osso.Context context) {
                stdout.printf ("Google Plugin Loaded.\n");
@@ -33,23 +41,12 @@ class GooglePlugin : Plugin {
                sources.append (source);
 
                locations = null;
+               gconf = GConf.Client.get_default ();
                try {
-                       var config_file = Path.build_filename (Environment.get_user_config_dir (), "cinaest", "cinaest.cfg");
-                       var keyfile = new KeyFile ();
-                       if (keyfile.load_from_file (config_file, KeyFileFlags.NONE)
-                           && keyfile.has_group ("GooglePlugin")) {
-                               if (keyfile.has_key ("GooglePlugin", "KnownLocations")) {
-                                       var l = keyfile.get_string_list ("GooglePlugin", "KnownLocations");
-                                       for (int i = 0; i < l.length; i++)
-                                               locations.append (l[i]);
-                               }
-                               if (keyfile.has_key ("GooglePlugin", "LastLocation")) {
-                                       source.location = last_location = keyfile.get_string ("GooglePlugin", "LastLocation");
-                               }
-                       }
+                       source.location = last_location = gconf.get_string ("/apps/cinaest/location");
+                       locations = gconf.get_list ("/apps/cinaest/locations", GConf.ValueType.STRING);
                } catch (Error e) {
-                       if (!(e is KeyFileError.NOT_FOUND))
-                               stdout.printf ("Error loading configuration: %s\n", e.message);
+                       stdout.printf ("Error getting GConf option: %s\n", e.message);
                }
 
                // FIXME - this forces the inclusion of config.h
@@ -66,7 +63,7 @@ class GooglePlugin : Plugin {
 
                if (movie != null) {
                        list.append (new MovieAction (_("Add to calendar"), on_add_calendar_event, movie, window));
-                       if (movie.cinema != null && movie.cinema.phone != null)
+                       if (movie.cinema_phone != null)
                                list.append (new MovieAction (_("Call cinema"), on_call_cinema, movie, window));
                }
 
@@ -99,13 +96,13 @@ class GooglePlugin : Plugin {
                        timeinfo.hour = hour;
                        showtime = timeinfo.mktime ();
 
-                       int runtime = 3600 * movie.runtime.to_int () + 60 * movie.runtime.str ("hr ").offset (3).to_int ();
+                       int runtime = movie.runtime;
                        if (runtime == 0) {
                                // Default to 120min if we failed to parse the runtime
                                runtime = 7200;
                        }
 
-                       res = Calendar.add_event (movie.title, _("Movie"), movie.cinema.name, showtime, showtime + runtime);
+                       res = Calendar.add_event (movie.title, _("Movie"), movie.cinema_name, showtime, showtime + runtime);
                        var banner = (Banner) Banner.show_information_with_markup (window, null, (res == 0) ?
                                                                                   _("Added calendar event at %d:%02d").printf (hour, min) :
                                                                                   _("Failed to add calendar event"));
@@ -116,7 +113,7 @@ class GooglePlugin : Plugin {
 
        private void on_call_cinema (Movie _movie, Gtk.Window window) {
                var movie = (GoogleMovie) _movie;
-               var url = "tel://" + movie.cinema.phone;
+               var url = "tel://" + movie.cinema_phone;
 
                try {
                        var action = Hildon.URIAction.get_default_action_by_uri (url);
@@ -138,6 +135,12 @@ class GooglePlugin : Plugin {
                var dialog = new Gtk.Dialog ();
                dialog.set_transient_for (window);
                dialog.set_title (_("Google plugin settings"));
+               try {
+                       source.location = gconf.get_string ("/apps/cinaest/location");
+                       locations = gconf.get_list ("/apps/cinaest/locations", GConf.ValueType.STRING);
+               } catch (Error e) {
+                       stdout.printf ("Error getting GConf option: %s\n", e.message);
+               }
 
                var selector = new TouchSelectorEntry.text ();
                insert_location_sorted (source.location);
@@ -158,38 +161,13 @@ class GooglePlugin : Plugin {
                int res = dialog.run ();
                if (res == ResponseType.ACCEPT) {
                        source.location = button.get_value ();
-                       if (insert_location_sorted (source.location) || source.location != last_location) {
-                               var config_dir = Path.build_filename (Environment.get_user_config_dir (), "cinaest");
-                               var config_file = Path.build_filename (config_dir, "cinaest.cfg");
-
-                               // Make sure the directory is available
-                               DirUtils.create_with_parents (config_dir, 0770);
-
-                               var keyfile = new KeyFile ();
-                               try {
-                                       keyfile.load_from_file (config_file, KeyFileFlags.NONE);
-                               } catch (Error e) {
-                                       if (!(e is KeyFileError.NOT_FOUND))
-                                               stdout.printf ("Error loading configuration: %s\n", e.message);
-                               }
-                               var l = new string[locations.length ()];
-                               for (int i = 0; i < l.length; i++) {
-                                       l[i] = locations.nth_data (i);
-                               }
-                               keyfile.set_string_list ("GooglePlugin", "KnownLocations", l);
-                               keyfile.set_string ("GooglePlugin", "LastLocation", source.location);
-                               last_location = source.location;
-
-                               try {
-                                       var file = File.new_for_path (config_file + ".part");
-                                       var stream = file.create (FileCreateFlags.REPLACE_DESTINATION, null);
-                                       var data = keyfile.to_data ();
-
-                                       stream.write (data, data.length, null);
-                                       FileUtils.rename (config_file + ".part", config_file);
-                               } catch (Error e) {
-                                       stdout.printf ("Failed to store configuration: %s\n", e.message);
-                               }
+                       try {
+                               if (insert_location_sorted (source.location))
+                                       gconf.set_list ("/apps/cinaest/locations", GConf.ValueType.STRING, locations);
+                               if (source.location != last_location)
+                                       gconf.set_string ("/apps/cinaest/location", source.location);
+                       } catch (Error e) {
+                               stdout.printf ("Error setting GConf option: %s\n", e.message);
                        }
                }
                dialog.destroy ();
@@ -199,7 +177,7 @@ class GooglePlugin : Plugin {
                if (location == null)
                        return false;
                if (locations != null) {
-                       for (unowned List<string> l = locations.first (); l != null; l = l.next) {
+                       for (unowned SList<string> l = locations; l != null; l = l.next) {
                                if (l.data == location) {
                                        return false;
                                }
@@ -221,6 +199,8 @@ class GooglePlugin : Plugin {
 class GoogleSource : MovieSource {
        public string location;
        public string description;
+       public MovieSource.ReceiveMovieFunction callback;
+       dynamic DBus.Object search;
 
        public override bool active { get; set construct; }
 
@@ -228,12 +208,75 @@ class GoogleSource : MovieSource {
                GLib.Object (active: true);
        }
 
-       public override async void get_movies (MovieFilter filter, MovieSource.ReceiveMovieFunction callback, int limit, Cancellable? cancellable) {
-               var parser = new GoogleParser ();
+       SourceFunc get_movies_callback;
+       public override async int get_movies (MovieFilter filter, MovieSource.ReceiveMovieFunction _callback, int limit, Cancellable? cancellable) {
+               try {
+                       string search_path;
+                       dynamic DBus.Object server;
+                       var conn = DBus.Bus.get (DBus.BusType.SESSION);
+
+                       server = conn.get_object ("org.maemo.cinaest.GoogleShowtimes",
+                                                 "/org/maemo/cinaest/googleshowtimes",
+                                                 "org.maemo.cinaest.MovieService");
+                       server.NewSearch (out search_path);
+
+                       search = conn.get_object ("org.maemo.cinaest.GoogleShowtimes",
+                                                 search_path,
+                                                 "org.maemo.cinaest.MovieSearch");
+
+                       callback = _callback;
+                       search.MoviesFound.connect (on_movies_found);
+                       search.start (filter.title);
+               } catch (Error e1) {
+                       Banner.show_information (null, null, e1.message);
+                       return 0;
+               }
+
+               get_movies_callback = get_movies.callback;
+               if (cancellable != null)
+                       cancellable.cancelled.connect (() => { search.abort (); Idle.add (get_movies_callback); });
+               yield;
+
+               var gc = GConf.Client.get_default ();
+               try {
+                       location = gc.get_string ("/apps/cinaest/location");
+               } catch (Error e) {
+                       stdout.printf ("Error getting GConf option: %s\n", e.message);
+               }
+
+               return 1 /*n*/;
+       }
+
+       private void on_movies_found (DBus.Object sender, string[] movies, bool finished) {
+               print ("found %d movies\n", movies.length);
+               var parser = new Json.Parser ();
+
+               for (int i = 0; i < movies.length; i++) {
+                       var movie = new GoogleMovie ();
+                       try {
+                               parser.load_from_data (movies[i], -1);
+                       } catch (Error e) {
+                               stderr.printf ("Error: %s\n%s\n", e.message, movies[i]);
+                       }
+
+                       var object = parser.get_root ().get_object ();
+                       movie.title = object.get_string_member ("title");
+                       movie.rating = (int) object.get_double_member ("rating");
+                       movie.cinema_name = object.get_string_member ("cinema_name");
+                       movie.cinema_phone = object.get_string_member ("cinema_phone");
+                       movie.runtime = (int) object.get_int_member ("runtime");
+                       movie.showtimes = object.get_string_member ("showtimes");
+                       if (movie.runtime > 0)
+                               movie.secondary = "%d min - %s - %s".printf (movie.runtime / 60, movie.cinema_name, movie.showtimes);
+                       else
+                               movie.secondary = movie.cinema_name + " - " + movie.showtimes;
+
+                       callback (movie);
+               }
 
-               yield parser.query (filter, location, callback, cancellable);
-               if (location == null) {
-                       location = parser.location;
+               if (finished) {
+                       search = null;
+                       Idle.add (get_movies_callback);
                }
        }
 
@@ -262,7 +305,7 @@ class GoogleSource : MovieSource {
 }
 
 [ModuleInit]
-public Type register_plugin () {
+public Type register_plugin (TypeModule module) {
        // types are registered automatically
        return typeof (GooglePlugin);
 }