Mercurial > prosody-modules
comparison mod_pubsub_feed/mod_pubsub_feed.lua @ 278:653c1826739e
mod_pubsub_feed: Fetches Atom feeds and publishes to PubSub
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 27 Nov 2010 04:14:53 +0100 |
| parents | |
| children | aa0df3db4901 |
comparison
equal
deleted
inserted
replaced
| 277:07c1c3eaf0c4 | 278:653c1826739e |
|---|---|
| 1 -- Fetches Atom feeds and publishes to PubSub nodes | |
| 2 -- | |
| 3 -- Config: | |
| 4 -- Component "pubsub.example.com" "pubsub" | |
| 5 -- modules_enabled = { | |
| 6 -- "pubsub_feed"; | |
| 7 -- } | |
| 8 -- feeds = { -- node -> url | |
| 9 -- telecomix = "https://status.telecomix.org/api/statuses/public_timeline.atom"; | |
| 10 -- } | |
| 11 -- feed_pull_interval = 20 -- minutes | |
| 12 | |
| 13 local modules = hosts[module.host].modules; | |
| 14 if not modules.pubsub then | |
| 15 module:log("warn", "Pubsub needs to be loaded on this host"); | |
| 16 end | |
| 17 local add_task = require "util.timer".add_task; | |
| 18 local date, time = os.date, os.time; | |
| 19 local dt_parse = require "util.datetime".parse; | |
| 20 local http = require "net.http"; | |
| 21 local parse_feed = require "feeds".feed_from_string; | |
| 22 | |
| 23 local config = module:get_option("feeds") or { | |
| 24 planet_jabber = "http://planet.jabber.org/atom.xml"; | |
| 25 prosody_blog = "http://blog.prosody.im/feed/atom.xml"; | |
| 26 }; | |
| 27 local refresh_interval = (module:get_option("feed_pull_interval") or 15) * 60; | |
| 28 local feed_list = { } | |
| 29 for node, url in pairs(config) do | |
| 30 feed_list[node] = { url = url }; | |
| 31 end | |
| 32 | |
| 33 local function update(item, callback) | |
| 34 local headers = { }; | |
| 35 if item.data and item.last_update then | |
| 36 headers["If-Modified-Since"] = date("!%a, %d %b %Y %T %Z", item.last_update); | |
| 37 end | |
| 38 http.request(item.url, {headers = headers}, function(data, code, req) | |
| 39 if code == 200 then | |
| 40 item.data = data; | |
| 41 callback(item) | |
| 42 item.last_update = time(); | |
| 43 end | |
| 44 if code == 304 then | |
| 45 item.last_update = time(); | |
| 46 end | |
| 47 end); | |
| 48 end | |
| 49 | |
| 50 local actor = module.host.."/"..module.name; | |
| 51 | |
| 52 local function refresh_feeds() | |
| 53 for node, item in pairs(feed_list) do | |
| 54 update(item, function(item) | |
| 55 local feed = parse_feed(item.data); | |
| 56 module:log("debug", "node: %s", node); | |
| 57 for _, entry in ipairs(feed) do | |
| 58 entry.attr.xmlns = "http://www.w3.org/2005/Atom"; | |
| 59 | |
| 60 local e_published = entry:get_child("published"); | |
| 61 e_published = e_published and e_published[1]; | |
| 62 e_published = e_published and dt_parse(e_published); | |
| 63 local e_updated = entry:get_child("updated"); | |
| 64 e_updated = e_updated and e_updated[1]; | |
| 65 e_updated = e_updated and dt_parse(e_updated); | |
| 66 | |
| 67 local timestamp = e_published or e_updated or nil; | |
| 68 module:log("debug", "timestamp is %s, item.last_update is %s", tostring(timestamp), tostring(item.last_update)); | |
| 69 if not timestamp or not item.last_update or timestamp > item.last_update then | |
| 70 local id = entry:get_child("id"); | |
| 71 id = id[1] or item.url.."#"..timestamp; | |
| 72 module:log("debug", "publishing to %s, id %s", node, id); | |
| 73 modules.pubsub.service:publish(node, actor, id, entry) | |
| 74 end | |
| 75 end | |
| 76 end); | |
| 77 end | |
| 78 return refresh_interval; | |
| 79 end | |
| 80 | |
| 81 function init() | |
| 82 add_task(0, refresh_feeds); | |
| 83 end | |
| 84 | |
| 85 if prosody.start_time then -- already started | |
| 86 init(); | |
| 87 else | |
| 88 prosody.events.add_handler("server-started", init); | |
| 89 end | |
| 90 |
