Download external images in ebook format

This commit is contained in:
Samy Pessé
2015-01-29 22:42:41 +01:00
parent 8a8ffb6134
commit 5690704444
6 changed files with 68 additions and 54 deletions
+12 -6
View File
@@ -70,20 +70,26 @@ function writeStream(filename, st) {
}
// Find a filename available
function getUniqueFilename(base) {
var ext = path.extname(base);
base = path.join(path.dirname(base), path.basename(base, ext));
function getUniqueFilename(base, filename) {
if (!filename) {
filename = base;
base = "/";
}
var filename = base+ext;
filename = path.resolve(base, filename);
var ext = path.extname(filename);
filename = path.join(path.dirname(filename), path.basename(filename, ext));
var _filename = filename+ext;
var i = 0;
while (1) {
if (!fs.existsSync(filename)) break;
filename = base+"_"+i+ext;
_filename = filename+"_"+i+ext;
i = i + 1;
}
return filename;
return path.relative(base, _filename);
}
+1 -18
View File
@@ -2,12 +2,11 @@ var _ = require("lodash");
var Q = require("q");
var fs = require("./fs");
var exec = require('child_process').exec;
var request = require("request");
var links = require("./links");
// Convert a svg file
var convertSVGFile = function(source, dest, options) {
var convertSVG = function(source, dest, options) {
if (!fs.existsSync(source)) return Q.reject(new Error("File doesn't exist: "+source));
var d = Q.defer();
@@ -29,22 +28,6 @@ var convertSVGFile = function(source, dest, options) {
return d.promise;
};
// Convert a svg file or url
var convertSVG = function(source, dest, options) {
if (!links.isExternal(source)) return convertSVGFile(source, dest, options);
return fs.tmp.file({ postfix: '.svg' })
// Download file
.then(function(tmpfile) {
return fs.writeStream(tmpfile, request(source))
.thenResolve(tmpfile);
})
.then(function(tmpfile) {
return convertSVGFile(tmpfile, dest, options);
});
};
module.exports = {
convertSVG: convertSVG,
INVALID: [".svg"]
+10
View File
@@ -84,6 +84,16 @@ module.exports = function(_write, logLevel) {
logger[levelKey].ln = _.partial(logger.logLn, level);
logger[levelKey].ok = _.partial(logger.ok, level);
logger[levelKey].fail = _.partial(logger.fail, level);
logger[levelKey].promise = function(p) {
return p.
then(function(st) {
logger[levelKey].ok();
return st;
}, function(err) {
logger[levelKey].fail();
throw err;
});
}
});
return logger;
+35 -29
View File
@@ -2,6 +2,7 @@ var Q = require('q');
var _ = require('lodash');
var path = require('path');
var cheerio = require('cheerio');
var request = require('request');
var links = require('./links');
var imgUtils = require('./images');
@@ -81,9 +82,7 @@ function normalizeHtml(src, options) {
var dest = svgId+".svg";
// Generate filename
dest = path.resolve(outputRoot, dest);
dest = fs.getUniqueFilename(dest);
dest = "/"+path.relative(outputRoot, dest);
dest = "/"+fs.getUniqueFilename(outputRoot, dest);
svgContent[dest] = content;
$(this).replaceWith($("<img>").attr("src", dest));
@@ -92,6 +91,7 @@ function normalizeHtml(src, options) {
// Find images to normalize
$("img").each(function() {
var origin = undefined;
var src = $(this).attr("src");
var isExternal = links.isExternal(src);
@@ -102,12 +102,19 @@ function normalizeHtml(src, options) {
// Convert if needed
if (options.convertImages) {
// If image is external and ebook, then downlaod the images
if (isExternal) {
origin = src;
src = "/"+fs.getUniqueFilename(outputRoot, path.basename(src));
src = links.toAbsolute(src, options.base, options.output);
isExternal = false;
}
var ext = path.extname(src);
var srcAbs = path.join("/", options.base, src);
// Test image extension
if (_.contains(imgUtils.INVALID, ext)) {
var srcAbs = isExternal? src : path.join("/", options.base, src);
if (imgConversionCache[outputRoot][srcAbs]) {
// Already converted
src = imgConversionCache[outputRoot][srcAbs];
@@ -116,21 +123,11 @@ function normalizeHtml(src, options) {
var dest = "";
// Replace extension
if (isExternal) {
dest = path.basename(srcAbs, ext)+".png";
} else {
dest = path.join(path.dirname(srcAbs), path.basename(srcAbs, ext)+".png");
dest = dest[0] == "/"? dest.slice(1) : dest;
}
// Absolute with input
dest = path.resolve(outputRoot, dest);
dest = path.join(path.dirname(srcAbs), path.basename(srcAbs, ext)+".png");
dest = dest[0] == "/"? dest.slice(1) : dest;
// Get a name that doesn't exists
dest = fs.getUniqueFilename(dest);
// Reset as relative to book
dest = path.relative(outputRoot, dest);
dest = fs.getUniqueFilename(outputRoot, dest);
options.book.log.debug.ln("detect invalid image (will be converted to png):", srcAbs);
@@ -139,6 +136,7 @@ function normalizeHtml(src, options) {
// Push to convert
toConvert.push({
origin: origin,
content: svgContent[srcAbs],
source: isExternal? srcAbs : path.join("./", srcAbs),
dest: path.join("./", dest)
@@ -150,6 +148,14 @@ function normalizeHtml(src, options) {
// Reset as relative to output
src = links.toAbsolute(src, options.base, options.output);
}
else if (origin) {
// Need to downlaod image
toConvert.push({
origin: origin,
source: path.join("./", srcAbs)
});
}
}
$(this).attr("src", src);
@@ -204,29 +210,29 @@ function convertImages(images, options) {
options.book.log.info.ln("convert ", images.length, "images to png");
return _.reduce(images, function(prev, image) {
var imgin = links. isExternal(image.source)? image.source : path.resolve(options.book.options.output, image.source);
var imgout = path.resolve(options.book.options.output, image.dest);
var imgin = path.resolve(options.book.options.output, image.source);
return prev
// Write image if need to be download
.then(function() {
if (!image.origin) return;
options.book.log.info("download image", image.origin);
return options.book.log.info.promise(fs.writeStream(imgin, request(image.origin)));
})
// Write svg if content
.then(function() {
if (!image.content) return;
return fs.writeFile(imgin, image.content);
})
// Convert
.then(function(){
if (!image.dest) return;
var imgout = path.resolve(options.book.options.output, image.dest);
options.book.log.debug("convert image", image.source, "to", image.dest, "...");
return imgUtils.convertSVG(imgin, imgout)
.then(function() {
options.book.log.debug.ok();
}, function(err) {
options.book.log.debug.fail();
throw err;
});
return options.book.log.debug.promise(imgUtils.convertSVG(imgin, imgout));
});
}, Q())
.then(function() {
+4
View File
@@ -18,6 +18,10 @@ describe('eBook Generator', function () {
var readmeContent = fs.readFileSync(path.join(output, "index.html"), {encoding: "utf8"});
var pageContent = fs.readFileSync(path.join(output, "sub/PAGE.html"), {encoding: "utf8"});
// Remote image
assert(pageContent.indexOf('src="../Tux.png"') >= 0);
assert(fs.existsSync(path.join(output, "Tux.png")));
assert(fs.existsSync(path.join(output, "test.png")));
assert(fs.existsSync(path.join(output, "NewTux.png")));
+6 -1
View File
@@ -1,9 +1,10 @@
##
## Image from root page
![test image to be converted](../test.svg)
![test url](http://upload.wikimedia.org/wikipedia/commons/b/b0/NewTux.svg)
## Inline svg
{% html %}
@@ -11,3 +12,7 @@
<rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)">
</svg>
{% endhtml %}
## Remote image
![remote url](http://upload.wikimedia.org/wikipedia/commons/a/af/Tux.png)