Photoshop scripting mantain same file name and whitespace - photoshop-script

I'm trying to add a layer to some images and then save them.
The problem is that many images have whitespace in the name. When I try to save the whitespaces are replaced with "-", but I want mantain the same name.
For example an image called "Google Analytics.png" become "Google-Analytics.png". But I need to preserve the name without that extra "-".
My code:
function SavePNG(saveFile){
var file = new File(saveFile);
var pngOpts = new ExportOptionsSaveForWeb;
pngOpts.format = SaveDocumentType.PNG
pngOpts.PNG8 = false;
pngOpts.transparency = false;
pngOpts.interlaced = false;
pngOpts.quality = 100;
$.writeln(file)
app.activeDocument.exportDocument(file,ExportType.SAVEFORWEB,pngOpts);
}

Try using saveAs instead of exportDocument; it'll respect the name of the file you give it. The options are yours to change:
var myfile = "C:\\temp\\Google Analytics.png";
SavePNG(saveFile)
function savePNG(saveFile)
{
// save out the image
var pngFile = new File(filepath);
pngSaveOptions = new PNGSaveOptions();
pngSaveOptions.embedColorProfile = true;
pngSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE;
pngSaveOptions.matte = MatteType.NONE;
pngSaveOptions.quality = 1;
activeDocument.saveAs(pngFile, pngSaveOptions, false, Extension.LOWERCASE);
}

Related

cannot read property "0" of undefined error

I have a code that pulls information from all excel type files in some folders on google drive. The problem is that there are over 100 files and the code only pulls data from around 30 files and shows the following error: "TypeError: Cannot read property '0' of undefined" The error is in line 12, "console.log(lista_carpetas_ok2[i][0]) // Here, you can see the folder ID in the log."
function listfechas() {
var ss2 = SpreadsheetApp.getActiveSpreadsheet();
var carpetasSheet = ss2.getSheetByName("carpetas");
var lista_carpetas = carpetasSheet.getRange("C2:C" + carpetasSheet.getLastRow()).getValues();
var lista_carpetas_ok2 = lista_carpetas.filter(([a]) => a);
var sheet2 = ss2.getSheetByName("SS23");
sheet2.clear();
sheet2.appendRow(["Folder", "Name", "SMS","rec SMS", "FIT", "rec FIT", "2FIT", "rec 2FIT" ,"3FIT" ,"rec 3FIT" ,"PP" ,"rec PP" ,"2PP" ,"rec 2PP", "3PP", "rec 3PP","SHIP", "rec SHIP", "2SHIP","rec 2SHIP"]);
for (var i = 0; i < 5; i++) {
console.log(lista_carpetas_ok2[i][0]) // Here, you can see the folder ID in the log.
var folderid = lista_carpetas_ok2[i][0];
try {
var parentFolder =DriveApp.getFolderById(folderid);
listFiles(parentFolder,parentFolder.getName())
listSubFolders(parentFolder,parentFolder.getName());
} catch (e) {
Logger.log(e.toString());
}
}
function listSubFolders(parentFolder,parent) {
var childFolders = parentFolder.getFolders();
while (childFolders.hasNext()) {
var childFolder = childFolders.next();
Logger.log("Fold : " + childFolder.getName());
listFiles(childFolder,parent)
listSubFolders(childFolder,parent + "|" + childFolder.getName());
}
}
function listFiles(fold,parent){
var data = [];
var files = fold.getFilesByType(MimeType.GOOGLE_SHEETS);
try {
while (files.hasNext()) {
var file = files.next();
var sms = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("A2").getValue();
var recsms = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("B2").getValue();
var fit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("C2").getValue();
var recfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("D2").getValue();
var dfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("E2").getValue();
var recdfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("F2").getValue();
var tfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("G2").getValue();
var rectfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("H2").getValue();
var pp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("I2").getValue();
var recpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("J2").getValue();
var dpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("K2").getValue();
var recdpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("L2").getValue();
var tpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("M2").getValue();
var rectpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("N2").getValue();
var ship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("O2").getValue();
var recship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("P2").getValue();
var dship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("Q2").getValue();
var recdship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("R2").getValue();
var fullRange = sheet2.getRange("A1:Z1001");
fullRange.setVerticalAlignment(DocumentApp.VerticalAlignment.TOP);
data = [
fold.getName(),
file.getName(),
sms,
recsms,
fit,
recfit,
dfit,
recdfit,
tfit,
rectfit,
pp,
recpp,
dpp,
recdpp,
tpp,
rectpp,
ship,
recship,
dship,
recdship,
];
sheet2.appendRow(data);
};
} catch (e) {
// In this modification, when your folder ID cannot be used, that folder ID is skipped. At that time, an error message can be seen in the log.
console.log(e.message);
}
}
}
When I wrote the code, I added catch (e) which I thought skipped the folder if there was no excel file in that folder, but the code stops at folder "QM0201" which does not have an excel file in it.
Does anybody know how I can fix it? I would like the code to run even if some folders don't have an excel files in them, those should just be skipped.
Thank you so much in advance! Any help is appreciated.
To avoid the error, replace
for (var i = 0; i < 5; i++) {
by
for (var i = 0; i < lista_carpetas_ok2.length; i++) {
This might also help to avoid the code to stop at certain folder.
Regarding the error
> Info Cannot read property 'getRange' of null"
This occurs because the spreadsheet hasn't a sheet named fechas
to avoid this error you might add
if(!SpreadsheetApp.open(file).getSheetByName("fechas")) break;
above of
var sms = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("A2").getValue();
if(
Debugging tips:
To verify that the correct values are assigned to lista_carpetas_ok2, add console.log(JSON.stringify(lista_carpetas_ok2)); just below lista_carpetas_ok2 declaration so you can review the values assigned to the variable.
To have more informative logs when an error occurs, instead of
} catch (e) {
Logger.log(e.toString()); // or console.log(e.message);
}
use
} catch (e) {
console.log(e.message, e.stack);
}
This is hardly a cause of the error but who knows, the code has the very unefficient part — 72 calls to the server. It can be greatly improved if you change this:
var sms = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("A2").getValue();
var recsms = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("B2").getValue();
var fit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("C2").getValue();
var recfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("D2").getValue();
var dfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("E2").getValue();
var recdfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("F2").getValue();
var tfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("G2").getValue();
var rectfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("H2").getValue();
var pp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("I2").getValue();
var recpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("J2").getValue();
var dpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("K2").getValue();
var recdpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("L2").getValue();
var tpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("M2").getValue();
var rectpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("N2").getValue();
var ship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("O2").getValue();
var recship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("P2").getValue();
var dship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("Q2").getValue();
var recdship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("R2").getValue();
To this:
var values = SpreadsheetApp.open(file).getSheetByName("fechas").getRange('A2:R2').getValues().flat();
var [sms,recsms,fit,recfit,dfit,recdfit,tfit,rectfit,pp,recpp,dpp,recdpp,tpp,rectpp,ship,recship,dship,recdship] = values;
It will reduce the quantity of calls to 4!
It should work faster and, if the real cause of the error is exceed of time limit (~6 min) this improvement can help. Try it.
Probably you could simplify the code further. Instead of this:
data = [
fold.getName(),
file.getName(),
sms,
recsms,
fit,
recfit,
dfit,
recdfit,
tfit,
rectfit,
pp,
recpp,
dpp,
recdpp,
tpp,
rectpp,
ship,
recship,
dship,
recdship,
];
You can use this:
var values = SpreadsheetApp.open(file).getSheetByName("fechas").getRange('A2:R2').getValues().flat();
var data = [fold.getName(), file.getName(), ...values];
No need to use the 18 variables, as far as I can see. It barely affects on the speed, though.

Google Apps Script to add links to google Spreadsheet adds 5000+ rows and i dont understand why?

Pretty self explanatory title, im trying to do a script where it takes the number on a column and uses that to search a list of files from google drive and then insert a link to that file.
HOWEVER, every time it inserts that link it also creates like 5000+ empty rows? why would this be?
The purpose is to take a number from a certain column, then look on google drive for the file that matches (at least partially) with that first number, then we should generate a link for that file and insert that link into another column, next to the number.
function CopiarResos() {
let ass = SpreadsheetApp.getActiveSpreadsheet();
let maxRows = ass.getSheetByName('set_de_datos_unificado').getMaxRows();
let columnaResos = ass.getSheetByName('set_de_datos_unificado').getSheetValues(2,2,maxRows,1);
let columnaLinks = ass.getSheetByName('set_de_datos_unificado').getSheetValues(2,53,maxRows,1);
let folder = DriveApp.getFolderById('1FJiet6tVgWXtM91Y7mmhgxDL2iYFm1VE'); // I change the folder ID here
let list = [];
let idList = [];
let files = folder.getFiles();
let match = '';
while (files.hasNext()){
file = files.next();
list.push(file.getName().toString());
idList.push(file.getId().toString());
}
console.log(list);
console.log(idList);
/*
let match = list.find(element => {
if (element.includes(substring)) {
return true;
}
});
*/
for (let i = 0; i in columnaResos; i++){
if(columnaLinks[i] == ""){
let substring = columnaResos[i];
match = list.find(element => {
if (element.includes(substring)) {
let idString = idList[i];
let insertStr = "https://drive.google.com/file/d/" + idString +"view";
let cellInsert = ass.getSheetByName('set_de_datos_unificado').getRange([i]+2,53);
cellInsert.setValue(insertStr);
return true;
}
});
}
};
}
getMaxRows() returns the number of rows that has the sheet (scroll down to the very bottom). You might delete the blank rows below your data or use getLastRow() instead.
References
https://developers.google.com/apps-script/reference/spreadsheet/sheet#getmaxrows
https://developers.google.com/apps-script/reference/spreadsheet/sheet#getlastrow
So, apart from all the thing wasnt written right turns out i was missing a bunch of lines! Mostly i was trying to get a fileid from an array even tho the indexes were completely unrelated (eg: trying to get list[300] instead of doing indexOf(match)
function copiarResos() {
let ass = SpreadsheetApp.getActiveSpreadsheet();
let maxRows = ass.getSheetByName('set_de_datos_unificado').getLastRow();
let columnaResos = ass.getSheetByName('set_de_datos_unificado').getSheetValues(2,2,maxRows,1);
let columnaLinks = ass.getSheetByName('set_de_datos_unificado').getSheetValues(2,53,maxRows,1);
let folder = DriveApp.getFolderById('1FJiet6tVgWXtM91Y7mmhgxDL2iYFm1VE'); // I change the folder ID here
let list = [];
let files = folder.getFiles();
let match = '';
while (files.hasNext()){
file = files.next();
list.push(file.getName().toString(), file.getId().toString());
}
console.log(list);
console.log(columnaLinks)
for (let i = 0; i in columnaResos; i++){
if(columnaLinks[i] == ''){
let substring = columnaResos[i];
match = list.find(element => {
if (element.includes(substring)) {
return true;
}
});
console.log(match);
matchId = list.indexOf(match);
if(matchId !== 0){
console.log(match + " id es" + matchId);
let idString = list[matchId+1];
console.log(idString)
let insertStr = "https://drive.google.com/file/d/" + idString +"/view?usp=sharing";
let cellInsert = ass.getSheetByName('set_de_datos_unificado').getRange(i+2 ,53);
cellInsert.setValue(insertStr);
}
}
match = ''
};
}

Search for a specific picture in google drive folder - Search file name by title

I have a list of possible image file names in a spreadsheet. I'm trying to get the file (if exist) and insert it into the cell next to the name. But I get an error when I call .hasNext(). The code that I am using is:
function listFilesInFolder(folderName) {
var sheet = SpreadsheetApp.getActiveSheet();
var i = 0;
var numberOfRows = sheet.getLastRow();
for (i=0;i<numberOfRows;i+=1) {
var range = sheet.getRange(i+1,1);
var data = range.getValue();
var file = DriveApp.getFolderById("FOLDER_ID_HERE").searchFiles(data);
if (file.hasNext()) {
var rangeDest =sheet.getRange(i+1,2);
var output = file.next();
rangeDest.setValue("=image(\"https://drive.google.com/uc?export=download&id=" + output.getId() +"\")");
};
};
};
Any Ideas?
Thanks!
The problem is from this line:
var file = DriveApp.getFolderById("FOLDER_ID_HERE").searchFiles(data);
Should be:
var searchString = 'title contains "' + data + '"';
var file = DriveApp
.getFolderById("FOLDER_ID_HERE")
.searchFiles(searchString);

Image Upload doesn't work in Server. Works fine in localhost

So, this code works just fine in localhost. It deletes the previous image and uploads the new one. It does nothing on server however. Any clue?
I have used AJAX for asynchorous call By the way if that makes a difference.
var db=Database.Open("StarterSite");
var contentQuery="Select * from Contents where id =#0";
var content=db.QuerySingle(contentQuery,"1");
var message="";
var imgCount=0;
var alreadyExist=false;
try{
if (IsPost && Request.Files.Count > 0) {
bool deleteSuccess = false;
var fileName = "";
var photoName = "";
var fileSavePath = "";
var uploadedFile = Request.Files[0];
var toDelete=Request["toDelete"];
var toUpload=Request["toUpload"];
if(uploadedFile.ContentLength>0){
#******************DELETE***************#
var fullPath = Server.MapPath("~/img/" + toDelete);
if (File.Exists(fullPath))
{
File.Delete(fullPath);
deleteSuccess = true;
}
#****************UPLOAD*******************#
fileName = Path.GetFileName(uploadedFile.FileName);
fileSavePath = Server.MapPath("~/img/" +
fileName);
uploadedFile.SaveAs(fileSavePath);
var updateQuery="Update Contents Set "+toUpload +"=#0";
db.Execute(updateQuery, fileName);
//Response.Redirect("editMode.cshtml");
}
}
}
catch(HttpException ex){
message="Image size you selected was too large. Please select a different Image.";
}
Try changing the permission of the folder to 777.

How do I fix charset problems in .gs script?

I have a problem with charsets.
I parsed a csv file in google-app-engine and I'm posting to an uiapp table.
But I checked special characters like áéíóú and those are not well displayed (?square symbol).
When I was setting up my code I played writing the string imported to a google docs document and it worked the same.
some advice please?
I search for:
a global charset definition to the code. or
string var transformation that makes the chars appear like I want to. (avoiding html &number definitions.
Is this related to the blob object?
The thing is important i come from spain and we need such characters.
app that get's a csv ';' delimited file and shows it's content
I post all my code, it's barely as the tutorial that is given.
function arreglaUrl(cadena){
var texto = cadena[cadena.length - 2]
if (texto == ''){
cadena[cadena.length - 2] = 'Sin enlace';
}
else{
cadena[cadena.length - 2] = '<center>Link.</center>' ;
};
}
function parsedCSV(){
var listaArchivos = DocsList.getFolderById('XXXXX').getFiles()
for (var i = 0; i < listaArchivos.length; i++) {
if (listaArchivos[i].getName() == 'baul.csv'){
var origen = listaArchivos[i];
};
}
var texto = origen.getContentAsString();
var arra = Utilities.parseCsv(texto,";");
return(arra);
}
function doGet() {
var datos = parsedCSV()
var baul = Charts.newDataTable()
for (i = 0; i < datos[0].length; i++){
baul.addColumn(Charts.ColumnType.STRING, datos[0][i])
}
for (i = 1; i < datos.length; i++){
arreglaUrl(datos[i]) // this only makes some html i need to post some links
baul.addRow(datos[i])
}
baul.build();
var sectorFilter = Charts.newCategoryFilter()
.setFilterColumnLabel("sector")
.build();
var tipoFilter = Charts.newCategoryFilter()
.setFilterColumnLabel("tipo")
.build();
var searchFilter = Charts.newStringFilter()
.setFilterColumnLabel("Titulo")
.build();
var searchDesc = Charts.newStringFilter()
.setFilterColumnLabel("descripcion")
.build();
var tableChart = Charts.newTableChart().setOption('allowHtml', true).setDimensions(0,0)
.build();
var dashboard = Charts.newDashboardPanel()
.setDataTable(baul)
.bind([sectorFilter, tipoFilter, searchFilter, searchDesc], [tableChart])
.build();
var uiApp = UiApp.createApplication().setTitle('Baul de Recursos');
var anchoTotal = '100%';
dashboard.add(uiApp.createVerticalPanel()
.add(uiApp.createHorizontalPanel()
.add(sectorFilter)
.add(tipoFilter)
.setSpacing(15)
)
.add(uiApp.createHorizontalPanel()
.add(searchFilter)
.add(searchDesc)
.setSpacing(15)
)
.add(uiApp.createHorizontalPanel()
.add(tableChart).setBorderWidth(1).setHorizontalAlignment(UiApp.HorizontalAlignment.CENTER).setWidth(anchoTotal)
)
);
uiApp.add(dashboard);
return uiApp;
}
I found it, we need to get the content of the file first with a Blob object.
This function is the one I use to parse some csv info into an array:
function parsedCSV(){
//searching the file. This gets only one file in var origen
var listaArchivos = DocsList.getFolderById('XXXXXXX').getFiles()
for (var i = 0; i < listaArchivos.length; i++) {
if (listaArchivos[i].getName() == 'baul.csv'){
var origen = listaArchivos[i];
};
}
// HERE IS THE GOOD DEFINITION OF CHAR:
var texto2= origen.getBlob().getDataAsString('ISO-8859-1');
// I put all the corrected text in an array
var arra = Utilities.parseCsv(texto2,";");
return(arra);
}
This is the solved thing: https://script.google.com/macros/s/AKfycbyHa-bLWBHBr3qifbvzxecqGgGUYX8mhyo-TKoyfGvy/exec
The trick:
var textVariableName = fileObjectVariableName.getBlob().getDataAsString('ISO-8859-1');

Resources