I have a script that returns all the files contained within a folder. However, there are some file types in there that I do not want my script to do anything with. I just want it to literally skip over it as if it wasn't there and only deal with the other file types.
How can I achieve this?
So far this is how I'm getting all the files contained within a folder:
var samplesFolder = Folder(Path)
//Get the files
var fileList = samplesFolder.getFiles()
//Creat Array to hold names
var renderTypes = new Array();
//Parse Initial name to get similar render elements
var beautyRender = fileList[0].name
beautyRender = beautyRender.substr(0, beautyRender.length-4)
//Get the render elements with a similar name
for (var i = 0; i < fileList.length; i++)
{
if(fileList[i].name.substring(0,beautyRender.length) === beautyRender)
{
renderTypes[i] = fileList[i].name
}
}
This is not used for web purposes I should hasten to add.
edit
Above is the complete code I have to get all the image files in a folder and bring them into photoshop once the user has selected the folder they want to use. At the moment it is bringing in every single image in the folder when there is a single type I want it to ignore.
You can iterate over the list and only collect those with extensions you care about. i see photoshop so I'll assume image files only:
var distilledFileList = [];
for (var i = 0; i < fileList.length; i++){
if (/\.(?:jpe?g|png|gif|psd)$/i.test(fileList[i].name)){
distilledFileList.push(fileList[i]);
}
}
Now distilledFileList contains only *.jpg, *.jpeg, *.png, *.gif, and *.psd files.
if you want an easier (more readable) way to check extensions (maybe you're not as fluent as regular expressions):
// fileList = ....
// setup an array of bad extensions here:
var bad = ['txt', 'log', 'db'],
// holds new list of files that are acceptable
distilledFileList = [];
// iterate over entire list
for (var i = 0; i < fileList.length; i++){
// grab the file extenion (if one exists)
var m = fileList[i].name.match(/\.([^\.]+)$/);
// if there is an extenions, make sure it's now in the
// 'bad' list:
if (m && bad.indexOf(m[1].toLowerCase()) != -1){
// it's safe, so add it to the distilled list
distilledFileList.push(fileList[is]);
}
}
Assuming fileList is just an array of strings you could do something along the lines of:
for (var i = 0, len = fileList.length; i < len; i++) {
var filename = fileList[i].name;
if (filename.match(/\.(txt|html|gif)$/i) !== null) { continue; }
// Your logic here
}
Where txt, html and gif are file extensions you want to skip over, you can add more by separating them with |
Related
I am new to JS and I have a program (written in the Common Workflow Language) that takes in two arrays, one of files one of strings. The arrays are initially the same length:
var headers = ["Header1", "Header2", "Header3"];
var files = [file1, file2, file3];
Each header corresponds to a particular file so Header1 -> file1, Header2 -> file2, Header3 -> file3. I have a step in my workflow that splits the files by a certain number of lines into an array of split files, so now I have an array of arrays of files like so:
var files = [[01.file1, 02.file1, 03.file1], [01.file2, 02.file2],
[01.file3, 02.file3, 03.file3, 04.file3, 05.file3]];
Since the files are split by a certain number of lines, I have no way of knowing beforehand how many times the file is going to be split (I am processing a lot of files at a time).
Basically, what I am trying to do now, is duplicate each header equal to the length of each subarray, so Header1 should be duplicated 3 times, Header2 should be duplicated twice, and Header3 should be duplicated 5 times.
I have seen a few posts on how to duplicate a single string into an array of known length that use the var arrayNew = new Array(int).fill(x) method, but this seems to statically assign a length to an array and fill it with a single value.
I am trying to duplicate the headers strings by the length of the files array of arrays. Here is what I have so far:
var dupStrings = [];
for (var i = 0; i < files.length; i++) {
var arrLen = files[i].length;
dupStrings.push(headers[i].repeat(arrLen));
}
But this is currently giving me:
var headers = ["Header1Header1Header1", "Header2Header2",
"Header3Header3Header3Header3Header3"]
I now understand why that is happening, but I don't know how to fix it. I would like it to be:
var headers = [["Header1", "Header1", "Header1"], ["Header2", "Header2"],
["Header3", "Header3", "Header3", "Header3", "Header3"]]
Your current issue occurs, because headers[i].repeat(arrLen) returns string, whereas you need an array, you may do dupStrings.push(Array(arrLen).fill(headers[i])) instead.
However, there's the other way around:
const headers = ["Header1", "Header2", "Header3"],
files = [[01.file1, 02.file1, 03.file1], [01.file2, 02.file2], [01.file3, 02.file3, 03.file3, 04.file3, 05.file3]],
result = headers.map((h,i) => Array.from({length: files[i].length}, () => h))
console.log(result)
Try map and fill:
var headers = ["Header1", "Header2", "Header3"];
var files = [["01.file1", "02.file1", "03.file1"], ["01.file2", "02.file2"],
["01.file3", "02.file3", "03.file3", "04.file3", "05.file3"]];
var dupStrings = headers.map(function(element, index) {
return Array(files[index].length).fill(element);
});
console.log(dupStrings)
Your for-loop is not correct, you have to iterate on files[i] in order to create an array because repeat is creating a string. The answer without using map of fill (it may be difficult for you, a newbie to understand how map and fill work) is :
for (let i = 0; i < files.length; i++) {
for (let j = 0; j < files[i].length; j++) {
dupStrings.push(headers[i]);
}
headers[i] = dupStrings;
dupStrings = [];
}
I am trying to process a *.gcode file (plain text) that is currently 2.5mb in size, but could be as large as 50mb. In the process it searches for the indexOf a key and then it finds the following new line character to insert the specific script needed to modify the gcode. For a 2.5mb file it takes nearly 6 seconds to process this request. I'd like to shorten this process if possible and test it against a 50mb file.
Thx for any input.
var loc_array = [2.500, 10.000];
var pos = 0;
for(var i = 0; i < loc_array.length;i++){
//Find Line
var p = gcode.indexOf("END_LAYER_OBJECT z="+loc_array[i], pos);
if (p != -1){
//Go to the following line and insert String
p = gcode.indexOf("\n", p);
gcode = gcode.slice(0, p)+ "G28 X\nM117\nM0\nG28 X"+gcode.slice(p);
pos = p;
}
}
First off, for Chromecast reasons, I want to, currently, limit the solution to the Chrome browser.
What I'd like to do is package up a directory of images, with a launcher batch file (cmd or sh) and an html file. The html file is to be completely self contained, with no imports.
The bat file would contain something like:
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files "file://%CD%\SlideShow1.2.html?slideDir=%CD%\Slides"
Currently I can use
<input type="file" id="slideInput" multiple="multiple" webkitdirectory="webkitdirectory" onchange="appendToSlideList();" accept=".png,.gif,.jpg,.jpeg" />
to manually select files, and
var slideList = [];
var numSlides = 0;
function appendToSlideList()
{
var slideInput = document.getElementById("slideInput");
var slides = slideInput.files;
for(j = 0; j < slides.length; j++)
{
slideList[numSlides++] = slides[j];
}
}
to append pictures from selected directories to the master slide list. Then the following, via a Timer() object displays the slides:
function showNext()
{
if(picture == null)
{
picture = document.getElementById("slideShow");
intervalElem = document.getElementById("interval");
}
if(currentPicture == numSlides)
{
currentPicture = 0;
}
// this comes from https://www.w3.org/TR/file-upload/#file
picture.src = window.URL.createObjectURL(slideList[currentPicture++]);
var interval = parseInt(intervalElem.value) * 1000;
timer = new Timer(showNext, interval);
}
If you've read this far, kudos :). So, all this (plus other auxiliary code that is not germane to the desired solution) works to show a slideshow based on user input from the object.
My desire is to package things up so that all the user has to do is double click on the bat file, and the browser proceeds to show the slide show.
So, after all this, my question is, how do I take the directory passed in, and get all the graphic files in that directory, for use in the already working code.
I've spent the last six hours researching this question, much on StackOverflow, and it appears, to me, currently, that this is an impossible quest.
Here's a fiddle with 'complete' minimalist code: https://jsfiddle.net/hrvrdfjs/
Thanks!
Tom.
There is currently no way for JavaScript in the browser to list files from a directory without the user explicitly choosing the directory in the browser.
However, you can easily create a JavaScript file that contains a list of the image files in the directory from a batch file like this:
#echo off
echo var toC = ` > "C:\slides\data.js"
dir C:\slides\*.png,*.gif,*.jpg,*.jpeg /B >> "C:\slides\data.js"
echo `; >> C:\slides\data.js
This will create file data.js which looks like this:
var toC = `
funny.png
serious.png
holidays.jpeg
`;
Explanations:
echo var toC = ` > "C:\slides\data.js"
Creates or overwrites the file C:\slides\data.js with the javascript code that is the first part of creating a template literal.
dir C:\slides\*.png,*.gif,*.jpg,*.jpeg /B >> "C:\slides\data.js"
Tells dir to list the files with the given extensions in the given directory and appends the file names to the file data.js. The parameter /B makes dir only output the files names, no other information and also skip outputting a header and footer for the listing.
echo `; >> C:\slides\data.js
This appends the end of the javascript template literal.
In JavaScript ES6 and newer, template literals can be used to create string literals that span multiple lines and can contain arbitrary characters.
Load the file data.js dynamically from your html document (by inserting a script tag that refers to the file) and you can access the variable toC which contains the list of files as a multi-line string.
This is a demo where the data.js file is statically included:
<html>
<head>
<script src="C:\slides\data.js"></script>
</head>
<body>
<script>
window.alert(toC);
</script>
</body>
</html>
I wasn't able to use the "dir" command as given above, perhaps because I'm using windows 7. Here is what I came up with, instead:
mkdir C:\Temp\slideShow
rem Replace each instance of a back slash with two, as javascript will remove a single backslash
rem (Unless it is followed by a 'valid' backslash char (r,n,etc.), which is not what we want.).
echo var topLocation = '%CD:\=\\%'; > C:\Temp\slideShow\topLocation.js
echo var slideDirContents = ' > "C:\Temp\slideShow\slideDirContents.js"
dir %CD%\Slides\*.jpeg %CD%\Slides\*.jpg %CD%\Slides\*.png %CD%\Slides\*.gif /B /ON >> "C:\Temp\slideShow\slideDirContents.js"
echo '; >> C:\Temp\slideShow\slideDirContents.js
Then, to split out each file from the input .js file, and create a file path that would later be used to build an URL that the img.src could present the file (NOTE: the add function had to be done after the page was loaded, so the textarea element would be present for the javascript to modify):
function doOnloadFunctions()
{
addStaticsToSlideList();
}
function addStaticsToSlideList()
{
// Empty dir on Windows == size 2 (CR-LF)
// Empty dir on others == size 1 (CR or LF)
if((slideDirContents.length != 2) && (slideDirContents.length != 1))
{
var slidelistElem = document.getElementById("slidelist");
// Linux/Unix/BSD based line separator = \n
// Windows based line separator = \r\n
// Mac based line separator = \r
var re = /\n|\r\n|\r/;
var slides = slideDirContents.split(re);
for(j = 0; j < slides.length; j++)
{
var aFile = {};
var theName = slides[j].trim();
if(theName.length > 0)
{
var fileName = slides[j];
aFile.fileName = topLocation + '\\Slides\\' + fileName;
// Set the original index to the current insertion point.
aFile.oi = numSlides;
// Set the shuffle index simply to instantiate it. We'll
// set the si for real when we want to shuffle the array.
aFile.si = 0;
var listElem = document.createElement("li");
listElem.appendChild(document.createTextNode(fileName));
slidelistElem.appendChild(listElem);
slideList[numSlides++] = aFile;
}
}
}
}
There's a <file> input element that can be used to append local files to the slide list, the <file> input doesn't fill in fileName it just fills in name thus this is the differentiating code that instantiates each <img> with the proper url:
if(!(typeof slideList[currentPicture].fileName === 'undefined' || slideList[currentPicture].fileName === null))
{
// variable is defined and not null
picture.src = "file://" + slideList[currentPicture++].fileName;
}
else
{
// this comes from https://www.w3.org/TR/file-upload/#file
picture.src = window.URL.createObjectURL(slideList[currentPicture++]);
}
Thanks to NineBerry for the code and suggestions!
So I need some help saving some files that people will submit via a file upload.
Right now my code replaces it each time, but I want it to not replace each time. Like for example my user chooses a certain amount of files like 3 files, uploads them, and then chooses 1 file and uploads that as well. That would be a total of 4 files. What my code is doing now is if my user uploads 3 files, it saves the 3 files and then if they upload 1 file it gets rid of the 3 and only has one file.
I want it to not get rewritten, and have 4 files. Please help. This seem very trivial but I can't seem to get it.
function handleFileSelect(e) {
if (!e.target.files) return;
selDiv.innerHTML = "";
var files = e.target.files;
for (var i = 0; i < files.length; i++) {
var f = files[i];
selDiv.innerHTML += f.name + "<br/>";
}
}
I believe your issue is you are resetting the innerHTML in the function call. I assume this function is called every time files are uploaded?
function handleFileSelect(e) {
if (!e.target.files) return;
selDiv.innerHTML = ""; // <--- this will empty the div
var files = e.target.files;
for (var i = 0; i < files.length; i++) {
var f = files[i];
selDiv.innerHTML += f.name + "<br/>";
}
}
If you have uploaded files, then called this function and displayed them and then upload more files and call this function it will constantly reset the innerHTML. I believe if you remove that line it will continue to append the uploaded files without overwriting the previous ones.
I am making an Illustrator CS6 Javascript that does the following:
Open a folder of Illustrator files
Open each file in the folder (these files are called the source files)
Select all the contents of the source file
Copy the contents of the source file
Create a new target file Paste these contents into the target file as a new layer
Ensure the new layer has the same name as the old source file
My script works except, it doesn't loop through the files in the source folder correctly. Instead, it runs fine on the first source file. But then it endlessly just pastes the second source file in the destination document (I.e. it doesn't move onto any of the other source file). It just endlessly pastes and so I have to force quit!
How can I get it to loop through the folders properly and then move onto the next file.
Here is my code:
// JavaScript Document
//Set up vairaibles
var destDoc, sourceDoc, sourceFolder, newLayer;
// Select the source folder.
sourceFolder = Folder.selectDialog('Select the folder with Illustrator files that you want to mere into one', '~');
destDoc = app.documents.add();
// If a valid folder is selected
if (sourceFolder != null) {
files = new Array();
// Get all files matching the pattern
files = sourceFolder.getFiles();
if (files.length > 0) {
// Get the destination to save the files
for (i = 0; i < files.length; i++) {
sourceDoc = app.open(files[i]); // returns the document object
var myLayers = sourceDoc.layers; // Select All layers in Active Document
//Go through all layers of source document and copy artwork
for (i = 0; i < myLayers.length; i++) {
myLayers[i].hasSelectedArtwork = true;
};
with(sourceDoc) {
var count = pageItems.length;
for (var i = 0; i < count; i++) {
pageItems[i].selected = true;
}
redraw();
copy();
for (var i = 0; i < count; i++) {
pageItems[i].selected = false;
}
}
//Create a new title variable that has the title of the source document
var title = sourceDoc.name;
var title = title.substring(0, title.length - 4); //(remove extension from name)
//Close the Source Document
sourceDoc.close(SaveOptions.DONOTSAVECHANGES);
//Open the Destination Document and create a new layer in it that is named after the title variation
newLayer = destDoc.layers.add();
newLayer.name = title;
//Paste into this new layer
newLayer = app.paste();
}
}
else {
alert('No matching files found');
}
}
Ps. I wasn't sure if I should post this in Code Review or Graphic Design, but I think Stack overflow is the best place to post this as it is a general question about javascript looping, so I hope this is the right place.
It appears that you are using "i" for the variable in each of your loops, giving it a range of unexpected values in other loops that also use that same variable. I would try using a separate variable for each loop. E.g. for j=0, for k=0, for l=0, etc.