128 lines
3.9 KiB
Lua
128 lines
3.9 KiB
Lua
|
local FEEDS = {
|
||
|
feeds = {}
|
||
|
}
|
||
|
|
||
|
local FEEDS_PATH = "./feeds"
|
||
|
local SLAXML = require('slaxml')
|
||
|
local LOG = require('log')
|
||
|
|
||
|
-- Retrieve feeds from config files and prepare them for use
|
||
|
function FEEDS:Load()
|
||
|
self.feeds = {}
|
||
|
|
||
|
local files = fs.find(FEEDS_PATH .. "/*.json")
|
||
|
for _, v in ipairs(files) do
|
||
|
local file = fs.open(v, "r")
|
||
|
local contents = file.readAll()
|
||
|
local feed = textutils.unserialiseJSON(contents)
|
||
|
|
||
|
local response, err, _ = http.get(feed.link)
|
||
|
if response == nil then
|
||
|
LOG:Error("HTTP Error loading feed (" .. v .. "): " .. err)
|
||
|
else
|
||
|
local xml = response.readAll()
|
||
|
response.close()
|
||
|
local element
|
||
|
local in_item = false
|
||
|
local function startElement(name, nsURI, nsPrefix)
|
||
|
-- Track the current element name
|
||
|
element = name
|
||
|
if element == "item" then
|
||
|
in_item = true
|
||
|
end
|
||
|
end
|
||
|
local function text(text, cdata)
|
||
|
-- Store the text content based on the current element name
|
||
|
if element == 'title' and not feed.title then
|
||
|
feed.title = text
|
||
|
elseif in_item and not feed.last and element == 'guid' then
|
||
|
feed.last = text
|
||
|
end
|
||
|
end
|
||
|
local parser = SLAXML:parser{
|
||
|
startElement = startElement,
|
||
|
text = text
|
||
|
}
|
||
|
parser:parse(xml)
|
||
|
|
||
|
if feed.title_override then
|
||
|
feed.title = feed.title_override
|
||
|
end
|
||
|
|
||
|
table.insert(self.feeds, feed)
|
||
|
LOG:Info("Loaded feed " .. feed.title)
|
||
|
end
|
||
|
end
|
||
|
if #self.feeds == 0 then
|
||
|
LOG:Info("No feeds loaded, nothing to do")
|
||
|
return true
|
||
|
end
|
||
|
return nil
|
||
|
end
|
||
|
|
||
|
function FEEDS:ParseLatest()
|
||
|
local output = {}
|
||
|
for _, feed in ipairs(self.feeds) do
|
||
|
local response, err, _ = http.get(feed.link)
|
||
|
if response == nil then
|
||
|
LOG:Error("HTTP Error fetching feed: " .. err)
|
||
|
else
|
||
|
local xml = response.readAll()
|
||
|
response.close()
|
||
|
|
||
|
local element
|
||
|
local new_last
|
||
|
local done = false
|
||
|
local current_item = {
|
||
|
colour = feed.colour,
|
||
|
source = feed.title
|
||
|
}
|
||
|
local in_item = false
|
||
|
local function startElement(name, nsURI, nsPrefix)
|
||
|
if done then return end
|
||
|
|
||
|
-- Track the current element name
|
||
|
element = name
|
||
|
if element == "item" then
|
||
|
in_item = true
|
||
|
current_item = {
|
||
|
colour = feed.colour,
|
||
|
source = feed.title
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
local function closeElement(name, nsURI, nsPrefix)
|
||
|
if done then return end
|
||
|
|
||
|
if name == 'item' and not done then
|
||
|
table.insert(output, current_item)
|
||
|
end
|
||
|
end
|
||
|
local function text(text, cdata)
|
||
|
if done or not in_item then return end
|
||
|
|
||
|
-- Store the text content based on the current element name
|
||
|
if element == 'title' then
|
||
|
current_item.title = text
|
||
|
elseif in_item and element == 'guid' then
|
||
|
if not new_last then
|
||
|
new_last = text
|
||
|
end
|
||
|
if feed.last == text then
|
||
|
done = true
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
local parser = SLAXML:parser{
|
||
|
startElement = startElement,
|
||
|
closeElement = closeElement,
|
||
|
text = text
|
||
|
}
|
||
|
parser:parse(xml)
|
||
|
feed.last = new_last
|
||
|
end
|
||
|
end
|
||
|
return output
|
||
|
end
|
||
|
|
||
|
return FEEDS
|