Skip to content

Commit

Permalink
added call to get stations
Browse files Browse the repository at this point in the history
  • Loading branch information
fterrier committed Feb 4, 2015
1 parent cf4fbb2 commit daf818a
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 27 deletions.
1 change: 1 addition & 0 deletions fixtures/zvv_responses/hirsch_xxxx.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SLs.sls={"suggestions":[{"value":"Ganterschwil, Hirschen","id":"A=1@O=Ganterschwil, Hirschen@X=9086395@Y=47379255@U=85@L=008574001@B=1@p=1423035832@","extId":"008574001","type":"1","typeStr":"[Bhf/Hst]","xcoord":"9086395","ycoord":"47379255","state":"id","prodClass":"64","weight":"389"},{"value":"Zürich, Hirschwiesenstrasse","id":"A=1@O=Zürich, Hirschwiesenstrasse@X=8543213@Y=47399994@U=85@L=008591193@B=1@p=1423035832@","extId":"008591193","type":"1","typeStr":"[Bhf/Hst]","xcoord":"8543213","ycoord":"47399994","state":"id","prodClass":"512","weight":"3268"},{"value":"Hirschberg","id":"A=1@O=Hirschberg@X=9422834@Y=47331316@U=85@L=008506380@B=1@p=1423035832@","extId":"008506380","type":"1","typeStr":"[Bhf/Hst]","xcoord":"9422834","ycoord":"47331316","state":"id","prodClass":"34","weight":"6179"},{"value":"Hirschlang","id":"A=1@O=Hirschlang@X=7755191@Y=47410124@U=85@L=008500094@B=1@p=1423035832@","extId":"008500094","type":"1","typeStr":"[Bhf/Hst]","xcoord":"7755191","ycoord":"47410124","state":"id","prodClass":"96","weight":"6082"},{"value":"Hirschthal","id":"A=1@O=Hirschthal@X=8052815@Y=47319882@U=85@L=008502197@B=1@p=1423035832@","extId":"008502197","type":"1","typeStr":"[Bhf/Hst]","xcoord":"8052815","ycoord":"47319882","state":"id","prodClass":"96","weight":"6082"},{"value":"Schwyz, Hirschen","id":"A=1@O=Schwyz, Hirschen@X=8629698@Y=47046843@U=85@L=008577477@B=1@p=1423035832@","extId":"008577477","type":"1","typeStr":"[Bhf/Hst]","xcoord":"8629698","ycoord":"47046843","state":"id","prodClass":"64","weight":"389"},{"value":"Hirschmatt (Guggisberg), Allme","id":"A=1@O=Hirschmatt (Guggisberg), Allme@X=7312347@Y=46748887@U=85@L=008571690@B=1@p=1423035832@","extId":"008571690","type":"1","typeStr":"[Bhf/Hst]","xcoord":"7312347","ycoord":"46748887","state":"id","prodClass":"64","weight":"124"},{"value":"Hirschmatt (Guggisberg), Fall","id":"A=1@O=Hirschmatt (Guggisberg), Fall@X=7311214@Y=46752447@U=85@L=008571689@B=1@p=1423035832@","extId":"008571689","type":"1","typeStr":"[Bhf/Hst]","xcoord":"7311214","ycoord":"46752447","state":"id","prodClass":"64","weight":"124"},{"value":"Hirschmatt (Guggisberg),Schule","id":"A=1@O=Hirschmatt (Guggisberg),Schule@X=7322361@Y=46755880@U=85@L=008571688@B=1@p=1423035832@","extId":"008571688","type":"1","typeStr":"[Bhf/Hst]","xcoord":"7322361","ycoord":"46755880","state":"id","prodClass":"64","weight":"124"},{"value":"Uznach, Hirschwiese","id":"A=2@O=Uznach, Hirschwiese@X=8975540@Y=47226843@U=103@b=990189668@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8975540","ycoord":"47226843","prodClass":"0","weight":"0"},{"value":"Zürich, Hirschwiesen","id":"A=4@O=Zürich, Hirschwiesen@X=8548004@Y=47412399@U=104@L=970103454@B=1@p=1408002019@","extId":"970103454","type":"4","typeStr":"[POI]","xcoord":"8548004","ycoord":"47412399","state":"id","prodClass":"0","weight":"0"},{"value":"Zürich, Hirschwiesenstrasse","id":"A=2@O=Zürich, Hirschwiesenstrasse@X=8544831@Y=47399904@U=103@b=990214632@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8544831","ycoord":"47399904","prodClass":"0","weight":"0"},{"value":"Bütschwil-Ganterschwil, Hirschen (Restaurant)","id":"A=4@O=Bütschwil-Ganterschwil, Hirschen (Restaurant)@X=9071895@Y=47359515@U=104@L=970055674@B=1@p=1408002019@","extId":"970055674","type":"4","typeStr":"[POI]","xcoord":"9071895","ycoord":"47359515","state":"id","prodClass":"0","weight":"0"},{"value":"Jonschwil, Hirschen (Restaurant)","id":"A=4@O=Jonschwil, Hirschen (Restaurant)@X=9070511@Y=47443259@U=104@L=970053673@B=1@p=1408002019@","extId":"970053673","type":"4","typeStr":"[POI]","xcoord":"9070511","ycoord":"47443259","state":"id","prodClass":"0","weight":"0"},{"value":"Zürich, Post Zürich Hirschwiesen","id":"A=4@O=Zürich, Post Zürich Hirschwiesen@X=8543653@Y=47400236@U=104@L=970010270@B=1@p=1408002019@","extId":"970010270","type":"4","typeStr":"[POI]","xcoord":"8543653","ycoord":"47400236","state":"id","prodClass":"0","weight":"0"},{"value":"Jonschwil - Schwarzenbach, Hirschenstrasse","id":"A=2@O=Jonschwil - Schwarzenbach, Hirschenstrasse@X=9070673@Y=47442306@U=103@b=990086547@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"9070673","ycoord":"47442306","prodClass":"0","weight":"0"},{"value":"Schaffhausen, Hirschwiesenweg","id":"A=2@O=Schaffhausen, Hirschwiesenweg@X=8646454@Y=47718616@U=103@b=990162406@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8646454","ycoord":"47718616","prodClass":"0","weight":"0"},{"value":"Wetzikon, Hirschwiesenstrasse","id":"A=2@O=Wetzikon, Hirschwiesenstrasse@X=8801077@Y=47327621@U=103@b=990202576@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8801077","ycoord":"47327621","prodClass":"0","weight":"0"},{"value":"Heiden, Hirschli","id":"A=1@O=Heiden, Hirschli@X=9519621@Y=47433973@U=85@L=008574080@B=1@p=1423035832@","extId":"008574080","type":"1","typeStr":"[Bhf/Hst]","xcoord":"9519621","ycoord":"47433973","state":"id","prodClass":"64","weight":"1229"},{"value":"Hirschthal, Egg","id":"A=2@O=Hirschthal, Egg@X=8061732@Y=47322605@U=103@b=990080121@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8061732","ycoord":"47322605","prodClass":"0","weight":"0"},{"value":"Honau, Hirschen","id":"A=1@O=Honau, Hirschen@X=8406496@Y=47133113@U=85@L=008582046@B=1@p=1423035832@","extId":"008582046","type":"1","typeStr":"[Bhf/Hst]","xcoord":"8406496","ycoord":"47133113","state":"id","prodClass":"64","weight":"124"},{"value":"Hirschthal, Hard","id":"A=2@O=Hirschthal, Hard@X=8044437@Y=47321518@U=103@b=990080129@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8044437","ycoord":"47321518","prodClass":"0","weight":"0"},{"value":"Hirschthal, Zelgli","id":"A=2@O=Hirschthal, Zelgli@X=8055880@Y=47322390@U=103@b=990080168@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8055880","ycoord":"47322390","prodClass":"0","weight":"0"},{"value":"Herblingen, Hirschen","id":"A=1@O=Herblingen, Hirschen@X=8663210@Y=47723749@U=85@L=008592495@B=1@p=1423035832@","extId":"008592495","type":"1","typeStr":"[Bhf/Hst]","xcoord":"8663210","ycoord":"47723749","state":"id","prodClass":"64","weight":"1229"},{"value":"Hirschthal, Auenweg","id":"A=2@O=Hirschthal, Auenweg@X=8047170@Y=47318398@U=103@b=990080109@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8047170","ycoord":"47318398","prodClass":"0","weight":"0"},{"value":"Hirschthal, Lenzweg","id":"A=2@O=Hirschthal, Lenzweg@X=8059440@Y=47320331@U=103@b=990080136@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8059440","ycoord":"47320331","prodClass":"0","weight":"0"},{"value":"Hirschthal, Weidweg","id":"A=2@O=Hirschthal, Weidweg@X=8057786@Y=47316241@U=103@b=990080166@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8057786","ycoord":"47316241","prodClass":"0","weight":"0"},{"value":"Hirschthal, Wuhrweg","id":"A=2@O=Hirschthal, Wuhrweg@X=8049849@Y=47316879@U=103@b=990080167@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8049849","ycoord":"47316879","prodClass":"0","weight":"0"},{"value":"Hirschthal, Föhreweg","id":"A=2@O=Hirschthal, Föhreweg@X=8073131@Y=47315756@U=103@b=990080126@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8073131","ycoord":"47315756","prodClass":"0","weight":"0"},{"value":"Hirschthal, Kanalweg","id":"A=2@O=Hirschthal, Kanalweg@X=8050343@Y=47317670@U=103@b=990080135@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8050343","ycoord":"47317670","prodClass":"0","weight":"0"},{"value":"Hirschthal, Rebhalde","id":"A=2@O=Hirschthal, Rebhalde@X=8057436@Y=47321931@U=103@b=990080147@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8057436","ycoord":"47321931","prodClass":"0","weight":"0"},{"value":"Hirschthal, Rosenweg","id":"A=2@O=Hirschthal, Rosenweg@X=8061912@Y=47320142@U=103@b=990080148@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8061912","ycoord":"47320142","prodClass":"0","weight":"0"},{"value":"Hirschthal, Becketweg","id":"A=2@O=Hirschthal, Becketweg@X=8065957@Y=47316277@U=103@b=990080110@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8065957","ycoord":"47316277","prodClass":"0","weight":"0"},{"value":"Hirschthal, Blumenweg","id":"A=2@O=Hirschthal, Blumenweg@X=8058406@Y=47320619@U=103@b=990080111@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8058406","ycoord":"47320619","prodClass":"0","weight":"0"},{"value":"Hirschthal, Möösliweg","id":"A=2@O=Hirschthal, Möösliweg@X=8070101@Y=47315171@U=103@b=990080143@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8070101","ycoord":"47315171","prodClass":"0","weight":"0"},{"value":"Hirschthal, Muldenweg","id":"A=2@O=Hirschthal, Muldenweg@X=8066551@Y=47315621@U=103@b=990080140@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8066551","ycoord":"47315621","prodClass":"0","weight":"0"},{"value":"Hirschthal, Stelliweg","id":"A=2@O=Hirschthal, Stelliweg@X=8078264@Y=47315702@U=103@b=990080153@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8078264","ycoord":"47315702","prodClass":"0","weight":"0"},{"value":"Hirschthal, Tränkiweg","id":"A=2@O=Hirschthal, Tränkiweg@X=8064789@Y=47320529@U=103@b=990080161@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8064789","ycoord":"47320529","prodClass":"0","weight":"0"},{"value":"Hirschthal, Zofoldweg","id":"A=2@O=Hirschthal, Zofoldweg@X=8054694@Y=47317580@U=103@b=990080172@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8054694","ycoord":"47317580","prodClass":"0","weight":"0"},{"value":"Hirschthal, Hirschthal","id":"A=4@O=Hirschthal, Hirschthal@X=8052662@Y=47318542@U=104@L=970066621@B=1@p=1408002019@","extId":"970066621","type":"4","typeStr":"[POI]","xcoord":"8052662","ycoord":"47318542","state":"id","prodClass":"0","weight":"0"},{"value":"Hirschthal, Chriesiweg","id":"A=2@O=Hirschthal, Chriesiweg@X=8065211@Y=47319154@U=103@b=990080116@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8065211","ycoord":"47319154","prodClass":"0","weight":"0"},{"value":"Hirschthal, Eggstrasse","id":"A=2@O=Hirschthal, Eggstrasse@X=8059566@Y=47321032@U=103@b=990080122@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8059566","ycoord":"47321032","prodClass":"0","weight":"0"},{"value":"Hirschthal, Im Wechsel","id":"A=2@O=Hirschthal, Im Wechsel@X=8053103@Y=47322515@U=103@b=990080134@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8053103","ycoord":"47322515","prodClass":"0","weight":"0"},{"value":"Hirschthal, Musrainweg","id":"A=2@O=Hirschthal, Musrainweg@X=8056842@Y=47320852@U=103@b=990080142@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8056842","ycoord":"47320852","prodClass":"0","weight":"0"},{"value":"Hirschthal, Sägiserweg","id":"A=2@O=Hirschthal, Sägiserweg@X=8078129@Y=47313248@U=103@b=990080156@B=1@p=1408000921@","type":"2","typeStr":"[Adr]","xcoord":"8078129","ycoord":"47313248","prodClass":"0","weight":"0"}]};SLs.showSuggestion();
1 change: 1 addition & 0 deletions project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
[ring/ring-defaults "0.1.2"]
[ring/ring-jetty-adapter "1.2.1"]
[ring/ring-mock "0.2.0"]
[ring/ring-codec "1.0.0"]
[bk/ring-gzip "0.1.1"]
[org.clojars.jws/ring-etag-middleware "0.1.2-SNAPSHOT"]]

Expand Down
11 changes: 6 additions & 5 deletions src/tramboard_clj/core/handler.clj
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@

(defroutes api-routes
(context "/api" []
(wrap-no-cache (GET "/stationboard/:id{[0-9]+}" [id] (station id)))))
(wrap-routes (GET "/stationboard/:id{[0-9]+}" [id] (station id)) wrap-no-cache)
(wrap-routes (GET "/stations/:query{.+}" [query] (query-stations query)) wrap-no-cache)))

(defroutes app-routes
(wrap-cache (GET "/" [] (index-page)))
(wrap-cache (route/resources "/"))
(wrap-routes (GET "/" [] (index-page)) wrap-cache)
(wrap-routes (route/resources "/") wrap-cache)
(route/not-found "Not Found"))

(def site
(wrap-defaults app-routes (assoc site-defaults :cookies false :session false)))
(wrap-routes app-routes wrap-defaults (assoc site-defaults :cookies false :session false)))

(def api
(wrap-defaults api-routes api-defaults))
(wrap-routes api-routes wrap-defaults api-defaults))

(def app
(wrap-gzip (wrap-etag (routes api site))))
4 changes: 4 additions & 0 deletions src/tramboard_clj/core/views.clj
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@

(defn station [id]
(json-response (zvv/station id)))

(defn query-stations [query]
(println query)
(json-response (zvv/query-stations query)))
41 changes: 31 additions & 10 deletions src/tramboard_clj/core/zvv.clj
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
(ns tramboard-clj.core.zvv
(:require [cheshire.core :as json]
[ring.util.codec :as codec]
[clj-time.core :as t]
[clj-time.format :as f]
[clojure.string :as str]
Expand All @@ -11,7 +12,8 @@
; :user-agent "User-Agent-string"
; :headers {"X-Header" "Value"}})

(def base-url "http://online.fahrplan.zvv.ch/bin/stboard.exe/dn?L=vs_stbzvv&boardType=dep&productsFilter=1:1111111111111111&additionalTime=0&disableEquivs=false&maxJourneys=30&start=yes&monitor=1&requestType=0&view=preview&input=")
(def query-stations-base-url "http://online.fahrplan.zvv.ch/bin/ajax-getstop.exe/dny?start=1&tpl=suggest2json&REQ0JourneyStopsS0A=7&getstop=1&noSession=yes&REQ0JourneyStopsB=25&REQ0JourneyStopsS0G=")
(def station-base-url "http://online.fahrplan.zvv.ch/bin/stboard.exe/dn?L=vs_stbzvv&boardType=dep&productsFilter=1:1111111111111111&additionalTime=0&disableEquivs=false&maxJourneys=30&start=yes&monitor=1&requestType=0&view=preview&input=")

(def zvv-timezone (t/time-zone-for-id "Europe/Zurich"))

Expand All @@ -26,7 +28,7 @@
(str/replace (str/replace text " " " ") #"S( )+" "S"))

; TODO add 1 day to realtime if it is smaller than scheduled (scheduled 23h59 + 3min delay ...)
(defn departure [zvv-journey]
(defn zvv-departure [zvv-journey]
(let [colors (vec (remove str/blank? (str/split (zvv-journey "lc") #" ")))
zvv-date-parser (partial zvv-parse-datetime (zvv-journey "da"))]
{;:meta zvv-journey
Expand All @@ -36,22 +38,41 @@
:colors {:fg (when (> (count colors) 0) (str "#" (colors 0)))
:bg (when (> (count colors) 1) (str "#" (colors 1)))}
:to (zvv-journey "st")
:departure {:scheduled (zvv-date-parser (zvv-journey "ti")) :realtime (zvv-date-parser (get-in zvv-journey ["rt" "dlt"]))}}))
:departure {:scheduled (zvv-date-parser (zvv-journey "ti"))
:realtime (zvv-date-parser (get-in zvv-journey ["rt" "dlt"]))}}))

; TODO tests (=> capture some data from zvv api)
(defn transform-response [response-body]
(defn transform-station-response [response-body]
;(spit "fixtures/zvv_responses/new.txt" response-body)
(let [unparsed (clojure.string/replace-first response-body "journeysObj = " "")
data (json/parse-string unparsed)
journeys (data "journey")]
{:meta {:station_id (data "stationEvaId") :station_name (data "stationName")} :departures (map departure journeys)}))
{:meta {:station_id (data "stationEvaId")
:station_name (data "stationName")}
:departures (map zvv-departure journeys)}))

; TODO error handling
(defn station [id]
(let [request-url (str base-url id)
response (http/get request-url)]
(transform-response (:body @response))))
(defn zvv-station [zvv-station]
(let [id nil]
{:id (zvv-station "extId")
:name (zvv-station "value")}))

(defn transform-query-stations-response [response-body]
(let [unparsed (reduce #(clojure.string/replace-first %1 %2 "") response-body [";SLs.showSuggestion();" "SLs.sls="])
data (json/parse-string unparsed)
stations (data "suggestions")]
{:stations (map zvv-station (remove #(or (nil? (% "extId")) (not= "1" (% "type"))) stations))}))

; TODO error handling
(defn do-api-call [url transform-fn]
(let [response (http/get url)]
(println response)
(transform-fn (:body @response))))

(defn station [id]
(let [request-url (str station-base-url id)]
(do-api-call request-url transform-station-response)))

(defn query-stations [query]
(let [request-url (str query-stations-base-url (codec/url-encode query))]
(do-api-call request-url transform-query-stations-response)))

7 changes: 6 additions & 1 deletion src/tramboard_clj/script/time.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
(parse (formatters :date-time) unparsed-date))

(defn minutes-from [timestamp from]
"Returns the difference in minutes between from and timestamp."
(if (after? from timestamp)
(- (in-minutes (interval timestamp from)))
(in-minutes (interval from timestamp))))

(defn format-to-hour-minute [timestamp]
"Formats a timestamp to HH:mm"
(unparse hour-minute-formatter (to-default-time-zone timestamp)))

(defn display-time [timestamp]
Expand All @@ -40,4 +42,7 @@
" at " hour-minute-format)]
display-time))

(def parse-from-date-time (memoize parse-from-date-time-uncached))
(def parse-from-date-time
"Parses a date in the format 21-12-2015T12:12:00.000+01:00 into a timestamp.
This call is memoized."
(memoize parse-from-date-time-uncached))
12 changes: 6 additions & 6 deletions src/tramboard_clj/script/tram.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
(let [view-id (:view-id (:params current-state))]
(get configured-views view-id)))

(defn update-updated-date [view]
(defn- update-updated-date [view]
(assoc view :last-updated (to-long (now))))

(defn get-stops-in-order [view]
Expand All @@ -71,15 +71,15 @@
selected-views-ids (into #{} (map #(:view-id (:params (val %))) (:split-states complete-state)))]
(remove #(contains? selected-views-ids (:view-id %)) views)))

(defn remove-stop-and-update-date [current-view stop-id]
(defn- remove-stop-and-update-date [current-view stop-id]
(let [new-stops (dissoc (:stops current-view) stop-id)
new-stops-order (vec (remove #(= stop-id %) (:stops-order current-view)))
new-current-view (update-updated-date (assoc current-view
:stops new-stops
:stops-order new-stops-order))]
new-current-view))

(defn add-stop-and-update-date [current-view {:keys [:id] :as stop}]
(defn- add-stop-and-update-date [current-view {:keys [:id] :as stop}]
(let [existing-stops (:stops current-view)
existing-stops-order (or (:stops-order current-view) [])
existing-stop (get existing-stops id)
Expand All @@ -90,7 +90,7 @@
:stops-order new-stops-order))]
new-current-view))

(defn delete-view-if-no-stops [configured-views view-id]
(defn- delete-view-if-no-stops [configured-views view-id]
(let [current-view (get configured-views view-id)
current-stops (:stops current-view)]
(if (empty? current-stops)
Expand Down Expand Up @@ -162,11 +162,11 @@
(when-not (<! abort-chan)
(goog.events/listen
xhr goog.net.EventType.SUCCESS
(fn [e] (put! suggestions-ch (js->clj (.getResponseJson xhr) :keywordize-keys true))))
(fn [e] (put! suggestions-ch (:stations (js->clj (.getResponseJson xhr) :keywordize-keys true)))))
(goog.events/listen
xhr goog.net.EventType.ERROR
(fn [e] (println "ERROR")))
(.send xhr (str "http://tramboard.herokuapp.com/stations/" value) "GET")))
(.send xhr (str "/api/stations/" value) "GET")))
(go
(<! cancel-ch)
(do
Expand Down
Loading

0 comments on commit daf818a

Please sign in to comment.