]> gitweb.factorcode.org Git - factor.git/commitdiff
Working on conversation scope to supercede asides and flash scopes
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Thu, 10 Jul 2008 00:48:40 +0000 (19:48 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Thu, 10 Jul 2008 00:48:40 +0000 (19:48 -0500)
extra/furnace/actions/actions.factor
extra/furnace/auth/auth.factor
extra/furnace/auth/login/login.factor
extra/furnace/conversations/conversations.factor [new file with mode: 0644]
extra/furnace/scopes/scopes.factor [new file with mode: 0644]
extra/furnace/sessions/sessions.factor

index 6448fcdf07c3ff0355cb6d04f1e451a029f2a2a6..ad8a36cca5a7001b96076d69e3365d8c31ce5d4f 100755 (executable)
@@ -75,12 +75,11 @@ TUPLE: action rest authorize init display validate submit ;
     revalidate-url-key param\r
     dup [ >url [ same-host? ] keep and ] when ;\r
 \r
-: validation-failed ( -- * )\r
-    post-request? revalidate-url and\r
-    [\r
+: validation-failed ( flashed -- * )\r
+    post-request? revalidate-url and dup [\r
         nested-forms-key param " " split harvest nested-forms set\r
-        { form nested-forms } <flash-redirect>\r
-    ] [ <400> ] if*\r
+        swap { form nested-forms } append <flash-redirect>\r
+    ] [ 2drop <400> ] if\r
     exit-with ;\r
 \r
 : handle-post ( action -- response )\r
@@ -113,7 +112,7 @@ M: action modify-form
     drop url get revalidate-url-key hidden-form-field ;\r
 \r
 : check-validation ( -- )\r
-    validation-failed? [ validation-failed ] when ;\r
+    validation-failed? [ { } validation-failed ] when ;\r
 \r
 : validate-params ( validators -- )\r
     params get swap validate-values check-validation ;\r
index 0c21c9f18d41f153bf83515e06daa7dcf4fe6efa..4fae10c30dd0a5ddabe60acfa9622af16fa1a188 100755 (executable)
@@ -152,7 +152,7 @@ M: protected call-responder* ( path responder -- response )
 \r
 : password-mismatch ( -- * )\r
     "passwords do not match" validation-error\r
-    validation-failed ;\r
+    { } validation-failed ;\r
 \r
 : same-password-twice ( -- )\r
     "new-password" value "verify-password" value =\r
@@ -160,4 +160,4 @@ M: protected call-responder* ( path responder -- response )
 \r
 : user-exists ( -- * )\r
     "username taken" validation-error\r
-    validation-failed ;\r
+    { } validation-failed ;\r
index 9246780a94c447782946c1cdaef45f71d99a9ef7..f2ac81c0667995d78625a700d77d4aaf607b7ac8 100755 (executable)
@@ -65,7 +65,7 @@ SYMBOL: capabilities
 \r
 : login-failed ( -- * )\r
     "invalid username or password" validation-error\r
-    validation-failed ;\r
+    flashed-variables validation-failed ;\r
 \r
 : <login-action> ( -- action )\r
     <page-action>\r
diff --git a/extra/furnace/conversations/conversations.factor b/extra/furnace/conversations/conversations.factor
new file mode 100644 (file)
index 0000000..cbc4e4b
--- /dev/null
@@ -0,0 +1,151 @@
+! 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
+
+: conversation-id-key "__f" ;
+
+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 ;
+
+: init-conversations ( -- )
+    request get request-conversation-id
+    [ conversation-id set ]
+    [ get-conversation conversation set ]
+    bi ;
+
+M: conversations call-responder*
+    init-conversations
+    [ conversations set ] [ call-next-method ] bi ;
+
+: empty-conversastion ( -- conversation )
+    conversation empty-scope
+        session get id>> >>session ;
+
+: add-conversation ( conversation -- id )
+    [ conversations get touch-state ] [ insert-tuple ] [ id>> ] tri ;
+
+: begin-conversation* ( -- id )
+    empty-conversastion add-conversation ;
+
+: begin-conversation ( -- )
+    conversation-id [ [ begin-conversation* ] unless* ] change ;
+
+: <conversation-redirect> ( url seq -- response )
+    begin-conversation
+    [ [ get ] keep cset ] each
+    <redirect> ;
+
+: restore-conversation ( seq -- )
+    conversation get dup [
+        namespace>>
+        [ '[ , key? ] filter ]
+        [ '[ [ , at ] keep set ] each ]
+        bi
+    ] [ 2drop ] if ;
+
+: begin-aside* ( -- id )
+    empty-conversastion
+        request get
+        [ method>> >>method ]
+        [ url>> >>url ]
+        [ post-data>> >>post-data ]
+        tri
+    add-conversation ;
+
+: begin-aside ( -- )
+    begin-aside* conversation-id set ;
+
+: end-aside-post ( aside -- response )
+    request [
+        clone
+            over post-data>> >>post-data
+            over url>> >>url
+    ] change
+    url>> path>> split-path
+    conversations get responder>> call-responder ;
+
+\ end-aside-post DEBUG add-input-logging
+
+ERROR: end-aside-in-get-error ;
+
+: end-aside* ( url id -- response )
+    post-request? [ end-aside-in-get-error ] unless
+    get-conversation [
+        dup method>> {
+            { "GET" [ url>> <redirect> ] }
+            { "HEAD" [ url>> <redirect> ] }
+            { "POST" [ end-aside-post ] }
+        } case
+    ] [ <redirect> ] ?if ;
+
+: end-aside ( default -- response )
+    conversation-id [ f ] change end-aside* ;
+
+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 ;
diff --git a/extra/furnace/scopes/scopes.factor b/extra/furnace/scopes/scopes.factor
new file mode 100644 (file)
index 0000000..daad0dc
--- /dev/null
@@ -0,0 +1,42 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel accessors assocs destructors
+db.tuples db.types furnace.cache ;
+IN: furnace.scopes
+
+TUPLE: scope < server-state namespace changed? ;
+
+: empty-scope ( class -- scope )
+    f swap new-server-state
+        H{ } clone >>namespace ; inline
+
+scope f
+{
+    { "namespace" "NAMESPACE" FACTOR-BLOB +not-null+ }
+} define-persistent
+
+: scope-changed ( scope -- )
+    t >>changed? drop ;
+
+: scope-get ( key scope -- value )
+    dup [ namespace>> at ] [ 2drop f ] if ;
+
+: scope-set ( value key scope -- )
+    [ namespace>> set-at ] [ scope-changed ] bi ;
+
+: scope-change ( key quot scope -- )
+    [ namespace>> swap change-at ] [ scope-changed ] bi ; inline
+
+! Destructor
+TUPLE: scope-saver scope manager ;
+
+C: <scope-saver> scope-saver
+
+M: scope-saver dispose
+    [ manager>> ] [ scope>> ] bi
+    dup changed?>> [
+        [ swap touch-state ] [ update-tuple ] bi
+    ] [ 2drop ] if ;
+
+: save-scope-after ( scope manager -- )
+    <scope-saver> &dispose drop ;
index 31711f54e9e2804d0b58f5c9eeeb7837c911655a..3aafadaf68d028c69e347687d0521c7aadac3e5b 100755 (executable)
@@ -7,17 +7,16 @@ io.servers.connection
 db db.tuples db.types
 http http.server http.server.dispatchers http.server.filters
 html.elements
-furnace furnace.cache ;
+furnace furnace.cache furnace.scopes ;
 IN: furnace.sessions
 
-TUPLE: session < server-state namespace user-agent client changed? ;
+TUPLE: session < scope user-agent client ;
 
 : <session> ( id -- session )
     session new-server-state ;
 
 session "SESSIONS"
 {
-    { "namespace" "NAMESPACE" FACTOR-BLOB +not-null+ }
     { "user-agent" "USER_AGENT" TEXT +not-null+ }
     { "client" "CLIENT" TEXT +not-null+ }
 } define-persistent
@@ -39,23 +38,14 @@ TUPLE: sessions < server-state-manager domain verify? ;
     sessions new-server-state-manager
         t >>verify? ;
 
-: (session-changed) ( session -- )
-    t >>changed? drop ;
-
 : session-changed ( -- )
-    session get (session-changed) ;
+    session get scope-changed ;
 
-: sget ( key -- value )
-    session get namespace>> at ;
+: sget ( key -- value ) session get scope-get ;
 
-: sset ( value key -- )
-    session get
-    [ namespace>> set-at ] [ (session-changed) ] bi ;
+: sset ( value key -- ) session get scope-set ;
 
-: schange ( key quot -- )
-    session get
-    [ namespace>> swap change-at ] keep
-    (session-changed) ; inline
+: schange ( key quot -- ) session get scope-change ; inline
 
 : init-session ( session -- )
     session [ sessions get init-session* ] with-variable ;
@@ -70,8 +60,7 @@ TUPLE: sessions < server-state-manager domain verify? ;
     } 0|| ;
 
 : empty-session ( -- session )
-    f <session>
-        H{ } clone >>namespace
+    session empty-scope
         remote-host >>client
         user-agent >>user-agent
         dup touch-session ;
@@ -79,18 +68,8 @@ TUPLE: sessions < server-state-manager domain verify? ;
 : begin-session ( -- session )
     empty-session [ init-session ] [ insert-tuple ] [ ] tri ;
 
-! Destructor
-TUPLE: session-saver session ;
-
-C: <session-saver> session-saver
-
-M: session-saver dispose
-    session>> dup changed?>> [
-        [ touch-session ] [ update-tuple ] bi
-    ] [ drop ] if ;
-
 : save-session-after ( session -- )
-    <session-saver> &dispose drop ;
+    sessions get <scope-saver> &dispose drop ;
 
 : existing-session ( path session -- response )
     [ session set ] [ save-session-after ] bi