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 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 ]
148 URL" $planet/admin" <redirect>
151 : <edit-blog-action> ( -- action )
156 "id" value <blog> select-tuple from-object
159 { planet "edit-blog" } >>template
168 [ deposit-blog-slots ]
174 "$planet/admin" >>path
175 "id" value "id" set-query-param
179 : <planet-admin> ( -- responder )
180 planet-admin new-dispatcher
181 <edit-blogroll-action> "" add-responder
182 <update-action> "update" add-responder
183 <new-blog-action> "new-blog" add-responder
184 <edit-blog-action> "edit-blog" add-responder
185 <delete-blog-action> "delete-blog" add-responder
187 "administer Planet Factor" >>description
188 { can-administer-planet? } >>capabilities ;
190 : <planet> ( -- responder )
191 planet new-dispatcher
192 <planet-action> "" add-responder
193 <planet-feed-action> "feed.xml" add-responder
194 <planet-admin> "admin" add-responder
196 { planet "planet-common" } >>template ;
198 : start-update-task ( db -- )
199 '[ _ [ update-cached-postings ] with-db ] 10 minutes every drop ;