1 ! Simple IRC bot written in Factor.
3 REQUIRES: apps/http-server ;
5 USING: errors generic hashtables help html http io kernel math
6 memory namespaces parser prettyprint sequences strings threads
7 words inspector network ;
15 : irc-write ( s -- ) irc-stream get stream-write ;
17 irc-stream get stream-print
18 irc-stream get stream-flush ;
21 dup nickname set "NICK " irc-write irc-print ;
25 "USER " irc-write irc-write
26 " hostname servername :irc.factor" irc-print ;
28 : connect ( server -- ) 6667 <inet> <client> irc-stream set ;
30 : disconnect ( -- ) irc-stream get stream-close ;
33 "JOIN " irc-write irc-print ;
35 GENERIC: handle-irc ( line -- )
36 PREDICATE: string privmsg " " split1 nip "PRIVMSG" head? ;
37 PREDICATE: string ping "PING" head? ;
39 M: object handle-irc ( line -- )
42 : parse-privmsg ( line -- text )
45 " " split1 swap receiver set
48 M: privmsg handle-irc ( line -- )
51 "factorbot-commands" lookup dup
52 [ execute ] [ 2drop ] if ;
54 M: ping handle-irc ( line -- )
55 "PING " ?head drop "PONG " swap append irc-print ;
57 : parse-irc ( line -- )
58 ":" ?head [ "!" split1 swap speaker set ] when handle-irc ;
60 : say ( line nick -- )
61 "PRIVMSG " irc-write irc-write " :" irc-write irc-print ;
64 receiver get nickname get = speaker receiver ? get say ;
67 irc-stream get stream-readln
68 [ dup print flush parse-irc irc-loop ] when* ;
71 "irc.freenode.net" connect
74 [ irc-loop ] [ irc-stream get stream-close ] cleanup ;
76 : factorbot-loop [ factorbot ] try 30000 sleep factorbot-loop ;
78 : multiline-respond ( string -- )
79 string-lines [ respond ] each ;
82 "http://factorcode.org" swap browser-link-href append ;
84 : not-found ( str -- )
85 "Sorry, I couldn't find anything for " swap append respond ;
87 IN: factorbot-commands
90 dup words-named dup empty? [
96 rot object-href 3append respond
101 drop [ room. ] with-string-writer multiline-respond ;
104 drop speaker get "slava" = [ disconnect ] when ;
106 PROVIDE: apps/factorbot ;
108 MAIN: apps/factorbot factorbot ;