! 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 syndication urls xml.writer xmode.catalog validators html.forms html.components html.templates.chloe http.server http.server.dispatchers http.server.redirection furnace furnace.actions furnace.redirection furnace.auth furnace.auth.login furnace.boilerplate furnace.syndication ; IN: webapps.pastebin TUPLE: pastebin < dispatcher ; SYMBOL: can-delete-pastes? can-delete-pastes? define-capability ! ! ! ! DOMAIN MODEL ! ! ! TUPLE: entity id summary author mode date contents ; entity f { { "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 GENERIC: entity-url ( entity -- url ) M: entity feed-entry-title summary>> ; M: entity feed-entry-date date>> ; M: entity feed-entry-url entity-url ; TUPLE: paste < entity annotations ; \ paste "PASTES" { } define-persistent : ( id -- paste ) \ paste new swap >>id ; : pastes ( -- pastes ) f select-tuples ; TUPLE: annotation < entity parent ; annotation "ANNOTATIONS" { { "parent" "PARENT" INTEGER +not-null+ } } define-persistent : ( parent id -- annotation ) annotation new swap >>id swap >>parent ; : paste ( id -- paste ) [ select-tuple ] [ f select-tuples ] bi >>annotations ; ! ! ! ! LINKS, ETC ! ! ! : pastebin-url ( -- url ) URL" $pastebin/list" ; : paste-url ( id -- url ) "$pastebin/paste" >url swap "id" set-query-param ; M: paste entity-url id>> paste-url ; : annotation-url ( parent id -- url ) "$pastebin/paste" >url swap number>string >>anchor swap "id" set-query-param ; M: annotation entity-url [ parent>> ] [ id>> ] bi annotation-url ; ! ! ! ! PASTE LIST ! ! ! : ( -- action ) [ pastes "pastes" set-value ] >>init { pastebin "pastebin" } >>template ; : ( -- action ) [ pastebin-url ] >>url [ "Factor Pastebin" ] >>title [ pastes ] >>entries ; ! ! ! ! PASTES ! ! ! : ( -- action ) [ validate-integer-id "id" value paste from-object "id" value "new-annotation" [ "parent" set-value mode-names "modes" set-value "factor" "mode" set-value ] nest-form ] >>init { pastebin "paste" } >>template ; : ( -- action ) [ validate-integer-id ] >>init [ "id" value paste-url ] >>url [ "Paste " "id" value number>string append ] >>title [ "id" value f select-tuples ] >>entries ; : validate-entity ( -- ) { { "summary" [ v-one-line ] } { "author" [ v-one-line ] } { "mode" [ v-mode ] } { "contents" [ v-required ] } { "captcha" [ v-captcha ] } } validate-params ; : deposit-entity-slots ( tuple -- ) now >>date { "summary" "author" "mode" "contents" } to-object ; : ( -- action ) [ "factor" "mode" set-value mode-names "modes" set-value ] >>init { pastebin "new-paste" } >>template [ mode-names "modes" set-value validate-entity ] >>validate [ f [ deposit-entity-slots ] [ insert-tuple ] [ id>> paste-url ] tri ] >>submit ; : ( -- action ) [ validate-integer-id ] >>validate [ [ "id" value delete-tuples "id" value f delete-tuples ] with-transaction URL" $pastebin/list" ] >>submit "delete pastes" >>description { can-delete-pastes? } >>capabilities ; ! ! ! ! ANNOTATIONS ! ! ! : ( -- action ) [ mode-names "modes" set-value { { "parent" [ v-integer ] } } validate-params validate-entity ] >>validate [ "parent" value f [ deposit-entity-slots ] [ insert-tuple ] [ entity-url ] tri ] >>submit ; : ( -- action ) [ { { "id" [ v-number ] } } validate-params ] >>validate [ f "id" value select-tuple [ delete-tuples ] [ parent>> paste-url ] bi ] >>submit "delete annotations" >>description { can-delete-pastes? } >>capabilities ; : ( -- responder ) pastebin new-dispatcher "list" add-main-responder "list.atom" add-responder "paste" add-responder "paste.atom" add-responder "new-paste" add-responder "delete-paste" add-responder "new-annotation" add-responder "delete-annotation" add-responder { pastebin "pastebin-common" } >>template ;