I am writing a photoshop script in JS, at this point I ask the user to select and folder location and add all those files to an array. I wish to then parse the array so only the filename remains.
I get this error : fileList[i].replace is not a function
I imagine its due to me passing in the wrong value or using the wrong type. Was hoping someone could explain the issue and help me resolve it please?
//Prompt for folder location
var Path = Folder.selectDialog("Select Folder Location for Renders")
// Use the path to the application and append the samples folder
var samplesFolder = Folder(Path)
var fileList = samplesFolder.getFiles()
for (var i = 0; i < fileList.length; i++)
{
fileList[i] = fileList[i].replace(/^.*[\\\/]/, '')
}
prompt("Complete")
Thanks for your time, AtB
S
The error is occuring because you're expecting a string, and it isn't one.
http://jongware.mit.edu/idcs5js_html_3.0.3i/idcs5js/pc_Folder.html says that getFiles
returns an array of File and Folder objects, or null if this object's referenced folder does not exist.
Fortunately, both File and Folder have these properties:
fsName - The platform-specific full path name for the referenced file
fullName - The full path name for the referenced file in URI notation.
name - The file name portion of the absolute URI for the referenced file, without the path specification
Of course, if you don't want any of the path, and just want the filename, use name, otherwise, use the replace command on whichever suits you - fsName or fullName.
So - in your loop, you want:
fileList[i] = fileList[i].name
You may want to filter out the Folders in your end result. That would entail something like this inside your loop:
if (fileList[i] instanceof Folder) {
fileList.splice(i, 1);
--i; // go back one i, because you just removed an index. Note, if you're not careful, such shenanigans may mess up the second term of the for loop.
continue;
}
One last suggestion: I would personally find it cleaner to make a new array, rather than doing the replacement in position. The language certainly supports what you're doing, but it still makes me twitch to go from File or Folder array to string array. (Granted, you thought you were doing string array to string array.) This would also simplify any issues with removing indices for folders, etc.
Related
Is this even possible to get specific file path from url
my file path is like
testing\abc\pqr\subfolder1\anotherFolder
or
testing\sufolder\anothersubfolder\abc\pqr\xyz\mno
my output will look like this
testing\abc\pqr
or
testing\sufolder\anothersubfolder\abc
Its should remove last few name of a folder and provide only specific length folder name from the start of the path which I will pass in an array
You can split the path and just grab the number of segments you want from the front. Since you're showing Windows-style paths, here's some sample code that uses the Windows path separator. This can be adapted to use path.sep if you want a cross platform version. Since your example paths do not start with a leading slash, this code assumes that.
function getFrontPathSegments(fullPath, numSegments) {
let pieces = fullPath.split("\\");
return pieces.slice(0, numSegments).join("\\");
}
// example usage
let front = getFrontPathSegments("testing\\sufolder\\anothersubfolder\\abc\\pqr\\xyz\\mno", 3);
console.log(front);
I am writing appscript code to search for files in my drive.
Below are files in my google drive.
t_abcd.txt
p_abcd_0211.txt
j_abcd.docx
bwt_abcd.txt
etc
Note that _abcd is common in all of the above and only the prefix and suffix change.
I want the search to find all the above files when the user searches for "abcd" or its substring.
In the documentation for DriveApp.searchFiles(params) I could not find anywhere regular expressions or substrings being used to search for files.
One solution would be to get all files from the drive and write separate logic to identify the required files.
Is there any simpler way to do this?
Please advise.
How about this workaround? Unfortunately, in the current stage, I think that there are no methods for directly retrieving the files with the such filenames. So for example, how about the following workaround?
Document of Search for Files says
fullText: Full text of the file including title, description, content, and indexable text.
The query which is used as the workaround is fullText contains '_abcd'. I think that when this is used as the search query, the process cost is lower than that of the full search. Sample script is as follows. I think that there are several workarounds for your situation. So please think of this as just one of them.
Sample script:
var q = "fullText contains '_abcd'";
var files = DriveApp.searchFiles(q);
while (files.hasNext()) {
var file = files.next();
var filename = file.getName();
if (filename.indexOf("_abcd") > -1) {
Logger.log(filename)
}
}
Reference:
Search for Files
If this was not what you want, I apologize.
With DriveApp.searchFiles(params) you can use title contains "X" to get your files without using regular expressions and without having to take extra steps needed when searching with fullText contains.
Building on Tanaike's answer, here's an example function that logs the names of all Drive files with names containing "_abcd":
function findFiles() {
var q = "title contains '_abcd'";
var files = DriveApp.searchFiles(q);
while (files.hasNext()) {
var file = files.next();
filename = file.getName();
Logger.log(filename)
}
}
References:
DriveApp.searchFiles
docs
Tanaike's answer
As of now the query behaves:
able to search abcd if file starts with it abcd_slide, abcd_sheets, abcd_doc.
able to search abcd if it is another word.
Cannot search it is a subtext doc_abcd, sheets_abcd, slide_abcd.
Try creating a bug, to clarify its function.
How to avoid Parse Server from returning file path on calling
parseFile.save()
Parse JS SDK. Right now it returns-
{"url":"https://dsdsdiet-dfdf-18926.dfdfgsddf.com/parse/files/sdasdsadasdaasdasdasd/9bde9df4b8cf6b288ab0abac69b634a1_ok.pdf","name":"9bde9df4b8cf6b288ab0abac69b634a1_ok.pdf"}
The API call in background-
* {"base64":"JVBERi0xLjMKKL1Jvb3QgMTkgMCBSCi9JbmZvIDE4IDAgUgo+PgpzdGFydHhyZWYKMjAyNTIKJSsdsdsdsdsdVFT0Y=","_ContentType":"application/pdf","_ApplicationId":"JxZv88OYGAFtaqdRXnVOYyA107LvsdasdfCbzAK8E7Nkv","_ClientVersion":"js1.6.14","_InstallationId”:”23ds24csdsdsd42b86c493bf5691dd","_SessionToken":"r:d336df5be5d25c75dsdsddfee62d80c44ffdb3ef9"}
Is there a way I can get only file name instead of absolute path?
You may simply split your string on the "/", and keep only the last string in the array returned by the split function.
Here is the doc of the split method : http://www.w3schools.com/jsref/jsref_split.asp
It would lead to something like that :
var res = myString.split("/");
var file = res[res.length];
Does it fill your need ?
I need to replace some images in an InDesign document with a given file. This happens using the InDesign server, but scripting is almost the same as with regular InDesign, except no user interaction is possible.
What I have is a InDesign Document, the ID of an Rectangle containing some image and the Path to a new image that should replace the image.
The image should be replaced, but the settings like FitOptions etc. should stay the same. Also, the new file shall be embedded in the InDesign Document. There is already some code that sort of works:
function changeImages(doc) {
var arrayLength = changeImage.length;
for (var i = 0; i < arrayLength; i++) {
var fr = doc.textFrames.itemByID(1 * changeImage[i].id);
if (!fr)
continue;
var file = File(imagePath + changeImage[i].file);
fr.place(file);
fr.fit (FitOptions.CONTENT_TO_FRAME);
fr.fit (FitOptions.PROPORTIONALLY);
fr.fit (FitOptions.CENTER_CONTENT);
}
}
This doesn't seem right. Why is it using doc.textFrames when the object is a rectangle? I am actually confused this even works.
Also it just sets some FitOptions, but I want to keep the existing.
I am very new to InDesign scripting, so I am lost here. I am reading the docs and other resources, but I am confused. e.g why is there doc.textFrames.itemByID but nothing like that for other Frames? Do I have to iterate doc.allPageItems and compare ids?
itemByID is a method available for all pageItems and both textFrames and rectangles are subclass of pageItem. So you have access to this method from both, and it'll give the same result. You should be able to use doc.rectangles.itemByID as well. See: http://www.indesignjs.de/extendscriptAPI/indesign11/#Rectangles.html#d1e201999__d1e202138
But you are right that the description is a bit confusing, it says:
Returns the TextFrame with the specified ID.
which is obviously not the case. If you already have the IDs you want to target, you could use doc.pageItems.itemByID, which is maybe less confusing, since basically you're looking for pageItems when using itemByID.
As for fitting options, they are a property of your rectangle object, so placing a new image shouldn't change the fitting options. If you want to keep the same, simply remove the calls to fit(). See in property list of Rectangle, frameFittingOptions: http://www.indesignjs.de/extendscriptAPI/indesign11/#Rectangle.html
Josef,
I've had the same problem with InDesign CS4 with keeping the original FitOptions. I was never able to figure out how to get the settings currently being used in InDesign CS4.
To get around the problem what I did was to set the value in the Fitting on Empty Frame in the Frame Fitting Options in the InDesign document.
Then in code I used that setting, something like this:
changeImages (app.activeDocument);
function changeImages(doc)
{
with(doc)
{
var rec = doc.rectangles.itemByID(207);
var file = new File("c:\\new_image.png");
rec.place(file);
rec.fit(rec.frameFittingOptions.fittingOnEmptyFrame);
}
}
Basically I have a string variable that is composed of two other variables separated by a comma:
item = "Pencil";
amount = 5;
entry = item + "," + amount;
*export entry to csv
So the "entry" variable should be in the correct format to save as a comma separated file. Is there some command that will take this variable and save it as a csv, or any other format easily opened in a spreadsheet for later use? The entry variable will change and the new information will need to be appended to the csv file if it already exists. So let's say if we also had:
item = "Paper";
amount = 25;
entry = item + "," + amount;
*export entry to csv
The resulting csv file should be:
Pencil,5
Paper,25
I've done a bit of searching through other questions, but most folks seem to be trying to do more complex things (e.g., dealing with server vs. client-side issues) while I'm just trying to figure out how to get data I'm working on my own computer in javascript to a saveable file. Seems like that isn't the case for many questions being asked though. I'm sure there's a simple answer out there and hopefully just a single command or two. However, I've been wading through a lot of semi-related posts that aren't too clear, so I figured this would be quicker.
It is perfectly possible, using some FileSaver implementation. I believe it exists natively on IE10, but still needs a shim on other browsers.
I've written a light-weight client-side CSV generator library that might come in handy. Check it out on http://atornblad.se/github/ (scroll down to the headline saying Client-side CSV file generator)
As I said, it requires a functioning FileSaver implementation handling calls to window.saveAs(). Check out Eli Grey's solution on http://eligrey.com/blog/post/saving-generated-files-on-the-client-side
When in place, you simply generate and save CSV files on the fly like this:
var propertyOrder = ["name", "age", "height"];
var csv = new Csv(propertyOrder);
csv.add({ name : "Anders",
age : 38,
height : "178cm" });
csv.add({ name : "John Doe",
age : 50,
height : "184cm" });
csv.saveAs("people.csv");