I am pulling a drive activity report using GCP/GAMadv which gives me file IDs of various users in our workspace domain on a google sheet. My goal is to find the folder path of these files using file IDs. I am using appscript to get to that. Here is the code that I am running so far.
function getFolderPath(fileID, folderPath =""){
var sheetID = "1YfZgkLvAnPj7kOIQOVkcXeJgnh-KTecMn6er1a0elkk"
var sheet = SpreadsheetApp.openById(sheetID)
// var file = sheet.Files.get(fileID)
var parent = Drive.Files.get(fileID);
console.log(parent)
// console.log(file)
var parentElement = parent.items[0]
console.log(parentElement)
// var parentElement = parent[0]
var parentFile = Drive.Files.get(parent.id);
var parentPath = parentFile.title;
if (parent.isRoot)
return "/" + folderPath;
else {
return getFolderPath(
parentFile.id,
parentPath + "/" + folderPath
);
}
}
Looks like this is returning ALL the files we have in our drive rather than the ones on the sheet.
Help would be greatly appreciated! Thanks.
Folder Path from Id
function getFolderPathFromId(id="fileid") {
try {
var file = DriveApp.getFileById(id)
var pA = [];
pA.push(file.getName());
var folder = file.getParents();
while (folder.hasNext()) {
var f = folder.next();
pA.push(f.getName());
folder = f.getParents()
}
var r = pA.reverse().slice(0,-1).join(' / ');
}
catch (e) {
return e;
}
Logger.log(r);
return r;
}
Related
Need help on simplifying this script. I still need to add more clusters in while loops.
function Files() {
var ss = SpreadsheetApp.getActive();
var names = ss.getSheetByName("AME");
var SupplierName = names.getRange(names.getLastRow(),5).getValue();
var Cluster = names.getRange(names.getLastRow(),3).getValue();
if (Cluster == 'US'){
var ClusterID = DriveApp.getFolderById("1z2R");
var newFolderID = ClusterID.createFolder(SupplierName);
var sourceFolder = DriveApp.getFoldersByName("US").next();
var files = sourceFolder.getFiles();
var destFolder = DriveApp.getFoldersByName(SupplierName).next();
while(files.hasNext()){
var file = files.next();
file.moveTo(destFolder);
}
return newFolderID.getId();
SUGGESTION:
We are still kind of lurking in the dark here but here are some opportunities I have identified on the provided script above.
/** Can be a global variable */
var ss = SpreadsheetApp.getActive();
var names = ss.getSheetByName("AME");
var SupplierName = names.getRange(names.getLastRow(),5).getValue();
var Cluster = names.getRange(names.getLastRow(),3).getValue();
function Files() {
if(Cluster == 'US') {
var ClusterID = DriveApp.getFolderById("SET FOLDER ID");
var folders = ClusterID.getFoldersByName(SupplierName).hasNext();
if(folders !== true){
ClusterID.createFolder(SupplierName);
moveFolders(SupplierName);
}
else {
moveFolders(SupplierName);
}
}
else {
Logger.log('Cluster is ' + Cluster);
}
}
function moveFolders() {
var sourceFolder = DriveApp.getFoldersByName("US").next();
var files = sourceFolder.getFiles();
Logger.log(files);
var destFolder = DriveApp.getFoldersByName(SupplierName).next();
while(files.hasNext()){
var file = files.next();
file.moveTo(destFolder);
}
}
Created a separate function moveFolders() to move files to the created folder ClusterID.createFolder(SupplierName); if Cluster 'US' was checked on the last row of the sheet. I assumed that your data is from a response that came from a Google Form that is why the last row is only being checked.
Sample Data:
Source parent folder for Cluster Folder and US Folder:
Files inside the "US" Folder:
After the script is run, created the SupplierName folder containing the files moved from the US Folder:
Now I haven't worked on dynamically adjusting the script to manually define the cluster name as of the moment due to lack of clarity of the question, but I'll modify my answer once questions are addressed.
i want creating new folder with new name from cell in the sheet, and i want copy to this folder files and folders with the sourcedestiny.
Could you help me to solve my problem.
It is possible change name newFolder witout change name folders and subfolders- after his creating?
function copyFolderass() {
const sourceFolder = DriveApp.getFolderById('');
const destinyFolder = DriveApp.getFolderById('');
copyFolder(sourceFolder, destinyFolder);
}
function copyFolderContents(source, target) {
const filesIterator = source.getFiles();
while (filesIterator.hasNext()) {
const file = filesIterator.next();
file.makeCopy(file.getName(), target);
}
}
function copyFolder(sourceFolder, destinyFolder) {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("nameFile");
var name = ss.getRange("F4").getValue();
const newFolder = destinyFolder.createFolder(sourceFolder.getName());
copyFolderContents(sourceFolder, newFolder);
const foldersIterator = sourceFolder.getFolders();
while (foldersIterator.hasNext()) {
const folder = foldersIterator.next();
copyFolder(folder, newFolder);
}
}
Create Folders and Copy Files
Reads a sheet to obtain FilesFolder Id FolderFolder Id and new FolderName
It creates the new folder and copies all of the files from the Files Folder to the newly created folder.
It records the new folder id in FolderId Column.
It records all of the file ids in the FileIds column.
It put the date in the created column.
It doesn't do anything for rows that have content in Created
//FilesFolder FolderFolder FolderName FolderId FileIds Created
function createFolderAndCopyFiles() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
const shsr = 2;
let [hA, ...vs] = sh.getDataRange().getValues();
let idx = {};
let col = {};
hA.forEach((h, i) => { idx[h] = i; col[h] = i + 1; });
vs.forEach((r, i) => {
if (!r[idx["Created"]]) {
let dfldr = DriveApp.getFolderById(r[idx["FolderFolder"]]);
let fldr = dfldr.createFolder(r[idx["FolderName"]]);
let fldrid = fldr.getId();
sh.getRange(i + shsr, col["FolderId"]).setValue(fldrid);
let files = DriveApp.getFolderById(r[idx["FilesFolder"]]).getFiles();
let ids = [];
while (files.hasNext()) {
let file = files.next();
let fid = file.getId();
file.makeCopy(file.getName(), fldr);
ids.push(fid);
}
sh.getRange(i + shsr, col["FileIds"]).setValue(ids.join('\n'));
sh.getRange(i + shsr, col["Created"]).setValue(new Date());
}
});
}
Spreadsheet
You fill in the stuff in yellow the program fills in the rest and it won't make folders again if the Created Column not empty.
Thx Cooper for the answer,
but this is not that what i want to do.
on google drive i have a template of structure od catalogs.
my code is one of the part code of my main code. main code working like this
i click send email and then run my code with creating folder from temtlace
when is creating a have name of the template folder but i want just change one part of this line of my code.
instead of this line
const newFolder = destinyFolder.createFolder(sourceFolder.getName());
i want to just like this - the name of the creating folder is from cell F4.
the remaining names of the folders may stays like from template.
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("nameFile");
var name = ss.getRange("F4").getValue();
const newFolder = destinyFolder.createFolder(sourceFolder.setName(name));
but this line change ale name in subfolders i all structure catalog when is creating.
I need the script to recognize that it should only search for files I created, because I'm not allowed to delete other people's files in this Google Drive folder.
var files = folder.searchFiles('modifiedDate < "' + cutOffDate + '"');
I confess that I tried to adjust by myself, but in every way is giving error, something always goes wrong. That form was my last attempt, which also failed:
var files = folder.searchFiles('modifiedDate < "' + cutOffDate + '" and "me#gmail.com" in owners ');
This answer is working for me on a folder that I have shared with one other account.
function getMyFilesFromFolder() {
var myFolderId = "FolderId";
var files = DriveApp.getFolderById(myFolderId).getFilesByType(MimeType.GOOGLE_SHEETS);
var myFiles=[];
while(files.hasNext()) {
var file = files.next();
if(file.getOwner().getEmail()==Session.getActiveUser().getEmail()) {
myFiles.push({name:file.getName(),id:file.getId(),owner:file.getOwner().getEmail(),currentuser:Session.getActiveUser().getEmail()});
Logger.log(Utilities.formatString('Name: %s Id: %s Owner: %s CurrentUser: %s', file.getName(),file.getId(),file.getOwner().getEmail(),Session.getActiveUser().getEmail()));
}
}
}
Let me know if it works for you. It should only be Logging files that you own. So current user email and owner email should be the same.
I also tested this on a shared folder and it works. I didn't want to delete anything so a changed a few things and I was just searching for Google Sheets.
function getOldFileIDs() {
// Old date is 3 Hours
var oldDate = new Date().getTime() - 3600*1000*3;
var cutOffDate = new Date(oldDate).toISOString();
// Get folderID using the URL on google drive
var folder = DriveApp.getFolderById('1iJTAdlhCM13c1CB5xMAjtLZlkaPMIlPb');
var files = folder.getFilesByType(MimeType.GOOGLE_SHEETS);//Just looking for Google Sheets
var obj = [];
while (files.hasNext()) {
var file = files.next();
obj.push({name: file.getName(),id: file.getId(), date: file.getDateCreated(), owner: file.getOwner().getEmail()}); // Modified
}
obj.sort(function(a, b) {
var a= new Date(a.date).valueOf();
var b= new Date(b.date).valueOf();
return b-a;
});
//obj.shift();//I wanted to log all of them
return obj; // Modified
};
function logFiles() {
var email = Session.getActiveUser().getEmail();// Added
var obj = getOldFileIDs(); // Modified
obj.forEach(function(e) { // Modified
if (e.owner == email) { // Added
//Drive.Files.remove(e.id); // Modified
Logger.log('FileName: %s,Owner Email: %s',e.name,e.owner);
}
});
};
I want to rename my all Audio files in particular folder in my drive by using google script.
How to get original name of file? And replace with new name that will erase first 23 words and remain all name as it was. I didn't understand how to do that.
I try following script.
function non_native_file_name_changer(folderID,fileName,fileType,iterator) {
var folder = DriveApp.getFolderById('ID');
var files = folder.getFilesByType(fileType);
var count = 1
while(files.hasNext()){
var file = files.next()
if(iterator === true){
file.setName(file.getName().slice(-23));
}else{
file.setName(fileName);
};
};
};
function start(){
var folder_ID = "ID";
var file_name = "Audio";
var file_type = "audio/amr";
var have_a_count = true;
var go = non_native_file_name_changer(folder_ID,file_name,file_type,have_a_count);
};
This not work...
Please help.
To call all files from folder but no run.
Please help.
You say you want the files from a specific folder but you didn't open a specific folder. What happens if you use
var id = "xxxxxxxxxxxxxx";
var files = DriveApp.getFolderById(id).getFiles();
while (files.hasNext()) {
var file = files.next();
Logger.log(file.getName());
}
I've been working on a script that lists the name and folder ids of the all the folders in a specific folder in my drive. Once the list is created, I run the function to get the id and change the folder permissions to private (only specific people can view), remove editors who do not have the company domain and switches them to viewers, and then it should change the permissions for any files in the folder as well. The initial step of creating the ids works fine. Unfortunately, the updatePermissions() function only seems to infinitely loop through the first folder and I'm not sure what next steps to take to ensure that the script pulls the next folder id from the list in the spreadsheet. Any help would be greatly appreciated.
function listSchoolFolders(){
var folderId = 'enter folder id here';
var myspreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var parentFolder = DriveApp.getFolderById(folderId);
var childFolders = parentFolder.getFolders();
// List folders inside the folder
while (childFolders.hasNext()) {
var childFolder = childFolders.next();
var data = [
childFolder.getName(),
childFolder.getId()
];
//Write
myspreadsheet.appendRow(data)
}
}
//------------------------- New Function -------------------------//
function updatePermissions() {
var myspreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var schoolRows = myspreadsheet.getDataRange();
var schoolNumRows = schoolRows.getNumRows();
var schoolValues = schoolRows.getValues();
//Loop through List of Schools
var row_num = schoolValues[0][2];
while(row_num<schoolNumRows){
//Retrieve folder id and go to folder
var folderId = schoolValues[row_num][1];
var folderName = schoolValues[row_num][0];
Logger.log(folderName);
try {
var schoolFolder = DriveApp.getFolderById(folderId);
}
catch (err){
Logger.log(folderName + ": " + err.message);
row_num = row_num+1;
myspreadsheet.getRange(1,3).setValue(row_num);
continue;
};
};
//Loop through folders and set permissions
var childFolders = DriveApp.getFolderById(folderId).getFolders();
while (childFolders.hasNext()) {
var childFolder = childFolders.next();
var childFolderPermissions = childFolder.setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.VIEW);
var files = DriveApp.getFolderById(folderId).getFiles();
while (files.hasNext()) {
Logger.log(files.next().getName());
var fileFolderPermissions = files.next().setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.VIEW);
//check for rogue editors
var viewEditors = schoolFolder.getEditors();
for (i in viewEditors) {
var email = viewEditors[i].getEmail();
var emailSource = email.split("#")[1]
if (emailSource != "tester.com") {
// add as a viewer or remove completely?
addViewer(email)
};
};
};
};
// Recursive call for any sub-folders
getChildFolders(childFolder);
The error was in the logic checking for child folders. If there was no child folder, the script completed. I've added two conditional checks on each top-level folder, one for child folders and one for files. This script functions with one-level depth.
function updatePermissions() {
// define several variables to use throughout the script
var editors, domain, email;
var myspreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var schoolValues = myspreadsheet.getDataRange().getValues();
// Loop through List of folders
// Skip row 1
for(var i=1; i<schoolValues.length; i++) {
//Retrieve folder id and go to folder
var folderId = schoolValues[i][1];
var folderName = schoolValues[i][0];
Logger.log(folderName);
var schoolFolder = DriveApp.getFolderById(folderId);
// Get the children
var childFolders = schoolFolder.getFolders();
// test for child folders.
if(!childFolders.hasNext()) {
// There is no child folder, so test for files
if(!schoolFolder.getFiles().hasNext()) {
// There are no files, so get the folder editors and loop
editors = schoolFolder.getEditors();
for(var j=0; j<editors.length; j++) {
email = editors[j].getEmail();
domain = editors[j].getDomain(); // easier than using a split function
// Check the domain. Remove if no match, add as viewer if there is a match
if(domain !== "testdomain.com") {
schoolFolder.removeEditor(email)
} else {
schoolFolder.removeEditor(email).addViewer(email);
}
}
}
// There are child folders, loop through and change permissions
} else {
while (childFolders.hasNext()) {
var childFolder = childFolders.next();
// Set permissions on the folder
childFolder.setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.VIEW);
// Get the files in the child folder and loop
var files = childFolder.getFiles();
while (files.hasNext()) {
files.next().setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.VIEW);
var viewEditors = schoolFolder.getEditors();
// Loop the array of editors
for (var j=0; j<viewEditors.length; j++) {
email = viewEditors[j].getEmail();
domain = viewEditors[j].getDomain();
if (domain !== "testdomain.com") {
// add as a viewer or remove completely?
Logger.log("add " + email + " as a viewer");
files.next().addViewer(email);
} else {
// Remove the editor
Logger.log("removed " + email + " from folder");
files.next().removeEditor(email);
}
};
}
}
};
}
// Recursive call for any sub-folders
//getChildFolders(childFolder);
};