public class Lift : Object {
public string city_from;
public string city_to;
- public string date;
- public string time;
+ public Time time;
public int places;
public string price;
public LiftFlags flags;
public string email;
public string description;
public string modified;
+
+ public Lift () {
+ time.hour = -1;
+ }
+}
+
+public class CallbackMessage : Soup.Message {
+ public SourceFunc callback;
+
+ public CallbackMessage (string url, SourceFunc? _callback) {
+ method = "GET";
+ callback = _callback;
+ set_uri (new Soup.URI (url));
+ }
}
public class AdacMitfahrclub {
const string BASE_URI = "http://mitfahrclub.adac.de";
- string response;
- int size;
+ Soup.SessionAsync session;
+ Soup.Message message;
List<City> city_list = null;
- static size_t write_memory_cb (void* ptr, size_t size, size_t nmemb, void* data) {
- unowned AdacMitfahrclub self = (AdacMitfahrclub) data;
-
- self.response += ((string) ptr).ndup (size * nmemb);
- self.size += (int) (size * nmemb);
-
- return size * nmemb;
+ public AdacMitfahrclub () {
+ session = new Soup.SessionAsync ();
}
- private Html.Doc* get_html_document (string url) {
- var handle = new Curl.EasyHandle ();
-
- handle.setopt (Curl.Option.URL, url);
- handle.setopt (Curl.Option.WRITEFUNCTION, write_memory_cb);
- handle.setopt (Curl.Option.WRITEDATA, (void*) this);
+ private void message_finished (Soup.Session session, Soup.Message message) {
+ Idle.add (((CallbackMessage) message).callback);
+ }
- this.response = "";
- this.size = 0;
+ private async Html.Doc* get_html_document (string url) {
+ message = new CallbackMessage (url, get_html_document.callback);
+ session.queue_message (message, message_finished);
- handle.perform ();
+ yield;
- return Html.Doc.read_memory ((char[]) this.response, this.size,
+ return Html.Doc.read_memory ((char[]) message.response_body.data, (int) message.response_body.length,
url, null, Html.ParserOption.NOERROR | Html.ParserOption.NOWARNING);
}
if (load_city_list ())
return city_list;
- var doc = get_html_document (BASE_URI);
+ return null;
+ }
+
+ public async unowned List<City>? download_city_list () {
+ var doc = yield get_html_document (BASE_URI);
if (doc == null) {
print ("Error: parsing failed");
- print ("%s\n", this.response);
+ print ("%s\n", (string) message.response_body.data);
return null;
}
var form = search_tag_by_id (doc->children, "form", "search_national_form");
if (form == null) {
print ("Error: does not contain search_national_form");
- print ("%s\n", this.response);
+ print ("%s\n", (string) message.response_body.data);
return null;
}
var select = search_tag_by_name (form->children, "select", "city_from");
if (select == null) {
print ("Error: does not contain city_from");
- print ("%s\n", this.response);
+ print ("%s\n", (string) message.response_body.data);
return null;
}
return result;
}
- public List<Lift>? get_lift_list (string city_from, string city_to, Date date, int tolerance = 0) {
+ public async List<Lift>? get_lift_list (string city_from, string city_to, Date date, int tolerance = 0) {
if (city_list == null)
get_city_list ();
tolerance
);
- var doc = get_html_document (url);
+ var doc = yield get_html_document (url);
if (doc == null) {
print ("Error: parsing failed");
- print ("%s\n", this.response);
+ print ("%s\n", (string) message.response_body.data);
return null;
}
var table = search_tag_by_class (doc->children, "table", "list p_15");
if (table == null) {
print ("Error: does not contain list p_15 table");
- print ("%s\n", this.response);
+ print ("%s\n", (string) message.response_body.data);
return null;
}
lift.city_to = n3->content;
break;
case 2:
- lift.date = n3->content;
+ parse_date (n3->content, out lift.time);
break;
case 3:
- lift.time = n3->content;
+ parse_time (n3->content.strip (), out lift.time);
break;
case 4:
lift.places = n3->content.to_int ();
return lift;
}
- public Lift? get_lift_details (string lift_url) {
- var lift = new Lift ();
- lift.href = lift_url;
- if (update_lift_details (lift))
- return lift;
- else
- return null;
- }
-
- public bool update_lift_details (Lift lift) {
+ public async bool update_lift_details (Lift lift) {
string url = BASE_URI + lift.href;
- var doc = get_html_document (url);
+ var doc = yield get_html_document (url);
if (doc == null) {
print ("Error: parsing failed");
- print ("%s\n", this.response);
+ print ("%s\n", (string) message.response_body.data);
return false;
}
var table = search_tag_by_class (doc->children, "table", "lift");
if (table == null) {
print ("Error: does not contain lift table");
- print ("%s\n", this.response);
+ print ("%s\n", (string) message.response_body.data);
return false;
}
- for (var n = table->children; n != null; n = n->next) {
+ Xml.Node* n;
+ for (n = table->children; n != null; n = n->next) {
if (n->name == "tr") {
var n2 = n->children;
if (n2 == null || n2->name != "td" ||
var text1 = n2->children->content.strip ();
- if (text == "Datum")
- lift.date = text1;
- else if (text == "Freie Pl\xc3\xa4tze")
+ if (text == "Freie Pl\xc3\xa4tze")
lift.places = text1.to_int ();
else if (text == "Name")
lift.name = text1;
else if (text1 == "nach")
lift.city_to = text2;
else if (text1 == "Datum")
- lift.date = text2;
+ parse_date (text2, out lift.time);
else if (text1 == "Uhrzeit")
- lift.time = text2;
+ parse_time (text2, out lift.time);
else if (text1 == "Raucher")
print ("Raucher: %s\n", text2);
else if (text1 == "Fahrpreis")
// The paragraph after the table contains the date of last modification
var p = table->next;
- for (var n = p->children; n != null; n = n->next) {
+ for (n = p->children; n != null; n = n->next) {
if (n->name != "text")
continue;
Xml.Node* search_tag_by_class (Xml.Node* node, string tag, string @class) requires (node != null) {
return search_tag_by_property (node, tag, "class", @class);
}
+
+ void parse_date (string date, out Time time) {
+ int year;
+ if (date.length == 11)
+ date = date.offset (3);
+ if (date.length != 8)
+ return;
+ var res = date.scanf ("%02d.%02d.%02d", out time.day, out time.month, out year);
+ time.year = year + 2000;
+ }
+
+ void parse_time (string time, out Time result) {
+ var res = time.scanf ("%d.%02d Uhr", out result.hour, out result.minute);
+ }
}