1 abstract class LineParser {
2 internal unowned IMDbSqlite sqlite;
4 public LineParser (IMDbSqlite _sqlite) {
8 public abstract void parse_line (string line);
10 internal bool skip_title (string title) {
11 if (title.has_suffix ("(TV)")) {
14 if (title.has_suffix ("(V)")) {
17 if (title.has_suffix ("(VG)")) {
24 class MovieLineParser : LineParser {
27 public MovieLineParser (IMDbSqlite _sqlite) {
30 re_movie = new Regex ("^([^\t]+)\t+([0-9]+)$");
31 } catch (RegexError e) {
32 critical ("Failed to initialize regex: %s\n", e.message);
36 public override void parse_line (string line) {
39 // Skip series episodes
43 if (!re_movie.match(line, 0, out matchinfo))
47 string year = matchinfo.fetch (2);
49 title = convert(matchinfo.fetch (1), -1, "utf-8", "latin1");
50 } catch (ConvertError e) {
54 if (skip_title (title))
57 sqlite.add_movie (title, year.to_int ());
61 class GenreLineParser : LineParser {
64 public GenreLineParser (IMDbSqlite _sqlite) {
67 re_genre = new Regex ("^([^\t]+)\t+([A-Za-z-]+)$");
68 } catch (RegexError e) {
69 critical ("Failed to initialize regex: %s\n", e.message);
73 public override void parse_line (string line) {
76 // Skip series episodes
80 if (!re_genre.match(line, 0, out matchinfo))
84 string genre = matchinfo.fetch (2);
86 title = convert(matchinfo.fetch (1), -1, "utf-8", "latin1");
87 } catch (ConvertError e) {
91 sqlite.movie_add_genre (title, genre);
95 class RatingLineParser : LineParser {
103 public RatingLineParser (IMDbSqlite _sqlite) {
105 state = RatingState.HEADER;
107 re_rating = new Regex ("^ .+ +([0-9]+) +([0-9.]+) +(.+)$");
108 } catch (RegexError e) {
109 critical ("Failed to initialize regex: %s\n", e.message);
113 public override void parse_line (string line) {
114 if (state == RatingState.HEADER) {
115 if (line == "MOVIE RATINGS REPORT")
116 state = RatingState.NONE;
120 if (state != RatingState.NONE)
125 // Skip series episodes
129 if (!re_rating.match(line, 0, out matchinfo))
133 string votes = matchinfo.fetch (1);
134 string rating = matchinfo.fetch (2);
136 title = convert(matchinfo.fetch (3), -1, "utf-8", "latin1");
137 } catch (ConvertError e) {
141 // Skip series episodes
145 if (skip_title (title))
148 sqlite.movie_set_rating (title, (int) (rating.to_double () * 10), votes.to_int ());
152 class AkaLineParser : LineParser {
161 public AkaLineParser (IMDbSqlite _sqlite) {
163 state = AkaState.HEADER;
167 public override void parse_line (string line) {
168 if (state == AkaState.HEADER) {
169 if (line == "AKA TITLES LIST") title = line;
170 if (line == "===============" && title != null)
171 state = AkaState.NONE;
175 if (state == AkaState.NONE) {
180 // Skip series episodes
189 title = convert (line, -1, "utf-8", "latin1");
190 } catch (ConvertError e) {
195 if (skip_title (title))
198 state = AkaState.TITLE;
201 if (state == AkaState.TITLE) {
202 // Empty lines mark end of title
204 state = AkaState.NONE;
208 if (line.has_prefix (" (aka ")) {
209 if (skip_title (title))
212 char* start = line.offset (8);
213 char* end = ((string) start).str ("))");
219 aka = convert ((string) start, -1, "utf-8", "latin1");
220 } catch (ConvertError e) {
224 sqlite.add_aka (title, aka);
230 class PlotLineParser : LineParser {
240 public PlotLineParser (IMDbSqlite _sqlite) {
242 state = PlotState.HEADER;
246 public override void parse_line (string line) {
247 if (state == PlotState.HEADER) {
248 if (line == "PLOT SUMMARIES LIST") title = line;
249 if (line == "===================" && title != null)
250 state = PlotState.NONE;
258 if (state == PlotState.NONE) {
259 if (line.has_prefix ("MV: ")) {
260 // Skip series episodes
265 title = convert (line.offset (4), -1, "utf-8", "latin1");
266 } catch (ConvertError e) {
267 stderr.printf ("Error converting title to UTF-8\n");
272 if (skip_title (title))
275 state = PlotState.TITLE;
281 if (state == PlotState.TITLE) {
282 if (line.has_prefix ("PL: ")) {
283 if (skip_title (title))
289 plot += convert (line.offset (4), -1, "utf-8", "latin1");
290 } catch (ConvertError e) {
291 stderr.printf ("Error converting plot for \"%s\" to UTF-8\n", title);
297 // BY: tag marks end of plot
298 if (line.has_prefix ("BY: ")) {
301 author = convert (line.offset (4), -1, "utf-8", "latin1");
302 } catch (ConvertError e) {
303 stderr.printf ("Error converting plot author for \"%s\" to UTF-8\n", title);
307 sqlite.add_plot (title, plot, author);
309 state = PlotState.NONE;
316 class PersonParser : LineParser {
333 public PersonParser (IMDbSqlite _sqlite) {
338 public void reset () {
339 state = PersonState.HEADER;
340 type = PersonType.NONE;
344 public override void parse_line (string line) {
345 if (state == PersonState.HEADER) {
346 if (line == "THE ACTORS LIST") type = PersonType.ACTOR;
347 else if (line == "THE ACTRESSES LIST") type = PersonType.ACTRESS;
348 else if (line == "THE DIRECTORS LIST") type = PersonType.DIRECTOR;
349 else if (line == "THE WRITERS LIST") type = PersonType.WRITER;
350 else if (line == "----\t\t\t------" && type != PersonType.NONE)
351 state = PersonState.NONE;
358 state = PersonState.NONE;
364 if (state == PersonState.NONE) {
365 if (line.has_prefix ("\t")) {
366 stderr.printf ("Invalid person entry: %s\n", line);
371 unowned string title = line.rstr ("\t");
374 title = title.offset (1);
376 char* end = line.str ("\t");
381 name = convert (line, -1, "utf-8", "latin1");
382 } catch (ConvertError e) {
383 stderr.printf ("Error converting name to UTF-8\n");
389 sqlite.add_person (name);
390 parse_title (convert (title, -1, "utf-8", "latin1"));
392 state = PersonState.PERSON;
397 if (state == PersonState.PERSON) {
398 if (line.has_prefix ("\t\t\t"))
399 parse_title (line.offset (3));
401 stderr.printf ("\t???: %s\n", line);
405 private void parse_title (string title) {
406 // Skip series episodes
410 char* end = title.str (" ");
413 next = ((string) end).offset (2);
419 if (skip_title (title))
423 if (type == PersonType.ACTOR || type == PersonType.ACTRESS) {
424 string character = null;
428 unowned string current = next;
429 end = current.str (" ");
431 next = ((string) end).offset (2);
435 if (current.has_prefix ("["))
436 character = current.substring (1, current.length - 2);
437 if (current.has_prefix ("<"))
438 number = current.offset (1).to_int ();
439 if (current.has_prefix ("("))
441 } while (end != null);
443 sqlite.add_actor (name, title, info, character, number);