Merge branch 'master' of git://tiodante.com/git/factor

db4
William Schlieper 2008-07-11 21:45:18 -04:00
commit a1bed6abe0
2 changed files with 75 additions and 32 deletions

View File

@ -2,8 +2,8 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: concurrency.mailboxes kernel io.sockets io.encodings.8-bit calendar USING: concurrency.mailboxes kernel io.sockets io.encodings.8-bit calendar
accessors destructors namespaces io assocs arrays qualified fry accessors destructors namespaces io assocs arrays qualified fry
continuations threads strings classes combinators continuations threads strings classes combinators splitting hashtables
irc.messages irc.messages.private ; ascii irc.messages irc.messages.private ;
RENAME: join sequences => sjoin RENAME: join sequences => sjoin
EXCLUDE: sequences => join ; EXCLUDE: sequences => join ;
IN: irc.client IN: irc.client
@ -27,7 +27,7 @@ TUPLE: irc-client profile stream in-messages out-messages join-messages
TUPLE: irc-listener in-messages out-messages ; TUPLE: irc-listener in-messages out-messages ;
TUPLE: irc-server-listener < irc-listener ; TUPLE: irc-server-listener < irc-listener ;
TUPLE: irc-channel-listener < irc-listener name password timeout ; TUPLE: irc-channel-listener < irc-listener name password timeout participants ;
TUPLE: irc-nick-listener < irc-listener name ; TUPLE: irc-nick-listener < irc-listener name ;
SYMBOL: +server-listener+ SYMBOL: +server-listener+
@ -37,10 +37,10 @@ SYMBOL: +server-listener+
<mailbox> <mailbox> irc-server-listener boa ; <mailbox> <mailbox> irc-server-listener boa ;
: <irc-channel-listener> ( name -- irc-channel-listener ) : <irc-channel-listener> ( name -- irc-channel-listener )
<mailbox> <mailbox> rot f 60 seconds irc-channel-listener boa ; [ <mailbox> <mailbox> ] dip f 60 seconds H{ } clone irc-channel-listener boa ;
: <irc-nick-listener> ( name -- irc-nick-listener ) : <irc-nick-listener> ( name -- irc-nick-listener )
<mailbox> <mailbox> rot irc-nick-listener boa ; [ <mailbox> <mailbox> ] dip irc-nick-listener boa ;
! ====================================== ! ======================================
! Message objects ! Message objects
@ -52,8 +52,8 @@ SINGLETON: irc-connected ! sent when connection is established
UNION: irc-broadcasted-message irc-end irc-disconnected irc-connected ; UNION: irc-broadcasted-message irc-end irc-disconnected irc-connected ;
: terminate-irc ( irc-client -- ) : terminate-irc ( irc-client -- )
[ in-messages>> irc-end swap mailbox-put ] [ [ irc-end ] dip in-messages>> mailbox-put ]
[ f >>is-running drop ] [ [ f ] dip (>>is-running) ]
[ stream>> dispose ] [ stream>> dispose ]
tri ; tri ;
@ -74,18 +74,27 @@ UNION: irc-broadcasted-message irc-end irc-disconnected irc-connected ;
listener> [ +server-listener+ listener> ] unless* listener> [ +server-listener+ listener> ] unless*
[ in-messages>> mailbox-put ] [ drop ] if* ; [ in-messages>> mailbox-put ] [ drop ] if* ;
: remove-participant ( nick channel -- )
listener> [ participants>> delete-at ] [ drop ] if* ;
: remove-participant-from-all ( nick -- )
irc> listeners>>
[ irc-channel-listener? [ swap remove-participant ] [ 2drop ] if ] with
assoc-each ;
: add-participant ( nick mode channel -- )
listener> [ participants>> set-at ] [ 2drop ] if* ;
DEFER: me?
: maybe-forward-join ( join -- )
[ prefix>> parse-name me? ] keep and
[ irc> join-messages>> mailbox-put ] when* ;
! ====================================== ! ======================================
! IRC client messages ! IRC client messages
! ====================================== ! ======================================
GENERIC: irc-message>string ( irc-message -- string )
M: irc-message irc-message>string ( irc-message -- string )
[ command>> ]
[ parameters>> " " sjoin ]
[ trailing>> dup [ CHAR: : prefix ] when ]
tri 3array " " sjoin ;
: /NICK ( nick -- ) : /NICK ( nick -- )
"NICK " irc-write irc-print ; "NICK " irc-write irc-print ;
@ -99,7 +108,7 @@ M: irc-message irc-message>string ( irc-message -- string )
: /JOIN ( channel password -- ) : /JOIN ( channel password -- )
"JOIN " irc-write "JOIN " irc-write
[ " :" swap 3append ] when* irc-print ; [ [ " :" ] dip 3append ] when* irc-print ;
: /PART ( channel text -- ) : /PART ( channel text -- )
[ "PART " irc-write irc-write ] dip [ "PART " irc-write irc-write ] dip
@ -153,17 +162,34 @@ M: privmsg handle-incoming-irc ( privmsg -- )
dup irc-message-origin to-listener ; dup irc-message-origin to-listener ;
M: join handle-incoming-irc ( join -- ) M: join handle-incoming-irc ( join -- )
[ [ prefix>> parse-name me? ] keep and [ maybe-forward-join ]
[ irc> join-messages>> mailbox-put ] when* ]
[ dup trailing>> to-listener ] [ dup trailing>> to-listener ]
bi ; [ [ drop f ] [ prefix>> parse-name ] [ trailing>> ] tri add-participant ]
tri ;
M: part handle-incoming-irc ( part -- ) M: part handle-incoming-irc ( part -- )
dup channel>> to-listener ; [ dup channel>> to-listener ] keep
[ prefix>> parse-name ] [ channel>> ] bi remove-participant ;
M: kick handle-incoming-irc ( kick -- ) M: kick handle-incoming-irc ( kick -- )
[ ] [ channel>> ] [ who>> ] tri me? [ dup unregister-listener ] when [ dup channel>> to-listener ]
to-listener ; [ [ who>> ] [ channel>> ] bi remove-participant ]
[ dup who>> me? [ unregister-listener ] [ drop ] if ]
tri ;
M: quit handle-incoming-irc ( quit -- )
[ prefix>> parse-name remove-participant-from-all ] keep
call-next-method ;
: >nick/mode ( string -- nick mode )
dup first "+@" member? [ unclip ] [ f ] if ;
: names-reply>participants ( names-reply -- participants )
trailing>> [ blank? ] trim " " split
[ >nick/mode 2array ] map >hashtable ;
M: names-reply handle-incoming-irc ( names-reply -- )
[ names-reply>participants ] [ channel>> listener> ] bi (>>participants) ;
M: irc-broadcasted-message handle-incoming-irc ( irc-broadcasted-message -- ) M: irc-broadcasted-message handle-incoming-irc ( irc-broadcasted-message -- )
broadcast-message-to-listeners ; broadcast-message-to-listeners ;
@ -188,8 +214,8 @@ M: part handle-outgoing-irc ( privmsg -- )
! ====================================== ! ======================================
: irc-mailbox-get ( mailbox quot -- ) : irc-mailbox-get ( mailbox quot -- )
swap 5 seconds [ 5 seconds ] dip
'[ , , , mailbox-get-timeout swap call ] '[ , , , [ mailbox-get-timeout ] dip call ]
[ drop ] recover ; inline [ drop ] recover ; inline
: handle-reader-message ( irc-message -- ) : handle-reader-message ( irc-message -- )
@ -199,11 +225,12 @@ DEFER: (connect-irc)
: (handle-disconnect) ( -- ) : (handle-disconnect) ( -- )
irc> irc>
[ in-messages>> irc-disconnected swap mailbox-put ] [ [ irc-disconnected ] dip in-messages>> mailbox-put ]
[ dup reconnect-time>> sleep (connect-irc) ] [ dup reconnect-time>> sleep (connect-irc) ]
[ profile>> nickname>> /LOGIN ] [ profile>> nickname>> /LOGIN ]
tri ; tri ;
! FIXME: do something with the exception, store somewhere to help debugging
: handle-disconnect ( error -- ) : handle-disconnect ( error -- )
drop irc> is-running>> [ (handle-disconnect) ] when ; drop irc> is-running>> [ (handle-disconnect) ] when ;
@ -275,7 +302,7 @@ M: irc-nick-listener (add-listener) ( irc-nick-listener -- )
[ name>> ] keep set+run-listener ; [ name>> ] keep set+run-listener ;
M: irc-server-listener (add-listener) ( irc-server-listener -- ) M: irc-server-listener (add-listener) ( irc-server-listener -- )
+server-listener+ swap set+run-listener ; [ +server-listener+ ] dip set+run-listener ;
GENERIC: (remove-listener) ( irc-listener -- ) GENERIC: (remove-listener) ( irc-listener -- )
@ -284,7 +311,7 @@ M: irc-nick-listener (remove-listener) ( irc-nick-listener -- )
M: irc-channel-listener (remove-listener) ( irc-channel-listener -- ) M: irc-channel-listener (remove-listener) ( irc-channel-listener -- )
[ [ out-messages>> ] [ name>> ] bi [ [ out-messages>> ] [ name>> ] bi
\ part new swap >>channel mailbox-put ] keep [ \ part new ] dip >>channel mailbox-put ] keep
name>> unregister-listener ; name>> unregister-listener ;
M: irc-server-listener (remove-listener) ( irc-server-listener -- ) M: irc-server-listener (remove-listener) ( irc-server-listener -- )
@ -294,10 +321,10 @@ M: irc-server-listener (remove-listener) ( irc-server-listener -- )
[ profile>> [ server>> ] [ port>> ] bi /CONNECT ] keep [ profile>> [ server>> ] [ port>> ] bi /CONNECT ] keep
swap >>stream swap >>stream
t >>is-running t >>is-running
in-messages>> irc-connected swap mailbox-put ; in-messages>> [ irc-connected ] dip mailbox-put ;
: with-irc-client ( irc-client quot -- ) : with-irc-client ( irc-client quot -- )
>r current-irc-client r> with-variable ; inline [ current-irc-client ] dip with-variable ; inline
PRIVATE> PRIVATE>

View File

@ -1,13 +1,15 @@
! Copyright (C) 2008 Bruno Deferrari ! Copyright (C) 2008 Bruno Deferrari
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel fry sequences splitting ascii calendar accessors combinators USING: kernel fry splitting ascii calendar accessors combinators qualified
classes.tuple math.order ; arrays classes.tuple math.order ;
RENAME: join sequences => sjoin
EXCLUDE: sequences => join ;
IN: irc.messages IN: irc.messages
TUPLE: irc-message line prefix command parameters trailing timestamp ; TUPLE: irc-message line prefix command parameters trailing timestamp ;
TUPLE: logged-in < irc-message name ; TUPLE: logged-in < irc-message name ;
TUPLE: ping < irc-message ; TUPLE: ping < irc-message ;
TUPLE: join < irc-message channel ; TUPLE: join < irc-message ;
TUPLE: part < irc-message channel ; TUPLE: part < irc-message channel ;
TUPLE: quit < irc-message ; TUPLE: quit < irc-message ;
TUPLE: privmsg < irc-message name ; TUPLE: privmsg < irc-message name ;
@ -16,8 +18,21 @@ TUPLE: roomlist < irc-message channel names ;
TUPLE: nick-in-use < irc-message asterisk name ; TUPLE: nick-in-use < irc-message asterisk name ;
TUPLE: notice < irc-message type ; TUPLE: notice < irc-message type ;
TUPLE: mode < irc-message name channel mode ; TUPLE: mode < irc-message name channel mode ;
TUPLE: names-reply < irc-message who = channel ;
TUPLE: unhandled < irc-message ; TUPLE: unhandled < irc-message ;
GENERIC: irc-message>client-line ( irc-message -- string )
M: irc-message irc-message>client-line ( irc-message -- string )
[ command>> ]
[ parameters>> " " sjoin ]
[ trailing>> dup [ CHAR: : prefix ] when ]
tri 3array " " sjoin ;
GENERIC: irc-message>server-line ( irc-message -- string )
M: irc-message irc-message>server-line ( irc-message -- string )
drop "not implemented yet" ;
<PRIVATE <PRIVATE
! ====================================== ! ======================================
! Message parsing ! Message parsing
@ -55,6 +70,7 @@ TUPLE: unhandled < irc-message ;
{ "NOTICE" [ \ notice ] } { "NOTICE" [ \ notice ] }
{ "001" [ \ logged-in ] } { "001" [ \ logged-in ] }
{ "433" [ \ nick-in-use ] } { "433" [ \ nick-in-use ] }
{ "353" [ \ names-reply ] }
{ "JOIN" [ \ join ] } { "JOIN" [ \ join ] }
{ "PART" [ \ part ] } { "PART" [ \ part ] }
{ "PRIVMSG" [ \ privmsg ] } { "PRIVMSG" [ \ privmsg ] }