1 ! Copyright (C) 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: kernel accessors sequences sorting math math.order
4 calendar alarms logging concurrency.combinators namespaces
5 sequences.lib db.types db.tuples db fry locals hashtables
6 syndication urls xml.writer validators
10 http.server.dispatchers
20 TUPLE: planet < dispatcher ;
22 SYMBOL: can-administer-planet?
24 can-administer-planet? define-capability
26 TUPLE: planet-admin < dispatcher ;
28 TUPLE: blog id name www-url feed-url ;
30 M: blog link-title name>> ;
32 M: blog link-href www-url>> ;
36 { "id" "ID" INTEGER +db-assigned-id+ }
37 { "name" "NAME" { VARCHAR 256 } +not-null+ }
38 { "www-url" "WWWURL" URL +not-null+ }
39 { "feed-url" "FEEDURL" URL +not-null+ }
42 TUPLE: posting < entry id ;
46 { "id" "ID" INTEGER +db-assigned-id+ }
47 { "title" "TITLE" { VARCHAR 256 } +not-null+ }
48 { "url" "LINK" URL +not-null+ }
49 { "description" "DESCRIPTION" TEXT +not-null+ }
50 { "date" "DATE" TIMESTAMP +not-null+ }
53 : <blog> ( id -- todo )
58 f <blog> select-tuples
59 [ [ name>> ] compare ] sort ;
62 posting new select-tuples
63 [ [ date>> ] compare invert-comparison ] sort ;
65 : <edit-blogroll-action> ( -- action )
67 [ blogroll "blogroll" set-value ] >>init
68 { planet "admin" } >>template ;
70 : <planet-action> ( -- action )
73 blogroll "blogroll" set-value
74 postings "postings" set-value
77 { planet "planet" } >>template ;
79 : <planet-feed-action> ( -- action )
81 [ "Planet Factor" ] >>title
82 [ URL" $planet" ] >>url
83 [ postings ] >>entries ;
85 :: <posting> ( entry name -- entry' )
87 name ": " entry title>> 3append >>title
89 entry description>> >>description
92 : fetch-feed ( url -- feed )
93 download-feed entries>> ;
95 \ fetch-feed DEBUG add-error-logging
97 : fetch-blogroll ( blogroll -- entries )
98 [ [ feed-url>> fetch-feed ] parallel-map ] [ [ name>> ] map ] bi
99 [ '[ _ <posting> ] map ] 2map concat ;
101 : sort-entries ( entries -- entries' )
102 [ [ date>> ] compare invert-comparison ] sort ;
104 : update-cached-postings ( -- )
105 blogroll fetch-blogroll sort-entries 8 short head [
106 posting new delete-tuples
107 [ insert-tuple ] each
110 : <update-action> ( -- action )
113 update-cached-postings
114 URL" $planet/admin" <redirect>
117 : <delete-blog-action> ( -- action )
119 [ validate-integer-id ] >>validate
122 "id" value <blog> delete-tuples
123 URL" $planet/admin" <redirect>
126 : validate-blog ( -- )
128 { "name" [ v-one-line ] }
129 { "www-url" [ v-url ] }
130 { "feed-url" [ v-url ] }
133 : deposit-blog-slots ( blog -- )
134 { "name" "www-url" "feed-url" } to-object ;
136 : <new-blog-action> ( -- action )
139 { planet "new-blog" } >>template
141 [ validate-blog ] >>validate
145 [ deposit-blog-slots ]
149 "$planet/admin/edit-blog" >>path
150 swap id>> "id" set-query-param
156 : <edit-blog-action> ( -- action )
161 "id" value <blog> select-tuple from-object
164 { planet "edit-blog" } >>template
173 [ deposit-blog-slots ]
177 "$planet/admin" >>path
178 swap id>> "id" set-query-param
184 : <planet-admin> ( -- responder )
185 planet-admin new-dispatcher
186 <edit-blogroll-action> "blogroll" add-main-responder
187 <update-action> "update" add-responder
188 <new-blog-action> "new-blog" add-responder
189 <edit-blog-action> "edit-blog" add-responder
190 <delete-blog-action> "delete-blog" add-responder
192 "administer Planet Factor" >>description
193 { can-administer-planet? } >>capabilities ;
195 : <planet> ( -- responder )
196 planet new-dispatcher
197 <planet-action> "list" add-main-responder
198 <planet-feed-action> "feed.xml" add-responder
199 <planet-admin> "admin" add-responder
201 { planet "planet-common" } >>template ;
203 : start-update-task ( db params -- )
204 '[ _ _ [ update-cached-postings ] with-db ] 10 minutes every drop ;