198 lines
4.8 KiB
Factor
Executable File
198 lines
4.8 KiB
Factor
Executable File
! Copyright (C) 2008 Slava Pestov.
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
USING: kernel accessors sequences sorting math math.order
|
|
calendar alarms logging concurrency.combinators namespaces
|
|
db.types db.tuples db fry locals hashtables
|
|
syndication urls xml.writer validators
|
|
html.forms
|
|
html.components
|
|
http.server
|
|
http.server.dispatchers
|
|
furnace
|
|
furnace.actions
|
|
furnace.redirection
|
|
furnace.boilerplate
|
|
furnace.auth.login
|
|
furnace.auth
|
|
furnace.syndication ;
|
|
IN: webapps.planet
|
|
|
|
TUPLE: planet < dispatcher ;
|
|
|
|
SYMBOL: can-administer-planet?
|
|
|
|
can-administer-planet? define-capability
|
|
|
|
TUPLE: planet-admin < dispatcher ;
|
|
|
|
TUPLE: blog id name www-url feed-url ;
|
|
|
|
M: blog link-title name>> ;
|
|
|
|
M: blog link-href www-url>> ;
|
|
|
|
blog "BLOGS"
|
|
{
|
|
{ "id" "ID" INTEGER +db-assigned-id+ }
|
|
{ "name" "NAME" { VARCHAR 256 } +not-null+ }
|
|
{ "www-url" "WWWURL" URL +not-null+ }
|
|
{ "feed-url" "FEEDURL" URL +not-null+ }
|
|
} define-persistent
|
|
|
|
TUPLE: posting < entry id ;
|
|
|
|
posting "POSTINGS"
|
|
{
|
|
{ "id" "ID" INTEGER +db-assigned-id+ }
|
|
{ "title" "TITLE" { VARCHAR 256 } +not-null+ }
|
|
{ "url" "LINK" URL +not-null+ }
|
|
{ "description" "DESCRIPTION" TEXT +not-null+ }
|
|
{ "date" "DATE" TIMESTAMP +not-null+ }
|
|
} define-persistent
|
|
|
|
: <blog> ( id -- todo )
|
|
blog new
|
|
swap >>id ;
|
|
|
|
: blogroll ( -- seq )
|
|
f <blog> select-tuples
|
|
[ name>> ] sort-with ;
|
|
|
|
: postings ( -- seq )
|
|
posting new select-tuples
|
|
[ date>> ] inv-sort-with ;
|
|
|
|
: <edit-blogroll-action> ( -- action )
|
|
<page-action>
|
|
[ blogroll "blogroll" set-value ] >>init
|
|
{ planet "admin" } >>template ;
|
|
|
|
: <planet-action> ( -- action )
|
|
<page-action>
|
|
[
|
|
blogroll "blogroll" set-value
|
|
postings "postings" set-value
|
|
] >>init
|
|
|
|
{ planet "planet" } >>template ;
|
|
|
|
: <planet-feed-action> ( -- action )
|
|
<feed-action>
|
|
[ "Planet Factor" ] >>title
|
|
[ URL" $planet" ] >>url
|
|
[ postings ] >>entries ;
|
|
|
|
:: <posting> ( entry name -- entry' )
|
|
posting new
|
|
name ": " entry title>> 3append >>title
|
|
entry url>> >>url
|
|
entry description>> >>description
|
|
entry date>> >>date ;
|
|
|
|
: fetch-feed ( url -- feed )
|
|
download-feed entries>> ;
|
|
|
|
\ fetch-feed DEBUG add-error-logging
|
|
|
|
: fetch-blogroll ( blogroll -- entries )
|
|
[ [ feed-url>> fetch-feed ] parallel-map ] [ [ name>> ] map ] bi
|
|
[ '[ _ <posting> ] map ] 2map concat ;
|
|
|
|
: sort-entries ( entries -- entries' )
|
|
[ date>> ] inv-sort-with ;
|
|
|
|
: update-cached-postings ( -- )
|
|
blogroll fetch-blogroll sort-entries 8 short head [
|
|
posting new delete-tuples
|
|
[ insert-tuple ] each
|
|
] with-transaction ;
|
|
|
|
: <update-action> ( -- action )
|
|
<action>
|
|
[
|
|
update-cached-postings
|
|
URL" $planet/admin" <redirect>
|
|
] >>submit ;
|
|
|
|
: <delete-blog-action> ( -- action )
|
|
<action>
|
|
[ validate-integer-id ] >>validate
|
|
|
|
[
|
|
"id" value <blog> delete-tuples
|
|
URL" $planet/admin" <redirect>
|
|
] >>submit ;
|
|
|
|
: validate-blog ( -- )
|
|
{
|
|
{ "name" [ v-one-line ] }
|
|
{ "www-url" [ v-url ] }
|
|
{ "feed-url" [ v-url ] }
|
|
} validate-params ;
|
|
|
|
: deposit-blog-slots ( blog -- )
|
|
{ "name" "www-url" "feed-url" } to-object ;
|
|
|
|
: <new-blog-action> ( -- action )
|
|
<page-action>
|
|
|
|
{ planet "new-blog" } >>template
|
|
|
|
[ validate-blog ] >>validate
|
|
|
|
[
|
|
f <blog>
|
|
[ deposit-blog-slots ]
|
|
[ insert-tuple ]
|
|
bi
|
|
URL" $planet/admin" <redirect>
|
|
] >>submit ;
|
|
|
|
: <edit-blog-action> ( -- action )
|
|
<page-action>
|
|
|
|
[
|
|
validate-integer-id
|
|
"id" value <blog> select-tuple from-object
|
|
] >>init
|
|
|
|
{ planet "edit-blog" } >>template
|
|
|
|
[
|
|
validate-integer-id
|
|
validate-blog
|
|
] >>validate
|
|
|
|
[
|
|
f <blog>
|
|
[ deposit-blog-slots ]
|
|
[ "id" value >>id update-tuple ] bi
|
|
|
|
<url>
|
|
"$planet/admin" >>path
|
|
"id" value "id" set-query-param
|
|
<redirect>
|
|
] >>submit ;
|
|
|
|
: <planet-admin> ( -- responder )
|
|
planet-admin new-dispatcher
|
|
<edit-blogroll-action> "" add-responder
|
|
<update-action> "update" add-responder
|
|
<new-blog-action> "new-blog" add-responder
|
|
<edit-blog-action> "edit-blog" add-responder
|
|
<delete-blog-action> "delete-blog" add-responder
|
|
<protected>
|
|
"administer Planet Factor" >>description
|
|
{ can-administer-planet? } >>capabilities ;
|
|
|
|
: <planet> ( -- responder )
|
|
planet new-dispatcher
|
|
<planet-action> "" add-responder
|
|
<planet-feed-action> "feed.xml" add-responder
|
|
<planet-admin> "admin" add-responder
|
|
<boilerplate>
|
|
{ planet "planet-common" } >>template ;
|
|
|
|
: start-update-task ( db -- )
|
|
'[ _ [ update-cached-postings ] with-db ] 10 minutes every drop ;
|