/* 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 Gtk; using Hildon; class IMDbPlugin : Plugin { private dynamic DBus.Object server; List sources; private weak Osso.Context osso_context; public override void hello (Gtk.Window window, Osso.Context context) { string filename = Path.build_filename (Environment.get_user_cache_dir(), "cinaest", "imdb.db", null); stdout.printf ("IMDb Plugin Loaded. Cache Db: %s\n", filename); if (!FileUtils.test (filename, FileTest.EXISTS)) { var note = new Note.confirmation (window, "There is no local copy of the Internet Movie Database (IMDb). Download it now?\n\nThis can be started later from the Settings dialog."); var response = note.run (); note.destroy (); if (response == ResponseType.OK) { download_imdb (window, false, false); } } var source = new IMDBSource (); sources = new List (); sources.append (source); osso_context = context; // FIXME - this forces the inclusion of config.h (void) Config.GETTEXT_PACKAGE; } private void download_imdb (Gtk.Window window, bool plots, bool actors) { var picker = new PickerDialog (window); var selector = new TouchSelector.text (); string[] mirrors; try { var conn = DBus.Bus.get (DBus.BusType.SESSION); server = conn.get_object (IMDbDownloader.DBUS_SERVICE, IMDbDownloader.DBUS_OBJECT, IMDbDownloader.DBUS_IFACE); mirrors = server.get_mirrors (); } catch (DBus.Error e) { warning ("Failed connect to IMDb downloader: %s", e.message); return; } foreach (string mirror in mirrors) { selector.append_text (mirror); } picker.set_title ("Please select a source mirror"); picker.set_selector (selector); int res = picker.run(); string mirror = selector.get_current_text (); picker.destroy(); if (res == ResponseType.OK) { var download = new IMDbDownloadDialog (window, plots, actors); download.run (server, mirror); download.destroy (); } } public override unowned List get_sources () { return sources; } public override List get_actions (Movie movie, Gtk.Window window) { List list = null; if (movie.year > 0) list.append (new MovieAction (_("IMDb page"), on_visit_imdb, movie, window)); else list.append (new MovieAction (_("Lookup on IMDb"), on_visit_imdb, movie, window)); return list; } private void on_visit_imdb (Movie movie, Gtk.Window window) { var url = "http://www.imdb.com/find?s=tt&q=" + movie.title.replace(" ", "+"); if (movie.year > 0) url += "+(%d)".printf (movie.year); var status = osso_context.rpc_run_with_defaults ("osso_browser", "open_new_window", null, 's', url, 'b', false); if (status != Osso.Status.OK) { var banner = (Banner) Hildon.Banner.show_information_with_markup (window, null, "Failed to open browser."); banner.set_timeout (1500); } } public override void settings_dialog (Gtk.Window window) { var dialog = new Gtk.Dialog (); dialog.set_transient_for (window); dialog.set_title (_("IMDb plugin settings")); bool download_plots; bool download_actors; try { var sqlite = new IMDbSqlite (Path.build_filename (Environment.get_user_cache_dir (), "cinaest", "imdb.db", null)); download_plots = sqlite.has_table ("Plots"); download_actors = sqlite.has_table ("Actors"); } catch (Error e) { download_plots = false; download_actors = false; } var plots = new Hildon.CheckButton (SizeType.FINGER_HEIGHT); plots.set_label (_("Download and store movie plots")); plots.set_active (download_plots); var actors = new Hildon.CheckButton (SizeType.FINGER_HEIGHT); actors.set_label (_("Download and store actors and actresses")); actors.set_active (download_actors); string updated; string filename = Path.build_filename (Environment.get_user_cache_dir(), "cinaest", "imdb.db", null); var file = File.new_for_path (filename); try { var info = file.query_info (FILE_ATTRIBUTE_TIME_MODIFIED, FileQueryInfoFlags.NONE, null); TimeVal tv; info.get_modification_time (out tv); var date = Date (); date.set_time_val (tv); char[] s = new char[64]; date.strftime (s, "%x"); updated = (string) s; } catch (Error e) { updated = _("unknown"); } var download = new Hildon.Button.with_text (SizeType.FINGER_HEIGHT, ButtonArrangement.VERTICAL, _("Download"), _("Last update: ") + updated); VBox content = (VBox) dialog.get_content_area (); content.pack_start (plots, true, true, 0); content.pack_start (actors, true, true, 0); content.pack_start (download, true, true, 0); var sizegroup = new Gtk.SizeGroup (SizeGroupMode.HORIZONTAL); // User name var hbox = new Gtk.HBox (false, MARGIN_DOUBLE); var label = new Gtk.Label (_("User name")); label.set_alignment (0, 0.5f); sizegroup.add_widget (label); var entry = new Hildon.Entry (SizeType.FINGER_HEIGHT); hbox.pack_start (label, false, false, 0); hbox.pack_start (entry, true, true, 0); content.pack_start (hbox, true, true, 0); // Password hbox = new Gtk.HBox (false, MARGIN_DOUBLE); label = new Gtk.Label (_("Password")); label.set_alignment (0, 0.5f); sizegroup.add_widget (label); entry = new Hildon.Entry (SizeType.FINGER_HEIGHT); hbox.pack_start (label, false, false, 0); hbox.pack_start (entry, true, true, 0); content.pack_start (hbox, true, true, 0); dialog.add_button (_("Save"), ResponseType.ACCEPT); // Connect signals plots.toggled.connect (() => { if (download_plots != plots.get_active ()) Hildon.Banner.show_information (window, null, _("Redownload the IMDb for this change to take effect.")); }); actors.toggled.connect (() => { if (download_actors != actors.get_active ()) Hildon.Banner.show_information (window, null, _("Redownload the IMDb for this change to take effect.")); }); download.clicked.connect (() => { download_imdb (window, plots.get_active (), actors.get_active ()); }); dialog.show_all (); dialog.run (); dialog.destroy (); } public override unowned string get_name () { return "IMDb"; } } class IMDbMovie : Movie { public override string get_plot () { var sqlite = new IMDbSqlite (Path.build_filename (Environment.get_user_cache_dir (), "cinaest", "imdb.db", null)); print ("IMDb get_plot(\"%s (%d)\")\n", title, year); return sqlite.get_plot ("%s (%d)".printf (title, year)); } public override List get_cast () { var sqlite = new IMDbSqlite (Path.build_filename (Environment.get_user_cache_dir (), "cinaest", "imdb.db", null)); print ("IMDb get_cast(\"%s (%d)\")\n", title, year); return sqlite.get_cast ("%s (%d)".printf (title, year)); } } class IMDBSource : MovieSource { SList result; int results_waiting; public override bool active { get; set construct; } public IMDBSource () { GLib.Object (active: true); } MovieSource.ReceiveMovieFunction _get_callback; public override async int get_movies (MovieFilter filter, MovieSource.ReceiveMovieFunction callback, int limit, Cancellable? cancellable) { var sqlite = new IMDbSqlite (Path.build_filename (Environment.get_user_cache_dir (), "cinaest", "imdb.db", null)); _get_callback = callback; result = new SList (); results_waiting = 0; int n = yield sqlite.query (filter, receive_movie, limit, cancellable); if (results_waiting > 0) _get_callback (result); result = new SList (); return n; } private void receive_movie (string title, string? aka, int year, int rating, int genres) { var movie = new IMDbMovie (); movie.title = title; movie.year = year; movie.rating = rating; movie.genres.field = genres; // TODO - depending on settings, this could be something else, like director info or runtime if (aka != null) { movie.secondary = "aka \"%s\" - %s".printf (aka, movie.genres.to_string ()); } else { movie.secondary = movie.genres.to_string (); } result.append (movie); if (++results_waiting >= 10) { _get_callback (result); result = new SList (); results_waiting = 0; } } public override void add_movie (Movie movie) { } public override void delete_movie (Movie movie) { } public override unowned string get_name () { return "IMDb"; } public override unowned string get_description () { return _("Movies on IMDb"); } public override SourceFlags get_flags () { return SourceFlags.REFERENCE; } } [ModuleInit] public Type register_plugin (TypeModule module) { // types are registered automatically return typeof (IMDbPlugin); }