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
7 syndication urls xml.writer
10 http.server.dispatchers
19 TUPLE: planet-factor < dispatcher ;
21 TUPLE: planet-factor-admin < dispatcher ;
23 TUPLE: blog id name www-url feed-url ;
25 M: blog link-title name>> ;
27 M: blog link-href www-url>> ;
31 { "id" "ID" INTEGER +db-assigned-id+ }
32 { "name" "NAME" { VARCHAR 256 } +not-null+ }
33 { "www-url" "WWWURL" { VARCHAR 256 } +not-null+ }
34 { "feed-url" "FEEDURL" { VARCHAR 256 } +not-null+ }
37 TUPLE: posting < entry id ;
41 { "id" "ID" INTEGER +db-assigned-id+ }
42 { "title" "TITLE" { VARCHAR 256 } +not-null+ }
43 { "url" "LINK" { VARCHAR 256 } +not-null+ }
44 { "description" "DESCRIPTION" TEXT +not-null+ }
45 { "date" "DATE" TIMESTAMP +not-null+ }
48 : init-blog-table ( -- ) blog ensure-table ;
50 : init-postings-table ( -- ) posting ensure-table ;
52 : <blog> ( id -- todo )
57 f <blog> select-tuples
58 [ [ name>> ] compare ] sort ;
61 posting new select-tuples
62 [ [ date>> ] compare invert-comparison ] sort ;
64 : <edit-blogroll-action> ( -- action )
66 [ blogroll "blogroll" set-value ] >>init
67 { planet-factor "admin" } >>template ;
69 : <planet-action> ( -- action )
72 blogroll "blogroll" set-value
73 postings "postings" set-value
76 { planet-factor "planet" } >>template ;
78 : <planet-feed-action> ( -- action )
80 [ "Planet Factor" ] >>title
81 [ URL" $planet-factor" ] >>url
82 [ postings ] >>entries ;
84 :: <posting> ( entry name -- entry' )
86 name ": " entry title>> 3append >>title
88 entry description>> >>description
91 : fetch-feed ( url -- feed )
92 download-feed entries>> ;
94 \ fetch-feed DEBUG add-error-logging
96 : fetch-blogroll ( blogroll -- entries )
97 [ [ feed-url>> fetch-feed ] parallel-map ] [ [ name>> ] map ] bi
98 [ '[ , <posting> ] map ] 2map concat ;
100 : sort-entries ( entries -- entries' )
101 [ [ date>> ] compare invert-comparison ] sort ;
103 : update-cached-postings ( -- )
104 blogroll fetch-blogroll sort-entries 8 short head [
105 posting new delete-tuples
106 [ insert-tuple ] each
109 : <update-action> ( -- action )
112 update-cached-postings
113 URL" $planet-factor/admin" <redirect>
116 : <delete-blog-action> ( -- action )
118 [ validate-integer-id ] >>validate
121 "id" value <blog> delete-tuples
122 URL" $planet-factor/admin" <redirect>
125 : validate-blog ( -- )
127 { "name" [ v-one-line ] }
128 { "www-url" [ v-url ] }
129 { "feed-url" [ v-url ] }
132 : deposit-blog-slots ( blog -- )
133 { "name" "www-url" "feed-url" } deposit-slots ;
135 : <new-blog-action> ( -- action )
137 { planet-factor "new-blog" } >>template
139 [ validate-blog ] >>validate
143 [ deposit-blog-slots ]
147 "$planet-factor/admin/edit-blog" >>path
148 swap id>> "id" set-query-param
154 : <edit-blog-action> ( -- action )
158 "id" value <blog> select-tuple from-object
161 { planet-factor "edit-blog" } >>template
170 [ deposit-blog-slots ]
174 "$planet-factor/admin" >>path
175 swap id>> "id" set-query-param
181 : <planet-factor-admin> ( -- responder )
182 planet-factor-admin new-dispatcher
183 <edit-blogroll-action> "blogroll" add-main-responder
184 <update-action> "update" add-responder
185 <new-blog-action> "new-blog" add-responder
186 <edit-blog-action> "edit-blog" add-responder
187 <delete-blog-action> "delete-blog" add-responder ;
189 SYMBOL: can-administer-planet-factor?
191 can-administer-planet-factor? define-capability
193 : <planet-factor> ( -- responder )
194 planet-factor new-dispatcher
195 <planet-action> "list" add-main-responder
196 <planet-feed-action> "feed.xml" add-responder
197 <planet-factor-admin> <protected>
198 "administer Planet Factor" >>description
199 { can-administer-planet-factor? } >>capabilities
200 "admin" add-responder
202 { planet-factor "planet-common" } >>template ;
204 : start-update-task ( db params -- )
205 '[ , , [ update-cached-postings ] with-db ] 10 minutes every drop ;