X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Fplugins%2Fgoogle-plugin.vala;h=65abc6fa992aff582493de62066786eca5fe6c4f;hb=edd1287bea8e81ddef04f2e47783e91a479a1537;hp=a617e55102068031e9dcf80533c67d28bca587dc;hpb=84333889de1b764174aeb1021f250848be0b3d2d;p=cinaest diff --git a/src/plugins/google-plugin.vala b/src/plugins/google-plugin.vala index a617e55..65abc6f 100644 --- a/src/plugins/google-plugin.vala +++ b/src/plugins/google-plugin.vala @@ -19,8 +19,18 @@ 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 sources; + SList locations; + string last_location; + GConf.Client gconf; public override void hello (Gtk.Window window, Osso.Context context) { stdout.printf ("Google Plugin Loaded.\n"); @@ -30,6 +40,15 @@ class GooglePlugin : Plugin { sources = new List (); sources.append (source); + locations = null; + gconf = GConf.Client.get_default (); + try { + source.location = last_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); + } + // FIXME - this forces the inclusion of config.h (void) Config.GETTEXT_PACKAGE; } @@ -38,20 +57,95 @@ class GooglePlugin : Plugin { return sources; } - public override List get_actions (Movie movie, Gtk.Window window) { + public override List get_actions (Movie _movie, Gtk.Window window) { List list = null; + var movie = _movie as GoogleMovie; + + if (movie != null) { + list.append (new MovieAction (_("Add to calendar"), on_add_calendar_event, movie, window)); + if (movie.cinema_phone != null) + list.append (new MovieAction (_("Call cinema"), on_call_cinema, movie, window)); + } return list; } + private void on_add_calendar_event (Movie _movie, Gtk.Window window) { + var movie = (GoogleMovie) _movie; + + var dialog = new PickerDialog (window); + dialog.set_title (_("Add showtime to calendar")); + + var selector = new TouchSelector.text (); + var showtimes = movie.showtimes.split (", "); + foreach (string s in showtimes) { + selector.append_text (s); + } + dialog.set_selector (selector); + + var res = dialog.run (); + if (res == ResponseType.OK) { + string s = selector.get_current_text (); + int hour = s.to_int (); + int min = s.str (":").offset (1).to_int (); + + var showtime = time_t (); + var timeinfo = Time.local (showtime); + timeinfo.second = 0; + timeinfo.minute = min; + timeinfo.hour = hour; + showtime = timeinfo.mktime (); + + 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); + 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")); + banner.set_timeout (1500); + } + dialog.destroy (); + } + + private void on_call_cinema (Movie _movie, Gtk.Window window) { + var movie = (GoogleMovie) _movie; + var url = "tel://" + movie.cinema_phone; + + try { + var action = Hildon.URIAction.get_default_action_by_uri (url); + if (action != null) { + action.open (url); + } else { + var banner = (Banner) Banner.show_information_with_markup (window, null, "Failed to get tel:// URI action"); + banner.set_timeout (1500); + } + } catch (Error e) { + if (e is Hildon.URIError) { + stdout.printf ("Error: %s\n", e.message); + } + } + } + public override void settings_dialog (Gtk.Window window) { GoogleSource source = (GoogleSource) sources.data; 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 (); - selector.append_text ("Berlin"); + insert_location_sorted (source.location); + foreach (string l in locations) + selector.append_text (l); var button = new PickerButton (SizeType.FINGER_HEIGHT, ButtonArrangement.HORIZONTAL); button.set_title (_("Location")); @@ -61,16 +155,42 @@ class GooglePlugin : Plugin { var content = (VBox) dialog.get_content_area (); content.pack_start (button, true, true, 0); - dialog.add_button ("Done", ResponseType.ACCEPT); + dialog.add_button (_("Done"), ResponseType.ACCEPT); dialog.show_all (); int res = dialog.run (); if (res == ResponseType.ACCEPT) { source.location = button.get_value (); + 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 (); } + private bool insert_location_sorted (string? location) { + if (location == null) + return false; + if (locations != null) { + for (unowned SList l = locations; l != null; l = l.next) { + if (l.data == location) { + return false; + } + if (l.data > location) { + l.insert (location, 0); + return true; + } + } + } + locations.append (location); + return true; + } + public override unowned string get_name () { return "Google"; } @@ -79,13 +199,87 @@ 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; } + + public GoogleSource () { + GLib.Object (active: true); + } + + 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 (); + var result = new SList (); + + 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; + + result.append (movie); + } - public override async void get_movies (MovieFilter filter, MovieSource.ReceiveMovieFunction callback, int limit, Cancellable? cancellable) { - var parser = new GoogleParser (); + callback (result); - yield parser.query (filter, location, callback, cancellable); - if (location == null) { - location = parser.location; + if (finished) { + search = null; + Idle.add (get_movies_callback); } } @@ -108,13 +302,13 @@ class GoogleSource : MovieSource { return description; } - public override bool get_editable () { - return false; + public override SourceFlags get_flags () { + return SourceFlags.ONLINE; } } [ModuleInit] -public Type register_plugin () { +public Type register_plugin (TypeModule module) { // types are registered automatically return typeof (GooglePlugin); }