Fix concurrent issue on render_multi_url example

webkit (thus phantomjs) load() does not call loadFinished at the expected timing when running concurrently. The example is changed to run non-concurrently as a work around.

Issue: http://code.google.com/p/phantomjs/issues/detail?id=1021
1.9
Dody Suria Wijaya 2013-02-01 19:56:31 -06:00 committed by Ariya Hidayat
parent fed209c546
commit 58566bbe76
2 changed files with 110 additions and 89 deletions

View File

@ -1,50 +1,60 @@
# Render Multiple URLs to file # Render Multiple URLs to file
# FIXME: For now it is fine with pure domain names: don't think it would work with paths and stuff like that
system = require 'system' system = require("system")
# Extend the Array Prototype with a 'foreach' # Render given urls
Array.prototype.forEach = (action) -> # @param array of URLs to render
for i, j in this # @param callbackPerUrl Function called after finishing each URL, including the last URL
action j, i, _len # @param callbackFinal Function called after finishing everything
RenderUrlsToFile = (urls, callbackPerUrl, callbackFinal) ->
# Render a given url to a given file urlIndex = 0 # only for easy file naming
# @param url URL to render webpage = require("webpage")
# @param file File to render to page = null
# @param callback Callback function getFilename = ->
renderUrlToFile = (url, file, callback) -> "rendermulti-" + urlIndex + ".png"
page = require('webpage').create()
page.viewportSize = { width: 800, height : 600 }
page.settings.userAgent = 'Phantom.js bot'
page.open url, (status) ->
if status isnt 'success'
console.log "Unable to render '#{url}'"
else
page.render file
next = (status, url, file) ->
page.close() page.close()
callback url, file callbackPerUrl status, url, file
retrieve()
# Read the passed args retrieve = ->
if urls.length > 0
url = urls.shift()
urlIndex++
page = webpage.create()
page.viewportSize =
width: 800
height: 600
page.settings.userAgent = "Phantom.js bot"
page.open "http://" + url, (status) ->
file = getFilename()
if status is "success"
window.setTimeout (->
page.render file
next status, url, file
), 200
else
next status, url, file
else
callbackFinal()
retrieve()
arrayOfUrls = null
if system.args.length > 1 if system.args.length > 1
arrayOfUrls = Array.prototype.slice.call system.args, 1 arrayOfUrls = Array::slice.call(system.args, 1)
else else
# Default (no args passed) # Default (no args passed)
console.log 'Usage: phantomjs render_multi_url.coffee [domain.name1, domain.name2, ...]' console.log "Usage: phantomjs render_multi_url.js [domain.name1, domain.name2, ...]"
arrayOfUrls = [ arrayOfUrls = ["www.google.com", "www.bbc.co.uk", "www.phantomjs.org"]
'www.google.com',
'www.bbc.co.uk',
'www.phantomjs.org'
]
# For each URL RenderUrlsToFile arrayOfUrls, ((status, url, file) ->
arrayOfUrls.forEach (pos, url, total) -> if status isnt "success"
file_name = "./#{url}.png" console.log "Unable to render '" + url + "'"
else
console.log "Rendered '" + url + "' at '" + file + "'"
), ->
phantom.exit()
# Render to a file
renderUrlToFile "http://#{url}", file_name, (url, file) ->
console.log "Rendered '#{url}' at '#{file}'"
if pos is total - 1
# Close Phantom if it's the last URL
phantom.exit()

View File

@ -1,62 +1,73 @@
// Render Multiple URLs to file // Render Multiple URLs to file
// FIXME: For now it is fine with pure domain names: don't think it would work with paths and stuff like that
var system = require('system'); var RenderUrlsToFile, arrayOfUrls, system;
// Extend the Array Prototype with a 'foreach' system = require("system");
Array.prototype.forEach = function (action) {
var i, len; /*
for ( i = 0, len = this.length; i < len; ++i ) { Render given urls
action(i, this[i], len); @param array of URLs to render
} @param callbackPerUrl Function called after finishing each URL, including the last URL
@param callbackFinal Function called after finishing everything
*/
RenderUrlsToFile = function(urls, callbackPerUrl, callbackFinal) {
var getFilename, next, page, retrieve, urlIndex, webpage;
urlIndex = 0;
webpage = require("webpage");
page = null;
getFilename = function() {
return "rendermulti-" + urlIndex + ".png";
};
next = function(status, url, file) {
page.close();
callbackPerUrl(status, url, file);
return retrieve();
};
retrieve = function() {
var url;
if (urls.length > 0) {
url = urls.shift();
urlIndex++;
page = webpage.create();
page.viewportSize = {
width: 800,
height: 600
};
page.settings.userAgent = "Phantom.js bot";
return page.open("http://" + url, function(status) {
var file;
file = getFilename();
if (status === "success") {
return window.setTimeout((function() {
page.render(file);
return next(status, url, file);
}), 200);
} else {
return next(status, url, file);
}
});
} else {
return callbackFinal();
}
};
return retrieve();
}; };
/** arrayOfUrls = null;
* Render a given url to a given file
* @param url URL to render
* @param file File to render to
* @param callback Callback function
*/
function renderUrlToFile(url, file, callback) {
var page = require('webpage').create();
page.viewportSize = { width: 800, height : 600 };
page.settings.userAgent = "Phantom.js bot";
page.open(url, function(status){ if (system.args.length > 1) {
if ( status !== "success") {
console.log("Unable to render '"+url+"'");
} else {
page.render(file);
}
page.close();
callback(url, file);
});
}
// Read the passed args
var arrayOfUrls;
if ( system.args.length > 1 ) {
arrayOfUrls = Array.prototype.slice.call(system.args, 1); arrayOfUrls = Array.prototype.slice.call(system.args, 1);
} else { } else {
// Default (no args passed)
console.log("Usage: phantomjs render_multi_url.js [domain.name1, domain.name2, ...]"); console.log("Usage: phantomjs render_multi_url.js [domain.name1, domain.name2, ...]");
arrayOfUrls = [ arrayOfUrls = ["www.google.com", "www.bbc.co.uk", "www.phantomjs.org"];
'www.google.com',
'www.bbc.co.uk',
'www.phantomjs.org'
];
} }
// For each URL RenderUrlsToFile(arrayOfUrls, (function(status, url, file) {
arrayOfUrls.forEach(function(pos, url, total){ if (status !== "success") {
var file_name = "./" + url + ".png"; return console.log("Unable to render '" + url + "'");
} else {
// Render to a file return console.log("Rendered '" + url + "' at '" + file + "'");
renderUrlToFile("http://"+url, file_name, function(url, file){ }
console.log("Rendered '"+url+"' at '"+file+"'"); }), function() {
if ( pos === total-1 ) { return phantom.exit();
// Close Phantom if it's the last URL
phantom.exit();
}
});
}); });