How to print html source to console with phantomjs - html

I just downloaed and installed phantomjs on my machine. I copy and pasted the following script into a file called hello.js:
var page = require('webpage').create();
var url = 'https://www.google.com'
page.onLoadStarted = function () {
console.log('Start loading...');
};
page.onLoadFinished = function (status) {
console.log('Loading finished.');
phantom.exit();
};
page.open(url);
I'd like to print the complete html source (in this case from the google page) to a file or to the console. How do I do this?

Spent some time to read the documentation, it should be obvious afterwards.
var page = require('webpage').create();
page.open('http://google.com', function () {
console.log(page.content);
phantom.exit();
});

Related

Display a pdf file in the browser with sails

I have some documents in a directory and I want to show one embedded in the browser, I save the path of the document in a table and I can read the path from that table and download the document, but I can't figure out how to show the file in the browser.
I'm using the following code to send the file:
loadDocument: async function (req,res){
var SkipperDisk = require('skipper-disk');
var fileAdapter = SkipperDisk(/* optional opts */);
var fd = await Documents.find(
{
where: {id:'1'},
select: ['uploadFileFd']
}
).limit(1);
let uploadFileFd = fd[0]["uploadFileFd"];
var fileStream = fileAdapter.read(uploadFileFd);
fileStream.on('error', function (err){
return res.serverError(err);
});
res.contentType("application/pdf");
res.set("Content-disposition", "attachment; filename=" + "file"+ fd[0]["id"]+".pdf");
fileStream.pipe(res);
},
I want to call the function and load the pdf file in the browser, preferably without reloading all the page.
Clients browsers will download the pdf without trying to open the built-in PDF viewer (ie, Chrome) because of the Content-disposition: attachment header that you're sending - try using inline instead.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
res.setHeader('Content-type', 'application/pdf');
res.setHeader('Content-disposition', 'inline; filename="file' + fd[0]["id"] + '.pdf"');
I found a solution to my problem.
First I have to create a way to serve the static folder where the files are located, I found the answer here.
Then I modify the code to send the data encoded as base64 using 'base64-stream':
var readStream = fs.createReadStream(uploadFileFd);
readStream.on('open', function () {
readStream.pipe(new Base64Encode()).pipe(res);
});
readStream.on('error', function(err) {
res.end(err);
});
Finally I show the pdf file in the browser as follows:
.done(function(data){
var parent = $('embed#pdf').parent();
var newElement = "<embed src=data:application/pdf;base64,"+data+" id='pdf' width='100%' height='1200'>";
$('embed#pdf').remove();
parent.append(newElement);
})
Now I can display a pdf file in the browser embedded in my own page, thanks to all the people that try to help.

meteorjs create pdf out of rendered html Blaze template

I need to make a PDF file put of rendered with data html Blaze Template.
I need it to support utf-8, because im using some hebrew charcters, so most of the packages I tried doesn't fit the job.
I tried using jsPDF and addHTML libraries with jspdf:core package, and I added html2canvas.js file to my compatibility folder on the client folder (at the demo I paste the file to common.js).
Meteor Pad as demo : http://meteorpad.com/pad/g5GBn8TRrNHxYJ9ip/Leaderboard%20to%20html
My problem is that the callback function of addHTML is never executed (line 20 on client/app.js at the demo):
var html = Blaze.toHTMLWithData(Template.filledform, {'text' : 'יום אחד, בא אלי בחור ואמר לי:'}),
pdf = new jsPDF('p','pt','a4'),
options = {
proxy: Meteor.absoluteUrl()
},
pdf = new jsPDF('p', 'pt', 'a4');
pdf.addHTML(html, options, function() {
console.log("callBack");
return pdf.output('datauri');
});
I also tried:
var href = '',
html = Blaze.toHTMLWithData(Template.filledform, {'text' : 'יום אחד, בא אלי בחור ואמר לי:'}),
pdf = new jsPDF('p','pt','a4'),
options = {
proxy: Meteor.absoluteUrl()
};
pdf.addHTML(html, options, function() {
return href = pdf.output('datauristring');
}).then(function(a) {
console.log(a);
console.log(href);
return location.href = href;
});
but the href value never changed.

PhantomJS failing to load Google Maps

My end goal is to open a local html file with javascript embedded, creating a map with polygons, and take a screenshot of it using PhantomJS. I have written a simple JS file to do this:
var page = require('webpage').create();
page.open('https://www.google.com/maps', function(status) {
console.log('State: ' + status);
if(status === 'success') {
page.render('example.pdf', {format: 'pdf', quality: '100'});
}
phantom.exit();
});
This returns the error:
ReferenceError: Can't find variable: google
I've tried this on a local html file and on other websites using google maps and I keep getting the same error. I have been successful in taking a screenshot of other websites without google maps. Searching the internet it doesn't seem like people have had issues like this, and have been successful in taking screenshots of pages with google maps...so I'm wondering what could be wrong.
Another note: I installed PhantomJS as a gem in my rails project and am running the javascript file through the rails console using this gem. I have tried it using the standard installation of PhantomJS (v 2.0.0) and it still didn't work.
You'll have to wait for an element in the DOM.
for example on maps.google.com, you can wait for the watermark which is loaded after all tiles are loaded.
var page = require('webpage').create();
page.open('https://www.google.com/maps', function (status) {
console.log('State: ' + status);
if (status === 'success') {
waitFor(function () {
return page.evaluate(function () {
var document_contains_watermark =
document.body.contains(document.getElementById('watermark'));
return document_contains_watermark;
});
}, function () {
page.render('maps-google-com.pdf', {format: 'pdf', quality: '100'});
phantom.exit();
});
}
});
function waitFor(testFn, onReady) {
var loaded = false;
var interval = setInterval(function () {
loaded = testFn();
if (loaded) {
onReady();
clearInterval(interval);
}
}, 1000);
}
If you want to take a screenshot on a page that you developed, use the same above logic but append by yourself an element on the google maps idle event.
google.maps.event.addListenerOnce(map, 'idle', function () {
var loadedElem = document.createElement('div');
loadedElem.setAttribute("id", "idLoadedElem");
document.body.appendChild(loadedElem);
});
you should give puppeter a go, it makes that easy:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({path: 'example.pdf'});
await browser.close();
})();

Reference Google Spreadsheet (CSV) in Jekyll Data

I am managing a website displaying a lot of tabular data (language stuff) and running on Jekyll. I really like to display content based on a CSV file stored in the _data folder of Jekyll.
I would like to be able to edit / add / remove content from this CSV directly on Google and then reference it to Jekyll (like a shortcut or something that sync the CSV content from Google to my static folder).
Which way would be the simplest to reference an external file (either in the _data folder or directly in my templace). I can find the CSV file with this kind of link but downloading it every time is a hassle (https://docs.google.com/spreadsheets/d//export?format=csv).
How can Jekyll understand data from external stored file (maybe in javascript ?).
Thank you.
Getting datas from google docs is becoming harder ;-(
I've tried with jquery.ajax but I met the CORS limitation.
Then I found tabletop and it works !
go to your google spreadsheet and File > Publish to the web > Start publishing
note the publish url
download tabletop script and save it to eg: js/tabletop.js
put a link at the bottom of your _includes/header.html eg
<script src="`{{ site.baseurl }}`/js/tabletop.js"></script>
in a data.html page put
---
title: csv to json
layout: page
---
<div id="csvDatas"></div>
you can now get your datas with a js/script.js file that you've also included at the very end of you _includes/footer.html
var csvParse = function() {
// put you document url here
var sharedDocUrl = 'https://docs.google.com/spreadsheets/d/1Rk9RMD6mcH-jPA321lFTKmZsHebIkeHx0tTU0TWQYE8/pubhtml'
// can also be only the ID
// var sharedDocUrl = '1Rk9RMD6mcH-jPA321lFTKmZsHebIkeHx0tTU0TWQYE8'
var targetDiv = 'csvDatas';
// holds datas at a closure level
// this then can be accessed by closure's functions
var dataObj;
function showInfo(data, tabletop) {
dataObj = data;
var table = generateTable();
var target = document.getElementById(targetDiv);
target.appendChild(table);
}
function generateTable(){
var table = document.createElement("table");
var head = generateTableHeader();
table.appendChild(head);
var body = generateTableBody();
table.appendChild(body);
return table;
}
function generateTableHeader(){
var d = dataObj[0];
var tHead = document.createElement("thead");
var colHeader = [];
$.each(d, function( index, value){
console.log(index + ' : ' + value);
colHeader.push(index);
});
var row = generateRow(colHeader, 'th');
tHead.appendChild(row);
return tHead;
}
// this can be factorized with generateTableHeader
function generateTableBody(){
var tBody = document.createElement("tbody");
$.each(dataObj, function( index, value ){
var rowVals = [];
$.each(value, function(colnum, colval){
rowVals.push(colval);
});
var row = generateRow(rowVals);
tBody.appendChild(row);
});
return tBody;
}
function generateRow(headersArray, cellTag){
cellTag = typeof cellTag !== 'undefined' ? cellTag : 'td';
var row = document.createElement("tr");
$.each(headersArray, function( index, value){
if( value != "rowNumber"){
var cell = document.createElement(cellTag);
var cellText = document.createTextNode(value);
cell.appendChild(cellText);
row.appendChild(cell);
}
});
return row;
}
return {
init: function() {
if( $('#' + targetDiv).length ){
Tabletop.init( { key: sharedDocUrl ,
callback: showInfo,
simpleSheet: true } );
}else{
console.log('Not the good page to parse csv datas');
}
}
};
}();
$( document ).ready(function() {
csvParse.init();
});

chrome.storage.sync does not store the data

I am trying to store the data a user enters inside a textarea in a popup.html. Using jQuery on window unload the data should be synced and on window ready the data should be restored. However, when opening popup.html the content of the textarea is undefined. This is the jQuery code which I am loading in popup.html:
$(window).unload (
function save() {
var textarea = document.querySelector("#contacts").value;
// Old method of storing data locally
//localStorage["contacts"] = textarea.value;
// Save data using the Chrome extension storage API.
chrome.storage.sync.set({contacts: textarea}, function() {
console.log("Contacts saved");
});
});
$(window).ready(
function restore() {
var textarea = document.querySelector("#contacts");
// Old method of retrieving data locally
// var content = localStorage["contacts"];
chrome.storage.sync.get('contacts', function(r) {
console.log("Contacts retrieved");
var content = r["contacts"];
textarea.value = content;
});
});
From popup.js you can invoke a method in background.js file to save the data:
popup.js:
addEventListener("unload", function(){
var background = chrome.extension.getBackgroundPage();
background.mySavefunction(data);
}
background.js:
function mySaveFunction(data){
chrome.storage.sync.set(data, function(){
console.log("Data saved.");
});
}
I found a solution. Instead of using $(window).unload() I now use a submit button which needs to be clicked before closing popup.html:
$("#save-button").click(function() {
var textarea = document.querySelector("#contacts").value;
var save = {};
save["contacts"] = textarea;
// Save data using the Chrome extension storage API.
chrome.storage.sync.set(save, function() {
console.log("Contacts saved");
});
$("#confirm").text("Contacts saved.").show().fadeOut(5000);
});