]> gitweb.factorcode.org Git - factor.git/commitdiff
Wiki
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 27 May 2008 05:02:16 +0000 (00:02 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 27 May 2008 05:02:16 +0000 (00:02 -0500)
extra/lcs/diff2html/diff2html.factor [new file with mode: 0644]
extra/webapps/factor-website/factor-website.factor
extra/webapps/factor-website/page.css
extra/webapps/wiki/articles.xml [new file with mode: 0644]
extra/webapps/wiki/diff.xml [new file with mode: 0644]
extra/webapps/wiki/edit.xml [new file with mode: 0644]
extra/webapps/wiki/revisions.xml [new file with mode: 0644]
extra/webapps/wiki/view.xml [new file with mode: 0644]
extra/webapps/wiki/wiki-common.xml [new file with mode: 0644]
extra/webapps/wiki/wiki.css [new file with mode: 0644]
extra/webapps/wiki/wiki.factor [new file with mode: 0644]

diff --git a/extra/lcs/diff2html/diff2html.factor b/extra/lcs/diff2html/diff2html.factor
new file mode 100644 (file)
index 0000000..a8f649e
--- /dev/null
@@ -0,0 +1,44 @@
+! Copyright (C) 2008 Slava Pestov
+! See http://factorcode.org/license.txt for BSD license.
+USING: lcs html.elements kernel qualified ;
+FROM: accessors => item>> ;
+FROM: io => write ;
+FROM: sequences => each empty? ;
+FROM: xml.entities => escape-string ;
+IN: lcs.diff2html
+
+GENERIC: diff-line ( obj -- )
+
+: write-item ( item -- )
+    item>> dup empty? [ drop "&nbsp;" ] [ escape-string ] if write ;
+
+M: retain diff-line
+    <tr>
+        dup [
+            <td "retain" =class td>
+                write-item
+            </td>
+        ] bi@
+    </tr> ;
+
+M: insert diff-line
+    <tr>
+        <td> </td>
+        <td "insert" =class td>
+            write-item
+        </td>
+    </tr> ;
+
+M: delete diff-line
+    <tr>
+        <td "delete" =class td>
+            write-item
+        </td>
+        <td> </td>
+    </tr> ;
+
+: htmlize-diff ( diff -- )
+    <table "comparison" =class table>
+        <tr> <th> "Old" write </th> <th> "New" write </th> </tr>
+        [ diff-line ] each
+    </table> ;
index 1fb5d4c1a6a032328860ef83b28536f6f766a836..9ad4a054922c01bf14819f2e3ea487d1656168b2 100644 (file)
@@ -11,10 +11,11 @@ http.server.auth.login
 http.server.auth.providers.db
 http.server.boilerplate
 html.templates.chloe
-webapps.user-admin
 webapps.pastebin
 webapps.planet
-webapps.todo ;
+webapps.todo
+webapps.wiki
+webapps.user-admin ;
 IN: webapps.factor-website
 
 : test-db "resource:test.db" sqlite-db ;
@@ -34,6 +35,9 @@ IN: webapps.factor-website
         init-postings-table
 
         init-todo-table
+
+        init-articles-table
+        init-revisions-table
     ] with-db ;
 
 : <factor-website> ( -- responder )
@@ -41,6 +45,7 @@ IN: webapps.factor-website
         <todo-list> "todo" add-responder
         <pastebin> "pastebin" add-responder
         <planet-factor> "planet" add-responder
+        <wiki> "wiki" add-responder
         <user-admin> "user-admin" add-responder
     <login>
         users-in-db >>users
index 606d5746186dee41e724f859a61a756e0505d438..49e26883adddffd84abc5615c5f0312492589b8a 100644 (file)
@@ -42,12 +42,15 @@ a:hover, .link:hover {
 }
 
 .description {
-       border: 1px dashed #ccc;
-       background-color: #f5f5f5;
        padding: 5px;
        color: #000;
 }
 
+.description pre {
+       border: 1px dashed #ccc;
+       background-color: #f5f5f5;
+}
+
 .description p:first-child {
        margin-top: 0px;
 }
diff --git a/extra/webapps/wiki/articles.xml b/extra/webapps/wiki/articles.xml
new file mode 100644 (file)
index 0000000..a552c26
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <t:title>All Articles</t:title>
+
+       <ul>
+               <t:each-tuple t:values="articles">
+                       <li>
+                               <t:a t:href="view" t:query="title"><t:label t:name="title"/></t:a>
+                       </li>
+               </t:each-tuple>
+       </ul>
+
+</t:chloe>
diff --git a/extra/webapps/wiki/diff.xml b/extra/webapps/wiki/diff.xml
new file mode 100644 (file)
index 0000000..378466f
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <t:bind-tuple t:name="old">
+               <t:title>Diff: <t:label t:name="title" /></t:title>
+       </t:bind-tuple>
+
+       <table>
+               <tr>
+                       <th class="field-label">Old revision:</th>
+                       <t:bind-tuple t:name="old">
+                               <td>Created on <t:label t:name="date" /> by <t:label t:name="author" />.</td>
+                       </t:bind-tuple>
+               </tr>
+               <tr>
+                       <th class="field-label">New revision:</th>
+                       <t:bind-tuple t:name="old">
+                               <td>Created on <t:label t:name="date" /> by <t:label t:name="author" />.</td>
+                       </t:bind-tuple>
+               </tr>
+       </table>
+
+       <t:comparison t:name="diff" />
+
+       <t:bind-tuple t:name="old">
+               <div class="navbar">
+                       <t:a t:href="$wiki/view" t:query="title">Latest</t:a>
+                       | <t:a t:href="$wiki/revisions" t:query="title">Revisions</t:a>
+                       | <t:a t:href="$wiki/edit" t:query="title">Edit</t:a>
+                       | <t:button t:action="$wiki/delete" t:for="title" class="link-button link">Delete</t:button>
+               </div>
+       </t:bind-tuple>
+
+</t:chloe>
diff --git a/extra/webapps/wiki/edit.xml b/extra/webapps/wiki/edit.xml
new file mode 100644 (file)
index 0000000..85c8490
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <t:title>Edit: <t:label t:name="title" /></t:title>
+
+       <t:form t:action="$wiki/edit" t:for="title">
+
+               <p>
+                       <t:textarea t:name="content" t:rows="30" t:cols="80" />
+               </p>
+
+               <p>
+                       <input type="submit" value="Save" />
+               </p>
+
+       </t:form>
+
+       <t:button t:action="$wiki/delete" t:for="title" class="link-button link">Delete</t:button>
+</t:chloe>
diff --git a/extra/webapps/wiki/revisions.xml b/extra/webapps/wiki/revisions.xml
new file mode 100644 (file)
index 0000000..fe74191
--- /dev/null
@@ -0,0 +1,48 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <t:title>Revisions of <t:label t:name="title" /></t:title>
+
+       <ul>
+               <t:each-tuple t:values="revisions">
+                       <li>
+                               <t:a t:href="revision" t:query="id">
+                                       <t:label t:name="date" /> by <t:label t:name="author" />
+                               </t:a>
+                       </li>
+               </t:each-tuple>
+       </ul>
+
+       <h2>View Differences</h2>
+
+       <form action="diff" method="get">
+               <table>
+                       <tr>
+                               <th class="field-label">Old revision:</th>
+                               
+                               <td>
+                                       <select name="old-id">
+                                               <t:each-tuple t:values="revisions">
+                                                       <option> <t:label t:name="id" /> </option>
+                                               </t:each-tuple>
+                                       </select>
+                               </td>
+                       </tr>
+                       <tr>
+                               <th class="field-label">New revision:</th>
+                               
+                               <td>
+                                       <select name="new-id">
+                                               <t:each-tuple t:values="revisions">
+                                                       <option> <t:label t:name="id" /> </option>
+                                               </t:each-tuple>
+                                       </select>
+                               </td>
+                       </tr>
+               </table>
+
+               <input type="submit" value="View" />
+       </form>
+
+</t:chloe>
diff --git a/extra/webapps/wiki/view.xml b/extra/webapps/wiki/view.xml
new file mode 100644 (file)
index 0000000..c3536f3
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <t:title><t:label t:name="title" /></t:title>
+
+       <div class="description">
+               <t:farkup t:name="content" />
+       </div>
+
+       <div class="navbar">
+               <t:a t:href="$wiki/view" t:query="title">Latest</t:a>
+               | <t:a t:href="$wiki/revisions" t:query="title">Revisions</t:a>
+               | <t:a t:href="$wiki/edit" t:query="title">Edit</t:a>
+               | <t:button t:action="$wiki/delete" t:for="title" class="link-button link">Delete</t:button>
+               | This revision created on <t:label t:name="date" /> by <t:label t:name="author" />.
+       </div>
+
+</t:chloe>
diff --git a/extra/webapps/wiki/wiki-common.xml b/extra/webapps/wiki/wiki-common.xml
new file mode 100644 (file)
index 0000000..d241f91
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <t:style t:include="resource:extra/webapps/wiki/wiki.css" />
+
+       <div class="navbar">
+
+               <t:a t:href="$wiki">Front Page</t:a>
+               | <t:a t:href="$wiki/articles">All Articles</t:a>
+
+               <t:if t:code="http.server.sessions:uid">
+
+                       <t:if t:code="http.server.auth.login:allow-edit-profile?">
+                               | <t:a t:href="$login/edit-profile" t:flow="begin">Edit Profile</t:a>
+                       </t:if>
+
+                       | <t:button t:action="$login/logout" t:flow="begin" class="link-button link">Logout</t:button>
+
+               </t:if>
+
+       </div>
+
+       <h1><t:write-title /></h1>
+
+        <t:call-next-template />
+
+</t:chloe>
diff --git a/extra/webapps/wiki/wiki.css b/extra/webapps/wiki/wiki.css
new file mode 100644 (file)
index 0000000..e737cdd
--- /dev/null
@@ -0,0 +1,25 @@
+.comparison table, {
+    border-color: #666;
+    border-style: solid;
+}
+
+.comparison th {
+    border-width: 1px;
+    border-color: #666;
+    border-style: solid;
+}
+
+.comparison table {
+    border-width: 1px;
+    border-spacing: 0;
+    border-collapse: collapse;
+}
+
+
+.insert {
+    background-color: #9f9;
+}
+
+.delete {
+    background-color: #f99;
+}
diff --git a/extra/webapps/wiki/wiki.factor b/extra/webapps/wiki/wiki.factor
new file mode 100644 (file)
index 0000000..2f28186
--- /dev/null
@@ -0,0 +1,175 @@
+! Copyright (C) 2008 Slava Pestov
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel hashtables calendar
+namespaces splitting sequences sorting math.order
+html.components
+html.templates.chloe
+http.server
+http.server.actions
+http.server.auth
+http.server.auth.login
+http.server.boilerplate
+validators
+db.types db.tuples lcs farkup ;
+IN: webapps.wiki
+
+TUPLE: article title revision ;
+
+article "ARTICLES" {
+    { "title" "TITLE" { VARCHAR 256 } +not-null+ +user-assigned-id+ }
+    ! { "AUTHOR" INTEGER +not-null+ } ! uid
+    ! { "PROTECTED" BOOLEAN +not-null+ }
+    { "revision" "REVISION" INTEGER +not-null+ } ! revision id
+} define-persistent
+
+: <article> ( title -- article ) article new swap >>title ;
+
+: init-articles-table article ensure-table ;
+
+TUPLE: revision id title author date content ;
+
+revision "REVISIONS" {
+    { "id" "ID" INTEGER +db-assigned-id+ }
+    { "title" "TITLE" { VARCHAR 256 } +not-null+ } ! article id
+    { "author" "AUTHOR" { VARCHAR 256 } +not-null+ } ! uid
+    { "date" "DATE" TIMESTAMP +not-null+ }
+    { "content" "CONTENT" TEXT +not-null+ }
+} define-persistent
+
+: <revision> ( id -- revision )
+    revision new swap >>id ;
+
+: init-revisions-table revision ensure-table ;
+
+: wiki-template ( name -- template )
+    "resource:extra/webapps/wiki/" swap ".xml" 3append <chloe> ;
+
+: <title-redirect> ( title next -- response )
+    swap "title" associate <standard-redirect> ;
+
+: validate-title ( -- )
+    { { "title" [ v-one-line ] } } validate-params ;
+
+: <main-article-action> ( -- action )
+    <action>
+        [ "Front Page" "$wiki/view" <title-redirect> ] >>display ;
+
+: <view-article-action> ( -- action )
+    <action>
+        "title" >>rest-param
+
+        [
+            validate-title
+            "view?title=" relative-link-prefix set
+        ] >>init
+
+        [
+            "title" value dup <article> select-tuple [
+                revision>> <revision> select-tuple from-tuple
+                "view" wiki-template <html-content>
+            ] [
+                "$wiki/edit" <title-redirect>
+            ] ?if
+        ] >>display ;
+
+: <view-revision-action> ( -- action )
+    <page-action>
+        [
+            { { "id" [ v-integer ] } } validate-params
+            "id" value <revision>
+            select-tuple from-tuple
+        ] >>init
+
+        "view" wiki-template >>template ;
+
+: add-revision ( revision -- )
+    [ insert-tuple ]
+    [
+        dup title>> <article> select-tuple [
+            swap id>> >>revision update-tuple
+        ] [
+            [ title>> ] [ id>> ] bi article boa insert-tuple
+        ] if*
+    ] bi ;
+
+: <edit-article-action> ( -- action )
+    <page-action>
+        [
+            validate-title
+            "title" value <article> select-tuple [
+                revision>> <revision> select-tuple from-tuple
+            ] when*
+        ] >>init
+
+        "edit" wiki-template >>template
+        
+        [
+            validate-title
+            { { "content" [ v-required ] } } validate-params
+
+            f <revision>
+                "title" value >>title
+                now >>date
+                logged-in-user get username>> >>author
+                "content" value >>content
+            [ add-revision ]
+            [ title>> "$wiki/view" <title-redirect> ] bi
+        ] >>submit ;
+
+: <list-revisions-action> ( -- action )
+    <page-action>
+        [
+            validate-title
+            f <revision> "title" value >>title select-tuples
+            [ [ date>> ] compare invert-comparison ] sort
+            "revisions" set-value
+        ] >>init
+
+        "revisions" wiki-template >>template ;
+
+: <delete-action> ( -- action )
+    <action>
+        [ validate-title ] >>validate
+
+        [
+            "title" value <article> delete-tuples
+            f <revision> "title" value >>title delete-tuples
+            "" f <standard-redirect>
+        ] >>submit ;
+
+: <diff-action> ( -- action )
+    <page-action>
+        [
+            {
+                { "old-id" [ v-integer ] }
+                { "new-id" [ v-integer ] }
+            } validate-params
+
+            "old-id" "new-id"
+            [ value <revision> select-tuple ] bi@
+            [ [ "old" set-value ] [ "new" set-value ] bi* ]
+            [ [ content>> string-lines ] bi@ diff "diff" set-value ]
+            2bi
+        ] >>init
+
+        "diff" wiki-template >>template ;
+
+: <list-articles-action> ( -- action )
+    <page-action>
+        [ f <article> select-tuples "articles" set-value ] >>init
+        "articles" wiki-template >>template ;
+
+TUPLE: wiki < dispatcher ;
+
+: <wiki> ( -- dispatcher )
+    wiki new-dispatcher
+        <main-article-action> "" add-responder
+        <view-article-action> "view" add-responder
+        <view-revision-action> "revision" add-responder
+        <edit-article-action> { } <protected> "edit" add-responder
+        <list-revisions-action> "revisions" add-responder
+        <delete-action> "delete" add-responder
+        <diff-action> "diff" add-responder
+        <list-articles-action> "articles" add-responder
+    <boilerplate>
+        "wiki-common" wiki-template >>template ;