mirror of
https://github.com/vale981/Vulcan
synced 2025-03-06 10:01:40 -05:00
refactoring API/RSS to use server-side router
This commit is contained in:
parent
d12c585e0c
commit
572f58ef4f
11 changed files with 86 additions and 480 deletions
1
packages/rss/.npm/.gitignore
vendored
Normal file
1
packages/rss/.npm/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
node_modules
|
7
packages/rss/.npm/README
Normal file
7
packages/rss/.npm/README
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
This directory and the files immediately inside it are automatically generated
|
||||||
|
when you change this package's NPM dependencies. Commit the files in this
|
||||||
|
directory (npm-shrinkwrap.json, .gitignore, and this README) to source control
|
||||||
|
so that others run the same versions of sub-dependencies.
|
||||||
|
|
||||||
|
You should NOT check in the node_modules directory that Meteor automatically
|
||||||
|
creates; if you are using git, the .gitignore file tells git to ignore it.
|
12
packages/rss/.npm/npm-shrinkwrap.json
generated
Normal file
12
packages/rss/.npm/npm-shrinkwrap.json
generated
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"rss": {
|
||||||
|
"version": "0.0.4",
|
||||||
|
"dependencies": {
|
||||||
|
"xml": {
|
||||||
|
"version": "0.0.7"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
packages/rss/package.js
Normal file
7
packages/rss/package.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
Package.describe("RSS feed generator");
|
||||||
|
|
||||||
|
Npm.depends({rss: '0.0.4'});
|
||||||
|
|
||||||
|
Package.on_use(function (api) {
|
||||||
|
api.add_files('rss.js', 'server');
|
||||||
|
});
|
1
packages/rss/rss.js
Normal file
1
packages/rss/rss.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
RSS = Npm.require('rss');
|
|
@ -1,29 +0,0 @@
|
||||||
// serve up api at the right url
|
|
||||||
Meteor.serve('api', function(request) {
|
|
||||||
var posts = [];
|
|
||||||
var limit = parseInt(request.query['limit']);
|
|
||||||
limit = limit ? limit : 100;
|
|
||||||
Posts.find({status: STATUS_APPROVED}, {sort: {submitted: -1}, limit: limit}).forEach(function(post) {
|
|
||||||
var url = (post.url ? post.url : getPostUrl(post._id));
|
|
||||||
var properties = {
|
|
||||||
headline: post.headline,
|
|
||||||
author: post.author,
|
|
||||||
date: post.submitted,
|
|
||||||
url: url,
|
|
||||||
guid: post._id
|
|
||||||
};
|
|
||||||
|
|
||||||
if(post.body)
|
|
||||||
properties['body'] = post.body;
|
|
||||||
|
|
||||||
if(post.url)
|
|
||||||
properties['domain'] = getDomain(url);
|
|
||||||
|
|
||||||
if(twitterName = getTwitterNameById(post.userId))
|
|
||||||
properties['twitterName'] = twitterName;
|
|
||||||
|
|
||||||
posts.push(properties);
|
|
||||||
});
|
|
||||||
|
|
||||||
return JSON.stringify(posts);
|
|
||||||
});
|
|
|
@ -1,299 +0,0 @@
|
||||||
// code lifted from: https://github.com/dylang/node-xml
|
|
||||||
// note: streaming stuff isn't going to work.
|
|
||||||
//
|
|
||||||
// (The MIT License)
|
|
||||||
//
|
|
||||||
// Copyright (c) 2011 Dylan Greene <dylang@gmail.com>
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
// a copy of this software and associated documentation files (the
|
|
||||||
// 'Software'), to deal in the Software without restriction, including
|
|
||||||
// without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
// permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
// the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be
|
|
||||||
// included in all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
XML = (function() {
|
|
||||||
|
|
||||||
var XML_CHARACTER_MAP = {
|
|
||||||
'&': '&',
|
|
||||||
'"': '"',
|
|
||||||
"'": ''',
|
|
||||||
'<': '<',
|
|
||||||
'>': '>'
|
|
||||||
};
|
|
||||||
|
|
||||||
var util = {
|
|
||||||
xml_safe: function(string) {
|
|
||||||
return string && string.replace ? string.replace(/([&"<>'])/g, function(str, item) {
|
|
||||||
return XML_CHARACTER_MAP[item];
|
|
||||||
})
|
|
||||||
: string;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var DEFAULT_INDENT = ' ';
|
|
||||||
|
|
||||||
function xml (input, options) {
|
|
||||||
|
|
||||||
if (typeof options != 'object') {
|
|
||||||
options = {
|
|
||||||
indent: options
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var stream = options.stream ? new Stream() : null,
|
|
||||||
output = "",
|
|
||||||
interrupted = false,
|
|
||||||
indent = !options.indent ? ''
|
|
||||||
: options.indent === true ? DEFAULT_INDENT
|
|
||||||
: options.indent,
|
|
||||||
instant = true;
|
|
||||||
|
|
||||||
|
|
||||||
function delay (func) {
|
|
||||||
if (!instant) {
|
|
||||||
func();
|
|
||||||
} else {
|
|
||||||
process.nextTick(func);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function append (interrupt, out) {
|
|
||||||
if (out !== undefined) {
|
|
||||||
output += out;
|
|
||||||
}
|
|
||||||
if (interrupt && !interrupted) {
|
|
||||||
stream = stream || new Stream();
|
|
||||||
interrupted = true;
|
|
||||||
}
|
|
||||||
if (interrupt && interrupted) {
|
|
||||||
var data = output;
|
|
||||||
delay(function () { stream.emit('data', data) });
|
|
||||||
output = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function add (value, last) {
|
|
||||||
format(append, resolve(value, indent, indent ? 1 : 0), last);
|
|
||||||
}
|
|
||||||
|
|
||||||
function end() {
|
|
||||||
if (stream) {
|
|
||||||
var data = output;
|
|
||||||
delay(function () { stream.emit('data', data) });
|
|
||||||
|
|
||||||
stream.emit('end');
|
|
||||||
stream.readable = false;
|
|
||||||
stream.emit('close');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// disable delay delayed
|
|
||||||
delay(function () { instant = false });
|
|
||||||
|
|
||||||
if (input && input.forEach) {
|
|
||||||
input.forEach(function (value, i) {
|
|
||||||
var last;
|
|
||||||
if (i + 1 === input.length)
|
|
||||||
last = end;
|
|
||||||
add(value, last);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
add(input, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream) {
|
|
||||||
stream.readable = true;
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
function element (/*input, …*/) {
|
|
||||||
var input = Array.prototype.slice.call(arguments),
|
|
||||||
self = {
|
|
||||||
_elem: resolve(input)
|
|
||||||
};
|
|
||||||
|
|
||||||
self.push = function (input) {
|
|
||||||
if (!this.append) {
|
|
||||||
throw new Error("not assigned to a parent!");
|
|
||||||
}
|
|
||||||
var that = this;
|
|
||||||
var indent = this._elem.indent;
|
|
||||||
format(this.append, resolve(
|
|
||||||
input, indent, this._elem.icount + (indent ? 1 : 0)),
|
|
||||||
function () { that.append(true) });
|
|
||||||
};
|
|
||||||
|
|
||||||
self.close = function (input) {
|
|
||||||
if (input !== undefined) {
|
|
||||||
this.push(input);
|
|
||||||
}
|
|
||||||
if (this.end) {
|
|
||||||
this.end();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
function create_indent(character, count) {
|
|
||||||
return (new Array(count || 0).join(character || ''))
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolve(data, indent, indent_count) {
|
|
||||||
indent_count = indent_count || 0;
|
|
||||||
var indent_spaces = create_indent(indent, indent_count);
|
|
||||||
var name;
|
|
||||||
var values = data;
|
|
||||||
var interrupt = false;
|
|
||||||
|
|
||||||
if (typeof data == 'object') {
|
|
||||||
var keys = Object.keys(data);
|
|
||||||
name = keys[0];
|
|
||||||
values = data[name];
|
|
||||||
|
|
||||||
if (values._elem) {
|
|
||||||
values._elem.name = name;
|
|
||||||
values._elem.icount = indent_count;
|
|
||||||
values._elem.indent = indent;
|
|
||||||
values._elem.indents = indent_spaces;
|
|
||||||
values._elem.interrupt = values;
|
|
||||||
return values._elem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var attributes = [],
|
|
||||||
content = [];
|
|
||||||
|
|
||||||
function get_attributes(obj){
|
|
||||||
var keys = Object.keys(obj);
|
|
||||||
keys.forEach(function(key){
|
|
||||||
attributes.push(attribute(key, obj[key]));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(typeof values) {
|
|
||||||
case 'object':
|
|
||||||
if (values === null) break;
|
|
||||||
|
|
||||||
if (values._attr) {
|
|
||||||
get_attributes(values._attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (values._cdata) {
|
|
||||||
content.push('<![CDATA[' + values._cdata + ']]>');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (values.forEach) {
|
|
||||||
content.push('');
|
|
||||||
values.forEach(function(value) {
|
|
||||||
if (typeof value == 'object') {
|
|
||||||
var _name = Object.keys(value)[0];
|
|
||||||
|
|
||||||
if (_name == '_attr') {
|
|
||||||
get_attributes(value._attr);
|
|
||||||
} else {
|
|
||||||
content.push(resolve(
|
|
||||||
value, indent, indent_count + 1));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//string
|
|
||||||
content.push(create_indent(
|
|
||||||
indent, indent_count + 1) + util.xml_safe(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
content.push('');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
//string
|
|
||||||
content.push(util.xml_safe(values));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: name,
|
|
||||||
interrupt: interrupt,
|
|
||||||
attributes: attributes,
|
|
||||||
content: content,
|
|
||||||
icount: indent_count,
|
|
||||||
indents: indent_spaces,
|
|
||||||
indent: indent
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function format(append, elem, end) {
|
|
||||||
|
|
||||||
if (typeof elem != 'object') {
|
|
||||||
return append(false, elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
var len = elem.interrupt ? 1 : elem.content.length;
|
|
||||||
|
|
||||||
function proceed () {
|
|
||||||
while (elem.content.length) {
|
|
||||||
var value = elem.content.shift();
|
|
||||||
|
|
||||||
if (value === undefined) continue;
|
|
||||||
if (interrupt(value)) return;
|
|
||||||
|
|
||||||
format(append, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
append(false, (len > 1 ? elem.indents : '')
|
|
||||||
+ (elem.name ? '</' + elem.name + '>' : '')
|
|
||||||
+ (elem.indent && !end ? '\n' : ''));
|
|
||||||
|
|
||||||
if (end) {
|
|
||||||
end();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function interrupt(value) {
|
|
||||||
if (value.interrupt) {
|
|
||||||
value.interrupt.append = append;
|
|
||||||
value.interrupt.end = proceed;
|
|
||||||
value.interrupt = false;
|
|
||||||
append(true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
append(false, elem.indents
|
|
||||||
+ (elem.name ? '<' + elem.name : '')
|
|
||||||
+ (elem.attributes.length ? ' ' + elem.attributes.join(' ') : '')
|
|
||||||
+ (len ? (elem.name ? '>' : '') : (elem.name ? '/>' : ''))
|
|
||||||
+ (elem.indent && len > 1 ? '\n' : ''));
|
|
||||||
|
|
||||||
if (!len) return append(false, elem.indent ? '\n' : '');
|
|
||||||
|
|
||||||
if (!interrupt(elem)) {
|
|
||||||
proceed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function attribute(key, value) {
|
|
||||||
return key + '=' + '"' + util.xml_safe(value) + '"';
|
|
||||||
}
|
|
||||||
|
|
||||||
xml.Element = element;
|
|
||||||
|
|
||||||
return xml;
|
|
||||||
}());
|
|
|
@ -1,111 +0,0 @@
|
||||||
// code lifted from: https://github.com/dylang/node-rss
|
|
||||||
//
|
|
||||||
// (The MIT License)
|
|
||||||
//
|
|
||||||
// Copyright (c) 2011 Dylan Greene <dylang@gmail.com>
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
// a copy of this software and associated documentation files (the
|
|
||||||
// 'Software'), to deal in the Software without restriction, including
|
|
||||||
// without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
// permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
// the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be
|
|
||||||
// included in all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
RSS = (function() {
|
|
||||||
|
|
||||||
function RSS (options, items) {
|
|
||||||
options = options || {};
|
|
||||||
|
|
||||||
this.title = options.title || 'Untitled RSS Feed';
|
|
||||||
this.description = options.description || '';
|
|
||||||
this.feed_url = options.feed_url;
|
|
||||||
this.site_url = options.site_url;
|
|
||||||
this.image_url = options.image_url;
|
|
||||||
this.author = options.author;
|
|
||||||
this.items = items || [];
|
|
||||||
|
|
||||||
this.item = function (options) {
|
|
||||||
options = options || {};
|
|
||||||
var item = {
|
|
||||||
title: options.title || 'No title',
|
|
||||||
description: options.description || '',
|
|
||||||
url: options.url,
|
|
||||||
guid: options.guid,
|
|
||||||
categories: options.categories || [],
|
|
||||||
author: options.author,
|
|
||||||
date: options.date
|
|
||||||
};
|
|
||||||
|
|
||||||
this.items.push(item);
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.xml = function(indent) {
|
|
||||||
return '<?xml version="1.0" encoding="UTF-8"?>\n'
|
|
||||||
+ XML(generateXML(this), indent);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function ifTruePush(bool, array, data) {
|
|
||||||
if (bool) {
|
|
||||||
array.push(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateXML (data){
|
|
||||||
// todo: xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
|
|
||||||
|
|
||||||
var channel = [];
|
|
||||||
channel.push({ title: { _cdata: data.title } });
|
|
||||||
channel.push({ description: { _cdata: data.description || data.title } });
|
|
||||||
channel.push({ link: data.site_url || 'http://github.com/dylan/node-rss' });
|
|
||||||
// image_url set?
|
|
||||||
if (data.image_url) {
|
|
||||||
channel.push({ image: [ {url: data.image_url}, {title: data.title}, {link: data.site_url} ] });
|
|
||||||
}
|
|
||||||
channel.push({ generator: 'NodeJS RSS Module' });
|
|
||||||
channel.push({ lastBuildDate: new Date().toGMTString() });
|
|
||||||
|
|
||||||
ifTruePush(data.feed_url, channel, { 'atom:link': { _attr: { href: data.feed_url, rel: 'self', type: 'application/rss+xml' } } });
|
|
||||||
// { updated: new Date().toGMTString() }
|
|
||||||
|
|
||||||
|
|
||||||
data.items.forEach(function(item) {
|
|
||||||
var item_values = [
|
|
||||||
{ title: { _cdata: item.title } }
|
|
||||||
];
|
|
||||||
ifTruePush(item.description, item_values, { description: { _cdata: item.description } });
|
|
||||||
ifTruePush(item.url, item_values, { link: item.url });
|
|
||||||
ifTruePush(item.link || item.guid || item.title, item_values, { guid: [ { _attr: { isPermaLink: !item.guid && !!item.url } }, item.guid || item.url || item.title ] });
|
|
||||||
|
|
||||||
ifTruePush(item.author || data.author, item_values, { 'dc:creator': { _cdata: item.author || data.author } });
|
|
||||||
ifTruePush(item.date, item_values, { pubDate: new Date(item.date).toGMTString() });
|
|
||||||
channel.push({ item: item_values });
|
|
||||||
});
|
|
||||||
|
|
||||||
return { rss: [
|
|
||||||
{ _attr: {
|
|
||||||
'xmlns:dc': 'http://purl.org/dc/elements/1.1/',
|
|
||||||
'xmlns:content': 'http://purl.org/rss/1.0/modules/content/',
|
|
||||||
'xmlns:atom': 'http://www.w3.org/2005/Atom',
|
|
||||||
version: '2.0'
|
|
||||||
} },
|
|
||||||
{ channel: channel }
|
|
||||||
] };
|
|
||||||
}
|
|
||||||
|
|
||||||
return RSS;
|
|
||||||
}());
|
|
|
@ -1,18 +0,0 @@
|
||||||
// Very simple function to serve a particular function at a particular URL
|
|
||||||
|
|
||||||
// The request's path has to be _exactly_ path.
|
|
||||||
// Sure, we could make it smarter, but I'm guessing this isn't the way things
|
|
||||||
// will work long term.
|
|
||||||
Meteor.serve = function(path, fn) {
|
|
||||||
var connect = (typeof(Npm) == "undefined") ? __meteor_bootstrap__.require("connect") : Npm.require("connect");
|
|
||||||
__meteor_bootstrap__.app
|
|
||||||
.use(connect.query()) // <- XXX: we can probably assume accounts did this
|
|
||||||
.use(function(req, res, next) {
|
|
||||||
var test = ('/' + path);
|
|
||||||
if (req.url.substring(0, test.length) !== test)
|
|
||||||
return next();
|
|
||||||
|
|
||||||
// just run fn() and return it to the requester
|
|
||||||
res.end(fn(req))
|
|
||||||
});
|
|
||||||
}
|
|
58
server/router.js
Normal file
58
server/router.js
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
serveAPI = function(limit){
|
||||||
|
var posts = [];
|
||||||
|
limit = typeof limit == 'undefined' ? 100 : limit;
|
||||||
|
console.log(limit)
|
||||||
|
Posts.find({status: STATUS_APPROVED}, {sort: {submitted: -1}, limit: limit}).forEach(function(post) {
|
||||||
|
var url = (post.url ? post.url : getPostUrl(post._id));
|
||||||
|
var properties = {
|
||||||
|
headline: post.headline,
|
||||||
|
author: post.author,
|
||||||
|
date: post.submitted,
|
||||||
|
url: url,
|
||||||
|
guid: post._id
|
||||||
|
};
|
||||||
|
|
||||||
|
if(post.body)
|
||||||
|
properties['body'] = post.body;
|
||||||
|
|
||||||
|
if(post.url)
|
||||||
|
properties['domain'] = getDomain(url);
|
||||||
|
|
||||||
|
if(twitterName = getTwitterNameById(post.userId))
|
||||||
|
properties['twitterName'] = twitterName;
|
||||||
|
|
||||||
|
posts.push(properties);
|
||||||
|
});
|
||||||
|
|
||||||
|
return JSON.stringify(posts);
|
||||||
|
}
|
||||||
|
|
||||||
|
Meteor.Router.add({
|
||||||
|
'/feed.xml': function() {
|
||||||
|
var feed = new RSS({
|
||||||
|
title: getSetting('title'),
|
||||||
|
description: getSetting('tagline'),
|
||||||
|
feed_url: Meteor.absoluteUrl()+'feed.xml',
|
||||||
|
site_url: Meteor.absoluteUrl(),
|
||||||
|
image_url: Meteor.absoluteUrl()+'img/favicon.png',
|
||||||
|
});
|
||||||
|
|
||||||
|
Posts.find({status: STATUS_APPROVED}, {sort: {submitted: -1}}).forEach(function(post) {
|
||||||
|
feed.item({
|
||||||
|
title: post.headline,
|
||||||
|
description: post.body+'</br></br> <a href="'+getPostUrl(post._id)+'">Comments</a>',
|
||||||
|
author: post.author,
|
||||||
|
date: post.submitted,
|
||||||
|
url: (post.url ? post.url : getPostUrl(post._id)),
|
||||||
|
guid: post._id
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return feed.xml();
|
||||||
|
},
|
||||||
|
|
||||||
|
'/api/': serveAPI,
|
||||||
|
|
||||||
|
'/api/:limit': serveAPI
|
||||||
|
|
||||||
|
});
|
|
@ -1,23 +0,0 @@
|
||||||
// serve up RSS at the right url
|
|
||||||
Meteor.serve('feed.xml', function() {
|
|
||||||
var feed = new RSS({
|
|
||||||
title: getSetting('title'),
|
|
||||||
description: getSetting('tagline'),
|
|
||||||
feed_url: Meteor.absoluteUrl()+'feed.xml',
|
|
||||||
site_url: Meteor.absoluteUrl(),
|
|
||||||
image_url: Meteor.absoluteUrl()+'img/favicon.png',
|
|
||||||
});
|
|
||||||
|
|
||||||
Posts.find({status: STATUS_APPROVED}, {sort: {submitted: -1}}).forEach(function(post) {
|
|
||||||
feed.item({
|
|
||||||
title: post.headline,
|
|
||||||
description: post.body+'</br></br> <a href="'+getPostUrl(post._id)+'">Comments</a>',
|
|
||||||
author: post.author,
|
|
||||||
date: post.submitted,
|
|
||||||
url: (post.url ? post.url : getPostUrl(post._id)),
|
|
||||||
guid: post._id
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return feed.xml();
|
|
||||||
});
|
|
Loading…
Add table
Reference in a new issue