I would like to write a little pet project using Clojure to study it, something like StackOverflow client.
Here is a my first code to get list of new questions from site. I am in the very beginning in Clojure so any help will be appreciated.
core.clj:
(ns stackify.core
(:require [clj-http.client :as client]
[clojure.data.json :as json]
[stackify.utils :as utils]
[stackify.configuration :as config]))
; TODO: move key to environment variables
(def ^:const stackKey "put-your-key-here")
(def ^:const baseUrl "https://api.stackexchange.com/2.2/questions?page=%d&pagesize=100&fromdate=%d&order=asc&sort=creation&site=%s&key=%s")
; Fetch questions
(defn fetch-json [url]
"fetch internet page by url and return JSON"
(let [data (client/get url)
body (get data :body)]
(json/read-str body)))
(defn fetch-questions [page from site accum]
"recursive function to get questions"
(let [url (format baseUrl page from site stackKey)
json-content (fetch-json url)
questions (get json-content "items")
has_more (get json-content "has_more")]
(println (format "Fetching page %d (has_more=%b)" page has_more))
(cond
(= has_more true) (fetch-site (+ page 1) from site (concat accum questions))
:else (concat accum questions))
))
(defn get-questions []
(let [from (config/read-time)
now (utils/current-time)]
(println from)
(config/save-time now)
(fetch-questions 1 from "stackoverflow" (vector))))
(defn print-questions [questions]
(doseq [q questions] (println (get q "title"))))
utils.clj:
(ns stackify.utils
(:require [clj-time.core :as time]
[clj-time.coerce :as tc]))
(defn current-time []
"returns unix time"
(let [moment (tc/to-long (time/now))]
(int (/ moment 1000))))
(defn parse-int [s]
"convert string to int"
(Integer. (re-find #"\d+" s )))
configuration.clj:
(ns stackify.configuration
(:require [stackify.utils :as utils]))
(def ^:const configFileName "last_sync_time")
(defn save-time [value]
"save value to configuration file; file will be overwritten"
(spit configFileName value))
(defn read-time []
"read last sync time from configuration file"
(let [value (slurp configFileName)]
(utils/parse-int value)))
(defn init []
"initiliza configuration file"
(save-time (utils/current-time)))