How to identify the most recent file in a Google Drive folder - google-apps-script

I have a folder in Google drive in to which files are regularly dumped from a reporting tool. The files are in .xls format. They all have the same name and I want to identify the most recent file so that I can import the data in to a Google sheet.
As you will be able to tell from the below I am new to Google Apps script. I have been trying to catch the various files from the file iterator into an array to run a Math.max function on the result to end up with just one value. Of course, once I have identified the newest date I also need to return the fileID associated with - but I haven't got that far yet. I am probably heading in the completely wrong direction so any tips/guidance would be greatly appreciated.
function listLatestFile(id) {
var folder = DriveApp.getFoldersByName("GmailAttachments");
var files = DriveApp.getFilesByName('mrp_out.xlsx');
while (files.hasNext()) {
var file = files.next();
var date = (1 - file.getDateCreated());
var datediff = new Array(date);
var datelast = Math.max(datediff);
Logger.log(datelast);
}
//Logger.log(date);
};

You were not very far from the solution... I tried using a slightly different approach : I store all dates and IDs in an 2D array, I sort the array and retrieve the first element (after sorting) in the 2cond dimension to return the file ID.
code :
function listLatestFile() {
var folder = DriveApp.getFoldersByName("GmailAttachments");
var files = DriveApp.getFilesByName('mrp_out.xlsx');
var result = [];
while (files.hasNext()) {
var file = files.next();
result.push([file.getDateCreated(),file.getId()]);
}
Logger.log(result);
var id = result.sort()[0][1];
Logger.log(id);
return id;// return most recent file ID
};
EDIT : if you want to have more control on the sorting method, you can use a more "sophisticated" sort method like below :
...// same as above
result.sort(function(x,y){
var xp = x[0];// get first element in inner array
var yp = y[0];
return xp == yp ? 0 : xp < yp ? -1 : 1;// choose the sort order
});
var id = result[0][1];
Logger.log(id);
return id;
};

The answer posted above didn't work for me, so I came up with my own solution, which works.
Obviously (in late 2017) google drive sorts the files. So the last created file is the first in the iterator.
Here's the code to get the latest file ID :
function getLatestFileId(){
var folder = DriveApp.getFoldersByName("Aff Comm");
var files = folder.next().getFiles();
var lastFileId = files.next().getId();
return lastFileId.toString();
}

Related

Search files in shared Google Drive [duplicate]

I have some Google Apps script code that searchs for files and folders on TeamDrive.
The issue I am having is that if a file or folder is created by my colleague, when I run my script it can't find the file. If I create a file, and my colleague runs the script, the script can't find the file even though we both have access to view, edit and can see the files and folders in Drive. If one of us edits the file made by the other person, then it becomes visible from the search.
I ran into a similar problem with the Drive REST api when doing some android development. In Android when calling files().list(), It took my a while to find out that I had to set the following in order for my search to be successfull every single time.
.setSupportsTeamDrives(true)
.setIncludeTeamDriveItems(true)
.setCorpora("teamDrive")
.setTeamDriveId(myFolder.getTeamDriveId())
I assume I am running into the same issue with my apps script code.
//Create the N Google docs files
function CreateNFiles(){
var spreadsheet = SpreadsheetApp.getActive();
var Nmain = spreadsheet.getSheetByName("Nmain")
var spreadsheetId = spreadsheet.getId();
var pdfDir = "Form Data";
var TemplatesFolder = null;
//Check and see if there is a 'Form Data' folder
var NFolderId = null;
var RFolderId = DriveApp.getFileById(spreadsheetId).getParents().next().getId();
var files = DriveApp.searchFolders('parents="'+RFolderId+'" and trashed=false');
while (files.hasNext()) {
var myfile = files.next();
if(myfile.getName() == pdfDir){
NOFolderId = myfile.getId();
}
}
https://developers.google.com/apps-script/reference/drive/drive-app#searchFiles(String)
this says to refer to
https://developers.google.com/drive/api/v3/search-parameters#examples_for_teamdriveslist
so I could potentially use
corpora="teamDrive"
is there a way to setSupportsTeamDrives? and setIncludeTeamDriveItems? and setTeamDriveId? in google apps scripts
Finding Files and Folders in a Team Drive
Here's a couple of functions I've been working on for my own needs. They're still a work in progress but one can file folders within a team drive folder and another can find items within a team drive folder. The Logger.log is setup to display item number, title, id, and mimeType.
This one finds Items (either files or folders). You can tell them apart by their types.
function findItemsInTeamDriveFolder(teamDriveId,folderId){
var teamDriveId=teamDriveId || '0AFN5OZjg48ZvUk9PVA';
var folderId=folderId || '1LK76CVE71fLputdFAN-zuL-HdRFDWBGv';
var options={
"corpora":"teamDrive",
"includeTeamDriveItems":true,
"orderBy":"folder",
"q":Utilities.formatString('\'%s\' in parents',folderId),
"supportsTeamDrives":true,
"teamDriveId":teamDriveId
};
var files=Drive.Files.list(options);
var data=JSON.parse(files);
for(var i=0;i<data.items.length;i++){
Logger.log('\nItem: %s - Title: %s - Id: %s - Type:%s - Trashed: %s\n',i+1,data.items[i].title,data.items[i].id,data.items[i].mimeType,data.items[i].explicitlyTrashed?'true':'false');
}
}
This one just finds folders in a folder. It's not reentrant it's a one level deal but currently that's all I need.
function findFoldersInATeamDriveFolder(teamDriveId,folderId){
var teamDriveId=teamDriveId || '0AAc6_2qyI7C0Uk9PVA';
var folderId=folderId || '1HenWOXTSCg96iAvA0ZkgEA9EGKlch4fz';
var optionalArgs={
"corpora":"teamDrive",
"includeTeamDriveItems":true,
"orderBy":"folder",
"q":Utilities.formatString('\'%s\' in parents and mimeType = \'application/vnd.google-apps.folder\'',folderId),
"supportsTeamDrives":true,
"teamDriveId":teamDriveId
}
var list=Drive.Files.list(optionalArgs)
var data=JSON.parse(list);
for(var i=0;i<data.items.length;i++){
Logger.log('\nItem: %s - Title: %s - Id: %s - Type: %s - Trashed;%s\n',i+1,data.items[i].title,data.items[i].id,data.items[i].mimeType,data.items[i].explicitlyTrashed?'true':'false');
findItemsInTeamDriveFolder(teamDriveId,data.items[i].id)
}
}
I thought that they might be helpful.
Meta Data for a file:
Search Parameters:
Drive.Files.List Documentation:
I just used Coopers code to list files that were in a shared drive. I added the code to find the teamdriveID. Two things that cost me some time and might be helpful for others: the number of files is restricted to 100 per default. So I changed it to 200 here. Also, the options file includes trashed files (very confusing) so I filtered them out with an if statement - I am sure this can be done more elegantly but this worked :)
var resource = {
'value': 'emailstring',
'type': 'user',
'role': 'writer'
}
var teamDriveId
// If you have several Team Drives, loop through and give access
var TeamDrive = Drive.Teamdrives.list();
for(var i = 0; i < TeamDrive.items.length; i++) {
if(TeamDrive.items[i].name == "foldernamestring") {
// This ID may also be a single file inside a Team Drive
teamDriveId = TeamDrive.items[i].id;
Logger.log("found "+TeamDrive.items[i].name);
}
}
var options={
"corpora":"teamDrive",
"maxResults":200,
"includeTeamDriveItems":true,
"supportsTeamDrives":true,
"teamDriveId":teamDriveId
};
var files=Drive.Files.list(options);
var data=JSON.parse(files);
var nritems= data.items.length
Logger.log("nritems "+nritems);
for(var i=0;i<nritems;i++){
if (data.items[i].explicitlyTrashed == false){
Logger.log('\nItem: %s - Title: %s - Id: %s - Type:%s - Trashed: %s\n',i+1,data.items[i].title,data.items[i].id,data.items[i].mimeType,data.items[i].explicitlyTrashed?'true':'false');
}
}
I use simple Apps Script code to search folders in a Shared Drive:
function searchFolderByTitle(title,ShDrId){
var folders = DriveApp.searchFolders("title contains '"+title+"' and '"+ShDrId+"' in parents");
while (folders.hasNext()) {
var folder = folders.next();
Logger.log(folder.getName());
}
}
You should use the operator "in" not "=" with "parents" parameter.

Copy files from one folder to another on Drive with Apps Script

Team members upload content (regardless of file type) into a folder on Drive. I need to copy this content into another folder automatically with a trigger, and be able to move it around from there.
I cannot use a "MoveFile" function as I am not the owner of the original content.
I have already tried to copy files automatically into the destination folder, and this works, using the code below:
function CopyFiles() {
var srcFldr = DriveApp.getFolderById("***ID***");
var srcFiles = srcFldr.getFiles();
var desFldr = DriveApp.getFolderById("***ID***");
var desFiles = desFldr.getFiles();
var dfnA = [];
while (desFiles.hasNext()) {
var df = desFiles.next();
dfnA.push(df.getName());
}
while (srcFiles.hasNext()) {
var sf = srcFiles.next();
if (dfnA.indexOf(sf.getName()) == -1) {
sf.makeCopy(sf.getName(), desFldr);
}
}
}
However, I need to move this copied content into other files throughout the day, yet every time I do, the same file gets copied back into the destination folder above with the new trigger, creating a permanent loop.
Is there a way of either:
moving the files from the original source folder despite not being the owner of those files?
copying contents only once, upon upload or modification?
Or 3) another, better, smarter way of doing this?
Thanks for your help!
I'd suggest the following workflow:
For every file that is copied to the destination folder, store the fileId. You could use Properties Service for this.
When copying files from one folder to the other, check the fileId has not been stored before.
Code snippet:
function CopyFiles() {
var srcFldr = DriveApp.getFolderById("***ID***");
var srcFiles = srcFldr.getFiles();
var desFldr = DriveApp.getFolderById("***ID***");
var desFiles = desFldr.getFiles();
var dfnA = [];
var key = "fileIDs";
var scriptProperties = PropertiesService.getScriptProperties();
var property = scriptProperties.getProperty(key); // Retrieve fileIDs property
// Get array of fileId, or empty array if no file has been copied before:
var arrayIDs = property ? JSON.parse(property) : [];
while (desFiles.hasNext()) {
var df = desFiles.next();
dfnA.push(df.getName());
}
while (srcFiles.hasNext()) {
var sf = srcFiles.next();
// Check not only file name, but also whether fileId has been stored before:
if (dfnA.indexOf(sf.getName()) == -1 && arrayIDs.indexOf(sf.getId()) == - 1) {
sf.makeCopy(sf.getName(), desFldr);
arrayIDs.push(sf.getId()); // Add fileId to array of IDs
}
}
scriptProperties.setProperty(key, JSON.stringify(arrayIDs)); // Store updated array
}
Reference:
Properties.getProperty(key)
Properties.setProperty(key, value)

Using Logger.Log to log different value

I was wondering: is it even possible to use Logger.Log in Google Apps Script to log different string to be posted to a spreadsheet?
I have the following code:
var ss = SpreadsheetApp.openByUrl("spreadsheet url");
var sheet = ss.getSheetByName("spreadsheet sheet");
var DocNumber = e.parameter.DocNumber;
var folderId = "Folder ID 1";
var lastFileUrl = getLatestFile(folderId); // just a function that retrieves url of latest file in the folder
Logger.log(lastFileUrl);
var addUrl = sheet.getRange(1,2,sheet.getLastRow(),1);
var fileURL = "https://drive.google.com/uc?export=view&id="+lastFileUrl;
var folderId2 = "Folder ID 2";
var lastFileUrl2 = getLatestFile(folderId2); // same as above
Logger.log(lastFileUrl2);
var addUrl2 = sheet.getRange(1,3,sheet.getLastRow(),1);
var fileURL2 = "https://drive.google.com/uc?export=view&id="+lastFileUrl2;
sheet.appendRow([DocNumber,fileURL,fileURL2]);
}
When this get posted to the spreadsheet, it only posts the second url (fileURL2) - I assume because the last value in the log is this. But I was hoping to post both URL into the spreadsheet.
I tried setting it as a var first as well:
var URL2 = Logger.log(lastFileURL2);
but then the posted value will be https://drive.google.com/uc?export=view&id=Logger
I also tried using appendRow before the second URL logging but it still only takes the second url and disregard the first url.
Therefore, I was curios whether this is even possible at all?
And if not, what's the best way to achieve this without using Logger.log?
Spreadsheet output:
URL1 and URL2 is the URL from Google Drive folder.
Also, forgot to mention, I'm using the script as a Web App, used by an android app. Posting files into the Drive folder is okay, the only problem is fetching the links of the files in different folders.
These are the codes I used to get the latest file url from my folders:
function getLatestFile(folderId) {
var files = DriveApp.getFolderById("Folder_1_ID").getFiles();
var fileObj = [];
while (files.hasNext()) {
var file = files.next();
fileObj.push({id: file.getId(), date: file.getDateCreated()});
}
fileObj.sort(function(a, b) {return new Date(b.date) - new Date(a.date)});
return fileObj[0].id;
}
function getLatestFile(folderId2) {
var files2 = DriveApp.getFolderById("Folder_2_ID").getFiles();
var fileObj2 = [];
while (files2.hasNext()) {
var file2 = files2.next();
fileObj2.push({id: file2.getId(), date: file2.getDateCreated()});
}
fileObj2.sort(function(a, b) {return new Date(b.date) - new Date(a.date)});
return fileObj2[0].id;
}
Problem
Having two functions declared under the same name
Solution
Step by step:
Remove one of the functions (they are identical in terms in usage)
Make the remaining one use the parameter passed in it:
function getLatestFile(folderId) {
var files = DriveApp.getFolderById(folderId).getFiles();
var fileObj = [];
while (files.hasNext()) {
var file = files.next();
fileObj.push({id: file.getId(), date: file.getDateCreated()});
}
fileObj.sort(function(a, b) {return new Date(b.date) - new Date(a.date)});
return fileObj[0].id;
}
Change Logger to console - as of recently, all logs are sent to Stackdriver service, and thus there is no benefit in using Logger (besides by using console you make script more portable).
Commentary
What happens when you declare two or more functions under same name? Normally, the last one declared gets executed (basically, second declaration overwrites the first):
function clone(original) {
return `I am the clone of ${original}`;
}
function clone(cloned) {
return `I am a clone of ${cloned}'s clone`;
}
const elem = document.querySelector("#cloned");
elem.textContent = clone("Gary");
<h2 id="cloned"></h2>

Iterate Through Folders/Subfolders/Files in Google Drive

I have a Google Drive structure setup like this:
Client A
--Project 1
----Drafts
----Presentations
----Minutes
--Project 2
----Drafts
----Presentations
----Minutes
Client B
<and so on>
I want to write a script where I can pass in the ID of Project 1, and it will loop through each of the three subfolders and count the total number of files (ultimately I want to count the number of files updated over a date range, but baby steps!).
I've tried using the Class FolderIterator code, but that wants you to assign a group of folders to a variable "folders" (it showed var folders = DriveApp.getFolders(); and I tried var folders = DriveApp.getFolderById("<id of Project 1 here>"); but in my version that's just one folder, and it really needs the collection of folders). Is there a way to assign those three subfolders to that folders variable if I have the ID of the parent folder? Or is there a better way to loop through the subfolders?
As a complement to Bryan's answer (thx, I upvoted) I wrote a test function to see results in the logger and to run the function with appropriate parameters to get the count you wanted.
(This answer should not be selected as the right answer since the main part is from Bryan P)
here is how it goes :
function testTraverse(){
var originFolder = DriveApp.getFoldersByName('Client A').next(); // use the folder name you want here
var totalCount = traverseFolder(originFolder,0);
Logger.log('total files = '+totalCount);// note that if some files are
// in more than one subfolder the count will count every occurrence of
//this file so the total might be > to the sum of intermediate values
}
function traverseFolder(folder,total) {
var name = folder.getName();
var count = 0;
var files = folder.getFiles();
while (files.hasNext()) {
count++;
Logger.log('fileName ('+count+') in '+name+' is : '+files.next().getName());
}
Logger.log('\n'+name+' has ' + count+' files\n----------------------\n' );
var subs = folder.getFolders();
while (subs.hasNext()) {
total+=traverseFolder(subs.next(),count);
}
return total;
}
Note that this code will work for a "reasonable" number of files, if you have many files and folders it might exceed the 5 minutes execution time limit. In this case you'll need to modify it in order to proceed by smaller bunches of files using the token provided by the method.
It may look some thing like this with DriveApp...
function traverseFolder(folder) {
var name = folder.getName();
if ( /^(Drafts|Presentations|Minutes)$/.test(name) ) {
var count = 0;
var files = folder.getFiles();
while ( files.hasNext() ) {
count++;
}
Logger.log(name + ' : ' + count);
}
var subs = folder.getFolders();
while (subs.hasNext()) {
traverseFolder(subs.next());
}
}
We now have access to the Advanced Drive Service too. Maybe I'll look at an example with that if some one doesn't post one soon.

How to Find duplicates files (by name and/or size) in a specific folder of my google drive?

Is it possible to create a Google apps script which would select automatically duplicate files inside a specific (current) folder (then I just had to delete them with one click) ?
https://developers.google.com/apps-script/reference/drive/
I am asking this because Google drive pc client create random duplicates files when updating them ! They want to solve this bug but I have to manually select them in each folders and then delete them. It is very annoying and time consuming.
https://productforums.google.com/forum/#!category-topic/drive/report-a-problem/_ApOopI-Xkw
Edit: Alternatively, as windows cannot create the same filename inside the same folder, find and put in the trash all duplicate filenames inside a specific main folder (and its each of its related subfolders).
For better readability I add the next part of this answer in a second answer.
Here is the code to handle the duplicates : it works in 2 steps :
detect the duplicates and mark them in the sheet to check if everything is fine (markDuplicates())
remove the red background on the files you want to preserve (they will become yellow after step 3 is done)
delete the selected (marked) files, actually move them to trash, you'll have to empty the trash manually from the drive Ui. (trashDuplicates()) The deleted files will be colored in deep red to confirm deletion.
LAST EDIT :
Placed the full code here and made some functions private to avoid errors due to bad script calls.
function startProcess(){
PropertiesService.getScriptProperties().deleteAllProperties();
try{
ScriptApp.deleteTrigger(ScriptApp.getProjectTriggers()[0]);
}catch(e){}
var sh = SpreadsheetApp.getActiveSheet();
sh.getDataRange().clear();
sh.getRange(1,1,1,4).setValues([['fileName (logged #'+Utilities.formatDate(new Date(),Session.getScriptTimeZone(),'MMM-dd-yyyy HH:mm')+')','fileSize','parent folders tree','fileID']]);
var trig = ScriptApp.newTrigger('getDriveFilesList_').timeBased().everyMinutes(5).create();
Logger.log(trig.getUniqueId()+' '+trig.getHandlerFunction());
getDriveFilesList_();
}
function getDriveFilesList_(){
var content = [];
var startTime = new Date().getTime();
var sh = SpreadsheetApp.getActiveSheet();
if( ! PropertiesService.getScriptProperties().getProperty('numberOfFiles')){
PropertiesService.getScriptProperties().setProperty('numberOfFiles',0);
}
var numberOfFiles = Number(PropertiesService.getScriptProperties().getProperty('numberOfFiles'));
Logger.log(numberOfFiles);
var max = numberOfFiles+10000;
if( ! PropertiesService.getScriptProperties().getProperty('continuationToken')){
var files = DriveApp.getFiles();
// var files = DriveApp.getFolderById('0B3qSFd_____MTFZMDQ').getFiles();// use this line and comment the above if you want to process a single folder
// use your chozen folder ID of course (available from the browser url , the part after "https://drive.google.com/?authuser=0#folders/")
}else{
var files = DriveApp.continueFileIterator(PropertiesService.getScriptProperties().getProperty('continuationToken'))
}
while(files.hasNext() && numberOfFiles<(max)){
var file = files.next()
if(file.getSize()>0){
numberOfFiles++;
var folder = '(shared)';
if(file.getParents().hasNext()){folder = getTree_(file)}
content.push([file.getName(),file.getSize(),folder,file.getId()])
}
if(new Date().getTime()-startTime > 250000){break};
}
sh.getRange(sh.getLastRow()+1,1,content.length,content[0].length).setValues(content);
if(!files.hasNext()){ScriptApp.deleteTrigger(ScriptApp.getProjectTriggers()[0]);Logger.log('done !'); sh.getRange(sh.getLastRow()+1,1).setValue('All files processed ('+numberOfFiles+' found)')};
var continuationToken = files.getContinuationToken()
PropertiesService.getScriptProperties().setProperty('numberOfFiles',numberOfFiles);
PropertiesService.getScriptProperties().setProperty('continuationToken',continuationToken);
}
function markDuplicates(){
handleDuplicates_(false)
}
function trashDuplicates(){
handleDuplicates_(true)
}
function handleDuplicates_(trash){
var sh = SpreadsheetApp.getActiveSheet();
sh.setFrozenRows(1);
sh.sort(1);
var data = sh.getDataRange().getValues()
var headers = data.shift()
var lastComment = data.pop();
var toDelete = [];
var item = data[0];
for(var n=1 ; n<data.length; n++){
if(data[n][0]==item[0] && data[n][1]==item[1]){
toDelete.push('delete '+n);
}
item=data[n];
}
var marker = sh.getRange(2,1,data.length,1).getBackgrounds();
for(var n in data){
if(!trash){marker.push(['#FFF'])};
if(toDelete.indexOf('delete '+n)>-1 && !trash){
marker[n][0] = '#F99';
}
if(toDelete.indexOf('delete '+n)>-1 && trash){
if(marker[n][0]=='#ff9999'){
try{
DriveApp.getFileById(data[n][3]).setTrashed(trash);
marker[n][0] = '#F33';
}catch(err){Logger.log(err)}
}else{
marker[n][0] = '#FF9';
}
}
}
sh.getRange(2,1,marker.length,1).setBackgrounds(marker);
}
function getTree_(file){
var tree = [];
var folderP = file.getParents()
while (folderP.hasNext()){
var folder = folderP.next();
folderP = folder.getParents();
tree.push(folder.getName());
}
return tree.reverse().join('/');
}
This is not going to be simple... DriveApp is not particularly fast and one have usually many files in Drive so a script won't be able to iterate all the files in one single shot.
You will have to process your files in batch and set a time trigger to continue automatically until all the files are processed.
Here is a script that shows how to iterate in small 100 items batches (in real life you can process more than 100, I limit to a small number for demo purpose, just change the value to a more realistic value when you have a realistic idea of how long it takes to execute, see comments in code).
I left aside the duplicate detection because I wasn't sure if all the files had to be examined (Google docs have size=0 so it made me think you wanted to work only on other format files but I wasn't sure) but this part shouldn't be too hard to deal with.
Here is the iteration code, it shows the filenames and size in the logger, along with the global counter :
function searchDupInDrive(){
if( ! PropertiesService.getScriptProperties().getProperty('numberOfFiles')){PropertiesService.getScriptProperties().setProperty('numberOfFiles',0)};
var numberOfFiles = Number(PropertiesService.getScriptProperties().getProperty('numberOfFiles'));
Logger.log(numberOfFiles);
var max = numberOfFiles+100;// use an appropriate value here so that execution time remains < 5 minutes
if(numberOfFiles >2000){Logger.log('done !');return}; // this is to limit the demo to a short total execution time
if( ! PropertiesService.getScriptProperties().getProperty('continuationToken')){
var files = DriveApp.getFiles();
}else{
var files = DriveApp.continueFileIterator(PropertiesService.getScriptProperties().getProperty('continuationToken'))
}
while(files.hasNext() && numberOfFiles<(max)){
var file = files.next()
Logger.log((numberOfFiles)+' : fileName = '+file.getName()+' size = '+file.getSize())
numberOfFiles++;
// set conditions, store file Names and sizes to be able to compare
}
var continuationToken = files.getContinuationToken()
PropertiesService.getScriptProperties().setProperty('numberOfFiles',numberOfFiles);
PropertiesService.getScriptProperties().setProperty('continuationToken',continuationToken);
}
Note : to achieve duplication detection you will probably have to store the criteria, file names and sizes somewhere between 2 script runs, I guess script properties would be useable for that too.
Please update here when you have a final result.
Note 2 : I read the thread about this issue : quite horrifying ! I'm glad I'm on Mac OS, no problem like that (for now :-)
EDIT
Here is a second version. In the comments you told me that you added the script to a spreadsheet so it gave me the idea to store the file list in a spreadsheet so that, in a second step, we can sort the files and see /select the duplicates more easily.
By the way, I noticed that the driveApp was faster then I thought, not even sure we have to process in batch... nevertheless I limited the execution time to less than 5 minutes and implemented the script trigger creation / suppression just in case you have a lot of files...
Here is the new code, I still left the duplicate detection aside, you'll find very easily a lot of code examples to select the duplicates in a spreadsheet... this first step of getting all the files was the most non obvious.
Now there are 2 functions, one to start the process (clear the sheet, create the trigger, set a title to columns) and the actual drive reading one (It takes only the files that are NOT google docs, ie files with size>0):
function startProcess(){
PropertiesService.getScriptProperties().deleteAllProperties();
var sh = SpreadsheetApp.getActiveSheet();
sh.getDataRange().clear();
sh.getRange(1,1,1,4).setValues([['fileName (logged #'+Utilities.formatDate(new Date(),Session.getScriptTimeZone(),'MMM-dd-yyyy HH:mm')+')','fileSize','parent folder','fileID']]);
var trig = ScriptApp.newTrigger('getDriveFilesList').timeBased().everyMinutes(5).create();
Logger.log(trig.getUniqueId()+' '+trig.getHandlerFunction());
getDriveFilesList();
}
function getDriveFilesList(){
var content = [];
var startTime = new Date().getTime();
var sh = SpreadsheetApp.getActiveSheet();
if( ! PropertiesService.getScriptProperties().getProperty('numberOfFiles')){
PropertiesService.getScriptProperties().setProperty('numberOfFiles',0);
}
var numberOfFiles = Number(PropertiesService.getScriptProperties().getProperty('numberOfFiles'));
Logger.log(numberOfFiles);
var max = numberOfFiles+10000;
if( ! PropertiesService.getScriptProperties().getProperty('continuationToken')){
var files = DriveApp.getFiles();
}else{
var files = DriveApp.continueFileIterator(PropertiesService.getScriptProperties().getProperty('continuationToken'))
}
while(files.hasNext() && numberOfFiles<(max)){
var file = files.next()
if(file.getSize()>0){
numberOfFiles++;
var folder = '(shared)';
if(file.getParents().hasNext()){folder = file.getParents().next().getName()}
content.push([file.getName(),file.getSize(),folder,file.getId()])
}
if(new Date().getTime()-startTime > 250000){break};
}
sh.getRange(sh.getLastRow()+1,1,content.length,content[0].length).setValues(content);
if(!files.hasNext()){ScriptApp.deleteTrigger(ScriptApp.getProjectTriggers()[0]);Logger.log('done !'); sh.getRange(sh.getLastRow()+1,1).setValue('All files processed ('+numberOfFiles+' found)')};
var continuationToken = files.getContinuationToken()
PropertiesService.getScriptProperties().setProperty('numberOfFiles',numberOfFiles);
PropertiesService.getScriptProperties().setProperty('continuationToken',continuationToken);
}