From: Philipp Zabel Date: Fri, 16 Jul 2010 16:59:57 +0000 (+0200) Subject: Google backend: use libcurl, parse runtimes X-Git-Url: http://vcs.maemo.org/git/?p=cinaest;a=commitdiff_plain;h=823f663fd396540cd7acf44513626d8e29d852a9 Google backend: use libcurl, parse runtimes --- diff --git a/Makefile.am b/Makefile.am index 1c6e11c..508db9d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -206,16 +206,18 @@ src/plugins/moviepilot-plugin.c: ${libmoviepilot_plugin_la_VALASOURCES} cinaest_google_backend_SOURCES = \ src/backends/google/google-backend.c \ + src/backends/google/curl-wrapper.c \ src/backends/google/google-parser.c cinaest_google_backend_VALASOURCES = \ src/backends/google/google-backend.vala \ + src/backends/google/curl-wrapper.vala \ src/backends/google/google-parser.vala -cinaest_google_backend_VALAFLAGS = --vapidir ./vapi --pkg dbus-glib-1 \ - --pkg gconf-2.0 --pkg gee-1.0 --pkg gio-2.0 --pkg libxml-2.0 -cinaest_google_backend_CFLAGS = ${DBUS_CFLAGS} ${GCONF_CFLAGS} ${GEE_CFLAGS} ${GIO_CFLAGS} ${XML_CFLAGS} -cinaest_google_backend_LDADD = ${DBUS_LIBS} ${GCONF_LIBS} ${GEE_LIBS} ${GIO_LIBS} ${XML_LIBS} +cinaest_google_backend_VALAFLAGS = --thread --vapidir ./vapi --pkg dbus-glib-1 \ + --pkg gconf-2.0 --pkg gee-1.0 --pkg gio-2.0 --pkg libcurl --pkg libxml-2.0 +cinaest_google_backend_CFLAGS = ${CURL_CFLAGS} ${DBUS_CFLAGS} ${GCONF_CFLAGS} ${GEE_CFLAGS} ${GIO_CFLAGS} ${GTHREAD_CFLAGS} ${XML_CFLAGS} +cinaest_google_backend_LDADD = ${CURL_LIBS} ${DBUS_LIBS} ${GCONF_LIBS} ${GEE_LIBS} ${GIO_LIBS} ${GTHREAD_LIBS} ${XML_LIBS} src/backends/google/google-backend.c: ${cinaest_google_backend_VALASOURCES} ${VALAC} -C ${cinaest_google_backend_VALASOURCES} ${cinaest_google_backend_VALAFLAGS} diff --git a/configure.ac b/configure.ac index cbd3215..1612dbb 100644 --- a/configure.ac +++ b/configure.ac @@ -47,6 +47,10 @@ PKG_CHECK_MODULES(GDK, gdk-pixbuf-2.0) AC_SUBST(GDK_LIBS) AC_SUBST(GDK_CFLAGS) +PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.20.3) +AC_SUBST(GTHREAD_LIBS) +AC_SUBST(GTHREAD_CFLAGS) + PKG_CHECK_MODULES(HILDON, hildon-1 >= 2.2.0) AC_SUBST(HILDON_LIBS) AC_SUBST(HILDON_CFLAGS) diff --git a/src/backends/google/curl-wrapper.vala b/src/backends/google/curl-wrapper.vala new file mode 100644 index 0000000..9f640af --- /dev/null +++ b/src/backends/google/curl-wrapper.vala @@ -0,0 +1,55 @@ +public class CurlWrapper : Object { + private Curl.EasyHandle curl; + private string url = null; + private SourceFunc callback = null; + private StringBuilder result; + + construct { + curl = new Curl.EasyHandle (); + // FIXME: Fremantle SDK doesn't come with certs + curl.setopt (Curl.Option.SSL_VERIFYPEER, 0); + // curl.setopt (Curl.Option.VERBOSE, 1); + } + + static construct { + Curl.global_init (Curl.GLOBAL_DEFAULT); + } + + private void* download_thread () { + curl.setopt (Curl.Option.WRITEFUNCTION, write_callback); + curl.setopt (Curl.Option.WRITEDATA, this); + curl.setopt (Curl.Option.URL, url); + var res = curl.perform (); + if (res != Curl.Code.OK) + print ("CURL: %d\n", res); + + if (callback != null) + Idle.add (callback); + callback = null; + + return null; + } + + [CCode (instance_pos = -1)] + private size_t write_callback (void *buffer, size_t size, size_t nmemb) { + result.append_len ((string) buffer, (ssize_t) (size * nmemb)); + + return size * nmemb; + } + + public async unowned string http_get (string _url) { + url = _url; + callback = http_get.callback; + result = new StringBuilder (); + try { + Thread.create(download_thread, false); + } catch (ThreadError e) { + critical ("Failed to create download thread\n"); + return ""; + } + + yield; + + return result.str; + } +} diff --git a/src/backends/google/google-parser.vala b/src/backends/google/google-parser.vala index 439c0a3..d8e51a1 100644 --- a/src/backends/google/google-parser.vala +++ b/src/backends/google/google-parser.vala @@ -36,17 +36,28 @@ class GoogleParser : Object { public string location; string _title; PatternSpec pattern; + CurlWrapper curlwrapper; + Regex re_runtime; public delegate void ReceiveMovie (GoogleMovie movie); public ReceiveMovie _get_callback; - private Html.Doc* get_html_document (ref char[] buf) { - return Html.Doc.read_memory (buf, (int) buf.length, + construct { + curlwrapper = new CurlWrapper (); + try { + re_runtime = new Regex ("([0-9]+)hr ([0-9]+)min"); + } catch (RegexError e) { + critical ("Failed to initialize regex: %s\n", e.message); + } + } + + private Html.Doc* get_html_document (string buf) { + return Html.Doc.read_memory ((char[]) buf, (int) buf.length, "http://movies.google.de", null, Html.ParserOption.NOERROR | Html.ParserOption.NOWARNING); } - public int parse (ref char[] buf) throws Error { - var doc = get_html_document (ref buf); + public int parse (string buf) throws Error { + var doc = get_html_document (buf); if (doc == null) { stderr.printf ("Error: parsing failed\n"); return 0; @@ -161,9 +172,15 @@ class GoogleParser : Object { private void parse_movie_info (Xml.Node* i, GoogleMovie movie) { var text = i->children; - if (text != null && text->name == "text") + if (text != null && text->name == "text") { + MatchInfo match; print ("\t\"%s\"\n", text->content); - // movie.runtime + if (re_runtime.match (text->content, 0, out match)) { + movie.runtime = match.fetch (1).to_int () * 3600 + + match.fetch (2).to_int () * 60; + } + movie.fsk = text->content.str ("Rated ").replace (" - ", ""); + } for (var n = text->next; n != null; n = n->next) { if (n->name == "nobr") { movie.rating = parse_rating (n); @@ -181,8 +198,8 @@ class GoogleParser : Object { if (img->name == "img") { var alt = img->get_prop ("alt"); // "Rated 0.0 out of 5.0" if (alt != null && alt != "") // ^ - return (int) (10 * alt.offset (6).to_double ()); print ("\trating: %s - %f\n", alt, alt.offset (6).to_double ()); + return (int) (10 * alt.offset (6).to_double ()); } } } @@ -234,22 +251,8 @@ class GoogleParser : Object { stdout.printf ("GET: %s\n", uri); - File file = File.new_for_uri (uri); - InputStream stream = yield file.read_async (Priority.DEFAULT_IDLE, null); - - char[] buf = new char[256*1024]; - size_t nread; - size_t total = 0; - while (total < 256*1024) { - nread = yield stream.read_async ((char *)buf + total, 256*1024 - total, Priority.DEFAULT_IDLE, cancellable); - total += nread; - if (cancellable.is_cancelled ()) - return 0; - if (nread == 0) - break; - } - buf[total] = 0; - return parse (ref buf); + string buf = yield curlwrapper.http_get (uri); + return parse (buf); } catch (Error e) { stderr.printf ("Error: %s\n", e.message); }