Last active
December 14, 2015 09:29
-
-
Save saolsen/5065547 to your computer and use it in GitHub Desktop.
markerbot
This file contains 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
(ns markerbot.core | |
(:require [taoensso.timbre :as log] | |
[clojure.data.json :as json] | |
[clojure.string :as s] | |
[clj-http.client :as client]) | |
(:import (java.net Socket) | |
(java.io PrintWriter InputStreamReader BufferedReader)) | |
(:gen-class)) | |
;; marksy | |
(defn payload [from to text] | |
(json/write-str {:input from, :output to, :text text})) | |
(defn transmarksify [from to text] | |
(let [req (client/post "http://marksy.arc90.com/convert" | |
{:headers {"x-marksy" "markerbot"} | |
:content-type :json | |
:accept :json | |
:body (payload from to text)})] | |
(-> req | |
(:body) | |
(json/read-str :key-fn keyword) | |
(:payload)))) | |
;; irc | |
(defn get-connection [server port] | |
(let [socket (Socket. server port) | |
in (BufferedReader. (InputStreamReader. (.getInputStream socket))) | |
out (PrintWriter. (.getOutputStream socket))] | |
{:in in :out out})) | |
;; types that contain and manage the state | |
(defprotocol PIrcConnection | |
"A connection to irc" | |
(readline [this] "read a line from irc") | |
(writeline [this command] "writes a command to irc")) | |
(defrecord IrcConnection [in out] | |
PIrcConnection | |
(readline [_] (.readLine in)) | |
(writeline [_ command] (doto out | |
(.println (str command "\r")) | |
(.flush)))) | |
(defprotocol PManagedChannel | |
"A managed irc channel" | |
(register-handler [this handler] "register a function to be called") | |
(setup [this] "sets everything up")) | |
(defrecord ManagedChannel [connection channel user | |
reads writes msg-handler] | |
PManagedChannel | |
(register-handler [_ handler] (reset! msg-handler handler)) | |
(setup [_] | |
;; watcher to log to console | |
(add-watch reads :log | |
(fn [_ _ _ msg] | |
(log/info "received: " msg))) | |
;; watcher to publish messages to irc | |
(add-watch writes :publish | |
(fn [_ _ _ msg] | |
(log/info "replied: " msg) | |
(writeline connection msg))) | |
;; watcher to check for pings | |
(add-watch reads :pingback | |
(fn [_ _ _ msg] | |
(when (re-find #"^PING" msg) | |
(reset! writes (str "PONG " (re-find #":.*" msg)))))) | |
;; watcher to call handler | |
(add-watch reads :handler | |
(fn [_ _ _ msg] | |
(future | |
(when-let [reply (@msg-handler msg)] | |
(doseq [m (s/split reply #"\n")] | |
(reset! writes | |
(str "PRIVMSG " channel " :" m))))))) | |
;; sign in and join channel | |
(reset! writes (str "NICK " user)) | |
(reset! writes (str "USER " user " 0 * :" user)) | |
(reset! writes (str "JOIN " channel)) | |
;; thread to read from the channel and publish notifications | |
(future | |
(while true | |
(let [next-message (readline connection)] | |
(reset! reads next-message)))) | |
nil | |
)) | |
(defn connect | |
"connects to an irc channel and returns an IrcConnection" | |
[server port] | |
(let [conn (get-connection server port) | |
irc (IrcConnection. (:in conn) (:out conn))] | |
irc)) | |
;; marksy coms | |
(defn marksinator [msg] | |
(when-let [match (re-find #"(\[)([A-z]*)(->)([A-z]*)(\])(.*)" msg)] | |
(transmarksify (nth match 2) (nth match 4) (nth match 6)))) | |
;; main | |
(defn -main [& args] | |
(let [conn (connect "irc.freenode.net" 6667) | |
channel (ManagedChannel. conn "#marksy" "markerbot" | |
(atom nil) (atom nil) (atom nil))] | |
(register-handler channel marksinator) | |
(setup channel))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment