-
-
Save ecarnevale/830590 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; I'm not saying this is good Clojure, but it was off the top of my head | |
;; It's a title bot for jschat.org | |
(import '(java.io BufferedReader InputStreamReader PrintWriter)) | |
(import '(java.net Socket)) | |
(import '(java.net HttpURLConnection URL)) | |
(use '[clojure.contrib.json.read :only (read-json)]) | |
(use '[clojure.contrib.json.write :only (json-str)]) | |
;; Data structures | |
(defstruct jschat-server :address :port) | |
(defstruct message :message :channel) | |
;; Settings | |
(def server (struct jschat-server "127.0.0.1" 6789)) | |
(def username "titlebot") | |
(def channel "#jschat") | |
(def socket (new Socket (server :address) (server :port))) | |
(def reader (new BufferedReader (new InputStreamReader (. socket (getInputStream))))) | |
(def writer (new PrintWriter (. socket getOutputStream) true)) | |
;; HTTP requests with length | |
(defn fetch-url | |
"Fetches 1000 lines of text from a URL." | |
[url] | |
(let [connection (. (new URL url) openConnection)] | |
(let [stream (new BufferedReader (new InputStreamReader (. connection getInputStream)))] | |
(if (re-find #"html" (. connection getContentType)) | |
(apply str (take 1000 (line-seq stream))))))) | |
(defn title-url | |
"Return the title of a web page" | |
[url] | |
(try | |
(let [src (fetch-url url) | |
title (second (re-find #"(?i)\s?<title>(.*)</title>" src))] | |
(str "Title: " (.trim title))) | |
(catch java.io.FileNotFoundException _ "Error: Page not found") | |
(catch Exception _ false))) | |
;; Connection | |
(defn write-jschat [data] | |
(. writer println (json-str data))) | |
(defn read-jschat [] | |
(read-json (. reader readLine))) | |
;; JsChat commands | |
(defn identify [name] | |
(write-jschat { "identify" name })) | |
(defn join [channel] | |
(write-jschat { "join" channel })) | |
(defn send-message [message channel] | |
(write-jschat { "send" message "to" channel })) | |
;; Return the significant part of a response | |
(defmulti jschat-response (fn [response] (response "display"))) | |
(defmethod jschat-response "message" [message] ((message "message") "message")) | |
(defmethod jschat-response "join" [message] (println "Joining room: " ((message "join") "room"))) | |
(defn extract-url [text] | |
(str "http://" (second (re-find #"http://([^\s]*)" text)))) | |
(defn extract-url-from-response [response] | |
(extract-url (jschat-response response))) | |
(defn get-title [response] | |
(try | |
(title-url (extract-url-from-response response)) | |
(catch Exception _ false))) | |
(.start (Thread. (fn [] | |
(while true | |
(let [title (get-title (read-jschat))] | |
(if title | |
(send-message title channel))))))) | |
;; Identify and join a channel | |
(identify username) | |
(join channel) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment