using GLib; class IMDbDownloaderCLI : Object, IMDbDownloader { MainLoop loop; Cancellable cancellable; bool running; uint source_id; unowned IMDbSqlite sqlite; // string mirrors[] = { // "ftp.fu-berlin.de/pub/misc/movies/database/" // }; string url; int flags; int percent_finished; delegate void ParseLineFunction (string line); construct { loop = new MainLoop (null, false); cancellable = new Cancellable (); } // IMDbDownloader implementation public void download (string mirror, int _flags) throws DBus.Error { if (running) { stdout.printf ("Download in progress. Abort.\n"); return; } running = true; if (source_id != 0) { Source.remove (source_id); } stdout.printf ("Download started (%x).", flags); progress (0); url = "ftp://anonymous@" + mirror; flags = _flags; try { Thread.create(download_thread, false); } catch (ThreadError e) { critical ("Failed to create download thread\n"); return; } } public void cancel () throws DBus.Error { cancellable.cancel (); } public string[] get_mirrors () throws DBus.Error { return null; } // Private methods private bool do_download () { try { download ("ftp.fu-berlin.de/pub/misc/movies/database/", MOVIES | GENRES | RATINGS | AKAS | PLOTS | ACTORS); } catch (Error e) { print ("Error: %s\n", e.message); } return false; } private void* download_thread () { description_changed ("Connecting to FTP ..."); progress (0); percent_finished = 0; var cache_dir = Path.build_filename (Environment.get_user_cache_dir (), "cinaest"); DirUtils.create_with_parents (cache_dir, 0770); var _sqlite = new IMDbSqlite (Path.build_filename (cache_dir, "imdb.db")); sqlite = _sqlite; _sqlite.clear (); try { var movie_parser = new MovieLineParser (sqlite); var genre_parser = new GenreLineParser (sqlite); var rating_parser = new RatingLineParser (sqlite); var aka_parser = new AkaLineParser (sqlite); var plot_parser = new PlotLineParser (sqlite); var person_parser = new PersonParser (sqlite); var downloader = new FtpDownloader (cancellable); var parser = new IMDbGzipParser (cancellable); downloader.progress.connect (on_progress); if (MOVIES in flags) { description_changed ("Downloading movie list ..."); downloader.download (url + "movies.list.gz", Path.build_filename (cache_dir, "movies.list.gz")); } percent_finished = 20; if (GENRES in flags) { description_changed ("Downloading genre data ..."); downloader.download (url + "genres.list.gz", Path.build_filename (cache_dir, "genres.list.gz")); } percent_finished = 40; if (RATINGS in flags) { description_changed ("Downloading rating data ..."); downloader.download (url + "ratings.list.gz", Path.build_filename (cache_dir, "ratings.list.gz")); } percent_finished = 60; if (AKAS in flags) { description_changed ("Downloading alternative titles ..."); downloader.download (url + "aka-titles.list.gz", Path.build_filename (cache_dir, "aka-titles.list.gz")); } percent_finished = 80; if (PLOTS in flags) { description_changed ("Downloading plots ..."); downloader.download (url + "plot.list.gz", Path.build_filename (cache_dir, "plot.list.gz")); } if (ACTORS in flags) { description_changed ("Downloading actors ..."); downloader.download (url + "actors.list.gz", Path.build_filename (cache_dir, "actors.list.gz")); description_changed ("Downloading actresses ..."); downloader.download (url + "actresses.list.gz", Path.build_filename (cache_dir, "actresses.list.gz")); } // composers // costume-designers if (DIRECTORS in flags) { description_changed ("Downloading directors ..."); downloader.download (url + "directors.list.gz", Path.build_filename (cache_dir, "directors.list.gz")); } // editors // producers // production-designers if (WRITERS in flags) { description_changed ("Downloading writers ..."); downloader.download (url + "writers.list.gz", Path.build_filename (cache_dir, "writers.list.gz")); } if (MOVIES in flags) { description_changed ("Parsing movie list ..."); parser.parse (Path.build_filename (cache_dir, "movies.list.gz"), movie_parser); } percent_finished = 20; if (GENRES in flags) { description_changed ("Parsing genre data ..."); parser.parse (Path.build_filename (cache_dir, "genres.list.gz"), genre_parser); } percent_finished = 40; if (RATINGS in flags) { description_changed ("Parsing rating data ..."); parser.parse (Path.build_filename (cache_dir, "ratings.list.gz"), rating_parser); } percent_finished = 60; if (AKAS in flags) { description_changed ("Parsing alternative titles ..."); parser.parse (Path.build_filename (cache_dir, "aka-titles.list.gz"), aka_parser); } percent_finished = 80; if (PLOTS in flags) { description_changed ("Parsing plots ..."); parser.parse (Path.build_filename (cache_dir, "plot.list.gz"), plot_parser); } if (ACTORS in flags) { description_changed ("Parsing actors ..."); parser.parse (Path.build_filename (cache_dir, "actors.list.gz"), person_parser); person_parser.reset (); description_changed ("Parsing actresses ..."); parser.parse (Path.build_filename (cache_dir, "actresses.list.gz"), person_parser); } } catch (Error e2) { if (e2 is IOError.CANCELLED) stdout.printf ("Download cancelled.\n"); else warning ("Failed to open/read stream: %s\n", e2.message); } description_changed ("Creating indices ..."); if (AKAS in flags) sqlite.create_aka_index (); if (MOVIES in flags) sqlite.create_votes_index (); if (!cancellable.is_cancelled ()) { stdout.printf ("Download complete.\n"); progress (100); } sqlite = null; running = false; timeout_quit (); return null; } private void on_progress (int dltotal, int dlnow) { /* progress (percent_finished + percent / 5); stdout.printf ("%d %%\r", percent_finished + percent / 5); */ stdout.printf ("%d / %d\r", dlnow, dltotal); stdout.flush (); } private void timeout_quit () { source_id = Timeout.add (3000, quit); } private bool quit () { loop.quit (); // One-shot only return false; } public void run () { loop.run (); } public void show_desc (string desc) { print ("DESC: \"%s\"\n", desc); } public static void main () { Curl.global_init (Curl.GLOBAL_DEFAULT); // Start server var downloader = new IMDbDownloaderCLI (); downloader.description_changed.connect (downloader.show_desc); Idle.add (downloader.do_download); downloader.run (); Curl.global_cleanup (); } }