如何扩展脚本执行时间? (Google脚本) [英] How do I extend script execution time? (Google Script)
问题描述
我使用此脚本从Google云端硬盘中删除所有 ._ *
文件。但有数百万个文件,并且脚本在5分钟左右退出,并显示超出最大执行时间。
函数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)
}
}
}
我如何让这个脚本运行足够长的时间来扫描整个Drive?
解决方案其中一种可能的解决方法是在没有运行时间限制的模式窗口中运行普通的JavaScript代码:
函数onOpen()
{
var ui = SpreadsheetApp.getUi();
ui.createMenu('垃圾点文件')
.addItem('Run','openWindow')
.addToUi();
}
函数openWindow()
{
var ui = SpreadsheetApp.getUi();
//获取模板
var template = HtmlService.createTemplateFromFile('deleteDriveFiles');
//需要下一行文本(甚至注释掉)才能触发脚本和令牌的正确范围:
// DriveApp.getFiles()
//传递令牌
template.data = {
token:ScriptApp.getOAuthToken()
};
//得到输出html
var html = template.evaluate();
//显示模式窗口
ui.showModalDialog(html,'从驱动器中删除文件');
}
[文件 - 新建 - Html文件] deleteDriveFiles .html:
<!DOCTYPE html>
< html>
< head>
< base target =_ top>
< / head>
< body>
< script>
//用于可视化日志
函数addParagraph(text)
{
var node = document.createElement('p');
node.innerText = text;
document.body.appendChild(node);
}
//用于统计
var totalProcessed = 0;
var totalTrashed = 0;
函数reqListener(){
//获取响应obj
var res = JSON.parse(this.responseText);如果(res.items&& res.items.length)
//循环文件
for(var i = 0; i< res.items.length; i ++)
{
var file = res.items [i];
$ b $ //删除文件
if(file.title.indexOf('._')== 0)
{
var xhr = new XMLHttpRequest();
xhr.addEventListener('load',function(){
//获取响应obj
var res = JSON.parse(this.responseText);
/ /成功抛弃
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','承载者<?= data.token?>');
xhr.send();
}
}
//统计数据
totalProcessed + = res.items.length;
//得到结果的下一页
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','承载者<?= data.token?>');
xhr.send();
}
//已完成
else
{
addParagraph('已完成,已处理总数:'+ totalProcessed +',已删除总数:'+ totalTrashed);
}
}
var xhr = new XMLHttpRequest();
xhr.addEventListener('load',reqListener);
xhr.open('GET','https://www.googleapis.com/drive/v2/files?trashed=false');
xhr.setRequestHeader('Authorization','承载者<?= data.token?>');
xhr.send();
< / script>
< / body>
< / html>
保存代码更新并刷新电子表格网页后,您将看到新的菜单项:
点击运行开始处理文件。
结果:
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:
这篇关于如何扩展脚本执行时间? (Google脚本)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!