2008-07-09 20:48:40 -04:00
|
|
|
! Copyright (C) 2008 Slava Pestov.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
USING: namespaces assocs kernel sequences accessors hashtables
|
|
|
|
urls db.types db.tuples math.parser fry logging combinators
|
|
|
|
html.templates.chloe.syntax
|
|
|
|
http http.server http.server.filters http.server.redirection
|
|
|
|
furnace
|
|
|
|
furnace.cache
|
|
|
|
furnace.scopes
|
|
|
|
furnace.sessions
|
|
|
|
furnace.redirection ;
|
|
|
|
IN: furnace.conversations
|
|
|
|
|
|
|
|
TUPLE: conversation < scope
|
|
|
|
session
|
|
|
|
method url post-data ;
|
|
|
|
|
|
|
|
: <conversation> ( id -- aside )
|
|
|
|
conversation new-server-state ;
|
|
|
|
|
|
|
|
conversation "CONVERSATIONS" {
|
|
|
|
{ "session" "SESSION" BIG-INTEGER +not-null+ }
|
|
|
|
{ "method" "METHOD" { VARCHAR 10 } }
|
|
|
|
{ "url" "URL" URL }
|
|
|
|
{ "post-data" "POST_DATA" FACTOR-BLOB }
|
|
|
|
} define-persistent
|
|
|
|
|
2008-07-10 00:41:45 -04:00
|
|
|
: conversation-id-key "__c" ;
|
2008-07-09 20:48:40 -04:00
|
|
|
|
|
|
|
TUPLE: conversations < server-state-manager ;
|
|
|
|
|
|
|
|
: <conversations> ( responder -- responder' )
|
|
|
|
conversations new-server-state-manager ;
|
|
|
|
|
|
|
|
SYMBOL: conversation
|
|
|
|
|
|
|
|
SYMBOL: conversation-id
|
|
|
|
|
|
|
|
: cget ( key -- value )
|
|
|
|
conversation get scope-get ;
|
|
|
|
|
|
|
|
: cset ( value key -- )
|
|
|
|
conversation get scope-set ;
|
|
|
|
|
|
|
|
: cchange ( key quot -- )
|
|
|
|
conversation get scope-change ; inline
|
|
|
|
|
|
|
|
: get-conversation ( id -- conversation )
|
|
|
|
dup [ conversation get-state ] when
|
|
|
|
dup [ dup session>> session get id>> = [ drop f ] unless ] when ;
|
|
|
|
|
|
|
|
: request-conversation-id ( request -- id )
|
|
|
|
conversation-id-key swap request-params at string>number ;
|
|
|
|
|
|
|
|
: request-conversation ( request -- conversation )
|
|
|
|
request-conversation-id get-conversation ;
|
|
|
|
|
2008-07-10 00:41:45 -04:00
|
|
|
: save-conversation-after ( conversation -- )
|
|
|
|
conversations get save-scope-after ;
|
|
|
|
|
|
|
|
: set-conversation ( conversation -- )
|
|
|
|
[
|
|
|
|
[ conversation set ]
|
|
|
|
[ id>> conversation-id set ]
|
|
|
|
[ save-conversation-after ]
|
|
|
|
tri
|
|
|
|
] when* ;
|
|
|
|
|
|
|
|
: init-conversations ( conversations -- )
|
|
|
|
conversations set
|
2008-07-09 20:48:40 -04:00
|
|
|
request get request-conversation-id
|
2008-07-10 00:41:45 -04:00
|
|
|
get-conversation
|
|
|
|
set-conversation ;
|
2008-07-09 20:48:40 -04:00
|
|
|
|
|
|
|
M: conversations call-responder*
|
2008-07-10 00:41:45 -04:00
|
|
|
[ init-conversations ]
|
|
|
|
[ conversations set ]
|
|
|
|
[ call-next-method ]
|
|
|
|
tri ;
|
2008-07-09 20:48:40 -04:00
|
|
|
|
|
|
|
: empty-conversastion ( -- conversation )
|
|
|
|
conversation empty-scope
|
|
|
|
session get id>> >>session ;
|
|
|
|
|
2008-07-10 00:41:45 -04:00
|
|
|
: touch-conversation ( conversation -- )
|
|
|
|
conversations get touch-state ;
|
2008-07-09 20:48:40 -04:00
|
|
|
|
2008-07-10 00:41:45 -04:00
|
|
|
: add-conversation ( conversation -- )
|
|
|
|
[ touch-conversation ] [ insert-tuple ] bi ;
|
|
|
|
|
|
|
|
: begin-conversation* ( -- conversation )
|
|
|
|
empty-conversastion dup add-conversation ;
|
2008-07-09 20:48:40 -04:00
|
|
|
|
|
|
|
: begin-conversation ( -- )
|
2008-07-10 00:41:45 -04:00
|
|
|
conversation get [
|
|
|
|
begin-conversation*
|
|
|
|
set-conversation
|
|
|
|
] unless ;
|
|
|
|
|
|
|
|
: end-conversation ( -- )
|
|
|
|
conversation off
|
|
|
|
conversation-id off ;
|
2008-07-09 20:48:40 -04:00
|
|
|
|
|
|
|
: <conversation-redirect> ( url seq -- response )
|
|
|
|
begin-conversation
|
|
|
|
[ [ get ] keep cset ] each
|
|
|
|
<redirect> ;
|
|
|
|
|
|
|
|
: restore-conversation ( seq -- )
|
|
|
|
conversation get dup [
|
|
|
|
namespace>>
|
2008-09-10 23:11:40 -04:00
|
|
|
[ '[ _ key? ] filter ]
|
|
|
|
[ '[ [ _ at ] keep set ] each ]
|
2008-07-09 20:48:40 -04:00
|
|
|
bi
|
|
|
|
] [ 2drop ] if ;
|
|
|
|
|
2008-07-10 00:41:45 -04:00
|
|
|
: begin-aside ( -- )
|
|
|
|
begin-conversation
|
|
|
|
conversation get
|
2008-07-09 20:48:40 -04:00
|
|
|
request get
|
|
|
|
[ method>> >>method ]
|
|
|
|
[ url>> >>url ]
|
|
|
|
[ post-data>> >>post-data ]
|
|
|
|
tri
|
2008-07-10 00:41:45 -04:00
|
|
|
touch-conversation ;
|
2008-07-09 20:48:40 -04:00
|
|
|
|
|
|
|
: end-aside-post ( aside -- response )
|
|
|
|
request [
|
|
|
|
clone
|
|
|
|
over post-data>> >>post-data
|
|
|
|
over url>> >>url
|
|
|
|
] change
|
2008-09-08 02:11:09 -04:00
|
|
|
[ url>> url set ]
|
|
|
|
[ url>> path>> split-path ] bi
|
2008-07-09 20:48:40 -04:00
|
|
|
conversations get responder>> call-responder ;
|
|
|
|
|
|
|
|
\ end-aside-post DEBUG add-input-logging
|
|
|
|
|
|
|
|
ERROR: end-aside-in-get-error ;
|
|
|
|
|
2008-07-10 00:41:45 -04:00
|
|
|
: move-on ( id -- response )
|
2008-07-09 20:48:40 -04:00
|
|
|
post-request? [ end-aside-in-get-error ] unless
|
2008-07-10 00:41:45 -04:00
|
|
|
dup method>> {
|
|
|
|
{ "GET" [ url>> <redirect> ] }
|
|
|
|
{ "HEAD" [ url>> <redirect> ] }
|
|
|
|
{ "POST" [ end-aside-post ] }
|
|
|
|
} case ;
|
|
|
|
|
|
|
|
: get-aside ( id -- conversation )
|
|
|
|
get-conversation dup [ dup method>> [ drop f ] unless ] when ;
|
|
|
|
|
|
|
|
: end-aside* ( url id -- response )
|
|
|
|
get-aside [ move-on ] [ <redirect> ] ?if ;
|
2008-07-09 20:48:40 -04:00
|
|
|
|
|
|
|
: end-aside ( default -- response )
|
2008-07-10 00:41:45 -04:00
|
|
|
conversation-id get
|
|
|
|
end-conversation
|
|
|
|
end-aside* ;
|
2008-07-09 20:48:40 -04:00
|
|
|
|
|
|
|
M: conversations link-attr ( tag -- )
|
|
|
|
drop
|
|
|
|
"aside" optional-attr {
|
|
|
|
{ "none" [ conversation-id off ] }
|
|
|
|
{ "begin" [ begin-aside ] }
|
|
|
|
{ "current" [ ] }
|
|
|
|
{ f [ ] }
|
|
|
|
} case ;
|
|
|
|
|
|
|
|
M: conversations modify-query ( query conversations -- query' )
|
|
|
|
drop
|
|
|
|
conversation-id get [
|
|
|
|
conversation-id-key associate assoc-union
|
|
|
|
] when* ;
|
|
|
|
|
|
|
|
M: conversations modify-form ( conversations -- )
|
|
|
|
drop
|
|
|
|
conversation-id get
|
|
|
|
conversation-id-key
|
|
|
|
hidden-form-field ;
|