i am using javascript in macros now i need to get all the names of subfolder from a local path, store these into an array and pass it to macros one bay one from javascript.using firefox where ActiveX is not available , so what the easiest way to get the subfolders names and pass it to macros?
Perhaps, this way is the easiest one:
/* indicate your folder */
var folder = "D:\\Temp";
var dir = imns.Cc["#mozilla.org/file/local;1"].createInstance(imns.Ci.nsILocalFile);
dir.initWithPath(folder);
var subFolders = [];
var subFolderEnum = dir.directoryEntries;
while (subFolderEnum.hasMoreElements()) {
var curSub = subFolderEnum.getNext().QueryInterface(imns.Ci.nsILocalFile);
if (curSub.isDirectory()) {
// subFolders.push(curSub.path); // for the full path
var subFolder = curSub.path;
subFolder = subFolder.substr(subFolder.lastIndexOf("\\") + 1);
subFolders.push(subFolder);
}
}
/* view the result */
alert(subFolders.join("\n"));
Related
In Google Drive I am trying to compare an id in a file name against folders named with that id, and if they match, to move that file to that folder.
Some of the problems that the program has to account for are:
Since the id is generated from the customer's name it does not have a set length
The id could be anywhere in the file name, not just at the beginning or end
There can be multiple files with different names containing the same id, so the program
has to loop
Things that make this easier:
All of the folders are in the same parent folder and have the id as their name, so the
program can use the list of folder names as a list of the ids
The files are all in the same parent folder, and there will be no other files in the
folder, so the loop can just run until the folder is empty
So far I have written a code that successfully:
Accesses both parent folders by id
Loops through the file folder until it has checked all files, and pushes the file names to
an array called "fileNames"
Loops through the folders and compares the current folder's name to the file names for a
match, and pushes the folder names to an array called "childNames"
I have created two files in the "files" folder to test with, "john1111_test.pdf" and "thomas2222_test.pdf", and two folders in the "childName" folder "john1111" and "thomas2222"
The part that I am stuck on is copying the file to the folder it matched with.
var childFolder = DriveApp.getFolderById('****').getFolders(); // Folder containing folders
var files = DriveApp.getFolderById('****').getFiles(); // Folder containing the files
var fileNames = [];
while (files.hasNext()) {
var file1 = files.next();
var fName = file1.getName()
Logger.log(fName);
fileNames.push(fName);
}
var childNames = [];
while (childFolder.hasNext()) {
var child = childFolder.next();
var cdName = child.getName();
Logger.log(cdName);
childNames.push(cdName);
const match = fileNames.find(element => {
if (element.includes(cdName)) {
// This is the area that I am having issues with
let folderMatch = childFolder.getFoldersByName(cdName);
let fileMatch = files.getFilesByName(element);
folderMatch.addFile(fileMatch)
return true;
}
});
console.log(match);
}
I receive an error saying that foldermatch.addFile is not a function. I have tried cdName.addFile(element) as well.
Moving Files
function movingFile() {
const files = DriveApp.getFolderById('1jeAihkCiA--EfAl150IXrXDUa-MhYSKY');
const folders = DriveApp.getFolderById('1xB4XTG8d1DYtthVQQqkSQCqvzv-TGWtW');
const fldrs = folders.getFolders();
let fldrNames = [];
let fldrA = [];
while (fldrs.hasNext()) {
let fldr = fldrs.next()
fldrNames.push(fldr.getName());
fldrA.push(fldr);
}
const fs = files.getFiles();
while (fs.hasNext()) {
let file = fs.next();
let idx = fldrNames.indexOf(file.getName().slice(0,file.getName().indexOf('_')));
if(~fldrNames.indexOf(file.getName().slice(0,file.getName().indexOf('_')))) {//if folder is present move it here
//SpreadsheetApp.getUi().alert(file.getName().slice(0,file.getName().indexOf('_')));
Drive.Files.update({"parents": [{"id": fldrA[idx].getId()}]}, file.getId());
} else {//if it is not then create it first and xfer
let f = folders.createFolder(file.getName().slice(0,file.getName().indexOf('_')));
fldrA.push(f);
Drive.Files.update({"parents": [{"id": f.getId()}]}, file.getId());
fldrNames.push(file.getName().slice(0,file.getName().indexOf('_')));//added folder name to fldrNames so that it will be used again if there are more files with that name
}
}
}
Before:
After:
Need to enable Drive API Version 2
I have a system whereby I automatically upload files to Gdrive and Gdrive searches those files, combines them and adds a template sheet to the combined sheets.
In the template gsheet I need to be able to reference cells inside other tabs without using the tabs name (the tabs name will be changing all the time). The only way I know how to do this is by using google apps script inside the gsheet. The problem is the way I generate the template is by opening the template and copying all values to a new tab in the newly created combined gsheet and it wont copy the google apps script with it.
Even if i can automatically add a script to a new sheet using code I still need that script to automatically run on that sheet because I have another master sheet that looks for all of the newly created files and adds summary information from all of them.
Here is my Gdrive script if it helps.
/* Head Master Info >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
/* Top Level Google Drive Folder ID */
var TopDriveFolderID = "0B2rN5b8fW77ldXZXOXFLZGlSamc";
var BaseNumberOfFilesInFolder = 4;
var NewSSAnalyzerSheetId = "1VyL8XL1x41H6yetcrwfUhVcch-DUsngY4-bHCbo-_xM";
/* End Head Master Info >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
/* Body >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
/* Functions to iterate through all sub folders */
function listFolders() {
var parentFolder = DriveApp.getFolderById(TopDriveFolderID);
var childFolders = parentFolder.getFolders();
while(childFolders.hasNext()) {
var child = childFolders.next();
// Logger.log(child.getName() + " |Drive_ID: " + child.getId());
var folderId = child.getId();
// **the folderId Variable is also the folder ID,
// hence they are used interchangeably **
/* SpreadSheet Combiner >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
/* Name of combined Spreadsheet*/
var newSpreadSheetName = DriveApp.getFolderById(folderId).getName();
/* Retrieve the desired folder */
var myFolder = DriveApp.getFolderById(folderId);
/* Get all spreadsheets that resided on that folder */
var spreadSheets = myFolder.getFilesByType("application/vnd.google-apps.spreadsheet");
var spreadSheetName = myFolder.getName();
// Logger.log(spreadSheetName);
/* Check if a file needs to be created or if one already exists*/
var theFolder = DriveApp.getFolderById(folderId);
var files = theFolder.getFiles();
var fname = theFolder.getName();
var cnt = 0;
var file;
/* Check the quantity of files in a folder to see if you need to combine the sheets and create a file*/
while (files.hasNext()) {
cnt++;
file = files.next();
//Logger.log(file.getName());
if (cnt > BaseNumberOfFilesInFolder) {
Logger.log("File already exists")
break;
}
;
};
// If a file needs to be created this checks it and creates it
Logger.log(cnt + " is the number of files '"+ newSpreadSheetName+ "' has.");
if (cnt > BaseNumberOfFilesInFolder){
Logger.log("No file needs to be created")
}else{
/* Create the new spreadsheet that you store other sheets */
var newSpreadSheet = SpreadsheetApp.create(newSpreadSheetName);
/* Iterate over the spreadsheets over the folder */
while(spreadSheets.hasNext()) {
var sheet = spreadSheets.next();
/* Open the spreadsheet */
var spreadSheet = SpreadsheetApp.openById(sheet.getId());
/* Get all its sheets */
for(var y in spreadSheet.getSheets()) {
/* Copy the sheet to the new merged Spread Sheet */
spreadSheet.getSheets()[y].copyTo(newSpreadSheet);
/* In order to move the file to the folder we want and because
google considers the SpreadSheet a Google Spreadsheet
instead of a file, we have to convert the SpreadSheet to a file in
order to move it.Thats what the next 2 lines of code do.*/
var getNewSSid = newSpreadSheet.getId();
var SStoGFile = DriveApp.getFileById(getNewSSid);
/* Actually moving the file*/
DriveApp.getFolderById(folderId).addFile(SStoGFile);
/* Deleting the duplicate file that was created in the process*/
var rootFolder = DriveApp.getRootFolder();
DriveApp.getRootFolder().removeFile(SStoGFile);
}
}
/*Code to add our base analysis template to the new combined template that was created;*/
//Grabs the template
var sss = SpreadsheetApp.openById(NewSSAnalyzerSheetId); //replace with source ID
var ss = sss.getSheetByName('Analysis Tab'); //replace with source Sheet tab name
var range = ss.getRange('A1:E6'); //assign the range you want to copy
var data = range.getValues();
//Copies the template info into the current newly created sheet
var tssId = newSpreadSheet.getId();
var tss = SpreadsheetApp.openById(tssId); //replace with destination ID
var ts = tss.getSheetByName('Sheet1'); //replace with destination Sheet tab name
ts.getRange(1,1,6,5).setValues(data); //you will need to define the size of the copied data see getRange()
Logger.log("New File was created with the name - " + newSpreadSheetName)
}
};
/* End SpreadSheet Combiner >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
getSubFolders(child);
}
/* Necessary Function to help the above loop through the sub folders */
function getSubFolders(parent) {
parent = parent.getId();
var childFolder = DriveApp.getFolderById(parent).getFolders();
while(childFolder.hasNext()) {
var child = childFolder.next();
Logger.log(child.getName());
getSubFolders(child);
}
return;
}
/* End iterate through Sub Folders */
How about instead of using SpreadsheetApp.create() use DriveApp.getFileById().makeCopy()? Then you could have whatever scripts you wanted already in the spreadsheet when you make it.
I'm trying to get my javascript to ignore one file type extension that's held in a folder with a bunch of photoshop images. For all of the other file types in the folder I have it so that these file types populate a window and the user can import into their work space.
I have modified my script to ignore the file extension I want ignored, however it no longer populates the window with all of the other file types containted in the folder. But when I take out the file I want ignore from the folder, the window gets populated as it should.
This is what I have at the moment that checks my folder for the file types:
//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)
//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++)
{
var filename = fileList[i].name;
if (filename.match(/\.(stitchinfo)$/i) == null)
{
if(fileList[i].name.substring(0,beautyRender.length) === beautyRender)
{
renderTypes.push(fileList[i].name);
}
}
}
Can anyone see what I've done wrong and need to modify?
Update
I'm still trying to get this to work and following the help from one of the posters below I have modified my code to the following:
for (var i = 0; i < fileList.length; i++)
{
var filename = fileList[i].name;
if (filename.match(/\.(stitchinfo)$/i) == null)
{
renderTypes.push(fileList[i].name);
}
}
However, with this new code comes a new problem in that it returns every file contained in the folders and displays it.
I'm still stumped as to how I can get this to work as I would like. Please can anyone help me?
You're creating a sparse array, because you skip elements in renderTypes when you ignore a filename in fileList. That may be confusing your rendering code. Change to:
renderTypes.push(fileList[i].name);
What if :
for (var i = 0; i < fileList.length; i++)
{
var filename = fileList[i].name;
if (filename.match(/\.(stitchinfo)$/i) == null)
{
if(fileList[i].name.substring(0,beautyRender.length) === beautyRender)
{
renderTypes.push(fileList[i].name);
}
}
}
Wrong usage of the array
Missing ";"
Unnecessary use of "continue".
Managed to get a fix for this.
What I've ended up doing is creating a new function and passing that into my call for checking the folder locations.
function ignoreMe(f)
{
return f.name.match(/\.(stitchinfo)$/i) == null;
}
And the folder check:
var fileList = samplesFolder.getFiles(ignoreMe);
I am using the following code in order to retrieve sub folder names from the path declared. This works fine but how do I then remove the path name so that the array is a list of just folder names?
var myPath = Folder ("Z:/My File System/Me/Work Files/Design");
var folders = getFolders (myPath);
function getFolders(sourceFolder) {
var folderArray = new Array();
var sFolders = sourceFolder.getFiles ();
var len = sFolders.length;
for (var i = 0; i < len; i++) {
var sFolder = sFolders[i];
if (sFolder instanceof Folder) {
folderArray.push(sFolder);
}
}
return folderArray;
}
Instead of returning:
Z:/My File System/Me/Work Files/Design/One
Z:/My File System/Me/Work Files/Design/Two
Z:/My File System/Me/Work Files/Design/Three
Z:/My File System/Me/Work Files/Design/Four
I need:
One
Two
Three
Four
You could implement something like this (assuming you can modify the Folder prototype, and it stores the path as this.path):
Folder.prototype.basename = function () {
return this.path.split('/').pop();
};
You would then append the base names to the array:
folderArray.push(sFolder.basename());
You could use split() like this, assuming there are no other slashes towards the end.
var sample = 'Z:/My File System/Me/Work Files/Design/Four'.split('/')
var result = sample[sample.length - 1]
Regexp the string. Start at the end, and work backward until the first '/'
I have real problem in displaying the content of the folders which are located inside the root directory. It managed to determine the folders which are in the Files directory but when I try to do the same to one of those folders It doesn't work.
I delieve the problem in the path name of a WL.api. However I may be mistaken.
I used code samples from skydrive page of live connect development center. in the sample below I tried to determine folders first, but eventually I would like to get the names of all files stored in a particular directory.
WL.api({ path: "me/skydrive/files/myfolder", method: "get" }).then(
function (response) {
var items = response.data;
var outPuts = "";
var number = items.length
var tempos = new Array();
var foundFolder = 0;
for (var i = 0; i < items.length; i++) {
if (items[i].type === "folder" || items[i].type === "album") {
tempos[i] = items[i].name;
foundFolder += 1;
}
}
if (foundFolder == 0) {
folderss.innerHTML = ("Unable to find any folders");
}
else {
for (var i = 0; i < number; i++) {
outPuts = outPuts + tempos[i] + "<br /> <br />"
}
folderss.innerHTML = outPuts;
}
}
);
if I retain only "me/skydrive/files" for WL path. it works. But if I add any particular folder name afer it like in my case "me/skydrive/files/myfolder" the call returns nothing. or may be I shall declare a path like: "me/skydrive/files/folder.567391047.34282821!"
Thank you for anyone who can help.
I believe your problem is due to the fact that you are using an invalid path format. According to the examples from the docs, a valid path to list files has the following form: /OBJECT_ID/files, where OBJECT_ID may be replaced by me/skydrive to reference the Skydrive root folder.
The important things to note are that:
there can be a reference (OBJECT_ID) to only one object;
this reference can only be the ID of an object (as returned by the API) or a special alias such as me/skydrive;
/files should always be the last part of the path (assuming we do not need to use a query string).
Thus, to list the contents of your subfolder folder.567391047.34282821!, you should try using the following path format instead:
/folder.567391047.34282821!/files or even folder.567391047.34282821!/files (without the leading slash, as it seems to be optional).
Please let me know if this solves your issue.