Amending a .JSX file to change the filenames of output files - javascript

I have a script but it doesn't do what I need, so I need to adjust it, but honestly, I can't find what I need to change to make it work. The script outputs a CSV file from a folder of images. It makes a list with the file path so my program knows what images to import which works fine, but also it it writes the filenames which I can then also import in my secondary program.
The problem is the filenames. It also puts the extension behind the names which I don't need in the name. What do I need to change in the code to make it work as I want it to?
Here is the script:
Array.prototype.inArray = function(obj){
var arrMax = this.length-1;
for(var i=arrMax; i>=0; i--){
if(this[i]===obj){
return true;
}
}
return false;
}
var csvParser = (function(){
var csvFile;
return{
create:function(fo){
csvFile=File(fo+"/"+fo.name+".csv");
},
write:function(csvContent){
csvFile.open('w');
csvFile.encoding="UTF-8";
csvFile.write(csvContent);
csvFile.close();
},
execute:function(){
csvFile.execute();
},
getCSV:function(){
return csvFile;
}
}
})();
function imagesToCSVthenChoose(){
var doc,
fo,
fis,
fiMax,
fi,
fiName,
fiPath,
imgFormats=["eps","jpg","tif","psd","pdf","png","ai","bmp","jpeg"],
imgFormatMax = imgFormats.length-1,
imgOk = [],
csvContent = [],
csvLine=[],
csvSep=",";
if(app.documents.length==0){
alert("No documents open !");
return
}
doc=app.activeDocument;
fo = Folder.selectDialog("Please choose a folder with images");
if(!fo) return
fis = fo.getFiles();
fiMax=fis.length;
for(var i=0; i<fiMax; i++){
fi=fis[i];
ext = fi.name.match(/\.([a-z]+)$/i);
if(ext==null) continue;
ext = ext[1].toLowerCase();
if(!imgFormats.inArray(ext)) continue;
fiName = decodeURI(fi.name);
fiPath=decodeURI(fi.fsName);
csvContent.push(fiName+csvSep+fiPath);
}
csvContent = "Name"+csvSep+"#images\r"+csvContent.join("\r");
csvParser.create(fo);
csvParser.write(csvContent);
/*
doc.dataMergeProperties.selectDataSource(csvParser.getCSV());
var myMenuAction = app.menuActions.item("$ID/DataMergePanelName");
myMenuAction.invoke();
*/
}
imagesToCSVthenChoose();
I didn't try much yet because I have no clue. And I couldn't find the right code on the internet.

Related

Why doesn't my .JSX script recognize every image in a folder which I want to mass-resize?

I have this JSX script I created but I feel like it's not checking for every file type in the filelist variable. Can someone take a look? It's very frustrating when I have it running and then for some reason a non-descript error message pops up and then it stops
Here is the script:
var inputFolder = Folder.selectDialog("Select a folder to process"),
fileList = inputFolder.getFiles(/\.(jpg|tif|psd|crw|cr2|nef|dcr|dc2|raw)$/i);
for(var i=0; i < fileList.length; i++) {
var doc = open(fileList[i]);
if(doc.width !== doc.height) {
if(doc.width > doc.height) {
doc.resizeCanvas(doc.width, doc.width)
} else {
doc.resizeCanvas(doc.height, doc.height)
}
}
if((doc.width && doc.height) > 1000) {
doc.resizeImage(1000, 1000);
} else {
doc.resizeImage(doc.width, doc.height);
}
doc.save();
doc.close();
}
This is the error message:
It seems that Folder.getFiles() doesn't accept RegExp objects, it only accepts a string or a function, beside that, it will also include Folder objects, you can change it to something like this to filter only files and only the file types you're interested in:
function filter(file) {
return (file instanceof File && /\.(jpg|tif|psd|crw|cr2|nef|dcr|dc2|raw)$/i.test(file.name))
}
fileList = inputFolder.getFiles(filter);

How to access a specific folder to get file names within my extension

So i need to get names of files in my "db" folder, that i later need to use in my extension. I searched on how to do this and I can get all file names from my root extension folder but not from any other.
This is the code that gives back all file names from extension folder that i found from this question: How do I get a list of filenames in a subfolder of a Chrome extension?
chrome.runtime.getPackageDirectoryEntry(function(directoryEntry) {
var directoryReader = directoryEntry.createReader();
// List of DirectoryEntry and/or FileEntry objects.
var filenames = [];
(function readNext() {
directoryReader.readEntries(function(entries) {
if (entries.length) {
for (var i = 0; i < entries.length; ++i) {
filenames.push(entries[i].name);
}
readNext();
} else {
// No more entries, so all files in the directory are known.
// Do something, e.g. print all file names:
console.log(filenames);
}
});
})();
});
This is the code that is supposed to do what i want but i cant figure out how to implement it here
directoryEntry.getDirectory('_locales', {}, function(subDirectoryEntry) {
var directoryReader = subDirectoryEntry.createReader();
// etc.. same code as in previous snippet.
});
The code I needed was this.
chrome.runtime.getPackageDirectoryEntry(function(directoryEntry) {
directoryEntry.getDirectory('index', {}, function(subDirectoryEntry) {
var directoryReader = subDirectoryEntry.createReader();
// List of DirectoryEntry and/or FileEntry objects.
var filenames = [];
(function readNext() {
directoryReader.readEntries(function(entries) {
if (entries.length) {
for (var i = 0; i < entries.length; ++i) {
filenames.push(entries[i].name);
}
readNext();
} else {
// No more entries, so all files in the directory are known.
// Do something, e.g. print all file names:
console.log(filenames);
}
});
})();
});
});

Javascript Rewrite Config File

I have a config.js file which I believe is JSON which is called when the application first starts:
var config={};
config.user = [
{id:'JSMITH', priceModify:'true'},
{id:'JBLOGGS', priceModify:'false'},
]
config.price = [
{id:"price01", name:"priceName01", primary:"57.25", secondary:"34.54"},
{id:"price02", name:"priceName02", primary:"98.26", secondary:"139.45"},
{id:"price03", name:"priceName03", primary:"13.87", secondary:"29.13"}
]
To pull / push data I just use the following:
// Read
var curPrice = config.price[0].primary;
// Write
config.price[0].primary = "98.24";
How do I go about exporting the config file with the new value so that it will load next time the application is opened? I can use the file system object to write the file, I just don't understand how I would export everything (and preferably keep the same format).
I originally thought about reading the whole config file into a variable, cycling through to find the required block, id, and key and replacing the value, then writing the whole thing back, but I can't seem to figure out how to replace that specific value only.
Any help would be greatly appreciated
Edit Apologies, I forgot to mention that this application is completely offline and uses local directories
Solution
I stumbled across a few solutions to different issues which, when combined, gave me the perfect solution. First we cycle the Javascript object, building an array of the detail and then converting the array to a string:
vMethod.convertToText = function(obj) {
var string = [];
var output = '';
var count= 0;
var countTotal = 0;
if (typeof(obj) == "object" && (obj.join == undefined)) {
count= 0;
countTotal = 0;
string.push("{");
for (prop in obj) {
countTotal++;
}
for (prop in obj) {
if(count==countTotal - 1) {
string.push(prop, ": ", vMethod.convertToText(obj[prop]),'}\r\n');
} else {
string.push(prop, ": ", vMethod.convertToText(obj[prop]), ",");
}
count++;
};
} else if (typeof(obj) == "object" && !(obj.join == undefined)) {
count= 0;
countTotal = 0;
string.push("[\r\n")
for (prop in obj) {
countTotal++;
}
for(prop in obj) {
if(count==countTotal - 1) {
string.push(vMethod.convertToText(obj[prop]),'];\r\n');
} else {
string.push(vMethod.convertToText(obj[prop]), ",");
}
count++;
}
} else if (typeof(obj) == "function") {
string.push(obj.toString())
} else {
string.push(JSON.stringify(obj))
}
output = string.join("").toString();
//output = output.slice(1, -1);
return output;
}
Then we clean the array (neccessary for me to remove excess characters)
vMethod.cleanConfigText = function() {
var outputText = vMethod.convertToText(config);
outputText = outputText.slice(1, -1);
outputText = 'var config = {};\r\n'+outputText;
outputText = outputText.replace('user:','config.user =');
outputText = outputText.replace(',price:','config.price =');
outputText = outputText.slice(0, -2);
outputText = outputText.replace(/"/g, "'")
return outputText;
}
Finally a function to export the object into my config.js file:
vMethod.writeToConfig = function() {
vObject.fileSystem = new ActiveXObject('Scripting.FileSystemObject');
vObject.fileSystemFile = vObject.fileSystem.CreateTextFile('source\\js\\config.js',true);
vObject.fileSystemFile.Write(vMethod.cleanConfigText());
vObject.fileSystemFile.Close();
delete vObject.fileSystemFile;
delete vObject.fileSystem;
}
So when I want to export a change in the config, I just call:
vMethod.writeToConfig();
The only difference in the file format is that the commas appear at the start of a trailing line rather than the end of a preceding line but I can live with that!
Edit Turns out I'm anally retentive and the commas were bugging me
Added these to the clean up function and now the config is identical to before but without the indent
outputText = outputText.replace(/[\n\r]/g, '_');
outputText = outputText.replace(/__,/g, ',\r\n');
outputText = outputText.replace(/__/g, '\r\n');
Thank you to those that looked at the question and tried to help, very much appreciated.
Edit
DO NOT READ THE SOLUTION ABOVE, IT IS IN THE WRONG PLACE AND THERFORE IS NOT A VALID ANSWER. YOU'VE BEEN WARNED.
You can use a very popular npm package: https://www.npmjs.com/package/jsonfile . There are many but I've choosen this one.
Usually config stuff should be in json or .env files.
Now, all you have to do is use jsonfile's API to read/write JSON and parse (the package does the serialization/deserialization) it at the beginning when the application starts.
Example:
var jsonfile = require('jsonfile');
var util = require('util');
var config = null;
var file = './config.json';
// Reading
jsonfile.readFile(file, function(err, obj) {
config = obj;
});
// Writing
// Edit your config blah blah
config.user = [
{id:'JSMITH', priceModify:'true'},
{id:'JBLOGGS', priceModify:'false'},
];
config.price = [
{id:"price01", name:"priceName01", primary:"57.25", secondary:"34.54"},
{id:"price02", name:"priceName02", primary:"98.26", secondary:"139.45"},
{id:"price03", name:"priceName03", primary:"13.87", secondary:"29.13"}
];
jsonfile.writeFile(file, config, function (err) {
if(err) return err;
console.log('Config saved to file!');
});

Batch Export Symbols to SVG - Illustrator

Question:
I've created a script that iterates through all symbols in an Illustrator document and exports them as PNGs.
I need it to work for SVGs as well, however, it's not as simple as just changing the file-type.
Because of Illustrator's default behaviour of making a recently saved svg the app.activeDocument, the for loop nests new directories for each symbol.
e.g.
exports/
symbol01.svg
exports/
symbol02.svg
exports/
symbol03.svg
etc..
I'm pretty sure the problem lays between //create directory and //choose directory, but I can't for the life of me figure it out.
var doc = app.activeDocument;
var symbolCount = doc.symbols.length;
if (symbolCount >= 1) {
if (confirm("Are all your layers hidden?")) {
// create temp layer
doc.layers.add();
for (var i = 0; i < doc.symbols.length; i++) {
// place a symbol instance - temp
var s = doc.symbolItems.add(doc.symbols[i]);
// create directory
var dest = new Folder(doc.path + "/exports");
if (!dest.exists) dest.create();
// choose directory
dest.changePath(doc.symbols[i].name);
// export symbols
saveSVG(dest);
// delete temp symbol instance
s.remove();
}
// remove temp layer
doc.layers[0].remove();
}
function saveSVG(file) {
// save options
var type = ExportType.SVG;
var options = new ExportOptionsSVG();
// export
doc.exportFile(file, type, options);
}
} else {
alert("You don't have any symbols in this document");
}
Having a way to store the initial app.activeDocument would probably fix the issue, but I can't figure out how to do that.. if that's even the best way?
Bonus:
Another problem with this script is the artboard doesn't resize to the symbols, so I found a function fitArtboardToSelectedArt() which I've tried implementing with no success.. can anyone can explain how it should work?
PS. Here's a link for the Illustrator scripting documentation: http://adobe.ly/1JxLlUK
Figured it out :)
Feel free to use the following script if you need to do the same.
/*
* Export Symbols as SVGs - Illustrator
* --------------------------------------
* Created By Shane Parsons - 30PT Design Inc.
* http://30ptdesign.com/
*/
var doc = app.activeDocument;
var symbolCount = doc.symbols.length;
if (symbolCount >= 1) {
if (confirm("Are all your layers hidden?")) {
// choose directory
var dest = Folder(doc.path).selectDlg();
// folder chosen
if (dest) {
// create temp layer
doc.layers.add();
// create temp artboard
doc.artboards.add(doc.artboards[0].artboardRect);
// get temp artboard
var tempAB = doc.artboards.getActiveArtboardIndex();
// loop through symbols
for (var i = 0; i < doc.symbols.length; i++) {
// place a symbol instance - temp
var symbol = doc.symbolItems.add(doc.symbols[i]);
// resize artboard
doc.artboards[tempAB].artboardRect = doc.visibleBounds;
app.redraw();
// choose directory
var filename = doc.symbols[i].name;
// export symbols
saveSVG(dest, filename);
// delete temp symbol instance
symbol.remove();
}
// remove temp layer
doc.layers[0].remove();
// remove temp artboard
doc.artboards[tempAB].remove();
}
}
function saveSVG(dest, filename) {
// save options
var type = ExportType.SVG;
var options = new ExportOptionsSVG();
// file
var file = new File(dest + "/" + filename);
// export
doc.exportFile(file, type, options);
}
} else {
alert("You don't have any symbols in this document");
}

Javascript returning empty array (which shoudn't) on IE

I've written some code to display my bookmarks on IE8. The code works fine except the array of favorites I should have ("favs") as output exists but is empty (when I put "favs" in the developer tools console I get {...}).
var fso, favs = [];
var favString="";
function GetFavourites(Folder) {
var FavFolder = fso.GetFolder(Folder);
//Gets Favourite Names & URL's for given folder.
var files = new Enumerator(FavFolder.Files);
for (; !files.atEnd(); files.moveNext()) {
var fil = files.item();
if (fil.Type == "Internet Shortcut") {
var textReader = fso.OpenTextFile(fil.Path, 1, false, -2);
var favtext = textReader.ReadAll();
var start = favtext.indexOf("URL", 16);
var stop = favtext.indexOf("\n", start);
favString = fil.Name.replace(/.url/, "");
favString += ":URL:";
//to separate favourite name & favorite URL
favString += favtext.substring(start + 4, stop - 1);
favs.push(favString);
}
}
//Checks any subfolder exists
var subfolders = new Enumerator(FavFolder.SubFolders);
for (; !subfolders.atEnd(); subfolders.moveNext()) {
var folder = subfolders.item();
GetFavourites(folder.Path);
}
}
function Import() {
try {
fso = new ActiveXObject("Scripting.FileSystemObject");
if (fso !== null) {
//Create windows script shell object to access Favorites folder in user system.
var object = new ActiveXObject("WScript.Shell");
var favfolderName = object.SpecialFolders("Favorites");
if (favString === "") {
GetFavourites(favfolderName);
}
}
}
catch (err) {
alert("Security settings to be modified in your browser ");
}
}
I've found where my mistake is : I forgot I was using IE in French so the test "if (fil.Type == "Internet Shortcut")" doesn't work; I must replace "Internet Shortcut" with the French equivalent "Raccourci Internet". :-))

Categories