Handle download dialog box in SlimerJS - phantomjs

I have written a script that clicks on a link which can download a mp3 file. The problem I am facing is when the script simulates the click on that link, a download dialog box pops up like this:
Download Dialog Box
Now, I want to save this file to some path of my choice and automate this whole process. I am clueless on how to handle this dialog box.

Here's a script adapted from this blog post to download a file.
In SlimerJS it is possible to use response.body inside the onResourceReceived handler. However to prevent using too much memory it does not get anything by default. You have to first set page.captureContent to say what you want. You assign an array of regexes to page.captureContent to say which files to receive. The regex is applied to the mime-type. In the example code below I use /.*/ to mean "get everything". Using [/^image/.+$/] should just get images, etc.
var fs=require('fs');
var page = require('webpage').create();
fs.makeTree('contents');
page.captureContent = [ /.*/ ];
page.onResourceReceived = function(response) {
if(response.stage!="end" || !response.bodySize)
{
return;
}
var matches = response.url.match(/[/]([^/]+)$/);
var fname = "contents/"+matches[1];
console.log("Saving "+response.bodySize+" bytes to "+fname);
fs.write(fname,response.body);
phantom.exit();
};
page.onResourceRequested = function(requestData, networkRequest) {
//console.log('Request (#' + requestData.id + '): ' + JSON.stringify(requestData));
};
page.open("http://....mp3", function(){
});

You can't control a dialog box. SlimerJS doesn't have API for this action.

Firefox generates a temp "downloadfile.extension.part" file which contains the content. Just simply rename the file ex. myfile.csv.part > myfile.csv
locally if working on a mac you should find the .part file in the downloads directory, on linux /temp/ folder
Not the most elegant solution but should do the trick

Related

Splitting pages within a PDF with ArcoJS / Acrobat JS with a given array of names

So, I am super new to using the JS interface within Acrobat and I am trying to write something for splitting PDF pages easily to an array of file names. I cannot find a lot of snippets around that seems to show me how to work with Acrobat JS. Can you provide some guidance on how a script similar to such will look like and how I can execute it within Acrobat? Thanks!
First, you will need Acrobat Professional or Standard for JS tasks generally. And you will execute code like you do within your normal terminal/immediates window within what they call the debugger tool for Javascript. You will need to first activate JS within Acrobat by going to Preferences and activate the Debugger. After you set the preferences, restart Acrobat, and find the tools for the Javascript debugger (different places based on your version, google it if you can't find it).
Once you get the debugger running, run the code below after modifying for the file names you wish to use and the appropriate file paths. Then highlight the entire code block and hit Ctrl+Enter and it will automatically split the pages for you. Enjoy.
Split();
function Split() {
var totalPages = this.numPages;
var i;
var arrNames = [ "SOME ARRAY" ];
var targetPath = "/C/Users/...SOMEPATH/";
try {
for (i = 0; i < totalPages; i++) {
this.extractPages({
nStart: i,
cPath: targetPath +arrNames[i] + ".pdf"
});
console.println("Completed: " + targetPath + arrNames[i] + ".pdf");
}
} catch (e) {
console.println("Aborted: " + e);
}
}

How to download single sheet as PDF to my local device directly (not export to Google Drive)?

I've come across a few scripts to use with Google Sheets that will let me export a single sheet to a file on my Google Drive. However, instead of sending it there, I want it to download to my computer directly.
I'm looking to replace this...
DriveApp.createFile()
with something else that will send the file, with a customized name, as a file to download in my browser.
You want to download a specific sheet in the active Spreadsheet as a PDF file.
If my understanding is correct, how about this sample script? This sample script supposes the following points.
Script is the container-bound script of Spreadsheet.
Sheet you want to download is in the active Spreadsheet.
When the script is run, a dialog is opened. When the button is clicked, the active sheet is downloaded as a PDF file to the local PC.
In this script, the PDF file is downloaded by Javascript. So I used a dialog to execute Javascript.
Sample script:
When you use this script, please copy and paste this script to the script editor. Script is the container-bound script of Spreadsheet. When you run downloadSheetAsPDF(), a dialog is opened on the Spreadsheet. Please check it. When you click the button, the PDF file is downloaded.
function downloadSheetAsPDF() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetId = ss.getActiveSheet().getSheetId();
var url = "https://docs.google.com/a/mydomain.org/spreadsheets/d/" + ss.getId() + "/export?exportFormat=pdf&gid=" + sheetId + "&access_token=" + ScriptApp.getOAuthToken();
var str = '<input type="button" value="Download" onClick="location.href=\'' + url + '\'" >';
var html = HtmlService.createHtmlOutput(str);
SpreadsheetApp.getUi().showModalDialog(html, "sample");
}
Note:
This is a simple sample script. So please modify this for your situation.
If you want to download the specific sheet name, please modify to var sheetId = ss.getSheetByName("sheetName").getSheetId();.
References:
Class HtmlService
Class Ui
If this was not the result you want, I apologize.
Edit:
You want to use the specific filename of PDF file, when the file is downloaded.
You want to automatically download when the script is run.
If my understanding is correct, how about this sample script? The flow of this sample script is as follows. I think that there might be several answers for your situation. So please think of this as just one of several answers.
PDF file is created as a temporal file.
Create the URL for downloading.
Open a dialog box and the PDF file is automatically downloaded by running Javascript.
Remove the temporary file.
Close the dialog box.
Sample script:
function downloadSheetAsPDF2() {
var filename = "sampleFilename.pdf"; // Please set the filename here.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetId = ss.getActiveSheet().getSheetId();
// Creat PDF file as a temporary file and create URL for downloading.
var url = "https://docs.google.com/a/mydomain.org/spreadsheets/d/" + ss.getId() + "/export?exportFormat=pdf&gid=" + sheetId + "&access_token=" + ScriptApp.getOAuthToken();
var blob = UrlFetchApp.fetch(url).getBlob().setName(filename);
var file = DriveApp.createFile(blob);
var dlUrl = "https://drive.google.com/uc?export=download&id=" + file.getId();
// Open a dialog and run Javascript for downloading the file.
var str = '<script>window.location.href="' + dlUrl + '"</script>';
var html = HtmlService.createHtmlOutput(str);
SpreadsheetApp.getUi().showModalDialog(html, "sample");
file.setTrashed(true);
// This is used for closing the dialog.
Utilities.sleep(3000);
var closeHtml = HtmlService.createHtmlOutput("<script>google.script.host.close()</script>");
SpreadsheetApp.getUi().showModalDialog(closeHtml, "sample");
}
Alternatively, You can use the anchor tag to download to local drive with a custom name:
Flow:
Create custom download url for pdf export from using spreadsheet id
UrlFetchApp to fetch the pdf
Serve pdf as Data URI using anchor tag
Use anchor tag's download attribute to provide the custom name for the download
Snippet:
function downloadPdfToDesktop() {
var ss = SpreadsheetApp.getActive(),
id = ss.getId(),
sht = ss.getActiveSheet(),
shtId = sht.getSheetId(),
url =
'https://docs.google.com/spreadsheets/d/' +
id +
'/export' +
'?format=pdf&gid=' +
shtId;
var val = 'PDFNAME';//custom pdf name here
val += '.pdf';
//can't download with a different filename directly from server
//download and remove content-disposition header and serve as a dataURI
//Use anchor tag's download attribute to provide a custom filename
var res = UrlFetchApp.fetch(url, {
headers: { Authorization: 'Bearer ' + ScriptApp.getOAuthToken() },
});
SpreadsheetApp.getUi().showModelessDialog(
HtmlService.createHtmlOutput(
'<a target ="_blank" download="' +
val +
'" href = "data:application/pdf;base64,' +
Utilities.base64Encode(res.getContent()) +
'">Click here</a> to download, if download did not start automatically' +
'<script> \
var a = document.querySelector("a"); \
a.addEventListener("click",()=>{setTimeout(google.script.host.close,10)}); \
a.click(); \
</script>'
).setHeight(50),
'Downloading PDF..'
);
}

Photoshop script suddenly stopped working - Error 8000

So I made a script for Photoshop based on this generator
The important part is
#target photoshop
function main() {
// prompt user to select source file, cancel returns null
var sourceFile = File.openDialog("Select a 1:1 sqaure PNG file that is at least 618x618.", "*.png", false);
if (sourceFile == null) {
// user canceled
return;
}
var doc = open(sourceFile, OpenDocumentType.PNG);
if (doc == null) {
alert("Oh shit!\nSomething is wrong with the file. Make sure it is a valid PNG file.");
return;
}
....
}
main();
this allways worked. But when today I wanted to change something in the script (I haven't even started yet and not used it for about 2 weeks) I suddendly only get an error (translated from german):
Error 8000: The file can not be opened since the parameters for opening are incorrect.
Line:764
-> doc = open(sourceFile, OpenDocumentType.PNG);
How can I open a PNG file via a File.Open dialog in a Photoshop script?
I already tried to add the app
var doc = app.open(sourceFile, OpenDocumentType.PNG);
to remove the document type specifier
var doc = open(sourceFile);
or to add this as I saw it in many forums
var doc = open(sourceFile, OpenDocumentType.PNG, undefined);
and variations between them. Nothing helped so far.
For debugging I also added
alert(sourceFile);
before the according line and get e.g.
~/Desktop/Example/originalImage_2000x2000.png
The problem apparently was with Photshop in general!
When I opened Photshop I didn't even get the default view of last opened files etc and actually was not able to open any file ... but never tested this first.
After rebooting the PC and launching Photshop now everything went back to normal and the script just runs fine and as expected.

How to check multiple PDF files for annotations/comments?

Problem: I routinely receive PDF reports and annotate (highlight etc.) some of them. I had the bad habit of saving the annotated PDFs together with the non-annotated PDFs. I now have hundreds of PDF files in the same folder, some annotated and some not. Is there a way to check every PDF file for annotations and copy only the annotated ones to a new folder?
Thanks a lot!
I'm on Win 7 64bit, I have Adobe Acrobat XI installed and I'm able to do some beginner coding in Python and Javascript
Please ignore the following suggestion, since the answers already solved the problem.
EDIT: Following Mr. Wyss' suggestion, I created the following code for Acrobat's Javascript console to be run only once at the beginning:
counter = 1;
// Open a new report
var rep = new Report();
rep.size = 1.2;
rep.color = color.blue;
rep.writeText("Files WITH Annotations");
Then this code should be applied to all PDFs:
this.syncAnnotScan();
annots = this.getAnnots();
path = this.path;
if (annots) {
rep.color = color.black;
rep.writeText(" ");
rep.writeText(counter.toString()+"- "+path);
rep.writeText(" ");
if (counter% 20 == 0) {
rep.breakPage();
}
counter++;
}
And, at last, one code to be run only once at the end:
//Now open the report
var docRep = rep.open("files_with_annots.pdf");
There are two problems with this solution:
1. The "Action Wizard" seems to always apply the same code afresh to each PDF (that means that the "counter" variable, for instance, is meaningless; it will always be = 1. But more importantly, var "rep" will be unassigned when the middle code is run on different PDFs).
2. How can I make the codes that should be run only once run only at the beginning or at the end, instead of running everytime for every single PDF (like it does by default)?
Thank you very much again for your help!
This would be possible using the Action Wizard to put together an action.
The function to determine whether there are annotations in the document would be done in Acrobat JavaScript. Roughly, the core function would look like this:
this.syncAnnotScan() ; // updates all annots
var myAnnots = this.getAnnots() ;
if (myAnnots != null) {
// do something if there are annots
} else {
// do something if there are no annots
}
And that should get you there.
I am not completely positive, but I think there is also a Preflight check which tells you whether there are annotations in the document. If so, you would create a Preflight droplet, which would sort out the annotated and not annotated documents.
Mr. Wyss is right, here's a step-by-step guide:
In Acrobat XI Pro, go to the 'Tools' panel on the right side
Click on the 'Action Wizard' tab (you must first make it visible, though)
Click on 'Create New Action...', choose 'More tools' > 'Execute Javascript' and add it to right-hand pane > click on 'Execute Javascript' > 'Specify Settings' (uncheck 'prompt user' if you want) > paste this code:
.
this.syncAnnotScan();
var annots = this.getAnnots();
var fname = this.documentFileName;
fname = fname.replace(",", ";");
var errormsg = "";
if (annots) {
try {
this.saveAs({
cPath: "/c/folder/"+fname,
bPromptToOverwrite: false //make this 'true' if you want to be prompted on overwrites
});
} catch(e) {
for (var i in e)
{errormsg+= (i + ": " + e[i]+ " / ");}
app.alert({
cMsg: "Error! Unable to save the file under this name ('"+fname+"'- possibly an unicode string?) See this: "+errormsg,
cTitle: "Damn you Acrobat"
});
}
;}
annots = 0;
Save and run it! All your annotated PDFs will be saved to 'c:\folder' (but only if this folder already exists!)
Be sure to enable first Javascript in 'Edit' > 'Preferences...' > 'Javascript' > 'Enable Acrobat Javascript'.
VERY IMPORTANT: Acrobat's JS has a bug that doesn't allow Docs to be saved with commas (",") in their names (e.g., "Meeting with suppliers, May 11th.pdf" - this will get an error). Therefore, I substitute in the code above all "," for ";".

Create FullPage Screenshot WebDriver

Does someone knows a way to create full page screenshots using WebDriver?
I want if one of my tests fails to create a FULL PAGE (even the not visible part on the screen) screenshot before the browser close and save it on share location.
Also, if it is possible I want to output the result to Jenkins Console log.
Thanks!
You can use the following extension for Firefox: https://addons.mozilla.org/nl/firefox/addon/fireshot/
You can find its javascript code in %APPDATA%\Mozilla\Firefox\Profiles\
The extensions provide the ability to copy the screenshot to the clipboard.
You can use its JS methods to perform the screenshot. After that, you can retrieve the image from the clipboard and save it to as a file on shared location.
Image image = default(Image);
if (Clipboard.GetDataObject() != null)
{
IDataObject data = Clipboard.GetDataObject();
if (data.GetDataPresent(DataFormats.Bitmap))
{
Image image = (Image)data.GetData(DataFormats.Bitmap,true);
image.Save("image.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
}
else
{
Console.WriteLine("The Data In Clipboard is not as image format");
}
}
else
{
Console.WriteLine("The Clipboard was empty");
}
string newImageName = string.Concat(#"C:\SampleSharedFolder\", Guid.NewGuid());
image.Save(newImageName );
Console.WriteLine("Image save location: {0}", newImageName);
Once you have populated the result to Console it is really easy to output it back to Jenkins. You can find more in my article: http://automatetheplanet.com/output-mstest-tests-logs-jenkins-console-log/
You can use Snagit to perform full page screenshots. More information here: https://www.techsmith.com/tutorial-snagit-documentation.html
First you need to start the Snagit server and then follow the documentation.