hackernews2nntp
Version:
Post Hacker News Stories & Comments to an NNTP Server
208 lines (181 loc) • 6.01 kB
JavaScript
// Generated by CoffeeScript 1.8.0
(function() {
var Message, Mustache, Q, crypto, fs, json_schema, mimelib, os, path, spawn;
fs = require('fs');
path = require('path');
crypto = require('crypto');
os = require('os');
spawn = require('child_process').spawn;
Mustache = require('mustache');
json_schema = require('jjv')();
Q = require('q');
mimelib = require('mimelib');
Message = (function() {
Message.NEWSGROUP_DEFAULT = 'news.ycombinator';
Message.SCHEMA = JSON.parse(fs.readFileSync(path.join(__dirname, 'schema.json')).toString());
Message.TemplateGet = function(name, alt_dir) {
var dirs, e, err, idx, result, _i, _len;
if (alt_dir == null) {
alt_dir = '';
}
dirs = [path.resolve(__dirname, '..', 'template')];
if (alt_dir) {
dirs.unshift(alt_dir);
}
result = null;
err = null;
for (_i = 0, _len = dirs.length; _i < _len; _i++) {
idx = dirs[_i];
try {
result = fs.readFileSync(path.join(idx, "" + name + ".txt")).toString();
err = null;
break;
} catch (_error) {
e = _error;
err = e;
}
}
if (!err) {
return result;
}
throw err;
};
function Message(json_data, parts) {
var err, idx, _i, _len, _ref;
this.json_data = json_data;
this.parts = parts != null ? parts : [];
this.opt = {};
_ref = this.parts.concat(this.json_data);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
idx = _ref[_i];
err = json_schema.validate(Message.SCHEMA, idx);
if (err) {
throw new Error('invalid json input: ' + JSON.stringify(err));
}
}
}
Message.prototype.id = function() {
return "<" + this.json_data.id + "@news.ycombinator.com>";
};
Message.prototype.parent_id = function() {
if (!this.json_data.parent) {
return '';
}
return "<" + this.json_data.parent + "@news.ycombinator.com>";
};
Message.prototype.date = function() {
var d;
d = new Date(this.json_data.time * 1000);
return d.toUTCString();
};
Message.prototype.content_id = function() {
var r;
r = "" + this.json_data.time + "_" + (crypto.pseudoRandomBytes(8).toString('hex')) + "@" + (os.hostname());
return {
global: "<" + r + ">",
text: "<text_" + r + ">",
html: "<html_" + r + ">"
};
};
Message.prototype.headers = function() {
return {
newsgroup: Message.NEWSGROUP_DEFAULT,
message_id: this.id(),
boundary: crypto.pseudoRandomBytes(16).toString('hex'),
parent_msgid: this.parent_id(),
content_id: this.content_id(),
permalink: "https://news.ycombinator.com/item?id=" + this.json_data.id,
from: "" + this.json_data.by + " <" + this.json_data.by + "@example.com>",
date: this.date(),
path: os.hostname(),
profile: "https://news.ycombinator.com/user?id=" + this.json_data.by,
subject: !this.json_data.title ? '' : mimelib.encodeMimeWord(this.json_data.title)
};
};
Message.HTML_filter = function(html) {
var deferred, stderr, text, w3m;
deferred = Q.defer();
text = '';
stderr = '';
if ((html == null) || html === "") {
deferred.resolve(text);
return deferred.promise;
}
w3m = spawn('w3m', ['-T', 'text/html', '-dump', '-I', 'UTF-8', '-O', 'UTF-8', '-cols', '72', '-no-graph']);
w3m.on('error', function(err) {
return deferred.reject(new Error("w3m exec failed: " + err.message));
});
w3m.stdout.on('data', function(data) {
return text += data;
});
w3m.stderr.on('data', function(data) {
return stderr += data;
});
w3m.on('close', function(code) {
if (code === 0) {
return deferred.resolve(text);
} else {
return deferred.reject(new Error("w3m failed w/ exit code " + code + "\nw3m stderr: " + stderr));
}
});
w3m.stdin.write(html);
w3m.stdin.end();
return deferred.promise;
};
Message.prototype.polparts_collect = function() {
var deferred, idx, item, parts, _i, _len, _ref;
deferred = Q.defer();
if (this.parts.length === 0) {
deferred.resolve([]);
return deferred.promise;
}
parts = [];
idx = 0;
_ref = this.parts;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
item = _ref[_i];
Message.HTML_filter(item.text).then((function(_this) {
return function(r) {
++idx;
parts.push(r.trim());
if (idx === _this.parts.length) {
return deferred.resolve(parts);
}
};
})(this));
}
return deferred.promise;
};
Message.prototype.render = function(_tdd_hash) {
var json;
json = JSON.parse(JSON.stringify(this.json_data));
json.mail = this.headers();
if (this.json_data.type === 'poll') {
return this.polparts_collect().then((function(_this) {
return function(r) {
json.mail.polparts = r;
if (_tdd_hash) {
_tdd_hash.polparts = r;
}
return Mustache.render(Message.TemplateGet(json.type, _this.opt.alt_dir), json);
};
})(this));
} else {
return Message.HTML_filter(this.json_data.text).then((function(_this) {
return function(r) {
json.mail.body_text = r.trim();
if (_tdd_hash) {
_tdd_hash.body_text = r.trim();
}
return Mustache.render(Message.TemplateGet(json.type, _this.opt.alt_dir), json);
};
})(this));
}
};
Message.prototype.toString = function() {
return this.render();
};
return Message;
})();
module.exports = Message;
}).call(this);