]> gitweb.factorcode.org Git - factor.git/commitdiff
Conversation scope work in progress
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Thu, 10 Jul 2008 04:41:45 +0000 (23:41 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Thu, 10 Jul 2008 04:41:45 +0000 (23:41 -0500)
14 files changed:
extra/furnace/actions/actions.factor
extra/furnace/alloy/alloy.factor
extra/furnace/asides/asides.factor [deleted file]
extra/furnace/auth/auth.factor
extra/furnace/auth/basic/basic.factor
extra/furnace/auth/features/deactivate-user/deactivate-user.factor
extra/furnace/auth/features/edit-profile/edit-profile.factor
extra/furnace/auth/login/login.factor
extra/furnace/conversations/conversations.factor
extra/furnace/flash/flash.factor [deleted file]
extra/furnace/sessions/sessions.factor
extra/http/http-tests.factor
extra/http/server/redirection/redirection-tests.factor
extra/webapps/blogs/blogs.factor

index ad8a36cca5a7001b96076d69e3365d8c31ce5d4f..d42972c360e7c63cc5eec8e1d6a43fa6546238e1 100755 (executable)
@@ -7,7 +7,8 @@ xml.entities
 http.server\r
 http.server.responses\r
 furnace\r
-furnace.flash\r
+furnace.redirection\r
+furnace.conversations\r
 html.forms\r
 html.elements\r
 html.components\r
@@ -38,20 +39,23 @@ TUPLE: action rest authorize init display validate submit ;
 : <action> ( -- action )\r
     action new-action ;\r
 \r
+: merge-forms ( form -- )\r
+    form get\r
+    [ [ errors>> ] bi@ push-all ]\r
+    [ [ values>> ] bi@ swap update ]\r
+    [ swap validation-failed>> >>validation-failed drop ]\r
+    2tri ;\r
+\r
 : set-nested-form ( form name -- )\r
     dup empty? [\r
-        drop form set\r
+        drop merge-forms\r
     ] [\r
-        dup length 1 = [\r
-            first set-value\r
-        ] [\r
-            unclip [ set-nested-form ] nest-form\r
-        ] if\r
+        unclip [ set-nested-form ] nest-form\r
     ] if ;\r
 \r
 : restore-validation-errors ( -- )\r
-    form fget [\r
-        nested-forms fget set-nested-form\r
+    form cget [\r
+        nested-forms cget set-nested-form\r
     ] when* ;\r
 \r
 : handle-get ( action -- response )\r
@@ -75,11 +79,13 @@ TUPLE: action rest authorize init display validate submit ;
     revalidate-url-key param\r
     dup [ >url [ same-host? ] keep and ] when ;\r
 \r
-: validation-failed ( flashed -- * )\r
-    post-request? revalidate-url and dup [\r
-        nested-forms-key param " " split harvest nested-forms set\r
-        swap { form nested-forms } append <flash-redirect>\r
-    ] [ 2drop <400> ] if\r
+: validation-failed ( -- * )\r
+    post-request? revalidate-url and [\r
+        begin-conversation\r
+        nested-forms-key param " " split harvest nested-forms cset\r
+        form get form cset\r
+        <redirect>\r
+    ] [ <400> ] if*\r
     exit-with ;\r
 \r
 : handle-post ( action -- response )\r
@@ -112,7 +118,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 28c34e6715c44782fc1a0c2c6313e6618f35f750..29cb37b557d79eb17a6683d2480fc3b3aa8f6c9a 100644 (file)
@@ -1,26 +1,24 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences db.tuples alarms calendar db fry
+furnace.db
 furnace.cache
-furnace.asides
-furnace.flash
-furnace.sessions
 furnace.referrer
-furnace.db
+furnace.sessions
+furnace.conversations
 furnace.auth.providers
 furnace.auth.login.permits ;
 IN: furnace.alloy
 
 : <alloy> ( responder db params -- responder' )
     '[
-        <asides>
-        <flash-scopes>
+        <conversations>
         <sessions>
         , , <db-persistence>
         <check-form-submissions>
     ] call ;
 
-: state-classes { session flash-scope aside permit } ; inline
+: state-classes { session conversation permit } ; inline
 
 : init-furnace-tables ( -- )
     state-classes ensure-tables
diff --git a/extra/furnace/asides/asides.factor b/extra/furnace/asides/asides.factor
deleted file mode 100644 (file)
index 6d41c63..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-! Copyright (C) 2008 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors namespaces sequences arrays kernel
-assocs hashtables math.parser urls combinators
-logging db.types db.tuples
-html.elements
-html.templates.chloe.syntax
-http
-http.server
-http.server.filters 
-furnace
-furnace.cache
-furnace.sessions
-furnace.redirection ;
-IN: furnace.asides
-
-TUPLE: aside < server-state session method url post-data ;
-
-: <aside> ( id -- aside )
-    aside new-server-state ;
-
-aside "ASIDES"
-{
-    { "session" "SESSION" BIG-INTEGER +not-null+ }
-    { "method" "METHOD" { VARCHAR 10 } +not-null+ }
-    { "url" "URL" URL +not-null+ }
-    { "post-data" "POST_DATA" FACTOR-BLOB }
-} define-persistent
-
-TUPLE: asides < server-state-manager ;
-
-: <asides> ( responder -- responder' )
-    asides new-server-state-manager ;
-
-: begin-aside* ( -- id )
-    f <aside>
-        session get id>> >>session
-        request get
-        [ method>> >>method ]
-        [ url>> >>url ]
-        [ post-data>> >>post-data ]
-        tri
-    [ asides get touch-state ] [ insert-tuple ] [ id>> ] tri ;
-
-: end-aside-post ( aside -- response )
-    request [
-        clone
-            over post-data>> >>post-data
-            over url>> >>url
-    ] change
-    url>> path>> split-path
-    asides get responder>> call-responder ;
-
-\ end-aside-post DEBUG add-input-logging
-
-ERROR: end-aside-in-get-error ;
-
-: get-aside ( id -- aside )
-    dup [ aside get-state ] when
-    dup [ dup session>> session get id>> = [ drop f ] unless ] when ;
-
-: end-aside* ( url id -- response )
-    post-request? [ end-aside-in-get-error ] unless
-    aside get-state [
-        dup method>> {
-            { "GET" [ url>> <redirect> ] }
-            { "HEAD" [ url>> <redirect> ] }
-            { "POST" [ end-aside-post ] }
-        } case
-    ] [ <redirect> ] ?if ;
-
-SYMBOL: aside-id
-
-: aside-id-key "__a" ;
-
-: begin-aside ( -- )
-    begin-aside* aside-id set ;
-
-: end-aside ( default -- response )
-    aside-id [ f ] change end-aside* ;
-
-: request-aside-id ( request -- aside-id )
-    aside-id-key swap request-params at string>number ;
-
-M: asides call-responder*
-    dup asides set
-    request get request-aside-id aside-id set
-    call-next-method ;
-
-M: asides link-attr ( tag -- )
-    drop
-    "aside" optional-attr {
-        { "none" [ aside-id off ] }
-        { "begin" [ begin-aside ] }
-        { "current" [ ] }
-        { f [ ] }
-    } case ;
-
-M: asides modify-query ( query responder -- query' )
-    drop
-    aside-id get [ aside-id-key associate assoc-union ] when* ;
-
-M: asides modify-form ( responder -- )
-    drop aside-id get aside-id-key hidden-form-field ;
index 4fae10c30dd0a5ddabe60acfa9622af16fa1a188..4487759719e563f1a0eb567db02fe5259c2044e7 100755 (executable)
@@ -58,13 +58,14 @@ V{ } clone capabilities set-global
 \r
 TUPLE: realm < dispatcher name users checksum secure ;\r
 \r
-GENERIC: login-required* ( realm -- response )\r
+GENERIC: login-required* ( description capabilities realm -- response )\r
 \r
 GENERIC: init-realm ( realm -- )\r
 \r
 GENERIC: logged-in-username ( realm -- username )\r
 \r
-: login-required ( -- * ) realm get login-required* exit-with ;\r
+: login-required ( description capabilities -- * )\r
+    realm get login-required* exit-with ;\r
 \r
 : new-realm ( responder name class -- realm )\r
     new-dispatcher\r
@@ -144,7 +145,10 @@ M: protected call-responder* ( path responder -- response )
         , ,\r
         dup protected set\r
         dup capabilities>> have-capabilities?\r
-        [ call-next-method ] [ 2drop realm get login-required* ] if\r
+        [ call-next-method ] [\r
+            [ drop ] [ [ description>> ] [ capabilities>> ] bi ] bi*\r
+            realm get login-required*\r
+        ] if\r
     ] if-secure-realm ;\r
 \r
 : <auth-boilerplate> ( responder -- responder' )\r
@@ -152,7 +156,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 +164,4 @@ M: protected call-responder* ( path responder -- response )
 \r
 : user-exists ( -- * )\r
     "username taken" validation-error\r
-    { } validation-failed ;\r
+    validation-failed ;\r
index e478f70dcca7fdf2a90450d0b9f470dd6ecbf743..ff3c302b40addc7d4d5f59e205b424cd2cad21de 100755 (executable)
@@ -20,8 +20,8 @@ TUPLE: basic-auth-realm < realm ;
     401 "Invalid username or password" <trivial-response>\r
     [ "Basic realm=\"" % swap % "\"" % ] "" make "WWW-Authenticate" set-header ;\r
 \r
-M: basic-auth-realm login-required* ( realm -- response )\r
-    name>> <401> ;\r
+M: basic-auth-realm login-required* ( description capabilities realm -- response )\r
+    2nip name>> <401> ;\r
 \r
 M: basic-auth-realm logged-in-username ( realm -- uid )\r
     drop\r
index cf6a56c2d4ca327a40d904ee2bd35549ff1b1df5..43560d021c28006477492a53694330322714bfd9 100644 (file)
@@ -2,7 +2,10 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel assocs namespaces accessors db db.tuples urls
 http.server.dispatchers
-furnace.asides furnace.actions furnace.auth furnace.auth.providers ;
+furnace.conversations
+furnace.actions
+furnace.auth
+furnace.auth.providers ;
 IN: furnace.auth.features.deactivate-user
 
 : <deactivate-user-action> ( -- action )
index da6acece61cd04e8644a594558770b759ed5ec8d..fb4fbb898fd061348084255fa6c0fdb28c180fce 100644 (file)
@@ -1,12 +1,10 @@
 ! Copyright (c) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors namespaces sequences assocs
-validators urls
-html.forms
-http.server.dispatchers
+validators urls html.forms http.server.dispatchers
 furnace.auth
-furnace.asides
-furnace.actions ;
+furnace.actions
+furnace.conversations ;
 IN: furnace.auth.features.edit-profile
 
 : <edit-profile-action> ( -- action )
@@ -54,7 +52,7 @@ IN: furnace.auth.features.edit-profile
 
             drop
 
-            URL" $login" end-aside
+            URL" $realm" end-aside
         ] >>submit
 
     <protected>
index f2ac81c0667995d78625a700d77d4aaf607b7ac8..1a4477023d6e32b2f3e7d5ff0d45431456c35479 100755 (executable)
@@ -5,12 +5,11 @@ calendar validators urls logging html.forms
 http http.server http.server.dispatchers\r
 furnace\r
 furnace.auth\r
-furnace.flash\r
-furnace.asides\r
 furnace.actions\r
 furnace.sessions\r
 furnace.utilities\r
 furnace.redirection\r
+furnace.conversations\r
 furnace.auth.login.permits ;\r
 IN: furnace.auth.login\r
 \r
@@ -65,14 +64,13 @@ SYMBOL: capabilities
 \r
 : login-failed ( -- * )\r
     "invalid username or password" validation-error\r
-    flashed-variables validation-failed ;\r
+    validation-failed ;\r
 \r
 : <login-action> ( -- action )\r
     <page-action>\r
         [\r
-            flashed-variables restore-flash\r
-            description get "description" set-value\r
-            capabilities get words>strings "capabilities" set-value\r
+            description cget "description" set-value\r
+            capabilities cget words>strings "capabilities" set-value\r
         ] >>init\r
 \r
         { login-realm "login" } >>template\r
@@ -92,16 +90,12 @@ SYMBOL: capabilities
 \r
 : <logout-action> ( -- action )\r
     <action>\r
-        [ logout ] >>submit\r
-    <protected>\r
-        "logout" >>description ;\r
+        [ logout ] >>submit ;\r
 \r
-M: login-realm login-required*\r
-    drop\r
+M: login-realm login-required* ( description capabilities login -- response )\r
     begin-aside\r
-    protected get description>> description set\r
-    protected get capabilities>> capabilities set\r
-    URL" $realm/login" >secure-url flashed-variables <flash-redirect> ;\r
+    [ description cset ] [ capabilities cset ] [ drop ] tri*\r
+    URL" $realm/login" >secure-url <redirect> ;\r
 \r
 : <login-realm> ( responder name -- auth )\r
     login-realm new-realm\r
index cbc4e4b2333bdfc411702c5aa2fd62cf446ce281..72169781107c3725a2b22e272c12f7707dd9018c 100644 (file)
@@ -25,7 +25,7 @@ conversation "CONVERSATIONS" {
     { "post-data" "POST_DATA" FACTOR-BLOB }
 } define-persistent
 
-: conversation-id-key "__f" ;
+: conversation-id-key "__c" ;
 
 TUPLE: conversations < server-state-manager ;
 
@@ -55,28 +55,51 @@ SYMBOL: conversation-id
 : request-conversation ( request -- conversation )
     request-conversation-id get-conversation ;
 
-: init-conversations ( -- )
+: 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
     request get request-conversation-id
-    [ conversation-id set ]
-    [ get-conversation conversation set ]
-    bi ;
+    get-conversation
+    set-conversation ;
 
 M: conversations call-responder*
-    init-conversations
-    [ conversations set ] [ call-next-method ] bi ;
+    [ init-conversations ]
+    [ conversations set ]
+    [ call-next-method ]
+    tri ;
 
 : empty-conversastion ( -- conversation )
     conversation empty-scope
         session get id>> >>session ;
 
-: add-conversation ( conversation -- id )
-    [ conversations get touch-state ] [ insert-tuple ] [ id>> ] tri ;
+: touch-conversation ( conversation -- )
+    conversations get touch-state ;
 
-: begin-conversation* ( -- id )
-    empty-conversastion add-conversation ;
+: add-conversation ( conversation -- )
+    [ touch-conversation ] [ insert-tuple ] bi ;
+
+: begin-conversation* ( -- conversation )
+    empty-conversastion dup add-conversation ;
 
 : begin-conversation ( -- )
-    conversation-id [ [ begin-conversation* ] unless* ] change ;
+    conversation get [
+        begin-conversation*
+        set-conversation
+    ] unless ;
+
+: end-conversation ( -- )
+    conversation off
+    conversation-id off ;
 
 : <conversation-redirect> ( url seq -- response )
     begin-conversation
@@ -91,17 +114,15 @@ M: conversations call-responder*
         bi
     ] [ 2drop ] if ;
 
-: begin-aside* ( -- id )
-    empty-conversastion
+: begin-aside ( -- )
+    begin-conversation
+    conversation get
         request get
         [ method>> >>method ]
         [ url>> >>url ]
         [ post-data>> >>post-data ]
         tri
-    add-conversation ;
-
-: begin-aside ( -- )
-    begin-aside* conversation-id set ;
+    touch-conversation ;
 
 : end-aside-post ( aside -- response )
     request [
@@ -116,18 +137,24 @@ M: conversations call-responder*
 
 ERROR: end-aside-in-get-error ;
 
-: end-aside* ( url id -- response )
+: move-on ( 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 ;
+    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 ;
 
 : end-aside ( default -- response )
-    conversation-id [ f ] change end-aside* ;
+    conversation-id get
+    end-conversation
+    end-aside* ;
 
 M: conversations link-attr ( tag -- )
     drop
diff --git a/extra/furnace/flash/flash.factor b/extra/furnace/flash/flash.factor
deleted file mode 100644 (file)
index 16d6148..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-! Copyright (C) 2008 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: namespaces assocs kernel sequences accessors
-urls db.types db.tuples math.parser fry
-http http.server http.server.filters http.server.redirection
-furnace furnace.cache furnace.sessions furnace.redirection ;
-IN: furnace.flash
-
-TUPLE: flash-scope < server-state session namespace ;
-
-: <flash-scope> ( id -- aside )
-    flash-scope new-server-state ;
-
-flash-scope "FLASH_SCOPES" {
-    { "session" "SESSION" BIG-INTEGER +not-null+ }
-    { "namespace" "NAMESPACE" FACTOR-BLOB +not-null+ }
-} define-persistent
-
-: flash-id-key "__f" ;
-
-TUPLE: flash-scopes < server-state-manager ;
-
-: <flash-scopes> ( responder -- responder' )
-    flash-scopes new-server-state-manager ;
-
-SYMBOL: flash-scope
-
-: fget ( key -- value )
-    flash-scope get dup
-    [ namespace>> at ] [ 2drop f ] if ;
-
-: get-flash-scope ( id -- flash-scope )
-    dup [ flash-scope get-state ] when
-    dup [ dup session>> session get id>> = [ drop f ] unless ] when ;
-
-: request-flash-scope ( request -- flash-scope )
-    flash-id-key swap request-params at string>number get-flash-scope ;
-
-M: flash-scopes call-responder*
-    dup flash-scopes set
-    request get request-flash-scope flash-scope set
-    call-next-method ;
-
-: make-flash-scope ( seq -- id )
-    f <flash-scope>
-        session get id>> >>session
-        swap [ dup get ] H{ } map>assoc >>namespace
-    [ flash-scopes get touch-state ] [ insert-tuple ] [ id>> ] tri ;
-
-: <flash-redirect> ( url seq -- response )
-    [ clone ] dip
-    make-flash-scope flash-id-key set-query-param
-    <redirect> ;
-
-: restore-flash ( seq -- )
-    flash-scope get dup [
-        namespace>>
-        [ '[ , key? ] filter ]
-        [ '[ [ , at ] keep set ] each ]
-        bi
-    ] [ 2drop ] if ;
index 3aafadaf68d028c69e347687d0521c7aadac3e5b..718953c58ce24f0206962550b312253dbe643ed8 100755 (executable)
@@ -69,7 +69,7 @@ TUPLE: sessions < server-state-manager domain verify? ;
     empty-session [ init-session ] [ insert-tuple ] [ ] tri ;
 
 : save-session-after ( session -- )
-    sessions get <scope-saver> &dispose drop ;
+    sessions get save-scope-after ;
 
 : existing-session ( path session -- response )
     [ session set ] [ save-session-after ] bi
index 52ae9c3e38a8228a79fded93b354646638e3c89e..bbf8161dd7dbe1d1e0d976e718b25686fc66391e 100755 (executable)
@@ -275,7 +275,7 @@ test-db [
 
 USING: html.components html.elements html.forms
 xml xml.utilities validators
-furnace furnace.flash ;
+furnace furnace.conversations ;
 
 SYMBOL: a
 
@@ -287,7 +287,7 @@ SYMBOL: a
                 [ [ <html> "a" <field> render </html> ] "text/html" <content> ] >>display
                 [ { { "a" [ v-integer ] } } validate-params ] >>validate
                 [ "a" value a set-global URL" " <redirect> ] >>submit
-            <flash-scopes>
+            <conversations>
             <sessions>
             >>default
             add-quit-action
index 04af89ec98f300aadc372fbab378de0ea7ae73af..c7a13703978711d58f16fc099b5badb6426af67d 100644 (file)
@@ -1,6 +1,6 @@
 IN: http.server.redirection.tests
 USING: http http.server.redirection urls accessors
-namespaces tools.test present ;
+namespaces tools.test present kernel ;
 
 \ relative-to-request must-infer
 
@@ -11,6 +11,7 @@ namespaces tools.test present ;
             "www.apple.com" >>host
             "/xxx/bar" >>path
             { { "a" "b" } } >>query
+        dup url set
         >>url
     request set
 
index 972c09f9b8143f4299facc69829e7a2aad5ba896..2858ad21f39e3bce9dac5ab58fa1534b6e3f5fb5 100644 (file)
@@ -179,7 +179,7 @@ M: comment entity-url
 : authorize-author ( author -- )
     username =
     { can-administer-blogs? } have-capabilities? or
-    [ login-required ] unless ;
+    [ "edit a blog post" f login-required ] unless ;
 
 : do-post-action ( -- )
     validate-integer-id