factor/extra/webapps/pastebin/pastebin.factor

262 lines
6.4 KiB
Factor
Raw Normal View History

! Copyright (C) 2007, 2010 Slava Pestov
2008-05-26 01:47:27 -04:00
! See http://factorcode.org/license.txt for BSD license.
2008-04-25 04:23:47 -04:00
USING: namespaces assocs sorting sequences kernel accessors
hashtables db.types db.tuples db combinators
2008-09-23 15:06:49 -04:00
calendar calendar.format math.parser math.order syndication urls
xml.writer xmode.catalog validators
html.forms
2008-06-02 16:00:03 -04:00
html.components
html.templates.chloe
2008-04-25 04:23:47 -04:00
http.server
2008-06-02 16:00:03 -04:00
http.server.dispatchers
http.server.redirection
http.server.responses
2008-06-02 16:00:03 -04:00
furnace
furnace.actions
2008-06-17 01:10:46 -04:00
furnace.redirection
furnace.auth
furnace.auth.login
2008-06-02 16:00:03 -04:00
furnace.boilerplate
furnace.recaptcha
furnace.syndication
furnace.conversations ;
2008-04-25 04:23:47 -04:00
IN: webapps.pastebin
2008-06-02 16:00:03 -04:00
TUPLE: pastebin < dispatcher ;
SYMBOL: can-delete-pastes?
can-delete-pastes? define-capability
2008-05-26 01:47:27 -04:00
! ! !
! DOMAIN MODEL
! ! !
2008-04-25 04:23:47 -04:00
TUPLE: entity id summary author mode date contents ;
2008-04-25 04:23:47 -04:00
entity f
2008-04-25 04:23:47 -04:00
{
2008-04-28 18:38:12 -04:00
{ "id" "ID" INTEGER +db-assigned-id+ }
2008-04-25 04:23:47 -04:00
{ "summary" "SUMMARY" { VARCHAR 256 } +not-null+ }
{ "author" "AUTHOR" { VARCHAR 256 } +not-null+ }
{ "mode" "MODE" { VARCHAR 256 } +not-null+ }
{ "date" "DATE" DATETIME +not-null+ }
2008-04-25 04:23:47 -04:00
{ "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 ;
2013-03-24 13:04:20 -04:00
TUPLE: paste-state < entity annotations ;
2013-03-24 13:04:20 -04:00
\ paste-state "PASTES" { } define-persistent
2013-03-24 13:04:20 -04:00
: <paste-state> ( id -- paste )
\ paste-state new
2008-04-25 04:23:47 -04:00
swap >>id ;
: pastes ( -- pastes )
2013-03-24 13:04:20 -04:00
f <paste-state> select-tuples
[ date>> ] sort-with
2008-09-23 15:06:49 -04:00
reverse ;
2008-04-25 04:23:47 -04:00
TUPLE: annotation < entity parent ;
2008-04-25 04:23:47 -04:00
\ annotation "ANNOTATIONS"
2008-04-25 04:23:47 -04:00
{
{ "parent" "PARENT" INTEGER +not-null+ }
2008-04-25 04:23:47 -04:00
} define-persistent
: <annotation> ( parent id -- annotation )
\ annotation new
swap >>id
swap >>parent ;
2008-04-25 04:23:47 -04:00
: lookup-annotation ( id -- annotation )
[ f ] dip <annotation> select-tuple ;
2008-05-26 01:47:27 -04:00
: paste ( id -- paste )
2013-03-24 13:04:20 -04:00
[ <paste-state> select-tuple ]
[ f <annotation> select-tuples ]
bi >>annotations ;
2008-04-25 04:23:47 -04:00
2008-05-26 01:47:27 -04:00
! ! !
! LINKS, ETC
! ! !
2008-04-25 04:23:47 -04:00
2009-03-15 21:05:59 -04:00
CONSTANT: pastebin-url URL" $pastebin/"
2008-04-25 04:23:47 -04:00
: paste-url ( id -- url )
"$pastebin/paste" >url swap "id" set-query-param ;
M: paste entity-url
id>> paste-url ;
2008-04-25 04:23:47 -04:00
: annotation-url ( parent id -- url )
"$pastebin/paste" >url
swap number>string >>anchor
swap "id" set-query-param ;
2008-04-25 04:23:47 -04:00
M: annotation entity-url
[ parent>> ] [ id>> ] bi annotation-url ;
2008-04-25 04:23:47 -04:00
2008-05-26 01:47:27 -04:00
! ! !
! PASTE LIST
! ! !
2008-04-25 04:23:47 -04:00
2008-05-26 01:47:27 -04:00
: <pastebin-action> ( -- action )
<page-action>
[ pastes "pastes" set-value ] >>init
2008-06-02 16:00:03 -04:00
{ pastebin "pastebin" } >>template ;
2008-04-25 04:23:47 -04:00
2008-05-26 01:47:27 -04:00
: <pastebin-feed-action> ( -- action )
<feed-action>
[ pastebin-url ] >>url
[ "Factor Pastebin" ] >>title
2008-09-23 15:06:49 -04:00
[ pastes ] >>entries ;
2008-04-25 04:23:47 -04:00
2008-05-26 01:47:27 -04:00
! ! !
! PASTES
! ! !
2008-04-25 04:23:47 -04:00
2008-05-26 01:47:27 -04:00
: <paste-action> ( -- action )
<page-action>
[
validate-integer-id
"id" value paste from-object
2008-04-25 04:23:47 -04:00
2008-05-26 03:54:53 -04:00
"id" value
2008-05-26 01:47:27 -04:00
"new-annotation" [
"parent" set-value
2008-05-26 01:47:27 -04:00
mode-names "modes" set-value
"factor" "mode" set-value
] nest-form
2008-05-26 01:47:27 -04:00
] >>init
2008-04-25 04:23:47 -04:00
2008-06-02 16:00:03 -04:00
{ pastebin "paste" } >>template ;
2008-04-25 04:23:47 -04:00
: <raw-paste-action> ( -- action )
<action>
[ validate-integer-id "id" value paste from-object ] >>init
[ "contents" value "text/plain" <content> ] >>display ;
2008-05-26 01:47:27 -04:00
: <paste-feed-action> ( -- action )
<feed-action>
[ validate-integer-id ] >>init
[ "id" value paste-url ] >>url
[ "Paste " "id" value number>string append ] >>title
[ "id" value f <annotation> select-tuples ] >>entries ;
2008-05-26 01:47:27 -04:00
: validate-entity ( -- )
2008-05-26 03:54:53 -04:00
{
{ "summary" [ v-one-line ] }
{ "author" [ v-one-line ] }
{ "mode" [ v-mode ] }
{ "contents" [ v-required ] }
} validate-params
validate-recaptcha ;
2008-05-26 03:54:53 -04:00
: deposit-entity-slots ( tuple -- )
2008-05-26 03:54:53 -04:00
now >>date
{ "summary" "author" "mode" "contents" } to-object ;
2008-05-26 03:54:53 -04:00
2008-05-26 01:47:27 -04:00
: <new-paste-action> ( -- action )
<page-action>
2008-04-25 04:23:47 -04:00
[
2008-05-26 01:47:27 -04:00
"factor" "mode" set-value
mode-names "modes" set-value
] >>init
2008-04-25 04:23:47 -04:00
2008-06-02 16:00:03 -04:00
{ pastebin "new-paste" } >>template
2008-05-26 01:47:27 -04:00
[
mode-names "modes" set-value
validate-entity
] >>validate
2008-05-26 01:47:27 -04:00
[
2013-03-24 13:04:20 -04:00
f <paste-state>
[ deposit-entity-slots ]
2008-05-26 01:47:27 -04:00
[ insert-tuple ]
[ id>> paste-url <redirect> ]
2008-05-26 03:54:53 -04:00
tri
2008-04-25 04:23:47 -04:00
] >>submit ;
2008-05-26 01:47:27 -04:00
: <delete-paste-action> ( -- action )
2008-04-25 04:23:47 -04:00
<action>
2008-05-26 01:47:27 -04:00
[ validate-integer-id ] >>validate
2008-04-25 04:23:47 -04:00
[
[
2013-03-24 13:04:20 -04:00
"id" value <paste-state> delete-tuples
"id" value f <annotation> delete-tuples
] with-transaction
2009-03-15 21:05:59 -04:00
pastebin-url <redirect>
] >>submit
<protected>
"delete pastes" >>description
{ can-delete-pastes? } >>capabilities ;
2008-04-25 04:23:47 -04:00
2008-05-26 01:47:27 -04:00
! ! !
! ANNOTATIONS
! ! !
: <new-annotation-action> ( -- action )
<action>
[
mode-names "modes" set-value
{ { "parent" [ v-integer ] } } validate-params
validate-entity
] >>validate
2008-04-25 04:23:47 -04:00
[
"parent" value f <annotation>
[ deposit-entity-slots ]
[ insert-tuple ]
[ entity-url <redirect> ]
tri
2008-05-26 01:47:27 -04:00
] >>submit ;
2008-04-25 04:23:47 -04:00
: <raw-annotation-action> ( -- action )
<action>
[ validate-integer-id "id" value lookup-annotation from-object ] >>init
[ "contents" value "text/plain" <content> ] >>display ;
2008-05-26 01:47:27 -04:00
: <delete-annotation-action> ( -- action )
<action>
[ { { "id" [ v-number ] } } validate-params ] >>validate
2008-04-25 04:23:47 -04:00
2008-05-26 01:47:27 -04:00
[
f "id" value lookup-annotation
2008-05-26 01:47:27 -04:00
[ delete-tuples ]
[ parent>> paste-url <redirect> ]
2008-05-26 01:47:27 -04:00
bi
] >>submit
2008-04-25 04:23:47 -04:00
<protected>
"delete annotations" >>description
{ can-delete-pastes? } >>capabilities ;
2008-05-01 17:24:50 -04:00
2008-04-25 04:23:47 -04:00
: <pastebin> ( -- responder )
pastebin new-dispatcher
2008-09-27 12:38:20 -04:00
<pastebin-action> "" add-responder
2008-05-26 01:47:27 -04:00
<pastebin-feed-action> "list.atom" add-responder
<paste-action> "paste" add-responder
<raw-paste-action> "paste.txt" add-responder
2008-05-26 01:47:27 -04:00
<paste-feed-action> "paste.atom" add-responder
<new-paste-action> "new-paste" add-responder
<delete-paste-action> "delete-paste" add-responder
2008-05-26 01:47:27 -04:00
<new-annotation-action> "new-annotation" add-responder
<raw-annotation-action> "annotation.txt" add-responder
<delete-annotation-action> "delete-annotation" add-responder
2008-04-25 04:23:47 -04:00
<boilerplate>
2008-06-02 16:00:03 -04:00
{ pastebin "pastebin-common" } >>template ;