1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
|
-- Authors: Sadrul Habib Chowdhury <imadil@gmail.com>
-- License: Public domain
-- Last Changed: Unknown
--
-- rss_feed.lua
--
-- Use:
-- You have to dopath() this script for it to work. I have set a binding
-- META+F12 for a popup-menu. You can also add %rss to the statusbar, which
-- will show a scrolling list of titles. You might want to give it a try
-- before disabling. :)
--
-- NOTES:
-- This is not a useful script. This script was written just to demonstrate
-- what idle time can do to a man.
--
-- Author:
-- Sadrul Habib Chowdhury (Adil)
-- imadil at gmail dot com
if not rss_feed then
rss_feed = {
interval=250, -- how often does the scroller update?
width = 40, -- the width of the scroller.. duh
refresh = 30 * (60*1000), -- how often to pull from the server?
url = { -- guess what
{"Slashdot", "http://slashdot.org/index.rss"},
{"CNN", "http://rss.cnn.com/rss/cnn_latest.rss"},
{"BBC", "http://newsrss.bbc.co.uk/rss/newsonline_world_edition/front_page/rss.xml"},
-- add other sites
}
}
end
local scroller_timer = nil -- the timer for the scroller
local rss_timer = nil -- timer for the rss refresh
rss_desc = ""
local rss_string = ""
local current = 1
local rss_length = 0
local feeds = {}
--
-- remove html-entities
--
local function clean(s)
s = string.gsub(s, "\r", "")
s = string.gsub(s, "\n", "")
s = string.gsub(s, "&", "&")
s = string.gsub(s, """, "\"")
s = string.gsub(s, " ", " ")
s = string.gsub(s, ">", ">")
s = string.gsub(s, "<", "<")
-- add any other conversions necessary here
return s
end
local function reconstruct_rss(src, tbl)
for _, info in pairs(tbl) do
rss_string = rss_string .. " --- "..src.."# "..clean(info[1])
end
end
--
-- If you have been looking for the worst possible rss-parser ever,
-- it's your lucky day.
--
local function get_next(str)
local t, d, r = nil,"",""
if str == nil then return t,d,r end
__, _ = string.find(str, "<item[^s]")
if not __ then return t,d,r end
r = string.sub(str, _)
__, _ = string.find(r, "<title>")
if not __ then return t,d,r end
e, s = string.find(r, "</title>")
if not e then return t,d,r end
t = string.sub(r, _+1, e-1)
r = string.sub(r, s+1)
__, _ = string.find(r, "<description>")
if not __ then return t,d,r end
e, s = string.find(r, "</description>")
if not e then return t,d,r end
d = string.sub(r, _+1, e-1)
r = string.sub(r, s+1)
return t,d,r
end
local function parse_rss(str)
local data = ""
while str do
data = data .. str
str = coroutine.yield()
end
local src = ""
local ret = ""
local new = {}
__, _ = string.find(data, "[^\n]+")
if __ then src = string.sub(data, __, _) end
-- for title, desc in string.gmatch(data,".-<item[^s].-<title>(.-)</title>.-<description>(.-)</description>.-</item>") do
title, desc, data = get_next(data)
while title do
title = clean(title)
desc = clean(desc)
rss_desc = rss_desc .. "\nTitle: "..title.."\n"..desc.."\n"
table.insert(new, {title, desc})
title,desc,data = get_next(data)
end
feeds[src] = new
rss_string = ""
for k,v in pairs(feeds) do
reconstruct_rss(k,v)
end
rss_length = string.len(rss_string)
rss_string = rss_string .. string.sub(rss_string, 1, rss_feed.width)
count = 1
rss_timer:set(rss_feed.refresh, retrieve)
end
local function retrieve_rss(src, str)
ioncore.popen_bgread("echo "..src.."&& curl " .. str .. " 2>/dev/null",
coroutine.wrap(parse_rss))
end
--
-- pull feed from each server
--
function retrieve()
local str = ""
for _, entry in pairs(rss_feed.url) do
retrieve_rss(entry[1], entry[2])
end
end
local function get_string()
return rss_string
end
local function scroll()
local st = get_string()
local show = string.sub(st, current, current+rss_feed.width)
mod_statusbar.inform("rss", "- "..show.." -")
mod_statusbar.update()
scroller_timer:set(rss_feed.interval, scroll)
current = current + 1
if current > rss_length then
current = 1
end
end
local function init_rss()
rss_timer = ioncore.create_timer()
rss_length = rss_feed.width
rss_string = string.rep('- ', rss_length)
if mod_statusbar then
-- do this iff mod_statusbar is loaded
scroller_timer = ioncore.create_timer()
mod_statusbar.inform("rss_template", string.rep("x", rss_feed.width))
scroll()
end
retrieve()
end
function show_menu()
local ret = {}
local count = 1
local function sub_rss_menu(tbl)
local ret = {}
for q, d in pairs(tbl) do
local title = clean(d[1])
local desc = clean(d[2])
table.insert(ret, menuentry(tostring(count)..". "..title,
"mod_query.message(_, '" .. string.gsub(desc, "'", "\\'") .. "')"))
count = count + 1
end
if count == 1 then
table.insert(ret, menuentry("No feed from server", "nil"))
end
return ret
end
table.insert(ret, menuentry("Re-read from server", "retrieve()"))
for title, tbl in pairs(feeds) do
count = 1
table.insert(ret, submenu("RSS Feeds from "..title, sub_rss_menu(tbl)))
end
return ret
end
init_rss()
ioncore.defbindings("WScreen", {
kpress(META.."Shift+D", "mod_query.message(_, rss_desc)"),
kpress(META.."F12", 'mod_menu.bigmenu(_, _sub, show_menu)'),
})
|