phantomjs rasterize has problems with url parameters - phantomjs

I'm on a windows machine using the standard commandline tool and using PhantomJS and a modified rasterize.js code. The problem I have is when I pass the url, http://time.com/3274245/e-cigarettes-debate/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+time/topstories+(TIME:+Top+Stories). I've redirected the StandardOutput and the StandardError and here's what I get with the above url.
StandardOutput
Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]
paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"
StandardErrror
'utm_source' is not recognized as an internal or external command,
operable program or batch file.
'utm_medium' is not recognized as an internal or external command,
operable program or batch file.
'utm_campaign' is not recognized as an internal or external command,
operable program or batch file.
So the question is, Is there any way resolve the problem with the parameters in the url?
Please let me know if there is any information that is missing or if anything needs to be clarified.
I'll add my modified rasterize.js below.
var page = require('webpage').create(),
system = require('system'),
address, output, size;
page.settings.userAgent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:31.0) Gecko/20100101 Firefox/31.0';
if (system.args.length < 3 || system.args.length > 5) {
console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]');
console.log(' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"');
phantom.exit(1);
} else {
address = system.args[1];
output = system.args[2];
page.viewportSize = { width: 1200, height: 1200 };
if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") {
size = system.args[3].split('*');
page.paperSize = size.length === 2 ? { width: size[0], height: size[1], margin: '0px' }
: { format: system.args[3], orientation: 'portrait', margin: '1cm' };
}
if (system.args.length > 4) {
page.zoomFactor = system.args[4];
}
page.open(address, function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
phantom.exit();
} else {
window.setTimeout(function () {
page.render(output);
phantom.exit();
}, 10000);
}
});
}

In windows cmd you need to use quotes around parameters that might have special characters. A = is a good candidate for when something breaks.
phantomjs rasterize.js "http://time.com/..." time.png
For this page specifically you might need to disable web security:
phantomjs --web-security=false rasterize.js "http://time.com/..." time.png

Related

Easiest way to convert from TIFF to PDF on AWS Lambda

I'm working on an AWS Lambda application that needs to take a TIFF file and convert it to a PDF. I'm using ImageMagick exensively, so the easiest thing to do was: convert input.tif output.pdf. That works fine in my Mac environment, but fails in to convert to a true PDF in the Lambda environment.
The ImageMagick build on Lambda seems to not support PDFs. If I run convert -list format in the Lambda environment, there's no entry for PDF. Here's my test Lambda function:
const im = require('imagemagick');
const fs = require('fs');
exports.handler = (event, context, callback) => {
var inputFileName = 'input.tif';
var imagesPath = 'assets/images';
var outputFile = '/tmp/output.pdf';
var args = [
imagesPath+'/'+inputFileName,
'-format',
'pdf',
outputFile
];
im.convert(args,
function(err, stdout, stderr){
if (err) throw err;
console.log('stdout:', stdout);
var imageRef = fs.readFileSync(outputFile);
callback(null, {
statusCode: 200,
headers: {
'Content-Type': 'application/pdf',
'Content-Disposition': 'attachment; filename=output.pdf'
},
body: imageRef.toString('base64'),
isBase64Encoded: true
});
});
}
When I run identify output.pdf (i.e. the downloaded file), the file is reported as a TIFF file:
/Users/myuser/Downloads/output.pdf TIFF 517x243 517x243+0+0 8-bit CMYK 1.1314MiB 0.000u 0:00.009
So ImageMagick seems to just be passing it through as a TIFF file.
I've tried using tiff2pdf - which is installed locally; not sure about Lambda - but that doesn't even work on my Mac. I get an error saying:
tiff2pdf: No support for /path/to/input.tif with 5 samples per pixel.

Login to salesforce.com with Phantomjs 2.0 keep asking for verification code

We are doing some tests to connect to the salesforce.com with Phantomjs 2.0.
It was working pretty good, but in the last couple of weeks salesforce.com kept asking for the verification code every new session.
Is anyone experiencing the same issue?
You can whitelist your IP address in order to stop Salesforce for asking the verification code.
Go to Setup -> Security -> Network Access and add your IP to whitelist.
This should perhaps be a comment, but as I do not have the required points to comment please forgive the "answer". This is a working answer, as I'm not very proficient in casper/phantom I will update on attempted solutions. Hopefully my attempts will help someone else.
Is anyone experiencing the same issue?
A: Yes
Problem: As of Salesforce Spring '16 update when logging into SF from a new browser SF authenticates the user with a verification code (can be tested with a new browser eg.firefox). Oddly the issue doesn't replicate with an incognito session.
Proposed solution: Create a cookies file & login to SF with the casper/phantom scripts. Saving the authentication to the JS cookies file, otherwise every login will require a verification.
Testing steps:
We can see the verification form using casper/phantom.
var fs = require('fs'); //top of script
var html = this.getHTML(); //place this in wait_function() after login()
fs.write('./output.html', html, 'w');
We can now "fill" the verification form with the emailed code
this.click('phSearchInput', function () { //'phSearchInput' found in above extract
this.fill('form', {
'phSearchInput' : '*verification_number_here*'
}, true);
2.1 There seems to be an issue with the final redirect after the verification. I'm not sure how much time I can give this (as it's not a priority) and I'm quite new to JS. I'll leave the code here for reference/testing
/*Altered from http://blog.deadlypenguin.com/blog/2013/07/09/logging-into-salesforce-with-casperjs/ */
var LOGIN_URL, LOGIN_USERNAME, LOGIN_PASSWORD, casp;
casp = require('casper').create({
viewportSize: {
width: 1024,
height: 768
},
verbose: true,
logLevel: 'debug'
});
casp.userAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4');
if (!casp.cli.has('username') && !casp.cli.has('password')) {
casp.echo('Usage: $ casperjs sfdclogin.casper.js --username=USERNAME --password=PASSWORD [--prod]').exit(-1);
}
if (casp.cli.has('prod')) {
LOGIN_URL = 'https://test.salesforce.com//';
} else {
LOGIN_URL = 'https://test.salesforce.com/';
}
LOGIN_USERNAME = casp.cli.get('username');
LOGIN_PASSWORD = casp.cli.get('password');
casp.start(LOGIN_URL, function () {
this.log('Logging in', 'debug');
//login
this.fill('form', {
'username': LOGIN_USERNAME,
'pw': LOGIN_PASSWORD
}, true);
this.log('Logged in', 'debug');
});
casp.wait(5000, function () {
this.log('Varification START', 'debug');
this.fill('form', {
'emc': '*verification_number_here*'
}, true);
this.captureSelector('test.png', 'html');
this.log('Varification FINISHED', 'debug');
this.wait(6000)
}, 12000);
casp.then(function () {
//casp.waitForUrl('https://cs31.salesforce.com/home/home.jsp', function() {
this.log('Are we logged in??');
this.captureSelector('test2.png', 'html');
}, 12000);
casp.run();
Add a cookies file in hopes the verification validation is saved there. (I'll get to this when I figure out step 3).

Angular JS file upload isn't processed properly by connect-multiparty

I have been tearing my hair out for the last couple of hours and I hope someone here could help me out. I have an angular application which is using (https://github.com/danialfarid/ng-file-upload) and no matter what I try I can't seem to be able to get the files out at the other end.
I do see the correct request payload in the Chrome developer tools:
------WebKitFormBoundaryEwG0XOfjS0IjwRji
Content-Disposition: form-data; name="file"; filename="images.png"
Content-Type: image/png
------WebKitFormBoundaryEwG0XOfjS0IjwRji-
My code on the server side looks as follows, I am using a router which is using connect-multiparty.
Router.js:
router.post('/api/v1/uploaddocument', multipartyMiddleware, UserFunctions.saveDocument);
The actual save document function:
saveDocument: function(req,res)
{
console.log(req.body, req.files, req.data, req.file)
}
The controller posting this message in angular is:
iSelectClient.controller('PageUploadDocumentCtrl', ['$scope', 'Upload', function ($scope, Upload) {
$scope.$watch('files', function () {
$scope.upload($scope.files);
});
$scope.upload = function (files) {
if (files && files.length) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
Upload.upload({
url: 'http://localhost:3000/api/v1/uploaddocument',
fields: {'username': $scope.username},
file: file
}).progress(function (evt) {
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
console.log('progress: ' + progressPercentage + '% ' + evt.config.file.name);
}).success(function (data, status, headers, config) {
console.log('file ' + config.file.name + 'uploaded. Response: ' + data);
});
}
}
};
}]);
I am not using app.use(bodyparser()) on the server side, for each individual route I am defining which parser to use.
What o what could it be?
EDIT
I had an interceptor on each call which set the application type to json, so it never reached the other end correctly. Fixed now, using the exact same setup as below
I had an interceptor on each call which set the application type to json, so it never reached the other end correctly. Fixed now, using the exact same setup as below

Opening local html file with SlimerJS

I have a script that works in PhantomJS but I'm trying to switch to SlimerJS. I keep getting an error when trying to open a local file:
var webPage = require('webpage');
var system = require('system');
var page = webPage.create();
page.viewportSize = { width: 2048, height: 1536 };
console.log('Processing',system.args[1]);
page.open(
'simple.html',
function start(status) {
setTimeout(function(){
page.render(system.args[2], {format: 'png'});
phantom.exit();
},1000);
}
);
simple.html is a file located in the same directory as the script. The resulting PNG says "Address Not Found", "simple.html could not be found. Please check the name and try again."
I've also tried:
full OS path, eg /User/blah/blah/simple.html
file URI file:///Users/blah/blah/simple.html
These yield a similar result.
I'd rather not have the script publicly available for a variety of reasons. Is it possible to launch a local file with SlimerJS?
I don't think its possible. Reading the docs it specifies a url.
I got around this by running a http server
python -m SimpleHTTPServer
Then accessing it through localhost.
page.open('http://localhost:8000/simple.html',...)
A file URI does work. Something like file:///Users/name/project/file.html.

Ckeditor searching for assets in root URI, while it's application is on sub URI

I've spent the past two days trying to fix this bug, but I really don't have anymore ideas or tools to solve it. I wonder if anyone here in stackoverflow can help me.
I'm trying to fix a website source code that uses the ckeditor gem. The ckeditor gem deliver a embedded web text editor. The problem is that the gem does not do it's job when the website is placed on a subdirectory. If the website is placed in the root directory like www.domain.com it works perfectly, but when I place it at a subdirectory, like www.domain.com/website, it does not show up the text editor.
The cause of not showing the editor is that the application try to find the assets of the ckeditor gem at the root directory of the server:
Failed to load resource: the server responded with a status of 404 (Not Found) http://domain.com/assets/ckeditor/config.js?t=C3HA5RM
Failed to load resource: the server responded with a status of 404 (Not Found) http://domain.com/assets/ckeditor/skins/kama/editor.css?t=C3HA5RM
Failed to load resource: the server responded with a status of 404 (Not Found) http://domain.com/assets/ckeditor/lang/pt-br.js?t=C3HA5RM
Failed to load resource: the server responded with a status of 404 (Not Found) http://domain.com/assets/ckeditor/plugins/embed/plugin.js?t=C3HA5RM
Failed to load resource: the server responded with a status of 404 (Not Found) http://domain.com/assets/ckeditor/plugins/attachment/plugin.js?t=C3HA5RM
When the right adress would be www.domain.com/website/assets/ckeditor/config.js?t=C3HA5RM
I've really searched over all the web trying to find the solution for this, but the only few similar situations that I found didn't provided me a solution.
In this Issue, at github, the user jronallo has the exactly same problem than me. But I tried to implement his solution but was not successful.
In this commit, at the ckeditor repository, the bug seems to be fixed, but even having this fix on my gem, (ckeditor 4.0.2 and rails 3.2.2) it keeps missing the assets on SubUri.
I've also tried manipulating the CKEDITOR_BASEPATH and the Ckeditor.relative_url, manually, but not succesfull again.
Does anyone have any idea about how can solve it? I would appreciate very much.
delete in your ckeditor config external plugins.
Failed to load resource: the server responded with a status of 404 (Not Found) http://domain.com/assets/ckeditor/plugins/embed/plugin.js?t=C3HA5RM
Failed to load resource: the server responded with a status of 404 (Not Found) http://domain.com/assets/ckeditor/plugins/attachment/plugin.js?t=C3HA5RM
And it's works!
My config:
/*
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.editorConfig = function( config )
{
// Define changes to default configuration here. For example:
config.language = I18n.locale;
// config.uiColor = '#AADC6E';
/* Filebrowser routes */
// The location of an external file browser, that should be launched when "Browse Server" button is pressed.
config.filebrowserBrowseUrl = "/ckeditor/attachment_files";
// The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Flash dialog.
config.filebrowserFlashBrowseUrl = "/ckeditor/attachment_files";
// The location of a script that handles file uploads in the Flash dialog.
config.filebrowserFlashUploadUrl = "/ckeditor/attachment_files";
// The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Link tab of Image dialog.
config.filebrowserImageBrowseLinkUrl = "/ckeditor/pictures";
// The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Image dialog.
config.filebrowserImageBrowseUrl = "/ckeditor/pictures";
// The location of a script that handles file uploads in the Image dialog.
config.filebrowserImageUploadUrl = "/ckeditor/pictures";
// The location of a script that handles file uploads.
config.filebrowserUploadUrl = "/ckeditor/attachment_files";
// Rails CSRF token
config.filebrowserParams = function(){
var csrf_token = jQuery('meta[name=csrf-token]').attr('content'),
csrf_param = jQuery('meta[name=csrf-param]').attr('content'),
params = new Object();
if (csrf_param !== undefined && csrf_token !== undefined) {
params[csrf_param] = csrf_token;
}
return params;
};
config.addQueryString = function (url, params) {
var queryString = [];
if (!params)
return url;
else {
for (var i in params)
queryString.push(i + "=" + encodeURIComponent(params[ i ]));
}
return url + ( ( url.indexOf("?") != -1 ) ? "&" : "?" ) + queryString.join("&");
};
// Integrate Rails CSRF token into file upload dialogs (link, image, attachment and flash)
CKEDITOR.on('dialogDefinition', function (ev) {
// Take the dialog name and its definition from the event data.
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
var content, upload;
if ($.inArray(dialogName, ['link', 'image', 'attachment', 'flash']) > -1) {
content = (dialogDefinition.getContents('Upload') || dialogDefinition.getContents('upload'));
upload = (content == null ? null : content.get('upload'));
if (upload && upload.filebrowser['params'] == null) {
upload.filebrowser['params'] = config.filebrowserParams();
upload.action = config.addQueryString(upload.action, upload.filebrowser['params']);
}
}
});
/* Extra plugins */
// works only with en, ru, uk locales
// config.extraPlugins = "embed,attachment";
//for orfografii
config.disableNativeSpellChecker = false;
// config.removePlugins = 'contextmenu';
/* Toolbars */
config.toolbar = 'Mini';
config.toolbar_Mini =
[
['Source','-','Preview'],
['Cut','Copy','Paste','PasteText','PasteFromWord'],
['Undo','Redo','-','SelectAll','RemoveFormat'],
// ['Styles','Format'],
['Subscript', 'Superscript'],
// ['Subscript', 'Superscript', 'TextColor'],
// ['Maximize','-','About'],
['Bold','Italic','Underline'], ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote']//,
// ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
// ['Link','Unlink','Anchor'], ['Image', 'Attachment', 'Flash', 'Embed'],
// ['Table','HorizontalRule','Smiley','SpecialChar','PageBreak']
];
config.toolbar = 'VeryEasy';
config.toolbar_VeryEasy =
[
['Source','-','Preview'],
['Cut','Copy','Paste','PasteText','PasteFromWord'],
['Undo','Redo','-','SelectAll','RemoveFormat'],
// ['Styles','Format'],
['Subscript', 'Superscript', 'TextColor'],
['Maximize','-','About'],
['Bold','Italic','Underline','Strike'], ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'],
// ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
// ['Link','Unlink','Anchor'], ['Image', 'Attachment', 'Flash', 'Embed'],
['Table','HorizontalRule','Smiley','SpecialChar','PageBreak']
];
config.toolbar = 'Easy';
config.toolbar_Easy =
[
['Source', '-', 'Preview'],
['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord'],
['Undo', 'Redo', '-', 'SelectAll', 'RemoveFormat'],
['Styles', 'Format'],
['Subscript', 'Superscript', 'TextColor'],
['Maximize', '-', 'About'],
'/',
['Bold', 'Italic', 'Underline', 'Strike'],
['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', 'Blockquote'],
['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
['Link', 'Unlink', 'Anchor'],
['Image', 'Attachment', 'Flash', 'Embed'],
['Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak']
];
config.jqueryOverrideVal = true;
};
I was having issues with ckeditor searching for skins on root dir because i was loading ckeditor.js dinamically after the whole page load.
The solution I've found in this thread
was to set the global var CKEDITOR_BASEPATH before the call to ckeditor.js.