|
1 local io = io; |
|
2 local http = require "socket.http"; |
|
3 local st = require "stanza"; |
|
4 local new_stream = require "xmppstream".new; |
|
5 |
|
6 local xmlns_atom = "http://www.w3.org/2005/Atom"; |
|
7 |
|
8 module "feeds" |
|
9 |
|
10 local function new_feed_stream(feed) |
|
11 local callbacks = { |
|
12 default_ns = xmlns_atom; |
|
13 stream_ns = xmlns_atom; stream_tag = "feed"; |
|
14 |
|
15 streamopened = function (feed, attr) |
|
16 feed.notopen = nil; |
|
17 end; |
|
18 |
|
19 streamclosed = function (feed) |
|
20 end; |
|
21 |
|
22 handlestanza = function (feed, stanza) |
|
23 -- Skip tags not in the feed's default namespace |
|
24 if stanza.attr.xmlns ~= nil then |
|
25 return; |
|
26 end |
|
27 |
|
28 if stanza.name == "entry" then |
|
29 feed[#feed+1] = stanza; |
|
30 else |
|
31 feed[stanza.name] = stanza:get_text(); |
|
32 end |
|
33 end; |
|
34 }; |
|
35 |
|
36 return new_stream(feed, callbacks); |
|
37 end |
|
38 |
|
39 function feed_from_string(data) |
|
40 local feed = {notopen = true}; |
|
41 |
|
42 local stream = new_feed_stream(feed); |
|
43 stream:feed(data); |
|
44 |
|
45 return feed; |
|
46 end |
|
47 |
|
48 function open(url) |
|
49 if url:match("^file://") then |
|
50 return open_file(url); |
|
51 elseif url:match("^https?://") then |
|
52 return open_http(url); |
|
53 else |
|
54 return false, "Could not understand URL: "..url; |
|
55 end |
|
56 end |
|
57 |
|
58 function open_file(filename) |
|
59 local file, err = io.open((filename:gsub("^file://", ""))); |
|
60 if not file then |
|
61 return file, err; |
|
62 end |
|
63 |
|
64 local feed = feed_from_string(file:read("*a")); |
|
65 |
|
66 file:close(); |
|
67 |
|
68 return feed; |
|
69 end |
|
70 |
|
71 function open_http(url) |
|
72 local data, err = http.request(url); |
|
73 if not data then |
|
74 return data, err; |
|
75 end |
|
76 |
|
77 local feed = feed_from_string(data); |
|
78 |
|
79 return feed; |
|
80 end |