Skip to content

Instantly share code, notes, and snippets.

@brdloush
Created July 27, 2022 09:26
Show Gist options
  • Save brdloush/ab29092edec5ef2d3c3efe7e70a284b0 to your computer and use it in GitHub Desktop.
Save brdloush/ab29092edec5ef2d3c3efe7e70a284b0 to your computer and use it in GitHub Desktop.
mobile IDOS.cz route search script for clojure
(ns idos
(:require [clojure.string :as str]
[hickory.select :as s]
[hickory.core :as h]
[org.httpkit.client :as http]
[clojure.tools.logging :refer [debug]])
(:import [javax.net.ssl SSLEngine SSLParameters SNIHostName]
[java.net URI URLEncoder]))
(defn sni-configure
[^SSLEngine ssl-engine ^URI uri]
(let [^SSLParameters ssl-params (.getSSLParameters ssl-engine)]
(.setServerNames ssl-params [(SNIHostName. (.getHost uri))])
(.setSSLParameters ssl-engine ssl-params)))
(def client (http/make-client {:ssl-configurer sni-configure}))
(defn mobdt->hh-mm [s]
(-> s (str/split #" ") second (->> (take 5)) str/join))
(defn train-hickory->route [train-hickory]
(let [train-body (first (s/select
(s/child (s/class "train-body"))
train-hickory))
train-paragraphs (->> (s/select
(s/child (-> (s/class "station-row")
(s/descendant (s/tag :p))))
train-body))
from-mob-hh-mm (->> train-paragraphs first :content (filter map?) first :attrs :ddate mobdt->hh-mm)]
{:station (-> train-paragraphs first :content (->> (filter string?)) (->> (apply str)) str/trim)
:time from-mob-hh-mm
:from-time from-mob-hh-mm
:end-station (-> train-paragraphs second :content (->> (filter string?)) (->> (apply str)) str/trim)
:end-time (->> train-paragraphs second :content (filter map?) first :attrs :adate mobdt->hh-mm)}))
(defn url-encode [s]
(URLEncoder/encode s))
(defn lookup-connections [transport-type from to date time]
(debug "lookup-connections" transport-type from to date time)
(let [from-encoded (url-encode from)
to-encoded (url-encode to)
time (url-encode time) ;; TODO patrne UTC
transport-type-path (condp = transport-type
:train
"vlaky"
:bus
"autobusy"
:train-and-bus
"vlakyautobusy")
{:keys [body] :as _resp}
@(http/get (str "https://t.idos.idnes.cz/" transport-type-path "/spojeni/"
"?fromT=" from-encoded "&toT=" to-encoded "&date=" date "&dateH=" date "&time=" time "&timeH=" time "&cmd=cmdSearch")
{:client client
:headers {"User-Agent" "User-Agent: Mozilla/5.0 (Linux; Android 6.0.1; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Mobile Safari/537.36"}})]
(->> body
h/parse
h/as-hickory
(s/select (s/child (s/class "conn")))
(map (fn [conn-h]
(let [itinerary (->> (s/select (s/child (s/class "train"))
conn-h)
(map train-hickory->route))
{start-station :station
start-time :from-time} (first itinerary)
{end-station :end-station
end-time :end-time} (last itinerary)]
{:start-station start-station
:start-time start-time
:end-station end-station
:end-time end-time
:itinerary itinerary}))))))
(comment
(take 1 (lookup-connections :train "Mrač" "Praha" "27.7.2022" "10:00"))
;; => ({:start-station "Mrač",
;; :start-time "10:00",
;; :end-station "Praha hl.n.",
;; :end-time "11:30",
;; :itinerary
;; ({:station "Mrač", :time "10:00", :from-time "10:00", :end-station "Benešov u Prahy", :end-time "10:07"}
;; {:station "Benešov u Prahy", :time "10:49", :from-time "10:49", :end-station "Praha hl.n.", :end-time "11:30"})})
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment