factor/extra/webapps/wiki/wiki.factor

301 lines
7.9 KiB
Factor
Raw Normal View History

2008-05-27 01:02:16 -04:00
! 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 present
2008-06-15 04:25:36 -04:00
syndication
html.components html.forms
2008-05-27 01:02:16 -04:00
http.server
2008-06-02 16:00:03 -04:00
http.server.dispatchers
furnace
furnace.actions
furnace.auth
furnace.auth.login
furnace.boilerplate
2008-06-05 02:56:06 -04:00
furnace.syndication
2008-05-27 01:02:16 -04:00
validators
db.types db.tuples lcs farkup urls ;
2008-05-27 01:02:16 -04:00
IN: webapps.wiki
: wiki-url ( rest path -- url )
[ "$wiki/" % % "/" % % ] "" make
<url> swap >>path ;
: view-url ( title -- url ) "view" wiki-url ;
: edit-url ( title -- url ) "edit" wiki-url ;
: revisions-url ( title -- url ) "revisions" wiki-url ;
: revision-url ( id -- url ) "revision" wiki-url ;
: user-edits-url ( author -- url ) "user-edits" wiki-url ;
2008-06-02 16:00:03 -04:00
TUPLE: wiki < dispatcher ;
SYMBOL: can-delete-wiki-articles?
can-delete-wiki-articles? define-capability
2008-05-27 01:02:16 -04:00
TUPLE: article title revision ;
article "ARTICLES" {
{ "title" "TITLE" { VARCHAR 256 } +not-null+ +user-assigned-id+ }
{ "revision" "REVISION" INTEGER +not-null+ } ! revision id
} define-persistent
: <article> ( title -- article ) article new swap >>title ;
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
M: revision feed-entry-title
[ title>> ] [ drop " by " ] [ author>> ] tri 3append ;
M: revision feed-entry-date date>> ;
M: revision feed-entry-url id>> revision-url ;
: reverse-chronological-order ( seq -- sorted )
[ [ date>> ] compare invert-comparison ] sort ;
2008-05-27 01:02:16 -04:00
: <revision> ( id -- revision )
revision new swap >>id ;
: validate-title ( -- )
{ { "title" [ v-one-line ] } } validate-params ;
: validate-author ( -- )
{ { "author" [ v-username ] } } validate-params ;
2008-05-27 01:02:16 -04:00
: <main-article-action> ( -- action )
<action>
[ "Front Page" view-url <redirect> ] >>display ;
2008-05-27 01:02:16 -04:00
: <view-article-action> ( -- action )
<action>
"title" >>rest
2008-05-27 01:02:16 -04:00
[
validate-title
] >>init
2008-05-27 01:02:16 -04:00
[
"title" value dup <article> select-tuple [
revision>> <revision> select-tuple from-object
2008-06-02 16:00:03 -04:00
{ wiki "view" } <chloe-content>
2008-05-27 01:02:16 -04:00
] [
edit-url <redirect>
2008-05-27 01:02:16 -04:00
] ?if
] >>display ;
: <view-revision-action> ( -- action )
<page-action>
"id" >>rest
2008-05-27 01:02:16 -04:00
[
validate-integer-id
2008-05-27 01:02:16 -04:00
"id" value <revision>
select-tuple from-object
URL" $wiki/view/" adjust-url present relative-link-prefix set
2008-05-27 01:02:16 -04:00
] >>init
2008-06-02 16:00:03 -04:00
{ wiki "view" } >>template ;
2008-05-27 01:02:16 -04:00
: amend-article ( revision article -- )
swap id>> >>revision update-tuple ;
: add-article ( revision -- )
[ title>> ] [ id>> ] bi article boa insert-tuple ;
2008-05-27 01:02:16 -04:00
: add-revision ( revision -- )
[ insert-tuple ]
[
dup title>> <article> select-tuple
[ amend-article ] [ add-article ] if*
2008-05-27 01:02:16 -04:00
] bi ;
: <edit-article-action> ( -- action )
<page-action>
"title" >>rest
2008-05-27 01:02:16 -04:00
[
validate-title
"title" value <article> select-tuple [
revision>> <revision> select-tuple from-object
2008-05-27 01:02:16 -04:00
] when*
] >>init
2008-06-02 16:00:03 -04:00
{ wiki "edit" } >>template
2008-05-27 01:02:16 -04:00
[
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>> view-url <redirect> ] bi
] >>submit
<protected>
"edit wiki articles" >>description ;
2008-05-27 01:02:16 -04:00
: list-revisions ( -- seq )
f <revision> "title" value >>title select-tuples
reverse-chronological-order ;
2008-05-27 01:02:16 -04:00
: <list-revisions-action> ( -- action )
<page-action>
"title" >>rest
2008-05-27 01:02:16 -04:00
[
validate-title
list-revisions "revisions" set-value
2008-05-27 01:02:16 -04:00
] >>init
2008-06-02 16:00:03 -04:00
{ wiki "revisions" } >>template ;
: <list-revisions-feed-action> ( -- action )
<feed-action>
"title" >>rest
[ validate-title ] >>init
[ "Revisions of " "title" value append ] >>title
[ "title" value revisions-url ] >>url
[ list-revisions ] >>entries ;
: <rollback-action> ( -- action )
<action>
[ validate-integer-id ] >>validate
[
"id" value <revision> select-tuple clone f >>id
[ add-revision ] [ title>> view-url <redirect> ] bi
] >>submit ;
2008-05-27 01:02:16 -04:00
: list-changes ( -- seq )
f <revision> select-tuples
reverse-chronological-order ;
2008-05-27 03:42:21 -04:00
: <list-changes-action> ( -- action )
<page-action>
[ list-changes "changes" set-value ] >>init
2008-06-02 16:00:03 -04:00
{ wiki "changes" } >>template ;
2008-05-27 03:42:21 -04:00
: <list-changes-feed-action> ( -- action )
<feed-action>
[ URL" $wiki/changes" ] >>url
[ "All changes" ] >>title
[ list-changes ] >>entries ;
2008-05-27 01:02:16 -04:00
: <delete-action> ( -- action )
<action>
2008-05-27 01:02:16 -04:00
[ validate-title ] >>validate
2008-05-27 01:02:16 -04:00
[
"title" value <article> delete-tuples
f <revision> "title" value >>title delete-tuples
URL" $wiki" <redirect>
] >>submit
<protected>
"delete wiki articles" >>description
{ can-delete-wiki-articles? } >>capabilities ;
2008-05-27 01:02:16 -04:00
: <diff-action> ( -- action )
<page-action>
[
{
{ "old-id" [ v-integer ] }
{ "new-id" [ v-integer ] }
} validate-params
"old-id" "new-id"
[ value <revision> select-tuple ] bi@
2008-06-02 16:33:33 -04:00
[
[ [ title>> "title" set-value ] [ "old" set-value ] bi ]
[ "new" set-value ] bi*
]
2008-05-27 01:02:16 -04:00
[ [ content>> string-lines ] bi@ diff "diff" set-value ]
2bi
] >>init
2008-06-02 16:00:03 -04:00
{ wiki "diff" } >>template ;
2008-05-27 01:02:16 -04:00
: <list-articles-action> ( -- action )
<page-action>
2008-05-27 03:42:21 -04:00
[
f <article> select-tuples
[ [ title>> ] compare ] sort
"articles" set-value
] >>init
2008-06-02 16:00:03 -04:00
{ wiki "articles" } >>template ;
2008-05-27 01:02:16 -04:00
: list-user-edits ( -- seq )
f <revision> "author" value >>author select-tuples
reverse-chronological-order ;
2008-05-27 03:42:21 -04:00
: <user-edits-action> ( -- action )
<page-action>
"author" >>rest
2008-05-27 03:42:21 -04:00
[
validate-author
list-user-edits "user-edits" set-value
2008-05-27 03:42:21 -04:00
] >>init
2008-06-02 16:00:03 -04:00
{ wiki "user-edits" } >>template ;
2008-05-27 01:02:16 -04:00
: <user-edits-feed-action> ( -- action )
<feed-action>
"author" >>rest
[ validate-author ] >>init
[ "Edits by " "author" value append ] >>title
[ "author" value user-edits-url ] >>url
[ list-user-edits ] >>entries ;
: <article-boilerplate> ( responder -- responder' )
<boilerplate>
{ wiki "page-common" } >>template ;
2008-05-27 01:02:16 -04:00
: <wiki> ( -- dispatcher )
wiki new-dispatcher
<main-article-action> <article-boilerplate> "" add-responder
<view-article-action> <article-boilerplate> "view" add-responder
<view-revision-action> <article-boilerplate> "revision" add-responder
<list-revisions-action> <article-boilerplate> "revisions" add-responder
<list-revisions-feed-action> "revisions.atom" add-responder
<diff-action> <article-boilerplate> "diff" add-responder
<edit-article-action> <article-boilerplate> "edit" add-responder
<rollback-action> "rollback" add-responder
2008-05-27 03:42:21 -04:00
<user-edits-action> "user-edits" add-responder
2008-05-27 01:02:16 -04:00
<list-articles-action> "articles" add-responder
2008-05-27 03:42:21 -04:00
<list-changes-action> "changes" add-responder
<user-edits-feed-action> "user-edits.atom" add-responder
<list-changes-feed-action> "changes.atom" add-responder
<delete-action> "delete" add-responder
2008-05-27 01:02:16 -04:00
<boilerplate>
2008-06-02 16:00:03 -04:00
{ wiki "wiki-common" } >>template ;