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