Skip to content

Instantly share code, notes, and snippets.

@satyr
Created April 20, 2009 16:06
Show Gist options
  • Save satyr/98601 to your computer and use it in GitHub Desktop.
Save satyr/98601 to your computer and use it in GitHub Desktop.
/* appjet:version 0.1 */
const
ItemMax = 16,
H = (function(m){
function f($){ return m[$] }
return function H(s){ return s.replace(/[&<>\"\']/g, f) };
}({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'})),
$ = function(s, a){
return s.replace(/\$[\d$]/g, function($x){
var x = $x[1];
return x === '$' ? x : a[x] || $x;
});
},
re_desc =
/<meta[^<]+name=([\'\"]?)description\1[^<]+content=([\"\']?)([^]+?)\2/i,
re_lang = /<html[^<]+lang=([\"\']?)(\w+?)\1/i;
for each(let m in (
'url,re,title,desc,author,link,ftitle,fdesc,fauthor,flink,'+
'max,lang,rev').split(',')) this[m] = request.params[m];
if(!url || !re || !title) printForm();
max = +max || ItemMax;
try { re = RegExp(re, 'mg') } catch(e){ die('Failed to compile "re".') }
({data:data, headers:headers}) = wget(url, {}, {complete: true});
data || die('wget() returned nothing.');
var channel = {
titl: ftitle || (/<title>([^<]+)<\/title/i(data) || '')[1] || url,
link: flink || url,
desc: fdesc || (re_desc(data) || 0)[3] || '',
auth: fauthor || '',
lang: lang || (re_lang(data) || 0)[2] || 'en',
date: (headers['Last-Modified'] || headers.Date || '')[0],
self: ['http://', appjet.appName, '.', appjet.mainDomain, request.path,
request.query ? '?'+ request.query : ''].join(''),
};
for(let [k, s] in channel) if(s) channel[k] = H(s);
var items = [], i = 0, m
while((m = re(data))){
let guid = md5(m[0]);
items.push({
titl: H($(title, m)),
link: H(link ? $(link, m) : channel.link + '#' + guid),
guid: guid,
desc: desc ? $(desc, m).replace(/\]\]>/g, ']]]]><![CDATA[>') : '',
auth: author ? H($(author, m)) : '',
});
if(++i >= max) break;
}
W = response.write;
page.setMode('plain');
response.setContentType('application/xml;charset=utf-8');
W("<?xml version='1.0' encoding='utf-8'?>"); W(supplant(channel, """
<rss version='2.0' xml:lang='{lang}'
xmlns:dc='http://purl.org/dc/elements/1.1/'
xmlns:atom='http://www.w3.org/2005/Atom'>
<channel>
<language>{lang}</language>
<title>{titl}</title>
<link>{link}</link>
<description>{desc}</description>
<dc:creator>{auth}</dc:creator>
<pubDate>{date}</pubDate>
<lastBuildDate>{date}</lastBuildDate>
<atom:link href='{self}' rel='self' type='application/rss+xml'/>"""));
for each(let item in rev ? items.reverse() : items) W(supplant(item, """
<item>
<title>{titl}</title>
<link>{link}</link>
<guid isPermaLink='false'>{guid}</guid>
<description><![CDATA[{desc}]]></description>
<dc:creator>{auth}</dc:creator>
</item>""")); W("""
</channel>
</rss>""");
function die(msg, err){
print(H3('Error:'), P(msg));
err && print(PRE(err.stack()));
response.stop();
}
function pli(name, desc, size){
return P(LABEL(
{'for': name},
name + (~desc.indexOf('$') ? ' [ '+ desc +' ] ' : ' ('+ desc +')'), BR(),
INPUT({name: name, id: name, size: size})));
}
function printForm(){ print(
H1('feed9en'),
P('See ', A({href: 'http://feedgen.appjet.net/'}, 'original'),' for usage.'),
FORM(
{action: '/', target: '_blank'},
FIELDSET(
LEGEND('Required'),
pli('url', 'URL', 80),
P('re (Regular expression for items)', BR(),
TEXTAREA({name: 're', rows: 3, cols: 60})),
pli('title', "Item title. Use $n to include captures ($$ for `$').", 80),
INPUT({type: 'submit'})),
FIELDSET(
LEGEND('Optional'),
pli('desc', 'Item description. Can use $n.', 80),
pli('author', 'Item author. Can use $n.', 80),
pli('link', 'Item link. Can use $n.', 80),
pli('ftitle', 'Feed title', 80),
pli('fdesc', 'Feed description', 80),
pli('fauthor', 'Feed author', 80),
pli('flink', 'Feed link', 80),
pli('lang', 'Language', 20),
pli('max', 'Max number of items. Defaults to '+ ItemMax, 10),
P(LABEL(
{'for': 'rev'},
'rev (Reverse order)', BR(),
INPUT({name: 'rev', id: 'rev', type: 'checkbox'}))))));
response.stop();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment