Need InDesign script to run on file open - javascript

I have this javascript that saves a copy of a file. I need it to run automatically every time a file is opened and also save that copy to a specific folder. Here's what I have so far:
var myDoc = app.activeDocument;
myDoc.save();
var myFile = myDoc.fullName;
var myDate = new Date;
var mySuffix = "_Backup_" + myDate.getDate() + "_" + myDate.getMonth() + "_" + myDate.getHours() + "-" + myDate.getMinutes() + "-" + myDate.getSeconds() +".indd"
var myBaseName = myDoc.fullName.fsName.match(/(.*)\.[^\.]+$/)[1] ;
var myNewFile = new File(myBaseName + mySuffix);
myFile.copy(myNewFile);

So what you want is called an event listener. (See the section "Working with event listeners" in the InDesign scripting guide.)
Save your .jsx file in the "startup scripts" folder. (On a Mac, it's in /Applications/Adobe InDesign CS6/Scripts/startup scripts/.)
#targetengine "session"
app.addEventListener('afterOpen', function(myEvent) {
// afterOpen fires twice: once when the document opens
// and once when the window loads. Choose one,
// ignore the other.
// See: http://forums.adobe.com/message/5410190
if (myEvent.target.constructor.name !== 'Document') {
return;
}
var myDoc = myEvent.target;
// Continue on with your code from here
}

Related

Google App Script - Export Active Sheet Without Sheet Name

I am using the script below to export a sheet as Excel file but the output file name is always Document Name + Sheet Name ("Exported - Report.xlsx"). How can I modify this to only use the sheet name as file name of the exported file ("Report.xlsx")?
function ExportSheet()
{
var SheetApp = SpreadsheetApp.getActive();
SheetApp.rename("Exported");
ShtURL = SheetApp.getUrl();
ShtID = SheetApp.getId();
ShtGID = SheetApp.getSheetId();
var url = ShtURL.toString().replace("/edit", "/export?format=xlsx&gid=" + ShtGID);
var html = HtmlService.createHtmlOutput('<html><script>'
+'window.close = function(){window.setTimeout(function(){google.script.host.close()},9)};'
+'var a = document.createElement("a"); a.href="'+url+'"; a.target="_blank";'
+'if(document.createEvent){'
+' var event=document.createEvent("MouseEvents");'
+' if(navigator.userAgent.toLowerCase().indexOf("firefox")>-1){window.document.body.append(a)}'
+' event.initEvent("click",true,true); a.dispatchEvent(event);'
+'}else{ a.click() }'
+'close();'
+'</script>'
// Offer URL as clickable link in case above code fails.
+'<body style="word-break:break-word;font-family:sans-serif;">Failed to open automatically. Click here to proceed.</body>'
+'<script>google.script.host.setHeight(40);google.script.host.setWidth(410)</script>'
+'</html>')
.setWidth( 90 ).setHeight( 1 );
SpreadsheetApp.getUi().showModalDialog( html, "Opening ..." );
SheetApp.rename("Template");
}
In your situation, unfortunately, using the URL of ShtURL.toString().replace("/edit", "/export?format=xlsx&gid=" + ShtGID), the filename cannot be directly changed. So, in this case, how about the following modification?
Modified script:
function ExportSheet() {
var SheetApp = SpreadsheetApp.getActive();
SheetApp.rename("Exported");
ShtURL = SheetApp.getUrl();
ShtID = SheetApp.getId();
ShtGID = SheetApp.getSheetId();
var url = ShtURL.toString().replace("/edit", "/export?format=xlsx&gid=" + ShtGID);
// --- I modified below script.
var blob = UrlFetchApp.fetch(url, { headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() } }).getBlob();
var file = DriveApp.createFile(blob.setName(SheetApp.getSheets()[0].getSheetName()));
url = "https://drive.google.com/uc?export=download&id=" + file.getId();
// ---
var html = HtmlService.createHtmlOutput('<html><script>'
+ 'window.close = function(){window.setTimeout(function(){google.script.host.close()},9)};'
+ 'var a = document.createElement("a"); a.href="' + url + '"; a.target="_blank";'
+ 'if(document.createEvent){'
+ ' var event=document.createEvent("MouseEvents");'
+ ' if(navigator.userAgent.toLowerCase().indexOf("firefox")>-1){window.document.body.append(a)}'
+ ' event.initEvent("click",true,true); a.dispatchEvent(event);'
+ '}else{ a.click() }'
+ 'close();'
+ '</script>'
// Offer URL as clickable link in case above code fails.
+ '<body style="word-break:break-word;font-family:sans-serif;">Failed to open automatically. Click here to proceed.</body>'
+ '<script>google.script.host.setHeight(40);google.script.host.setWidth(410)</script>'
+ '</html>')
.setWidth(90).setHeight(1);
SpreadsheetApp.getUi().showModalDialog(html, "Opening ...");
SheetApp.rename("Template");
file.setTrashed(true); // Added
}
In this modification, the converted XLSX is created as a temporal file. Here, the filename is changed. And, the file is downloaded using the URL of the created file. The temporal file is removed.
Note:
From your script, I thought that you might have wanted to use the sheet name of the 1st tab. But, if you want to give the specific filename, please modify SheetApp.getSheets()[0].getSheetName() of blob.setName(SheetApp.getSheets()[0].getSheetName()).

SaveAs .rgba file extention

I'm trying to do automate my file saving to saveAs file .rgba in photoshop. So far I only manage to modify the code to save out .sgi files. Please help. Thanks
var Name = app.activeDocument.name.replace(/\.[^\.]+$/,'');
var Path = app.activeDocument.path;
var saveFile = File(Path + "/" + Name +".sgi");
var saveFile2 = File(Path + "/" + Name +".rgba");
if(saveFile2.exists)
{
saveFile2.remove();
}
rgbaSaveOptions = new SGIRGBSaveOptions();
activeDocument.saveAs(saveFile, rgbaSaveOptions, true, Extension.LOWERCASE);
saveFile.rename(Name+'.rgba');

Remove Google Form Submitted File

WORKING CODE HERE: https://jsfiddle.net/nateomardavis/e0317gb6/
ORIGINAL QUESTION BELOW
How do I remove a form-submitted file from Drive itself?
I'm having trouble sorting out why a google form is submitting files to both my drive (not in a folder) but also into an auto-generated submission folder.
I've been able to move the renamed file to a new folder and delete the copy in the auto-generated submission folder. I cannot figure out how to remove the copy that's just listed in "Drive", not in any folder.
THE PROCESS (EDIT)
Let me try to explain the process more. I have a form that collects files. Google automatically makes a folder and sub-folders. I have successfully renamed the submitted files, moved them to a new folder, and deleted them from the Google-generated folder. However, a copy of the original, unchanged file is going to Google Drive, the root folder. Steps 1-3 (below) work as expected. Step 4 is where I'm running into issues.
The original file being uploaded to a form. Note the file name.
The Google-generated folder. The file is submitted this folder.
The renamed file in a new folder. The original file is deleted from the folder above.
The original file is now showing up in Drive, not in a folder but there. The name of this file is the same as the originally uploaded one. The one which went to the "passes" folder and was then deleted from that folder.
SNIPPET
//RENAME PASSES
if (itemResponses[f].getItem().getTitle() == "PASSES") {
var files = itemResponses[f].getResponse();
//Logger.log(files.length);
if (files.length > 0) {
for (var n in files) {
var dFile = DriveApp.getFileById(files[n]);
dFile.setName("LSS - " + year + " - " + teamName + " - " + "PASSES - " + today );
teamFolder.addFile(dFile); //MOVE SUBMITTED DOCUMENTS TO THAT FOLDER
passesFolder.removeFile(dFile); //REMOVE FROM SUBMISSION FOLDER
DriveApp.getRootFolder().removeFile(dFile) // (DOES NOT WORK) REMOVE FROM DRIVE FOLDER
DriveApp.removeFile(dFile) // (DOES NOT WORK) REMOVE FROM DRIVE FOLDER
}
}
FULL CODE
function getLastResponse() {
var form = FormApp.openById('ID');
var today = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MM/dd/yyyy hh:mm a");
var year = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "YYYY");
Logger.log(today);
var formResponses = form.getResponses();
//Logger.log(formResponses.length);
var formResponse = formResponses[formResponses.length-1];
var respondentEmail = formResponse.getRespondentEmail()
var itemResponses = formResponse.getItemResponses();
Logger.log(itemResponses.length);
var teamName = itemResponses[2].getResponse();
//Logger.log("team name: " + teamName);
//CHECK FOLDERS
var dropbox = "Lititz Summer Showcase Team Check In (File responses)";
var folder, folders = DriveApp.getFoldersByName(dropbox);
var teamBox = teamName;
var teamFolder, teamFolders = DriveApp.getFoldersByName(teamBox);
var passesFolder = DriveApp.getFolderById('ID');
var rosterFolder = DriveApp.getFolderById('ID');
var teamInfoFolder = DriveApp.getFolderById('ID');
var permissionToTravelFolder = DriveApp.getFolderById('ID');
if (folders.hasNext()) { //CHECK IF DRIVE HAS FOLDER FOR FORM
folder = folders.next();
} else { //IF NOT CREATE FOLDER
folder = DriveApp.createFolder(dropbox);
}
if (teamFolders.hasNext()) { //CHECK IF FOLDER FOR TEAM EXISTS
teamFolder = teamFolders.next();
} else { //IF NOT CREATE FOLDER
teamFolder = folder.createFolder(teamBox);
teamFolder.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.COMMENT);
}
for (var f = 0; f < itemResponses.length; f++) {
Logger.log(itemResponses[f].getItem().getType());
Logger.log(itemResponses[f].getItem().getTitle());
if (itemResponses[f].getItem().getType() == "FILE_UPLOAD") {
Logger.log("THERE IS A FILE UPLOAD");
//RENAME PASSES
if (itemResponses[f].getItem().getTitle() == "PASSES") {
var files = itemResponses[f].getResponse();
//Logger.log(files.length);
if (files.length > 0) {
for (var n in files) {
var dFile = DriveApp.getFileById(files[n]);
dFile.setName("LSS - " + year + " - " + teamName + " - " + "PASSES - " + today );
teamFolder.addFile(dFile); //MOVE SUBMITTED DOCUMENTS TO THAT FOLDER
passesFolder.removeFile(dFile); //REMOVE FROM SUBMISSION FOLDER
DriveApp.removeFile(dFile); // REMOVE FROM DRIVE FOLDER
}
}
//RENAME ROSTER
} else if (itemResponses[f].getItem().getTitle() == "ROSTER") {
var files = itemResponses[f].getResponse();
//Logger.log(files.length);
if (files.length > 0) {
for (var n in files) {
var dFile = DriveApp.getFileById(files[n]);
dFile.setName("LSS - " + year + " - " + teamName + " - " + "ROSTER - " + today );
teamFolder.addFile(dFile);
}
}
//RENAME TEAM INFO SHEET
} else if (itemResponses[f].getItem().getTitle() == "TEAM INFO SHEET") {
var files = itemResponses[f].getResponse();
//Logger.log(files.length);
if (files.length > 0) {
for (var n in files) {
var dFile = DriveApp.getFileById(files[n]);
dFile.setName("LSS - " + year + " - " + teamName + " - " + "TEAM INFO SHEET - " + today );
teamFolder.addFile(dFile);
}
}
//RENAME PERMISSION TO TRAVEL
} else if (itemResponses[f].getItem().getTitle() == "PERMISSION TO TRAVEL") {
var files = itemResponses[f].getResponse();
//Logger.log(files.length);
if (files.length > 0) {
for (var n in files) {
var dFile = DriveApp.getFileById(files[n]);
Logger.log(ownerEmail);
dFile.setName("LSS - " + year + " - " + teamName + " - " + "PERMISSION TO TRAVEL - " + today );
teamFolder.addFile(dFile);
}
}
}
}//END 'IF FILE UPLOAD'
}//END FOR LOOP
}//END FUNCTION
How about this answer?
Issue:
The flow of upload from Google Form is as follows.
When the file is uploaded in the Form, the file is created to root folder.
When the form is submitted, the file in the root folder is copied by renaming the filename to the folder created by the form.
In above case, the file in root folder is different from the file in the folder created by Google Form. By this, DriveApp.getRootFolder().removeFile(dFile) in your "SNIPPET" didn't work. This is the reason of your issue of script.
Workaround:
You want to delete the file remained in the root folder.
In order to delete the file created in the root folder, how about this workaround?
Unfortunately, the original filename cannot be retrieved from the form response. But the file which was copied to the folder created by the form has the filename of the format like {original filename} - ####.{extension}. In this workaround, the original filename is retrieved from this filename, and move the file to the trash using the retrieved original filename.
Sample script:
This sample script is run by the installable form submit trigger. So when the form was submitted, the script is run and the uploaded file is moved to the destination folder and the original file in the root folder is moved to the trash.
Before run the script:
In this sample script, it supposes that the script is the container-bound script of Google Form. Please be careful this.
After cope and paste the script to the script editor, please set the destination folder ID to the script.
please install the installable form submit trigger. If the trigger has already been installed, please remove it and install again.
Please upload and submit a file using Google Form. By this, the script is run.
Script:
function formsubmit(e) {
var destFolderId = "###"; // Destination folder ID
if (e) {
Utilities.sleep(3000); // This is required.
var destfolder = DriveApp.getFolderById(destFolderId);
var items = e.response.getItemResponses();
for (var i = 0; i < items.length; i++) {
if (items[i].getItem().getType() == "FILE_UPLOAD") {
var files = items[i].getResponse();
for (var j = 0; j < files.length; j++) {
var file = DriveApp.getFileById(files[j]);
var filename = file.getName();
// Move uploaded file to the destination folder.
var uploadedFile = DriveApp.getFileById(files[j]);
var sourcefolder = uploadedFile.getParents().next();
destfolder.addFile(file);
sourcefolder.removeFile(file);
// Retrieve original filename.
var p1 = filename.split(" - ");
var extension = p1[p1.length - 1];
p1.pop();
var name = p1.join(" - ");
var p2 = "";
if (extension.indexOf(".") > -1) {
p2 = "." + extension.split(".")[1];
}
var orgFilename = name + p2;
// Move uploaded file to the trash.
var orgFiles = DriveApp.getRootFolder().getFilesByName(orgFilename);
if (orgFiles.hasNext()) {
var orgFile = orgFiles.next();
orgFile.setTrashed(true);
}
}
}
}
} else {
throw new Error("This sample script is run by the installable form submit trigger.");
}
}
Note:
This is a simple sample script for explaining this workaround. So please modify this for your situation.
In my environment, it was found Utilities.sleep(3000) was required. When the file is uploaded and the file is copied, the installable form submit trigger is run. At this time, if Utilities.sleep(3000) is not used, the file is moved before copying file is completed. By this, an error occurs. So I used it.
But I'm not sure whether the wait time of 3 seconds is the best. So if in your environment, an error occurs, please modify this.
I think that when a large file is uploaded, this value might be required to be large. Or also I think that running the script by the time-driven trigger might be better.
In this sample script, I used the installable form submit trigger. And when the form is submitted, the original file in the root folder is moved to the trash.
But I think that you can also run the script by the time-driven trigger. In this case, you can retrieve the response items by opening the form. About this, please select for your situation.
References:
Installable Triggers
setTrashed(trashed)
sleep(milliseconds)

How to save the current webpage with casperjs/phantomjs?

Is there a way to save the current webpage by using casperjs or phantomjs?
I tried to get the html and save it into a file. But the resulting file was a lot different from the screenshot of that time (with casper.capture). Is there a way to save the current webpage?
Andrey Borisko suggested to use the disk cache to retrieve the resources. My solution is not that efficient, but you don't need to decompress text files.
I use XMLHttpRequest to retrieve all resources after I registered them with the resource.received event handler. I then filter the resources into images, css and fonts. The current limitation is that remote resource paths that contain something like ../ or ./ are not handled correctly.
I retrieve the current page content with getHTML and iterate over all captured resources to replace the path used in the markup, that is identified by a portion of the complete resource URL, with a randomly generated file name. The file extension is created from the content type of the resource. It is converted using mimeType from this gist.
Since CSS files may contain background images or fonts, they have to be processed before saving to disk. The provided loadResource function loads the resource, but does not save it.
Since XMLHttpRequest to download the resources the script has to be invoked with the --web-security=false flag:
casperjs script.js --web-security=false
script.js
var casper = require("casper").create();
var utils = require('utils');
var fs = require('fs');
var mimetype = require('./mimetype'); // URL provided below
var cssResources = [];
var imgResources = [];
var fontResources = [];
var resourceDirectory = "resources";
var debug = false;
fs.removeTree(resourceDirectory);
casper.on("remote.message", function(msg){
this.echo("remote.msg: " + msg);
});
casper.on("resource.error", function(resourceError){
this.echo("res.err: " + JSON.stringify(resourceError));
});
casper.on("page.error", function(pageError){
this.echo("page.err: " + JSON.stringify(pageError));
});
casper.on("downloaded.file", function(targetPath){
if (debug) this.echo("dl.file: " + targetPath);
});
casper.on("resource.received", function(resource){
// don't try to download data:* URI and only use stage == "end"
if (resource.url.indexOf("data:") != 0 && resource.stage == "end") {
if (resource.contentType == "text/css") {
cssResources.push({obj: resource, file: false});
}
if (resource.contentType.indexOf("image/") == 0) {
imgResources.push({obj: resource, file: false});
}
if (resource.contentType.indexOf("application/x-font-") == 0) {
fontResources.push({obj: resource, file: false});
}
}
});
// based on http://docs.casperjs.org/en/latest/modules/casper.html#download
casper.loadResource = function loadResource(url, method, data) {
"use strict";
this.checkStarted();
var cu = require('clientutils').create(utils.mergeObjects({}, this.options));
return cu.decode(this.base64encode(url, method, data));
};
function escapeRegExp(string) {
// from https://stackoverflow.com/a/1144788/1816580
return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}
function replaceAll(find, replace, str) {
// from https://stackoverflow.com/a/1144788/1816580
return str.replace(find, replace);
}
var wrapFunctions = [
function wrapQuot1(s){
return '"' + s + '"';
},
function wrapQuot2(s){
return "'" + s + "'";
},
function csswrap(s){
return '(' + s + ')';
}
];
function findAndReplace(doc, resources, resourcesReplacer) {
// change page on the fly
resources.forEach(function(resource){
var url = resource.obj.url;
// don't download again
if (!resource.file) {
// set random filename and download it **or** call further processing which in turn will load ans write to disk
resource.file = resourceDirectory+"/"+Math.random().toString(36).slice(2)+"."+mimetype.ext[resource.obj.contentType];
if (typeof resourcesReplacer != "function") {
if (debug) casper.echo("download resource (" + resource.obj.contentType + "): " + url + " to " + resource.file);
casper.download(url, resource.file, "GET");
} else {
resourcesReplacer(resource);
}
}
wrapFunctions.forEach(function(wrap){
// test the resource url (growing from the back) with a string in the document
var lastURL;
var lastRegExp;
var subURL;
// min length is 4 characters
for(var i = 0; i < url.length-5; i++) {
subURL = url.substring(i);
lastRegExp = new RegExp(escapeRegExp(wrap(subURL)), "g");
if (doc.match(lastRegExp)) {
lastURL = subURL;
break;
}
}
if (lastURL) {
if (debug) casper.echo("replace " + lastURL + " with " + resource.file);
doc = replaceAll(lastRegExp, wrap(resource.file), doc);
}
});
});
return doc;
}
function capturePage(){
// remove all <script> and <base> tags
this.evaluate(function(){
Array.prototype.forEach.call(document.querySelectorAll("script"), function(scr){
scr.parentNode.removeChild(scr);
});
Array.prototype.forEach.call(document.querySelectorAll("base"), function(scr){
scr.parentNode.removeChild(scr);
});
});
// TODO: remove all event handlers in html
var page = this.getHTML();
page = findAndReplace(page, imgResources);
page = findAndReplace(page, cssResources, function(cssResource){
var css = casper.loadResource(cssResource.obj.url, "GET");
css = findAndReplace(css, imgResources);
css = findAndReplace(css, fontResources);
fs.write(cssResource.file, css, "wb");
});
fs.write("page.html", page, "wb");
}
casper.start("http://www.themarysue.com/").wait(3000).then(capturePage).run(function(){
this.echo("DONE");
this.exit();
});
The magic happens in findAndReplace. capturePage is completely synchronous so it can be dropped anywhere without much head ache.
URL for mimetype.js
No, I don't think there is an easy way to do this as phantomjs doesn't support rendering pages in mht format (Render as a .mht file #10117). I believe that's what you wanted.
So, it needs some work to accomplish this. I did something similar, but i was doing it the other way around I had a rendered html code that I was rendering into image/pdf through phantomjs. I had to clean the file first and it worked fine for me.
So, what I think you need to do is:
strip all js calls, like script tags or onload attributes, etc..
if you have access from local to the resources like css, images and so on (and you don't need authentication to that domain where you grab the page) than you need to change relative paths of src attributes to absolute to load images/etc.
if you don't have access to the resources when you open the page then I think you need to implement similar script to download those resources at the time phantomjs loads the page and then redirect src attributes to that folder or maybe use data uri.
You might need to change links in css files as well.
This will bring up the images\fonts and styling you are missing currently.
I'm sure there are more points. I'll update the answer if you need more info, once I see my code.

Create a copy of document in SharePoint 2010 document library using JavaScript

I want to create a copy of document in the SharePoint document library.
Basically let us assume there is a template and every user will open the document by clicking on it. I want to create a copy of file user has clicked and open that file for editting.
I have tried using JavaScript Client Object model of SharePoint. But the examples are for manipulating list items but not for document library.
Can any one please point to any sources that I can use to manipulate the files in document library
One restriction being I need to use JavaScript object model or web services to achive this functionality. i.e., NO server side code
Following is the code I got till now
The approach I am planning to use is copy the existing file object
Rename it and
Save it to other document library
Please ignore formatting as I am not able to do it properly and this is under development code
<script type="text/javascript">
var clientContext = null;
var web = null;
var meetingItems = null;
var filePath = null;
var file = null;
debugger;
ExecuteOrDelayUntilScriptLoaded(Initialize, "sp.js");
function Initialize() {
clientContext = new SP.ClientContext.get_current();
web = clientContext.get_web();
this.list = web.get_lists().getByTitle("Documents");
clientContext.load(list, 'Title', 'Id');
var queryStart = "<View>"+ "<Query>"+ "<Where>"+ "<Eq>"+ "<FieldRef Name='Title'/>" + "<Value Type='Text'>";
var queryEnd = "</Value>"+ "</Eq>"+ "</Where>"+ "</Query>"+ "</View>";
camlQuery = new SP.CamlQuery();
queryMeeting = queryStart + 'DevCookbook'+ queryEnd;
camlQuery.set_viewXml(queryMeeting);
meetingItems = list.getItems(camlQuery);
clientContext.load(meetingItems);
clientContext.executeQueryAsync(Function.createDelegate(this, this.onListLoadSuccess), Function.createDelegate(this, this.onQueryFailed));
}
function onListLoadSuccess(sender, args) {
filePath = meetingItems.get_item(0).get_path();
file = meetingItems.get_item(0);
debugger;
clientContext.load(file);
clientContext.executeQueryAsync(Function.createDelegate(this, this.onFileLoadSuccess), Function.createDelegate(this, this.onFileFailed));
// alert("List title : " + this.list.get_title() + "; List ID : " + this.list.get_id());
// doclist();
}
function doclist()
{
var path = file.get_title();
path = meetingItems.get_item(0).get_file().get_title();
}
function onQueryFailed(sender, args) {
alert('request failed ' + args.get_message() + '\n' + args.get_stackTrace());
}
function onFileLoadSuccess(sender, args) {
debugger;
alert("List title : " + this.list.get_title() + "; List ID : " + this.list.get_id());
}
function onFileFailed(sender, args) {
alert('request failed ' + args.get_message() + '\n' + args.get_stackTrace());
}
</script>
I used copy webservice to do the functionality.
Approach is combination of Object Model and JavaScript functions
Copy the file from templates library.
Check out file using "CheckoutDocument" function
Add metadata in background
Show edits metadata pop up to user using
var oDialog = {
url: "../Library/Forms/Edit.aspx?ID=" + itemID,
title: "Create a new document"
};
SP.UI.ModalDialog.showModalDialog(oDialog)
After user input check in the document

Categories

Resources