I have a main folder Folder 1
inside Folder 1 there is multiple subfolder which have files. i want to change all subfolder files sharing permission Access.ANYONE_WITH_LINK no sign in require. currently i have follow code but it only work if there is no subfolders.
function myFunction() {
var folderId = "Folder ID";
var files = DriveApp.getFolderById(folderId).getFiles();
var result = [];
while (files.hasNext()) {
var file = files.next();
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
var temp = {
file_name: file.getName(),
url: "http://drive.google.com/uc?export=view&id=" + file.getId(),
};
result.push(temp);
};
}
This code will help you with your current problem:
function myFunction() {
var folderId = "main-id-folder";
// Take the mainder folder
var mainFolder = DriveApp.getFolderById(folderId);
// Take the subfolders inside your main folder
var subFolders = mainFolder.getFolders();
var result = [];
// Iterate over each subfolder
while(subFolders.hasNext()){
var subFolder = subFolders.next();
// Take the files inside the current subfolder
var files = subFolder.getFiles();
// Take each file inside the current subfolder
while(files.hasNext()){
var file = files.next();
var tmp = {
file_name: file.getName(),
url: "https://docs.google.com/spreadsheets/d/" + file.getId() + "/edit#gid=0"
};
// For the current file, stablish the permissions you want
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
result.push(tmp);
}
}
Logger.log(result);
}
The problem you had is you were only trying to get the files from your main folder but in order to get the files inside each subfolder, you needed to first take each subfolder using .getFolders(); and then for each one of them, you could use .getFiles();.
Docs
These are the docs I used to help you, in case you want to see them or anyone else who has a similar issue:
Class File
Enum Access
Related
I want to navigate into a specific folder and then print all the files inside that specified folder using Google Apps Script:
function listFilesinSpecFolder(){
var files = DriveApp.getFolderById("specific folder id placed here");
while (files.hasNext()) {
var file = files.next();
Logger.log(file.getName());
}
}
When I tried to log this it gives me an error saying that hasNext() function is not a function.
But when I run the below code it gives me no errors...
function folder(){
var folders = DriveApp.getFolders();
while (folders.hasNext()) {
var folder = folders.next();
Logger.log(folder.getName());
}
}
The following script will help you 'to navigate into a specific folder and then print all the files inside that specified folder'
CODE:
function listFilesinSpecFolder() {
var folder = DriveApp.getFolderById('FOLDER ID GOES HERE');
var file;
var contents = folder.getFiles();
while(contents.hasNext()) {
file = contents.next();
Logger.log(file.getName());
}
}
var files = DriveApp.getFolderById("specific folder id placed here");
this does not return files, it will return a folder
instead try something like:
var folder = DriveApp.getFolderById("specific folder id placed here");
var files = folder.getFiles()
I'm trying to automate my duplicating folder process in google drive. As part of the process, I want to rename files and folders for each new client.
I've adapted some code found previously. It was previously working well, but for some reason now any folders/files that are more than 1 level deep of the root folder come back "undefined" in the replace section of the command.
function duplicatefolder(){
var newclientname = Browser.inputBox('Client Name')
var sourceFolder = "1. Master Client Folder";
var targetFolder = newclientname;
var source = DriveApp.getFoldersByName(sourceFolder);
var target = DriveApp.createFolder(targetFolder);
if (source.hasNext()) {
copyFolder(source.next(), target, newclientname);
}
}
function copyFolder(source, target,client) {
var folders = source.getFolders();
var files = source.getFiles();
while(files.hasNext()) {
var file = files.next();
var newname= file.getName().toString().replace("Master",client)
file.makeCopy(newname, target);
}
while(folders.hasNext()) {
var subFolder = folders.next();
var folderName = subFolder.getName();
var newFolderName = subFolder.getName().replace("Master",client)
var targetFolder = target.createFolder(newFolderName);
copyFolder(subFolder, targetFolder);
}
}
The script also creates the folder in the root directory of google drive. Ideally, I'd like it to be created inside the folder "Clients". How would I add this to the script?
Appreciate the help.
Cheers
Please see attached link hope this is it what you are looking for
https://yagisanatode.com/2018/07/08/google-apps-script-how-to-create-folders-in-directories-with-driveapp/
I'm starting to learn google apps script and suffering a little, :S.
So, when I run this function:
function importXLSX(){
var files = DriveApp.getFolderById('0B5HXuvZIdqQ3bWlKNXFXZzhIcmc').searchFiles('title contains ".xlsx"');
while(files.hasNext()){
var xFile = files.next();
var name = xFile.getName();
if (name.indexOf('.xlsx')){
var ID = xFile.getId();
var xBlob = xFile.getBlob();
var newFile = { title : name+'_converted',
key : ID,
}
file = Drive.Files.insert(newFile, xBlob, {
convert: true
});
}
}
}
The files converteds are set in Drive's root, but I´d like that
When I run the code, the files are saved in the root folder but I would like them to be saved to a specific folder, like "Converteds", so if anyone knows how to solve it, I would be very grateful!
This is a reference link about the function: Convert all xls files available in a folder into "Google Doc Spreadsheets"?
Thanks!
Since you use Drive API, you can directly create a file to the specific folder.
I added parents: [{"id": "### Folder ID ###"}] to newFile. Please change ### Folder ID ### to the specific folder and try this.
Modified script :
function importXLSX(){
var files = DriveApp.getFolderById('0B5HXuvZIdqQ3bWlKNXFXZzhIcmc').searchFiles('title contains ".xlsx"');
while(files.hasNext()) {
var xFile = files.next();
var name = xFile.getName();
if (name.indexOf('.xlsx')) {
var ID = xFile.getId();
var xBlob = xFile.getBlob();
var newFile = {
title : name+'_converted',
key : ID,
parents: [{"id": "### Folder ID ###"}]
}
file = Drive.Files.insert(newFile, xBlob, {convert: true});
}
}
}
If you want to retrieve folder ID from folder name. Please use following script.
var folderId = DriveApp.getFoldersByName("### Folder name ###").next().getId();
If I misunderstand your question, I'm sorry.
First you need to get the Folder id (right-click the folder in Google Drive and check its share options by clicking "Get Shareable Link", the string at the tail-end of the share URL is the folder's id) and then for each file you convert add the file to the target folder.
var folder = DriveApp.getFolderById([folder-id]);
while(files.hasNext()) {
var file = files.next();
...
...
folder.addFile(file);
}
And that should do the trick!
So I created my first script by copying and pasting stuff from others. Somewhere down the line it look like I removed something that allows for triggers (both time & onchange) to work.
I tried applying some suggestions from other questions like these but without result..
function DolistFilesInFolder() {
listFilesInFolder("specified folder"); //Enter folder name in between " "
}
function listFilesInFolder(folderName) {
Logger.log(folderName);
var folders = DriveApp.getFoldersByName(folderName);
var folder = folders.next();
var contentfolders = folder.getFolders(); //fetches the folders inside the folder
var contentfiles = folder.getFiles(); //fetches the files inside the folder
// Find or add sheet with folder name
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName(folderName);
if (sheet) {
Logger.log("found");
}
else {
sheet = ss.insertSheet(folderName);
}
sheet.clear();
sheet.appendRow(["Name", "Date", "URL"]);
// Loop over folders in folder, using file iterator
while (contentfolders.hasNext()) {
var file = contentfolders.next();
var data = [
file.getName(),
file.getDateCreated(),
file.getUrl()
];
sheet.appendRow(data);
// Loop over files in folder, using file iterator
while (contentfiles.hasNext()) {
var file = contentfiles.next();
var data = [
file.getName(),
file.getDateCreated(),
file.getUrl()
];
sheet.appendRow(data)
}}
}
*For anyone interested this script lists both the Files and Folders in a Google Sheet based on the "specified folder"
I have a folder in Google Drive folder containing few files. I want to make a Google Apps Script that will zip all files in that folder and create the zip file inside same folder.
I found a video that has Utilities.zip() function, but there is no API reference for that. How do I use it? Thanks in advance.
Actually it's even easier than that. Files are already Blobs (anything that has getBlob() can be passed in to any function that expects Blobs). So the code looks like this:
var folder = DocsList.getFolder('path/to/folder');
folder.createFile(Utilities.zip(folder.getFiles(), 'newFiles.zip'));
Additionally, it won't work if you have multiple files with the same name in the Folder... Google Drive folders support that, but Zip files do not.
To make this work with multiple files that have the same name:
var folder = DocsList.getFolder('path/to/folder');
var names = {};
folder.createFile(Utilities.zip(folder.getFiles().map(function(f){
var n = f.getName();
while (names[n]) { n = '_' + n }
names[n] = true;
return f.getBlob().setName(n);
}), 'newFiles.zip'));
As DocsList has been deprecated, You can use the following code to zip an entire folder containing files and sub-folders and also keep its structure:
var folder = DriveApp.getFolderById('<YOUR FOLDER ID>');
var zipped = Utilities.zip(getBlobs(folder, ''), folder.getName()+'.zip');
folder.getParents().next().createFile(zipped);
function getBlobs(rootFolder, path) {
var blobs = [];
var files = rootFolder.getFiles();
while (files.hasNext()) {
var file = files.next().getBlob();
file.setName(path+file.getName());
blobs.push(file);
}
var folders = rootFolder.getFolders();
while (folders.hasNext()) {
var folder = folders.next();
var fPath = path+folder.getName()+'/';
blobs.push(Utilities.newBlob([]).setName(fPath)); //comment/uncomment this line to skip/include empty folders
blobs = blobs.concat(getBlobs(folder, fPath));
}
return blobs;
}
getBlobs function makes an array of all files in the folder and changes each file name to it's relative path to keep structure when became zipped.
To zip a folder containing multiple items with the same name use this getBlob function:
function getBlobs(rootFolder, path) {
var blobs = [];
var names = {};
var files = rootFolder.getFiles();
while (files.hasNext()) {
var file = files.next().getBlob();
var n = file.getName();
while(names[n]) { n = '_' + n }
names[n] = true;
blobs.push(file.setName(path+n));
}
names = {};
var folders = rootFolder.getFolders();
while (folders.hasNext()) {
var folder = folders.next();
var n = folder.getName();
while(names[n]) { n = '_' + n }
names[n] = true;
var fPath = path+n+'/';
blobs.push(Utilities.newBlob([]).setName(fPath)); //comment/uncomment this line to skip/include empty folders
blobs = blobs.concat(getBlobs(folder, fPath));
}
return blobs;
}
I was able to use the code that #Hafez posted but I needed to modify it because It was not working for me. I added the first three lines because I needed the folder ID which is a string value and is not the name of the folder.
var folderName = DriveApp.getFoldersByName("<folderName>");
var theFolder = folderName.next();
var folderID =theFolder.getId();
var folder = DriveApp.getFolderById(folderID);
var zipped = Utilities.zip(getBlobs(folder, ''), folder.getName()+'.zip');
folder.getParents().next().createFile(zipped);
function getBlobs(rootFolder, path) {
var blobs = [];
var files = rootFolder.getFiles();
while (files.hasNext()) {
var file = files.next().getBlob();
file.setName(path+file.getName());
blobs.push(file);
}
var folders = rootFolder.getFolders();
while (folders.hasNext()) {
var folder = folders.next();
var fPath = path+folder.getName()+'/';
blobs.push(Utilities.newBlob([]).setName(fPath)); //comment/uncomment this line to skip/include empty folders
blobs = blobs.concat(getBlobs(folder, fPath));
}
return blobs;
}
The only weird thing that I'm experiencing is that when I run the script it says TypeError: Cannot call method "getFiles" of undefined. (line 10, file "Code"). When I happened to look at the place where this script lives there was also 5 zip files that were complete. It works but I still get that error. Weird...but this code works for me. Thanks to everyone on this thread. Cheers!
There's no API reference indeed. You could open an issue request regarding this on Apps Script issue tracker. But deducing from what the code-completion shows, here is my understanding:
var folder = DocsList.getFolder('path/to/folder');
var files = folder.getFiles();
var blobs = [];
for( var i in files )
blobs.push(files[i].getBlob());
var zip = Utilities.zip(blobs, 'newFiles.zip');
folder.createFile(zip);
But I have not tested this code, so I don't know if it will work. Also, it may work only for files not converted to Google's format, or maybe only for those or a subset of it. Well, if you try it out and find something, please share here with us. One limit that you'll sure face is the filesize, it will probably not work if the zip file gets "too" big... yeah, you'll have to test this limit too.
If Hafez solution didn't worked out, and you get this error
TypeError: Cannot read property 'getFiles' of undefined
Try doing this
/**
* Creates a zipFile of the mentioned document ID and store it in Drive. You can search the zip by folderName.zip
*/
function createAndSendDocument() {
var files = DriveApp.getFolderById("DOCUMENT ID CAN BE FIND IN THE URL WHEN A DOCUMENT IS OPENED");
var folder = files;
var zipped = Utilities.zip(getBlobs(folder, ''), folder.getName() + '.zip');
folder.getParents().next().createFile(zipped);
}
function getBlobs(rootFolder, path) {
var blobs = [];
var files = rootFolder.getFiles();
while (files.hasNext()) {
var file = files.next().getBlob();
file.setName(path+file.getName());
blobs.push(file);
}
var folders = rootFolder.getFolders();
while (folders.hasNext()) {
var folder = folders.next();
var fPath = path+folder.getName() + '/';
blobs.push(Utilities.newBlob([]).setName(fPath)); //comment/uncomment this line to skip/include empty folders
blobs = blobs.concat(getBlobs(folder, fPath));
}
return blobs;
}