Hi guys!
When it rains my internet connection is a pain in the neck, by the way I want to show you the Clojure version of Don’t Panic.
If you don’t remember it, Don’t Panic is a simple application developed with university students in mind, it periodically checks a site, looking for an update. It was a good occasion to play with Leningen!
Here is the full code (Leningen version):
;; Don't panic (ns dontpanic.core (:gen-class)) (defn fetch-url "Fetches an URL. Returns a string made by the page's html." [address] (with-open [stream (.openStream (java.net.URL. address))] (let [buf (java.io.BufferedReader. (java.io.InputStreamReader. stream))] (apply str (line-seq buf))))) (defn hash-code "Simple wrapper. Returns a string hashcode." [string] (.hashCode string)) (defn -main "Periodically check if a site has been modified." [& args] (let [address (nth args 0) site-hashcode (hash-code (fetch-url address))] (while true (do (if (not (= site-hashcode (hash-code (fetch-url address)))) (println "Maybe an update! Finger crossed.") (println "Nothing changed, calm down.")) (Thread/sleep 5000)))))
The idea behind the scenes is very simple: fetch-url returns the entire page’s html as a string, the hash-code function returns the string hash code. The eternal loop (while true) fetch the url, computes the hash code: if it’s different from the previous one, an maybe an update is occurred!
Shortly I will post a standalone jar!!
Usage (code version):
(-main [<site url as string>])
Usage (jar version):
java -jar dontpanic.jar <site-url>
Enjoy!
Nice utility – and I share the enthusiasm for Clojure – a great language for sure.
I just wanted to suggest a possible design improvement. Perhaps you’re aware of this already, but you don’t have to fetch and hash a page to know if it has changed. Web clients have long avoided unnecessary fetching by using timestamps and the 304 (not modified) HTTP response code.
Here’s a pointer to the appropriate part of the spec. http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3
I’m afraid this would become more of a “calling java from Clojure” exercise than anything else, but it would probably still be a useful example
What I’m not sure of though, is how hard this would be in clojure. You have to get into
In first place, thanks for your comment, the first one by long time 🙂
In second place, I will take a look to your suggestion: mine implementation is the easiest one, despite you can archive the same purpose looking at the “Last Modified” attribute on some html pages 🙂
Watch out, not all the pages have this attribute 🙂
Bye!
Alfredo