pubsubhubbub support by samueltardieu. Fixes #148.

db4
John Benediktsson 2011-11-28 09:57:03 -08:00
parent 3356a3a3bb
commit 1eaea88912
5 changed files with 120 additions and 25 deletions

View File

@ -39,16 +39,18 @@ M: object >entry
"UTF-8" >>content-charset "UTF-8" >>content-charset
utf8 >>content-encoding ; utf8 >>content-encoding ;
TUPLE: feed-action < action title url entries ; TUPLE: feed-action < action title url hubs entries ;
: <feed-action> ( -- action ) : <feed-action> ( -- action )
feed-action new-action feed-action new-action
dup '[ dup '[
feed new feed new
_ _
[ title>> call >>title ] {
[ url>> call adjust-url >>url ] [ title>> call >>title ]
[ entries>> call process-entries >>entries ] [ url>> call adjust-url >>url ]
tri [ hubs>> [ call [ adjust-url ] map >>hubs ] when* ]
[ entries>> call process-entries >>entries ]
} cleave
<feed-content> <feed-content>
] >>display ; ] >>display ;

View File

@ -0,0 +1,41 @@
! Copyright (c) 2010 Samuel Tardieu.
! See http://factorcode.org/license.txt for BSD license.
USING: http syndication.pubsubhubbub tools.test urls ;
[
T{ request
{ method "POST" }
{ url URL" http://rfc1149.superfeedr.com:80/" }
{ version "1.1" }
{ header
H{
{ "user-agent" "Factor http.client" }
{ "connection" "close" }
}
}
{ post-data
T{ post-data
{ data
B{
104 117 98 46 109 111 100 101 61 112 117 98
108 105 115 104 38 104 117 98 46 117 114
108 61 104 116 116 112 58 47 47 119 119 119
46 114 102 99 49 49 52 57 46 110 101 116 47
98 108 111 103 47 102 101 101 100 47 38 104
117 98 46 117 114 108 61 104 116 116 112 58
47 47 119 119 119 46 114 102 99 49 49 52 57
46 110 101 116 47 98 108 111 103 47 101 110
47 102 101 101 100 47
}
}
{ content-type
"application/x-www-form-urlencoded"
}
}
}
{ cookies V{ } }
{ redirects 10 }
}
] [
{ "http://www.rfc1149.net/blog/feed/" "http://www.rfc1149.net/blog/en/feed/" } "http://rfc1149.superfeedr.com/" <ping-request>
] unit-test

View File

@ -0,0 +1,20 @@
! Copyright (c) 2010 Samuel Tardieu.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors byte-arrays kernel http http.client sequences urls.encoding ;
IN: syndication.pubsubhubbub
<PRIVATE
: <ping-data> ( feeds -- post-data )
[ url-encode "hub.url=" prepend ] map "&" join
"hub.mode=publish&" prepend >byte-array
"application/x-www-form-urlencoded" <post-data> [ data<< ] keep ;
PRIVATE>
: <ping-request> ( feeds url -- request )
[ <ping-data> ] [ <post-request> ] bi* ;
: ping ( feeds url -- )
<ping-request> http-request drop
dup code>> 204 = [ drop ] [ download-failed ] if ;

View File

@ -5,13 +5,13 @@ USING: xml.traversal kernel assocs math.order strings sequences
xml.data xml.writer io.streams.string combinators xml xml.data xml.writer io.streams.string combinators xml
xml.entities.html io.files io http.client namespaces make xml.entities.html io.files io http.client namespaces make
xml.syntax hashtables calendar.format accessors continuations xml.syntax hashtables calendar.format accessors continuations
urls present byte-arrays ; urls present byte-arrays fry arrays ;
IN: syndication IN: syndication
: any-tag-named ( tag names -- tag-inside ) : any-tag-named ( tag names -- tag-inside )
[ f ] 2dip [ tag-named nip dup ] with find 2drop ; [ f ] 2dip [ tag-named nip dup ] with find 2drop ;
TUPLE: feed title url entries ; TUPLE: feed title url entries hubs ;
: <feed> ( -- feed ) feed new ; : <feed> ( -- feed ) feed new ;
@ -65,15 +65,19 @@ TUPLE: entry title url description date ;
[ "item" tags-named [ rss2.0-entry ] map set-entries ] [ "item" tags-named [ rss2.0-entry ] map set-entries ]
tri ; tri ;
: atom-entry-link ( tag -- url/f ) : atom-links ( tag rel -- seq )
"link" tags-named [ "links" tags-named ] dip
[ "rel" attr { f "alternate" } member? ] find nip dup "alternate" = [ f 2array ] [ 1array ] if
dup [ "href" attr >url ] when ; '[ "rel" attr _ member? ] filter
[ "href" attr >url ] map ;
: atom-link ( tag rel -- url/f )
atom-links [ f ] [ first ] if-empty ;
: atom1.0-entry ( tag -- entry ) : atom1.0-entry ( tag -- entry )
<entry> swap { <entry> swap {
[ "title" tag-named children>string >>title ] [ "title" tag-named children>string >>title ]
[ atom-entry-link >>url ] [ "alternate" atom-link >>url ]
[ [
{ "content" "summary" } any-tag-named { "content" "summary" } any-tag-named
dup children>> [ string? not ] any? dup children>> [ string? not ] any?
@ -88,11 +92,12 @@ TUPLE: entry title url description date ;
} cleave ; } cleave ;
: atom1.0 ( xml -- feed ) : atom1.0 ( xml -- feed )
<feed> swap <feed> swap {
[ "title" tag-named children>string >>title ] [ "title" tag-named children>string >>title ]
[ "link" tag-named "href" attr >url >>url ] [ "alternate" atom-link >>url ]
[ "entry" tags-named [ atom1.0-entry ] map set-entries ] [ "hub" atom-links >>hubs ]
tri ; [ "entry" tags-named [ atom1.0-entry ] map set-entries ]
} cleave ;
: xml>feed ( xml -- feed ) : xml>feed ( xml -- feed )
dup main>> { dup main>> {
@ -129,14 +134,21 @@ M: byte-array parse-feed [ bytes>xml xml>feed ] with-html-entities ;
</entry> </entry>
XML] ; XML] ;
: hub>xml ( hub -- xml )
present [XML <link rel="hub" href=<-> /> XML] ;
: feed>xml ( feed -- xml ) : feed>xml ( feed -- xml )
[ title>> ] {
[ url>> present ] [ title>> ]
[ entries>> [ entry>xml ] map ] tri [ url>> present ]
[ hubs>> [ hub>xml ] map ]
[ entries>> [ entry>xml ] map ]
} cleave
<XML <XML
<feed xmlns="http://www.w3.org/2005/Atom"> <feed xmlns="http://www.w3.org/2005/Atom">
<title><-></title> <title><-></title>
<link href=<-> /> <link href=<-> />
<-> <->
<->
</feed> </feed>
XML> ; XML> ;

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel accessors sequences sorting math math.order USING: kernel accessors sequences sorting math math.order
calendar timers logging concurrency.combinators namespaces calendar timers logging concurrency.combinators namespaces
db.types db.tuples db fry locals hashtables db.types db.tuples db fry locals hashtables continuations
syndication urls xml.writer validators syndication urls xml.writer validators
html.forms html.forms
html.components html.components
@ -15,7 +15,8 @@ furnace.redirection
furnace.boilerplate furnace.boilerplate
furnace.auth.login furnace.auth.login
furnace.auth furnace.auth
furnace.syndication ; furnace.syndication
syndication.pubsubhubbub ;
IN: webapps.planet IN: webapps.planet
TUPLE: planet < dispatcher ; TUPLE: planet < dispatcher ;
@ -51,6 +52,9 @@ posting "POSTINGS"
{ "date" "DATE" TIMESTAMP +not-null+ } { "date" "DATE" TIMESTAMP +not-null+ }
} define-persistent } define-persistent
CONSTANT: hubs { { URL" http://pubsubhubbub.appspot.com/"
URL" http://pubsubhubbub.appspot.com/publish" } }
: <blog> ( id -- todo ) : <blog> ( id -- todo )
blog new blog new
swap >>id ; swap >>id ;
@ -59,9 +63,12 @@ posting "POSTINGS"
f <blog> select-tuples f <blog> select-tuples
[ name>> ] sort-with ; [ name>> ] sort-with ;
: sort-postings ( seq -- seq )
[ date>> ] inv-sort-with ;
: postings ( -- seq ) : postings ( -- seq )
posting new select-tuples posting new select-tuples
[ date>> ] inv-sort-with ; sort-postings ;
: <edit-blogroll-action> ( -- action ) : <edit-blogroll-action> ( -- action )
<page-action> <page-action>
@ -77,10 +84,19 @@ posting "POSTINGS"
{ planet "planet" } >>template ; { planet "planet" } >>template ;
: hubs-urls ( -- seq )
hubs [ first ] map ;
: ping-hubs ( -- )
{ URL" http://planet.factorcode.org/feed.xml" }
hubs [ second ] map
[ [ ping ] [ 3drop ] recover ] with each ;
: <planet-feed-action> ( -- action ) : <planet-feed-action> ( -- action )
<feed-action> <feed-action>
[ "Planet Factor" ] >>title [ "Planet Factor" ] >>title
[ URL" $planet" ] >>url [ URL" $planet" ] >>url
[ hubs-urls ] >>hubs
[ postings ] >>entries ; [ postings ] >>entries ;
:: <posting> ( entry name -- entry' ) :: <posting> ( entry name -- entry' )
@ -102,12 +118,16 @@ posting "POSTINGS"
: sort-entries ( entries -- entries' ) : sort-entries ( entries -- entries' )
[ date>> ] inv-sort-with ; [ date>> ] inv-sort-with ;
: update-cached-postings ( -- ) : set-cached-postings ( seq -- )
blogroll fetch-blogroll sort-entries 8 short head [ [
posting new delete-tuples posting new delete-tuples
[ insert-tuple ] each [ insert-tuple ] each
] with-transaction ; ] with-transaction ;
: update-cached-postings ( -- )
blogroll fetch-blogroll sort-entries 8 short head sort-postings
dup postings = [ drop ] [ set-cached-postings ping-hubs ] if ;
: <update-action> ( -- action ) : <update-action> ( -- action )
<action> <action>
[ [