! Copyright (C) 2007, 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: namespaces assocs sorting sequences kernel accessors hashtables sequences.lib db.types db.tuples db combinators calendar calendar.format math.parser rss xml.writer xmode.catalog validators html.components html.templates.chloe http.server http.server.actions http.server.auth http.server.auth.login http.server.boilerplate ; IN: webapps.pastebin ! ! ! ! DOMAIN MODEL ! ! ! TUPLE: paste id summary author mode date contents annotations ; \ paste "PASTE" { { "id" "ID" INTEGER +db-assigned-id+ } { "summary" "SUMMARY" { VARCHAR 256 } +not-null+ } { "author" "AUTHOR" { VARCHAR 256 } +not-null+ } { "mode" "MODE" { VARCHAR 256 } +not-null+ } { "date" "DATE" DATETIME +not-null+ , } { "contents" "CONTENTS" TEXT +not-null+ } } define-persistent : ( id -- paste ) \ paste new swap >>id ; : pastes ( -- pastes ) f select-tuples ; TUPLE: annotation aid id summary author mode contents date ; annotation "ANNOTATION" { { "aid" "AID" INTEGER +db-assigned-id+ } { "id" "ID" INTEGER +not-null+ } { "summary" "SUMMARY" { VARCHAR 256 } +not-null+ } { "author" "AUTHOR" { VARCHAR 256 } +not-null+ } { "mode" "MODE" { VARCHAR 256 } +not-null+ } { "date" "DATE" DATETIME +not-null+ } { "contents" "CONTENTS" TEXT +not-null+ } } define-persistent : ( id aid -- annotation ) annotation new swap >>aid swap >>id ; : fetch-annotations ( paste -- paste ) dup annotations>> [ dup id>> f select-tuples >>annotations ] unless ; : paste ( id -- paste ) select-tuple fetch-annotations ; : ( id next -- response ) swap "id" associate ; ! ! ! ! LINKS, ETC ! ! ! : pastebin-link ( -- url ) "$pastebin/list" f link>string ; GENERIC: entity-link ( entity -- url ) M: paste entity-link id>> "id" associate "$pastebin/paste" swap link>string ; M: annotation entity-link [ id>> "id" associate "$pastebin/paste" swap link>string ] [ aid>> number>string "#" prepend ] bi append ; : pastebin-template ( name -- template ) "resource:extra/webapps/pastebin/" swap ".xml" 3append ; ! ! ! ! PASTE LIST ! ! ! : ( -- action ) [ pastes "pastes" set-value ] >>init "pastebin" pastebin-template >>template ; : pastebin-feed-entries ( seq -- entries ) 20 short head [ entry new swap [ summary>> >>title ] [ date>> >>pub-date ] [ entity-link >>link ] tri ] map ; : pastebin-feed ( -- feed ) feed new "Factor Pastebin" >>title pastebin-link >>link pastes pastebin-feed-entries >>entries ; : ( -- action ) [ pastebin-feed ] >>feed ; ! ! ! ! PASTES ! ! ! : ( -- action ) [ validate-integer-id "id" value paste from-tuple "id" value "new-annotation" [ "id" set-value mode-names "modes" set-value "factor" "mode" set-value ] nest-values ] >>init "paste" pastebin-template >>template ; : paste-feed-entries ( paste -- entries ) fetch-annotations annotations>> pastebin-feed-entries ; : paste-feed ( paste -- feed ) feed new swap [ "Paste #" swap id>> number>string append >>title ] [ entity-link >>link ] [ paste-feed-entries >>entries ] tri ; : ( -- action ) [ validate-integer-id ] >>init [ "id" value paste annotations>> paste-feed ] >>feed ; : validate-paste ( -- ) { { "summary" [ v-one-line ] } { "author" [ v-one-line ] } { "mode" [ v-mode ] } { "contents" [ v-required ] } { "captcha" [ v-captcha ] } } validate-params ; : deposit-paste-slots ( tuple -- ) now >>date { "summary" "author" "mode" "contents" } deposit-slots ; : ( -- action ) [ "factor" "mode" set-value mode-names "modes" set-value ] >>init "new-paste" pastebin-template >>template [ validate-paste f [ deposit-paste-slots ] [ insert-tuple ] [ id>> "$pastebin/paste" ] tri ] >>submit ; : ( -- action ) [ validate-integer-id ] >>validate [ "id" value delete-tuples "id" value f delete-tuples "$pastebin/list" f ] >>submit ; ! ! ! ! ANNOTATIONS ! ! ! : ( -- action ) [ validate-paste ] >>validate [ "id" param "$pastebin/paste" ] >>display [ f f { [ deposit-paste-slots ] [ { "id" } deposit-slots ] [ insert-tuple ] [ ! Add anchor here id>> "$pastebin/paste" ] } cleave ] >>submit ; : ( -- action ) [ { { "aid" [ v-number ] } } validate-params ] >>validate [ f "aid" value select-tuple [ delete-tuples ] [ id>> "$pastebin/paste" ] bi ] >>submit ; TUPLE: pastebin < dispatcher ; SYMBOL: can-delete-pastes? can-delete-pastes? define-capability : ( -- responder ) pastebin new-dispatcher "list" add-main-responder "list.atom" add-responder "paste" add-responder "paste.atom" add-responder "new-paste" add-responder { can-delete-pastes? } "delete-paste" add-responder "new-annotation" add-responder { can-delete-pastes? } "delete-annotation" add-responder "pastebin-common" pastebin-template >>template ; : init-pastes-table \ paste ensure-table ; : init-annotations-table annotation ensure-table ;