! Copyright (C) 2008 Slava Pestov
! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel hashtables calendar random assocs
-namespaces make splitting sequences sorting math.order present
-io.files io.encodings.ascii
-syndication farkup
-html.components html.forms
-http.server
-http.server.dispatchers
-furnace
-furnace.actions
-furnace.redirection
-furnace.auth
-furnace.auth.login
-furnace.boilerplate
-furnace.syndication
-validators
-db.types db.tuples lcs farkup urls ;
+USING: accessors calendar db.tuples db.types farkup
+furnace.actions furnace.auth furnace.boilerplate
+furnace.recaptcha furnace.redirection furnace.syndication
+furnace.utilities html.forms http.server http.server.dispatchers
+http.server.static kernel lcs make namespaces present random
+regexp sequences simple-tokenizer sorting splitting unicode urls
+validators ;
IN: webapps.wiki
: wiki-url ( rest path -- url )
: <article> ( title -- article ) article new swap >>title ;
-TUPLE: revision id title author date content parsed description ;
+TUPLE: revision id title author date content description ;
revision "REVISIONS" {
{ "id" "ID" INTEGER +db-assigned-id+ }
{ "author" "AUTHOR" { VARCHAR 256 } +not-null+ } ! uid
{ "date" "DATE" TIMESTAMP +not-null+ }
{ "content" "CONTENT" TEXT +not-null+ }
- { "parsed" "PARSED" FACTOR-BLOB +not-null+ } ! Farkup AST
{ "description" "DESCRIPTION" TEXT }
} define-persistent
M: revision feed-entry-url id>> revision-url ;
: reverse-chronological-order ( seq -- sorted )
- [ [ date>> ] compare invert-comparison ] sort ;
+ [ date>> ] inv-sort-with ;
: <revision> ( id -- revision )
revision new swap >>id ;
-: compute-html ( revision -- )
- dup content>> parse-farkup >>parsed drop ;
-
: validate-title ( -- )
{ { "title" [ v-one-line ] } } validate-params ;
] >>init
{ wiki "view" } >>template
-
+
<article-boilerplate> ;
: <random-article-action> ( -- action )
[ title>> ] [ id>> ] bi article boa insert-tuple ;
: add-revision ( revision -- )
- [ compute-html ]
[ insert-tuple ]
[
dup title>> <article> select-tuple
[ amend-article ] [ add-article ] if*
]
- tri ;
+ bi ;
: <edit-article-action> ( -- action )
<page-action>
: <submit-article-action> ( -- action )
<action>
[
+ validate-recaptcha
+
validate-title
{
[ list-revisions ] >>entries ;
: rollback-description ( description -- description' )
- [ "Rollback of '" swap "'" 3append ] [ "Rollback" ] if* ;
+ [ "Rollback to '" "'" surround ] [ "Rollback" ] if* ;
: <rollback-action> ( -- action )
<action>
[ add-revision ]
[ title>> revisions-url <redirect> ] bi
] >>submit
-
+
<protected>
"rollback wiki articles" >>description ;
[ "new" [ from-object ] nest-form ]
bi*
]
- [ [ content>> string-lines ] bi@ diff "diff" set-value ]
+ [ [ content>> split-lines ] bi@ lcs-diff "diff" set-value ]
2bi
] >>init
[
f <article> select-tuples
- [ [ title>> ] compare ] sort
+ [ title>> ] sort-with
"articles" set-value
] >>init
{ wiki "articles" } >>template ;
+: <search-articles-action> ( -- action )
+ <page-action>
+
+ [
+ "search" param [ unicode:blank? ] trim
+ dup "search" set-value
+
+ [ f ] [
+ tokenize [
+ " " "\s+" replace "\\b" dup surround
+ "i" <optioned-regexp>
+ ] map
+ ] if-empty
+
+ [ f ] [
+ f <article> select-tuples
+ [ title>> ] sort-with
+ [ revision>> <revision> select-tuple ] map
+ swap '[ content>> _ [ first-match ] with all? ] filter
+ ] if-empty
+
+ [ "results" set-value ]
+ [ not "empty" set-value ] bi
+ ] >>init
+
+ { wiki "search" } >>template ;
+
: list-user-edits ( -- seq )
f <revision> "author" value >>author select-tuples
reverse-chronological-order ;
<rollback-action> "rollback" add-responder
<user-edits-action> "user-edits" add-responder
<list-articles-action> "articles" add-responder
+ <search-articles-action> "search" add-responder
<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
+ "vocab:webapps/wiki/icons/" <static> "icons" add-responder
<boilerplate>
[ init-sidebars init-relative-link-prefix ] >>init
{ wiki "wiki-common" } >>template ;
-
-: init-wiki ( -- )
- "resource:extra/webapps/wiki/initial-content" [
- [
- dup ".txt" ?tail [
- swap ascii file-contents
- f <revision>
- swap >>content
- swap >>title
- "slava" >>author
- now >>date
- add-revision
- ] [ 2drop ] if
- ] each
- ] with-directory-files ;