98 lines
3.0 KiB
Factor
98 lines
3.0 KiB
Factor
! Copyright (C) 2006 Chris Double.
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
IN: rss
|
|
! USING: kernel http-client xml xml-utils xml-data errors io strings
|
|
! sequences xml-writer parser-combinators lazy-lists entities ;
|
|
USING: xml.utilities kernel promises parser-combinators assocs
|
|
parser-combinators.replace strings sequences xml.data xml.writer
|
|
io.streams.string combinators xml xml.entities io.files io
|
|
http.client ;
|
|
|
|
: ?children>string ( tag/f -- string/f )
|
|
[ children>string ] [ f ] if* ;
|
|
|
|
LAZY: '&' ( -- parser )
|
|
"&" token
|
|
[ blank? ] satisfy &>
|
|
[ "&" swap add ] <@ ;
|
|
|
|
: &>& ( string -- string )
|
|
'&' replace ;
|
|
|
|
TUPLE: feed title link entries ;
|
|
|
|
C: <feed> feed
|
|
|
|
TUPLE: entry title link description pub-date ;
|
|
|
|
C: <entry> entry
|
|
|
|
: rss1.0 ( xml -- feed )
|
|
[
|
|
"channel" tag-named
|
|
[ "title" tag-named children>string ] keep
|
|
"link" tag-named children>string
|
|
] keep
|
|
"item" tags-named [
|
|
[ "title" tag-named children>string ] keep
|
|
[ "link" tag-named children>string ] keep
|
|
[ "description" tag-named children>string ] keep
|
|
f "date" "http://purl.org/dc/elements/1.1/" <name>
|
|
tag-named ?children>string
|
|
<entry>
|
|
] map <feed> ;
|
|
|
|
: rss2.0 ( xml -- feed )
|
|
"channel" tag-named
|
|
[ "title" tag-named children>string ] keep
|
|
[ "link" tag-named children>string ] keep
|
|
"item" tags-named [
|
|
[ "title" tag-named children>string ] keep
|
|
[ "link" tag-named ] keep
|
|
[ "guid" tag-named dupd ? children>string ] keep
|
|
[ "description" tag-named children>string ] keep
|
|
"pubDate" tag-named children>string <entry>
|
|
] map <feed> ;
|
|
|
|
: atom1.0 ( xml -- feed )
|
|
[ "title" tag-named children>string ] keep
|
|
[ "link" tag-named "href" swap at ] keep
|
|
"entry" tags-named [
|
|
[ "title" tag-named children>string ] keep
|
|
[ "link" tag-named "href" swap at ] keep
|
|
[
|
|
dup "content" tag-named
|
|
[ nip ] [ "summary" tag-named ] if*
|
|
dup tag-children [ tag? ] contains?
|
|
[ tag-children [ write-chunk ] string-out ]
|
|
[ children>string ] if
|
|
] keep
|
|
dup "published" tag-named
|
|
[ nip ] [ "updated" tag-named ] if*
|
|
children>string <entry>
|
|
] map <feed> ;
|
|
|
|
: feed ( xml -- feed )
|
|
dup name-tag {
|
|
{ "RDF" [ rss1.0 ] }
|
|
{ "rss" [ rss2.0 ] }
|
|
{ "feed" [ atom1.0 ] }
|
|
} case ;
|
|
|
|
: read-feed ( string -- feed )
|
|
! &>& ! this will be uncommented when parser-combinators are fixed
|
|
[ string>xml ] with-html-entities feed ;
|
|
|
|
: load-news-file ( filename -- feed )
|
|
#! Load an news syndication file and process it, returning
|
|
#! it as an feed tuple.
|
|
<file-reader> [ contents read-feed ] keep stream-close ;
|
|
|
|
: news-get ( url -- feed )
|
|
#! Retrieve an news syndication file, return as a feed tuple.
|
|
http-get rot 200 = [
|
|
nip read-feed
|
|
] [
|
|
2drop "Error retrieving newsfeed file" throw
|
|
] if ;
|