Skip to content

Instantly share code, notes, and snippets.

@czlang
Created November 16, 2016 10:55
Show Gist options
  • Save czlang/35ee8826ffb3b5e651a742e28593f398 to your computer and use it in GitHub Desktop.
Save czlang/35ee8826ffb3b5e651a742e28593f398 to your computer and use it in GitHub Desktop.
(ns fotbal.fotbal
(:require [hiccup.page :as hiccup]
[clojure.string :as str]
[compojure.core :refer :all]
[ring.util.response :as response])
(:import (org.jsoup Jsoup Connection Connection$Method)))
(defn hiccup-response
[body]
(-> (hiccup/html5 {:lang "cs"}
body)
response/response
(response/content-type "text/html")
(response/charset "utf-8")))
(defn hiccup-frame-bare [title body]
(list
[:head
[:meta {:charset "UTF-8"}]
[:meta {:name "viewport" :content "width=device-width, initial-scale=1"}]
[:title title]]
[:body body]))
(defn get-raw-data [filepath selector]
(map #(.text %) (.select (Jsoup/parse (slurp filepath)) selector)))
(defn get-matches-summary [raw-data]
(map second (partition 4 raw-data)))
(defn add-final-score [matches-summary]
(reduce
(fn [out in]
(conj out (let [final-score (re-find #"\d+:\d+" in)]
{:summary in
:final-score final-score
:played (boolean final-score)})))
[]
matches-summary))
(defn create-all-games-data [matches-data]
(let [all-games-data (mapcat
(fn [{:keys [summary final-score played] :as data}]
(map-indexed
(fn [idx team]
(let [goals-for (if (:final-score data)
(read-string
(if (= 0 idx)
(first (clojure.string/split (:final-score data) #":"))
(second (clojure.string/split (:final-score data) #":")))))
goals-against (if (:final-score data)
(read-string
(if (= 0 idx)
(second (clojure.string/split (:final-score data) #":"))
(first (clojure.string/split (:final-score data) #":")))))]
{:team team
:goals (merge {}
(when goals-for {:goals-for goals-for
:goals-against goals-against}))
:win (when played (> goals-for goals-against))
:loss (when played (< goals-for goals-against))
:tie (when played (= goals-for goals-against))
:played played}))
(clojure.string/split (clojure.string/replace (:summary data) #" \d+:\d+ \(\d+:\d+\)" "") #" - ")))
matches-data)]
all-games-data))
(defn create-table-data [all-games-data]
(reduce
(fn [out {:keys [team goals win loss tie played] :as in}]
(if (get out team)
(-> out
(update-in [team :games] (if played inc identity))
(update-in [team :wins] (if win inc identity))
(update-in [team :loses] (if loss inc identity))
(update-in [team :ties] (if tie inc identity))
(assoc-in [team :points] (cond
(= true win) (+ (get-in out [team :points]) 3)
(= true tie) (+ (get-in out [team :points]) 1)
:else (get-in out [team :points])))
(assoc-in [team :goals] (merge-with + (get-in out [team :goals]) (:goals in))))
(assoc out team
{:games (if played 1 0)
:wins (if (= true win) 1 0)
:loses (if (= true loss) 1 0)
:ties (if (= true tie) 1 0)
:points (cond
(= true win) 3
(= true tie) 1
:else 0)
:goals goals})))
{}
all-games-data))
(defn sort-by-points [table-data]
(reverse
(sort-by
(fn [[_ v]] (:points v))
table-data)))
(defn data-api-endpoint []
(context ""
(GET "/fotbal" []
(let [teams-table-data-sorted (-> (get-raw-data "resources/fotbal/fotbal.html" "div.match div.row div.col-100")
get-matches-summary
add-final-score
create-all-games-data
create-table-data
sort-by-points)]
(hiccup-response
(hiccup-frame-bare
"Tabulka fotbal"
[:div
[:style ".ft td {padding: 5px;} .ft .even {background: #f7f7f7;} "]
[:a {:href "https://souteze.fotbal.cz/turnaje/zapas/fbd63883-283a-4903-b022-bbe2f8e49745"} "Data ze souteze.fotbal.cz"]
[:table.ft
[:tr
[:td ""]
[:td ""]
[:td "Zápasů"]
[:td "Výhry"]
[:td "Remízy"]
[:td "Prohry"]
[:td "Vstřelené góly"]
[:td "Obdržené góly"]
[:td "Body"]]
(map-indexed
(fn [idx [team {:keys [games wins loses ties points goals] :as data}]]
[:tr {:class (if (even? idx) "even" "odd")}
[:td (str (inc idx)".")]
[:td team]
[:td (str games)]
[:td (str wins)]
[:td (str ties)]
[:td (str loses)]
[:td (str (:goals-for goals))]
[:td (str (:goals-against goals))]
[:td (str points)]])
teams-table-data-sorted)]]))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment