Debian packaging: 0.0.4-1
[beifahrer] / src / adac-mitfahrclub.vala
index bf5f25d..810a861 100644 (file)
@@ -43,7 +43,8 @@ public enum LiftFlags {
        SMOKER = 1,
        NON_SMOKER = 2,
        ADAC_MEMBER = 4,
-       WOMEN_ONLY = 8
+       WOMEN_ONLY = 8,
+       ACTIVE = 16,
 }
 
 public class Lift : Object {
@@ -413,7 +414,7 @@ public class AdacMitfahrclub {
                        return null;
 
                string url = HTTP_BASE_URI + "/mitfahrclub/%s/%s/b.html".printf (
-                       city_from,
+                       city_from.replace ("/", "_"),
                        city_to
                );
 
@@ -501,7 +502,7 @@ public class AdacMitfahrclub {
                                                                        lift.places = n3->content.to_int ();
                                                                        break;
                                                                case 5:
-                                                                       lift.price = n3->content;
+                                                                       lift.price = n3->content.replace (" EUR", " €");
                                                                        break;
                                                                default:
                                                                        print ("TEXT:%s\n", n3->content);
@@ -657,7 +658,7 @@ public class AdacMitfahrclub {
                                else if (text1 == "Raucher")
                                        print ("Raucher: %s\n", text2);
                                else if (text1 == "Fahrpreis")
-                                       lift.price = text2;
+                                       lift.price = text2.replace (" EUR", " €");
                                else if (text1 == "ADAC-Mitglied" && text2 != "nein")
                                        lift.flags |= LiftFlags.ADAC_MEMBER;
                        }
@@ -812,6 +813,136 @@ public class AdacMitfahrclub {
                return my_info;
        }
 
+       public string get_my_offers_url () {
+               return HTTP_BASE_URI + "/lifts/mysinglelifts";
+       }
+
+       public async List<Lift>? get_my_offers () {
+               var doc = yield get_html_document (get_my_offers_url ());
+               if (doc == null) {
+                       stderr.printf ("Error: parsing failed\n");
+                       return null;
+               }
+
+               var table = search_tag_by_class (doc->children, "table", "list");
+               if (table == null) {
+                       stderr.printf ("Error: does not contain user table\n");
+                       return null;
+               }
+
+               var list = new List<Lift> ();
+               for (var n = table->children; n != null; n = n->next) {
+                       if (n->name == "tr") {
+                               var lift = parse_offer_row (n);
+                               if (lift != null) // Skip the title row
+                                       list.append ((owned) lift);
+                       }
+               }
+
+               if (table->next != null && table->next->name == "div") {
+                       var text = get_child_text_content (table->next);
+                       if (text != null) {
+                               print ("\"%s\"\n", text);
+                               if (text == "Sie haben derzeit keine einmaligen Fahrten eingetragen") {
+                                       print ("NO ENTRIES\n");
+                               }
+                       }
+               }
+
+               return list;
+       }
+
+       Lift? parse_offer_row (Xml.Node *tr) {
+               var lift = new Lift ();
+
+               // checkbox
+               var td = get_next_td (tr->children);
+               if (td == null)
+                       return null;
+
+               // action
+               td = get_next_td (td->next);
+               if (td == null)
+                       return null;
+               // FIXME: get uri
+
+               // type
+               td = get_next_td (td->next);
+               if (td == null)
+                       return null;
+               var text = get_child_text_content (td);
+               if (text == null)
+                       return null;
+               // FIXME ==
+               if (text != "Mitfahrer")
+                       return null;
+
+               // point of departure
+               td = get_next_td (td->next);
+               if (td == null)
+                       return null;
+               text = get_child_text_content (td);
+               if (text == null)
+                       return null;
+               lift.city_from = text;
+
+               // point of arrival
+               td = get_next_td (td->next);
+               if (td == null)
+                       return null;
+               text = get_child_text_content (td);
+               if (text == null)
+                       return null;
+               lift.city_to = text;
+
+               // date
+               td = get_next_td (td->next);
+               if (td == null)
+                       return null;
+               text = get_child_text_content (td);
+               if (text == null)
+                       return null;
+               parse_date (text, out lift.time);
+
+               // time
+               td = get_next_td (td->next);
+               if (td == null)
+                       return null;
+               text = get_child_text_content (td);
+               if (text == null)
+                       return null;
+               parse_time (text, out lift.time);
+
+               // active?
+               td = get_next_td (td->next);
+               if (td == null)
+                       return null;
+               var a = td->children;
+               if (a == null || a->name != "a")
+                       return null;
+               text = a->get_prop ("class");
+               if (text == "status icon icon_ajax_active")
+                       lift.flags |= LiftFlags.ACTIVE;
+
+               return lift;
+       }
+
+       Xml.Node* get_next_td (Xml.Node *n) {
+               while (n != null) {
+                       if (n->name == "td")
+                               return n;
+                       n = n->next;
+               }
+               return null;
+       }
+
+       unowned string get_child_text_content (Xml.Node *n) {
+               if (n->children != null && n->children->name == "text")
+                       return n->children->content;
+               else
+                       return null;
+       }
+
        Xml.Node* search_tag_by_property (Xml.Node* node, string tag, string prop, string val) requires (node != null) {
                for (var n = node; n != null; n = n->next) {
                        if (n->name == tag && n->get_prop (prop) == val)
@@ -839,9 +970,11 @@ public class AdacMitfahrclub {
 
        void parse_date (string date, out Time time) {
                int year;
-               if (date.length == 11)
+               if (date.length == 12)          // "Mo, 01.02.03"
+                       date = date.offset (4);
+               else if (date.length == 11)     // "Mo 01.02.03"
                        date = date.offset (3);
-               if (date.length != 8)
+               if (date.length != 8)           // "01.02.03"
                        return;
                var res = date.scanf ("%02d.%02d.%02d", out time.day, out time.month, out year);
                time.year = year + 2000;