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}
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)
--- /dev/null
+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;
+ }
+}
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;
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);
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 ());
}
}
}
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);
}