1 ! Copyright (C) 2007, 2008 Slava Pestov
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: namespaces assocs sorting sequences kernel accessors
4 hashtables db.types db.tuples db combinators
5 calendar calendar.format math.parser math.order syndication urls
6 xml.writer xmode.catalog validators
11 http.server.dispatchers
12 http.server.redirection
22 TUPLE: pastebin < dispatcher ;
24 SYMBOL: can-delete-pastes?
26 can-delete-pastes? define-capability
32 TUPLE: entity id summary author mode date contents ;
36 { "id" "ID" INTEGER +db-assigned-id+ }
37 { "summary" "SUMMARY" { VARCHAR 256 } +not-null+ }
38 { "author" "AUTHOR" { VARCHAR 256 } +not-null+ }
39 { "mode" "MODE" { VARCHAR 256 } +not-null+ }
40 { "date" "DATE" DATETIME +not-null+ }
41 { "contents" "CONTENTS" TEXT +not-null+ }
44 GENERIC: entity-url ( entity -- url )
46 M: entity feed-entry-title summary>> ;
48 M: entity feed-entry-date date>> ;
50 M: entity feed-entry-url entity-url ;
52 TUPLE: paste < entity annotations ;
54 \ paste "PASTES" { } define-persistent
56 : <paste> ( id -- paste )
60 : pastes ( -- pastes )
61 f <paste> select-tuples
62 [ [ date>> ] compare ] sort
65 TUPLE: annotation < entity parent ;
67 annotation "ANNOTATIONS"
69 { "parent" "PARENT" INTEGER +not-null+ }
72 : <annotation> ( parent id -- annotation )
77 : paste ( id -- paste )
78 [ <paste> select-tuple ]
79 [ f <annotation> select-tuples ]
86 : pastebin-url ( -- url )
87 URL" $pastebin/list" ;
89 : paste-url ( id -- url )
90 "$pastebin/paste" >url swap "id" set-query-param ;
95 : annotation-url ( parent id -- url )
96 "$pastebin/paste" >url
97 swap number>string >>anchor
98 swap "id" set-query-param ;
100 M: annotation entity-url
101 [ parent>> ] [ id>> ] bi annotation-url ;
107 : <pastebin-action> ( -- action )
109 [ pastes "pastes" set-value ] >>init
110 { pastebin "pastebin" } >>template ;
112 : <pastebin-feed-action> ( -- action )
114 [ pastebin-url ] >>url
115 [ "Factor Pastebin" ] >>title
116 [ pastes ] >>entries ;
122 : <paste-action> ( -- action )
126 "id" value paste from-object
131 mode-names "modes" set-value
132 "factor" "mode" set-value
136 { pastebin "paste" } >>template ;
138 : <paste-feed-action> ( -- action )
140 [ validate-integer-id ] >>init
141 [ "id" value paste-url ] >>url
142 [ "Paste " "id" value number>string append ] >>title
143 [ "id" value f <annotation> select-tuples ] >>entries ;
145 : validate-entity ( -- )
147 { "summary" [ v-one-line ] }
148 { "author" [ v-one-line ] }
149 { "mode" [ v-mode ] }
150 { "contents" [ v-required ] }
151 { "captcha" [ v-captcha ] }
154 : deposit-entity-slots ( tuple -- )
156 { "summary" "author" "mode" "contents" } to-object ;
158 : <new-paste-action> ( -- action )
161 "factor" "mode" set-value
162 mode-names "modes" set-value
165 { pastebin "new-paste" } >>template
168 mode-names "modes" set-value
174 [ deposit-entity-slots ]
176 [ id>> paste-url <redirect> ]
180 : <delete-paste-action> ( -- action )
183 [ validate-integer-id ] >>validate
187 "id" value <paste> delete-tuples
188 "id" value f <annotation> delete-tuples
190 URL" $pastebin/list" <redirect>
194 "delete pastes" >>description
195 { can-delete-pastes? } >>capabilities ;
201 : <new-annotation-action> ( -- action )
204 mode-names "modes" set-value
205 { { "parent" [ v-integer ] } } validate-params
210 "parent" value f <annotation>
211 [ deposit-entity-slots ]
213 [ entity-url <redirect> ]
217 : <delete-annotation-action> ( -- action )
220 [ { { "id" [ v-number ] } } validate-params ] >>validate
223 f "id" value <annotation> select-tuple
225 [ parent>> paste-url <redirect> ]
230 "delete annotations" >>description
231 { can-delete-pastes? } >>capabilities ;
233 : <pastebin> ( -- responder )
234 pastebin new-dispatcher
235 <pastebin-action> "" add-responder
236 <pastebin-feed-action> "list.atom" add-responder
237 <paste-action> "paste" add-responder
238 <paste-feed-action> "paste.atom" add-responder
239 <new-paste-action> "new-paste" add-responder
240 <delete-paste-action> "delete-paste" add-responder
241 <new-annotation-action> "new-annotation" add-responder
242 <delete-annotation-action> "delete-annotation" add-responder
244 { pastebin "pastebin-common" } >>template ;