I have this script to delete all ._*
files from my Google Drive. But there are millions of files, and the script quits after 5 minutes or so with "Exceeded maximum execution time."
function TrashDotFiles() {
var files = DriveApp.getFiles();
while (files.hasNext()) {
var file = files.next();
var name = file.getName();
if (name.indexOf("._")==0) {
console.log(name + " • trashed");
file.setTrashed(true)
}
}
}
How can I let this script run long enough to scan the entire Drive?
One of the possible workarounds is to run plain JavaScript code in modal window that has no limit of running time:
function onOpen()
{
var ui = SpreadsheetApp.getUi();
ui.createMenu('Trash dot files')
.addItem('Run', 'openWindow')
.addToUi();
}
function openWindow()
{
var ui = SpreadsheetApp.getUi();
// get template
var template = HtmlService.createTemplateFromFile('deleteDriveFiles');
// need to have next line of text somewhere (even commented out) to trigger correct scopes for script and token:
// DriveApp.getFiles()
// pass token
template.data = {
token: ScriptApp.getOAuthToken()
};
// get output html
var html = template.evaluate();
// show modal window
ui.showModalDialog(html, 'Delete files from Drive');
}
[File - New - Html file] deleteDriveFiles.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<script>
// used for visual log
function addParagraph(text)
{
var node = document.createElement('p');
node.innerText = text;
document.body.appendChild(node);
}
// for stats
var totalProcessed = 0;
var totalTrashed = 0;
function reqListener(){
// get response obj
var res = JSON.parse(this.responseText);
if (res.items && res.items.length)
{
// loop files
for (var i = 0; i < res.items.length; i++)
{
var file = res.items[i];
// delete file
if (file.title.indexOf('._') == 0)
{
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', function(){
// get response obj
var res = JSON.parse(this.responseText);
// sucessfully trashed
if (this.status == 200)
{
totalTrashed++;
addParagraph('Trashed '+res.title);
}
}.bind(xhr));
xhr.open('POST', 'https://www.googleapis.com/drive/v2/files/'+file.id+'/trash');
xhr.setRequestHeader('Authorization', 'Bearer <?=data.token?>');
xhr.send();
}
}
// for stats
totalProcessed += res.items.length;
}
// get next page of results
if (res.nextPageToken)
{
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', reqListener);
xhr.open('GET', 'https://www.googleapis.com/drive/v2/files?trashed=false&pageToken='+res.nextPageToken);
xhr.setRequestHeader('Authorization', 'Bearer <?=data.token?>');
xhr.send();
}
// finished
else
{
addParagraph('Finished. Processed total: '+totalProcessed+'. Trashed total: '+totalTrashed);
}
}
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', reqListener);
xhr.open('GET', 'https://www.googleapis.com/drive/v2/files?trashed=false');
xhr.setRequestHeader('Authorization', 'Bearer <?=data.token?>');
xhr.send();
</script>
</body>
</html>
After saving changes in code and refreshing spreadsheet web page you will see new menu item:
Click on Run to start processing files.
Result: