Автоматическое удаление файлов с Google Диска старше n дней - проблема "getFolderById"
Я пытаюсь удалить файлы и папки старше 7 дней на определенном командном диске (а не на всем диске Google).
Чтобы добиться этого, я попытался объединить то, что читаю здесь: " Сценарий приложений" - автоматическое удаление файлов с Google Drive старше 3 дней - получение списка файлов
У меня недостаточно представителей, чтобы добавить туда комментарий, поэтому я открываю новую тему. Здесь вы можете найти мой user1588938 от пользователя user1588938:
function getOldFileIDs() {
var fileIDs = [];
// Old date is 30 days
var oldDate = new Date().getTime() - 3600*1000*24*30;
var cutOffDate = Utilities.formatDate(new Date(oldDate), "GMT", "yyyy-MM-dd");
// Get folderID using the URL on google drive
var folder = DriveApp.getFolderById('XXXXXXX');
var files = folder.searchFiles('modifiedDate < "' + cutOffDate + '"');
while (files.hasNext()) {
var file = files.next();
fileIDs.push(file.getId());
Logger.log('ID: ' + file.getId() + ', Name: ' + file.getName());
}
return fileIDs;
};
function deleteFiles() {
var fileIDs = getOldFileIDs();
fileIDs.forEach(function(fileID) {
DriveApp.getFileById(fileID).setTrashed(true);
});
};
Я застрял с функцией 'getFolderById', потому что я полагаю, что она не применяется к корню Team Drive, а работает только для папок внутри нее. Действительно, когда я просматриваю логи, я вижу, что вывод для:
var folder = DriveApp.getFolderById('this-is-my-team-drive-id');
является общим: [18-07-30 06: 34: 49: 146 PDT] Team Drive, а не название Team Drive, которое я выбрал.
Я не могу идти дальше со сценарием из-за этого.
Любой совет о том, как перечислить каждый файл и подпапку в Team Drive, используя searchFiles?
Это решение может применяться, но оно работает для папки внутри Team Drive, а не в корне Team Drive: просмотрите файлы на групповом диске Google
Спасибо!
4 ответа
Сценарий @Daniele INeDiA не работает по разным причинам:
- Сценарий не работает с
ReferenceError: "Drive" is not defined. (line 24, file "Code")
, который относится к//uncomment this line to delete them immediately;
- Сценарий также не работает из-за
Access denied: DriveApp. (line 39, file "Code")
в случае, если корневая папка пуста. Это потому, что он не различает корневую папку и ее подпапки.
Я исправил #1, просто оставив его закомментированным, но вот исправленная версия для #2.
В то же время, я также добавил функциювсегда удалять(всегда вкл / выкл). Таким образом, вы можете запланировать его запуск каждую ночь, чтобы начать день с пустой папки.
PS Я видел комментарий от Tehhowch, что "для каждого (... in ...) не рекомендуется", поэтому не стесняйтесь добавлять альтернативу, и я буду использовать ее вместо этого.
function deleteOldFiles() {
var Folders = new Array(
'YOUR-TEAM-DRIVE-ID' //you can find this in the team drive's url
);
var DaysRetentionNumber = 15; //how many days old your files and folders must be before getting deleted?
var RetentionPeriod = DaysRetentionNumber * 24 * 60 * 60 * 1000;
var always_delete = true;
Logger.clear();
for each (var FolderID in Folders) {
folder = DriveApp.getFolderById(FolderID);
processFolder(folder, FolderID);
}
function processFolder(folder, FolderID){
Logger.log('Folder: ' + folder.getName());
var files = folder.getFiles();
while (files.hasNext()) {
var file = files.next();
if (!always_delete)
Logger.log('File: ' + file.getName());
if (always_delete || new Date() - file.getLastUpdated() > RetentionPeriod) {
file.setTrashed(true); //uncomment this line to put them in the trash
// Don't uncomment the following because it breaks the script!
//Drive.Files.remove(file.getId()); //uncomment this line to delete them immediately; CAREFUL!
Logger.log('File '+ file.getName() + ' trashed');
}
}
var subfolders = folder.getFolders();
while (subfolders.hasNext()) {
subfolder = subfolders.next();
processFolder(subfolder);
}
if(Folders.indexOf(FolderID) == -1)
checkEmptyFolder(folder);
}
function checkEmptyFolder(folder){
if(!folder.getFiles().hasNext() && !folder.getFolders().hasNext()){
Logger.log('Empty folder: '+ folder.getName());
folder.setTrashed(true); // put them in the trash
}
}
if(Logger.getLog() != '')
MailApp.sendEmail('youremailaddresshere', 'Team Drive weekly cleanup report', Logger.getLog()); //get a log in your email so that you can see what will be deleted; try this before uncommenting the trash/delete lines!
}
Если кто-то пытается достичь того же результата, это то, как вы это делаете.
function deleteOldFiles() {
var Folders = new Array(
'YOUR-TEAM-DRIVE-ID' //you can find this in the team drive url
);
var DaysRetentionNumber = 15; //how many days old your files and folders must be before getting deleted?
var RetentionPeriod = DaysRetentionNumber * 24 * 60 * 60 * 1000;
Logger.clear();
for each (var FolderID in Folders) {
folder = DriveApp.getFolderById(FolderID);
processFolder(folder);
}
function processFolder(folder){
Logger.log('Folder: ' + folder.getName());
var files = folder.getFiles();
while (files.hasNext()) {
var file = files.next();
Logger.log('File: ' + file.getName());
if (new Date() - file.getLastUpdated() > RetentionPeriod) {
//file.setTrashed(true); //uncomment this line to put them in the trash
//Drive.Files.remove(file.getId()); //uncomment this line to delete them immediately; CAREFUL!
Logger.log('File '+ file.getName() + ' trashed');
}
}
var subfolders = folder.getFolders();
while (subfolders.hasNext()) {
subfolder = subfolders.next();
processFolder(subfolder);
}
checkEmptyFolder(folder);
}
function checkEmptyFolder(folder){
if(!folder.getFiles().hasNext() && !folder.getFolders().hasNext()){
Logger.log('Empty folder: '+ folder.getName());
folder.setTrashed(true); // put them in the trash
}
}
if(Logger.getLog() != '')
MailApp.sendEmail('youremailaddresshere', 'Team Drive weekly cleanup report', Logger.getLog()); //get a log in your email so that you can see what will be deleted; try this before uncommenting the trash/delete lines!
}
Не работает. пока я пытался запустить этот код
function deleteOldFiles() {
var sendlog = false, Folders = new Array(
'YOUR-TEAM-DRIVE-ID' //you can find this in the team drive url
);
var DaysRetentionNumber = 15; //how many days old your files and folders must be before getting deleted?
var RetentionPeriod = DaysRetentionNumber * 24 * 60 * 60 * 1000;
var always_delete = true;
Logger.clear();
for each (var FolderID in Folders) {
folder = DriveApp.getFolderById(FolderID);
processFolder(folder, FolderID);
}
function processFolder(folder, FolderID){
Logger.log('Folder: ' + folder.getName());
var files = folder.getFiles();
while (files.hasNext()) {
var file = files.next();
if (!always_delete)
Logger.log('File: ' + file.getName());
if (always_delete || new Date() - file.getLastUpdated() > RetentionPeriod) {
file.setTrashed(true); //uncomment this line to put them in the trash
// Don't uncomment the following because it breaks the script!
//Drive.Files.remove(file.getId()); //uncomment this line to delete them immediately; CAREFUL!
Logger.log('File '+ file.getName() + ' trashed');
}
}
var subfolders = folder.getFolders();
while (subfolders.hasNext()) {
subfolder = subfolders.next();
processFolder(subfolder);
}
if(Folders.indexOf(FolderID) == -1)
checkEmptyFolder(folder);
}
function checkEmptyFolder(folder){
if(!folder.getFiles().hasNext() && !folder.getFolders().hasNext()){
Logger.log('Empty folder: '+ folder.getName());
folder.setTrashed(true); // put them in the trash
}
}
if(sendlog && Logger.getLog() != '')
MailApp.sendEmail('youremailaddresshere', 'Team Drive cleanup report', Logger.getLog()); //get a log in your email so that you can see what will be deleted; try this before uncommenting the trash/delete lines!
}
я получаю сообщение об ошибке
Syntax error: SyntaxError: Unexpected identifier line: 11 file: Code.gs
можешь сказать, в чем ошибка?
В моем случае мне нужна была вариативность того, как долго хранить файлы в зависимости от того, в какой верхней папке они находятся. В некоторых папках есть тысячи сгенерированных изображений, которые необходимо часто очищать, а в других папках есть отчеты, которые следует хранить дольше. Также есть много вложенных папок. Этот сценарий должен запускаться много раз, чтобы не отставать. Любые советы по оптимизации были бы замечательными!
Мне не удалось найти подобный пример, поэтому я надеюсь, что он может быть полезен для тех, кто ищет, как я искал.
/**
* Clean up Google Drive folders sending all files
* last modified older than daysToKeep to the trash
*/
function cleanUpFolders() {
let folders = [
{ id: "folderId1", daysToKeep: 14 },
{ id: "folderId2", daysToKeep: 30 },
{ id: "folderId3", daysToKeep: 90 }
];
for (let f = 0; f < folders.length; f++) {
let folder = DriveApp.getFolderByIdAndResourceKey(folders[f].id, "");
let daysAgo = getDaysAgo(folders[f].daysToKeep);
cleanUpFolder(folder, daysAgo);
}
}
/**
* Cleans up a folder sending all files last modified more than filterDate to the trash
*
* @param {DriveApp.Folder} folder to proccess
* @param {String} filterDate date to search files older than in format YYYY-MM-DD
*/
function cleanUpFolder(folder, filterDate) {
console.log("searching in " + folder.getName());
let trashCount = 0;
// Send files last modified before filterDate to the trash
let query = 'modifiedDate < "' + filterDate + '"';
let files = folder.searchFiles(query);
while (files.hasNext()) {
let file = files.next();
file.setTrashed(true);
// console.log(file.getName() + " modified " + formatDate(file.getLastUpdated()));
trashCount++;
}
// Recursively clean up all sub folders
let folders = folder.getFolders();
while (folders.hasNext()) {
trashCount += cleanUpFolder(folders.next(), filterDate);
}
// Check if the folder is now empty and trash it as well
if (isEmptyFolder(folder)) {
folder.setTrashed(true);
console.log(folder.getName() + " is empty and has been trashed");
}
console.log(trashCount + " files found last modified before " + filterDate + " in " + folder.getName() + " have been trashed");
return trashCount;
}
/**
* Check if a folder has any files or folders
*
* @param {DriveApp.Folder} folder to check
*/
function isEmptyFolder(folder) {
return !folder.getFiles().hasNext() && !folder.getFolders().hasNext();
}
/**
* get date string "YYYY-MM-DD" days ago from now
*
* @param {number} days ago from now
*/
function getDaysAgo(days) {
let date = new Date(Date.now());
let nowString = formatDate(date);
date.setDate(date.getDate() - days);
let daysAgoString = formatDate(date);
console.log("now: " + nowString + ", " + days + " days ago: " + daysAgoString);
return daysAgoString;
}
/**
* Format date as "YYYY-MM-DD"
*
* @param {Date} date to format
*/
function formatDate(date) {
return date.getFullYear() + '-' +
(date.getMonth()+1).toString().padStart(2,'0') + '-' +
date.getDate().toString().padStart(2, '0');
}