ComputerCraft/RSS/feeds.lua

128 lines
3.9 KiB
Lua
Raw Normal View History

2024-03-10 23:45:44 +03:00
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