2015-03-19 02:44:47 +00:00
|
|
|
var debug = false;
|
|
|
|
|
|
|
|
var path = require("path");
|
|
|
|
var fs = require("fs");
|
|
|
|
var jsdom = require("jsdom").jsdom;
|
2015-04-21 08:26:15 +00:00
|
|
|
var prettyPrint = require("./utils").prettyPrint;
|
2015-03-19 02:44:47 +00:00
|
|
|
var serializeDocument = require("jsdom").serializeDocument;
|
|
|
|
var http = require("http");
|
2015-04-22 15:16:43 +00:00
|
|
|
var urlparse = require("url").parse;
|
2018-04-28 03:43:42 +00:00
|
|
|
var htmltidy = require("htmltidy2").tidy;
|
2015-03-19 02:44:47 +00:00
|
|
|
|
2015-04-03 10:29:05 +00:00
|
|
|
var readability = require("../index");
|
|
|
|
var Readability = readability.Readability;
|
|
|
|
var JSDOMParser = readability.JSDOMParser;
|
2015-03-19 02:44:47 +00:00
|
|
|
|
2015-04-22 15:16:43 +00:00
|
|
|
var FFX_UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:38.0) Gecko/20100101 Firefox/38.0";
|
|
|
|
|
2015-03-19 02:44:47 +00:00
|
|
|
if (process.argv.length < 3) {
|
|
|
|
console.error("Need at least a destination slug and potentially a URL (if the slug doesn't have source).");
|
|
|
|
process.exit(0);
|
2016-03-08 14:32:00 +00:00
|
|
|
throw "Abort";
|
2015-03-19 02:44:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var slug = process.argv[2];
|
2016-07-19 20:44:27 +00:00
|
|
|
var argURL = process.argv[3]; // Could be undefined, we'll warn if it is if that is an issue.
|
2015-03-19 02:44:47 +00:00
|
|
|
|
|
|
|
var destRoot = path.join(__dirname, "test-pages", slug);
|
|
|
|
|
|
|
|
fs.mkdir(destRoot, function(err) {
|
|
|
|
if (err) {
|
|
|
|
var sourceFile = path.join(destRoot, "source.html");
|
|
|
|
fs.exists(sourceFile, function(exists) {
|
|
|
|
if (exists) {
|
2016-07-19 20:44:27 +00:00
|
|
|
fs.readFile(sourceFile, {encoding: "utf-8"}, function(readFileErr, data) {
|
|
|
|
if (readFileErr) {
|
2015-03-19 02:44:47 +00:00
|
|
|
console.error("Source existed but couldn't be read?");
|
|
|
|
process.exit(1);
|
|
|
|
return;
|
|
|
|
}
|
2018-05-12 07:57:39 +00:00
|
|
|
onResponseReceived(null, data);
|
2015-03-19 02:44:47 +00:00
|
|
|
});
|
|
|
|
} else {
|
2016-07-19 20:44:27 +00:00
|
|
|
fetchSource(argURL, onResponseReceived);
|
2015-03-19 02:44:47 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
2016-07-19 20:44:27 +00:00
|
|
|
fetchSource(argURL, onResponseReceived);
|
2015-03-19 02:44:47 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
function fetchSource(url, callbackFn) {
|
|
|
|
if (!url) {
|
|
|
|
console.error("You should pass a URL if the source doesn't exist yet!");
|
|
|
|
process.exit(1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var client = http;
|
|
|
|
if (url.indexOf("https") == 0) {
|
|
|
|
client = require("https");
|
|
|
|
}
|
2015-04-22 15:16:43 +00:00
|
|
|
var options = urlparse(url);
|
|
|
|
options.headers = {'User-Agent': FFX_UA};
|
|
|
|
|
|
|
|
client.get(options, function(response) {
|
2015-03-19 02:44:47 +00:00
|
|
|
if (debug) {
|
|
|
|
console.log("STATUS:", response.statusCode);
|
|
|
|
console.log("HEADERS:", JSON.stringify(response.headers));
|
|
|
|
}
|
|
|
|
response.setEncoding("utf-8");
|
|
|
|
var rv = "";
|
|
|
|
response.on("data", function(chunk) {
|
|
|
|
rv += chunk;
|
|
|
|
});
|
|
|
|
response.on("end", function() {
|
|
|
|
if (debug) {
|
|
|
|
console.log("End received");
|
|
|
|
}
|
2018-05-25 04:32:28 +00:00
|
|
|
sanitizeSource(rv, callbackFn);
|
2015-03-19 02:44:47 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-05-25 04:32:28 +00:00
|
|
|
function sanitizeSource(html, callbackFn) {
|
|
|
|
htmltidy(serializeDocument(jsdom(html)), {
|
|
|
|
"indent": true,
|
|
|
|
"indent-spaces": 4,
|
|
|
|
"numeric-entities": true,
|
|
|
|
"output-xhtml": true,
|
|
|
|
"wrap": 0
|
|
|
|
}, callbackFn);
|
|
|
|
}
|
|
|
|
|
2018-04-28 03:43:42 +00:00
|
|
|
function onResponseReceived(error, source) {
|
|
|
|
if (error) {
|
|
|
|
console.error("Couldn't tidy source html!");
|
|
|
|
console.error(error);
|
|
|
|
return;
|
|
|
|
}
|
2015-03-19 02:44:47 +00:00
|
|
|
if (debug) {
|
|
|
|
console.log("writing");
|
|
|
|
}
|
|
|
|
var sourcePath = path.join(destRoot, "source.html");
|
|
|
|
fs.writeFile(sourcePath, source, function(err) {
|
|
|
|
if (err) {
|
|
|
|
console.error("Couldn't write data to source.html!");
|
|
|
|
console.error(err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (debug) {
|
|
|
|
console.log("Running readability stuff");
|
|
|
|
}
|
2015-03-19 21:18:58 +00:00
|
|
|
runReadability(source, path.join(destRoot, "expected.html"), path.join(destRoot, "expected-metadata.json"));
|
2015-03-19 02:44:47 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-03-19 21:18:58 +00:00
|
|
|
function runReadability(source, destPath, metadataDestPath) {
|
2018-04-24 07:41:23 +00:00
|
|
|
var uri = "http://fakehost/test/page.html";
|
|
|
|
var doc = new JSDOMParser().parse(source, uri);
|
2016-07-19 20:44:27 +00:00
|
|
|
var myReader, result, readerable;
|
2015-03-19 02:44:47 +00:00
|
|
|
try {
|
2017-11-29 13:49:50 +00:00
|
|
|
// We pass `caption` as a class to check that passing in extra classes works,
|
|
|
|
// given that it appears in some of the test documents.
|
2018-04-24 07:41:23 +00:00
|
|
|
myReader = new Readability(doc, { classesToPreserve: ["caption"] });
|
2016-07-19 20:44:27 +00:00
|
|
|
result = myReader.parse();
|
2015-03-19 02:44:47 +00:00
|
|
|
} catch (ex) {
|
|
|
|
console.error(ex);
|
2015-03-23 14:59:06 +00:00
|
|
|
ex.stack.forEach(console.log.bind(console));
|
2015-03-19 02:44:47 +00:00
|
|
|
}
|
2016-12-14 13:44:29 +00:00
|
|
|
// Use jsdom for isProbablyReaderable because it supports querySelectorAll
|
|
|
|
try {
|
|
|
|
var jsdomDoc = jsdom(source, {
|
|
|
|
features: {
|
|
|
|
FetchExternalResources: false,
|
|
|
|
ProcessExternalResources: false
|
|
|
|
}
|
|
|
|
});
|
2018-04-24 07:41:23 +00:00
|
|
|
myReader = new Readability(jsdomDoc);
|
2016-12-14 13:44:29 +00:00
|
|
|
readerable = myReader.isProbablyReaderable();
|
|
|
|
} catch (ex) {
|
|
|
|
console.error(ex);
|
|
|
|
ex.stack.forEach(console.log.bind(console));
|
|
|
|
}
|
2015-03-19 02:44:47 +00:00
|
|
|
if (!result) {
|
|
|
|
console.error("No content generated by readability, not going to write expected.html!");
|
|
|
|
return;
|
|
|
|
}
|
2015-03-19 21:18:58 +00:00
|
|
|
|
2016-07-19 20:44:27 +00:00
|
|
|
fs.writeFile(destPath, prettyPrint(result.content), function(fileWriteErr) {
|
|
|
|
if (fileWriteErr) {
|
2015-03-19 02:44:47 +00:00
|
|
|
console.error("Couldn't write data to expected.html!");
|
2016-07-19 20:44:27 +00:00
|
|
|
console.error(fileWriteErr);
|
2015-03-19 02:44:47 +00:00
|
|
|
}
|
|
|
|
|
2015-03-19 21:18:58 +00:00
|
|
|
// Delete the result data we don't care about checking.
|
|
|
|
delete result.content;
|
2016-12-09 23:28:56 +00:00
|
|
|
delete result.textContent;
|
2015-03-19 21:18:58 +00:00
|
|
|
delete result.length;
|
|
|
|
|
2015-04-03 10:29:05 +00:00
|
|
|
// Add isProbablyReaderable result
|
|
|
|
result.readerable = readerable;
|
|
|
|
|
2016-07-19 20:44:27 +00:00
|
|
|
fs.writeFile(metadataDestPath, JSON.stringify(result, null, 2) + "\n", function(metadataWriteErr) {
|
|
|
|
if (metadataWriteErr) {
|
2015-03-19 21:18:58 +00:00
|
|
|
console.error("Couldn't write data to expected-metadata.json!");
|
2016-07-19 20:44:27 +00:00
|
|
|
console.error(metadataWriteErr);
|
2015-03-19 21:18:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
process.exit(0);
|
|
|
|
});
|
2015-03-19 02:44:47 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|