#!/usr/bin/env gosh (use rfc.http) (use rfc.uri) (use rfc.json) (use file.util) (use srfi-19) (use gauche.collection) (use gauche.parseopt) (use gauche.process) (define (main args) (let-args (cdr args) ((adir "d|dir=s") (baseurl "u|url=s") (statefile "s|statefile=s") (help "h|help" => (cut show-help (car args))) . restargs) (if (equal? baseurl #f) (show-help (car args)) (guesstimate (if (equal? adir #f) "." adir) baseurl (if statefile statefile "./obu-state.edn"))) (exit 0))) (define (show-help progname) (display (format "~a: tracktrain's on-board guesstimater for which trip you're on Arguments: -u --url: base url of the tracktrain server [required] -s --statefile: state file -c --config: config file (default is /etc/tracktrain/obu.conf) -h --help: display this help " progname)) (exit 0)) (define (guesstimate dir url statefile) (define stops (fetch-stations url)) (define pos (with-input-from-process `(obu-ping -s ,statefile -n 1 -d) read)) (define trip (assoc-ref (closest-stop-to stops pos) 'trip)) (display trip)) (define (closest-stop-to stops pos) (define stops-by-station (apply vector-append (vector->list (vector-map (lambda (trip) (vector-map (lambda (stop) (cons `(trip . ,(assoc-ref trip 'trip)) stop)) (assoc-ref trip 'stops))) stops)))) (find-min stops-by-station :key (lambda (stop) (+ (square (- (assoc-ref pos 'lat) (assoc-ref stop 'lat))) (square (- (assoc-ref pos 'lon) (assoc-ref stop 'lon))))) :default (vector-ref stops 0))) (define (fetch-stations url) (define day (date->string (current-date) "~1")) (define tls (equal? (uri-ref url 'scheme) 'https)) (parameterize ; replace all json keys with symbols; everything else is confusing ([json-object-handler (cut map (lambda p `(,(string->symbol (car (car p))) . ,(cdr (car p)))) <>)]) (parse-json-string (values-ref (http-get (uri-ref url 'host+port) (format "/api/timetable/stops/~a" day) :secure tls) 2))))