this repo has no description

initial commit (broken)

+91
+91
weather/weather.bb
··· 1 + #!/usr/bin/env bb 2 + (require '[babashka.http-client :as http] 3 + '[babashka.process :refer [shell process alive?]] 4 + '[clojure.java.io :as io] 5 + '[babashka.fs :as fs]) 6 + 7 + (def URL "https://api.weather.gov/gridpoints/LWX/88,80/forecast") 8 + 9 + (def endpoints {:points "https://api.weather.gov/points/"}) 10 + (def pgeocode-cache-path (str (fs/home) "/.cache/pgeocode/US.txt")) 11 + 12 + (defn get-all 13 + [coll keyset] 14 + (for [k keyset] 15 + (vector k (get coll k)))) 16 + 17 + (defn read-csv-to-maps 18 + ([] (read-csv-to-maps pgeocode-cache-path)) 19 + ([fname] 20 + (let [csv-data (-> fname slurp csv/read-csv)] 21 + (map zipmap 22 + (->> (first csv-data) 23 + (map keyword) 24 + repeat) 25 + (rest csv-data))))) 26 + 27 + (defn geocode [zipcode] 28 + (first (filter 29 + (fn [{zc :postal_code}] (= zc zipcode)) 30 + (read-csv-to-maps)))) 31 + 32 + (defn api-get 33 + "Make an HTTP GET to url and return the json result" 34 + [url] 35 + (let [response (-> url http/get)] 36 + (if (= (:status response) 500) 37 + (do 38 + (print "Server responded with 500. Rate limit (probably) exceeded. Wait a bit then try again") 39 + (System/exit 1)) 40 + (-> response :body json/parse-string)))) 41 + 42 + (defn form-request 43 + "Forms a request url" 44 + [request-type & args] 45 + (apply str (request-type endpoints) (interpose "," args))) 46 + 47 + (defn get-forecast-url 48 + "Gets the endpoint url for the requested latitude and longitude using a points request" 49 + [{latitude :latitude longitude :longitude}] 50 + (-> (form-request :points latitude longitude) 51 + api-get 52 + (get-in ["properties" "forecastHourly"]))) 53 + 54 + (defn get-forecast [location] 55 + (-> location get-forecast-url api-get 56 + (get-in ["properties" "periods"]) 57 + first 58 + (get-all ["temperature" "shortForecast"]))) 59 + 60 + (defn check-rc [] 61 + (let [path (str (fs/home) "/.weatherrc")] 62 + (when (fs/exists? path) 63 + (-> path slurp str/trim-newline)))) 64 + 65 + (defn display-results 66 + [{city :place_name state :state_code} 67 + [[_ temperature] [_ forecast]]] 68 + (doseq [line ["" 69 + (str "The weather in " city ", " state " is:") 70 + (str temperature " F") 71 + (str "Forecast: " forecast)]] 72 + (println line))) 73 + 74 + (defn get-weather [postal-code] 75 + (let [location (geocode postal-code) 76 + forecast (get-forecast location)] 77 + (display-results location forecast))) 78 + 79 + (defn -main 80 + ([] 81 + (if-let [postal-code (check-rc)] 82 + (get-weather postal-code) 83 + (println "No postal code provided"))) 84 + 85 + ([postal-code] 86 + (if (re-matches #"\d{5}" postal-code) 87 + (get-weather postal-code) 88 + (println "Not a valid postal code")))) 89 + 90 + (when (= *file* (System/getProperty "babashka.file")) 91 + (apply -main *command-line-args*))