G-Drive 智慧工坊 – 磁碟檔案 002 – 檔案屬性與日期比對


0. 前言


在上回我們說到,若是我們很常分享設定期效的檔案,逐個設定也是相當累人。

不只是檔案分享,假如我們今天有份重要檔案每日有個備份,我們通常只會留下 7 日的復原點,那此次我們會依靠檔案的建立日期進行比較,雖然降低點精確度,但可以自動將到期的檔案進行刪除。

1. 重點


普遍 Apps Script 回傳的 Date 格式為 UTC,但普遍 API 主要採用 ISO 8601 格式 。
Trigger 的 Day Timer 為時段觸發而非整點觸發

2. 內容


2.1. 時間格式

在程式碼中的時間記錄,各位或許都聽過 Date 型態,然若沒有深入探索而不清楚其多種的樣式的,相對在處理與解析上就會有不同的麻煩點。

2.1.1. 常用格式

那在下方我們首先依靠 new Date() 取得現在時間,可以看到我們分別列出四種常用的紀錄方式。

JavaScript
function getDateFormat() {
  let now = new Date();

  // ISO 8601
  console.log(now.toISOString()); // 2024-06-26T09:16:29.183Z
  // Local Time
  console.log(now.toString()); // Wed Jun 26 2024 17:16:29 GMT+0800 (GMT+08:00)
  // RFC 7231
  console.log(now.toUTCString()); // Wed, 26 Jun 2024 09:16:29 GMT
  // Milliseconds
  console.log(now.getTime()); // 1719393389183
}

ISO 8601 是國際標準日期和時間格式,其中的 T 區隔日期與時間,尾端的 Z 代表時區偏移。而 Local Time 則是生活中最常使用,區分時區之後的時間,可以看到尾端還會標示加減多少。RFC 7231 則主要用於 HTTP 其 Header 中攜帶的 HTTP-date 參數。

最後多介紹個毫秒數的表示法,它有致命的缺點是其開始自 UNIX 時間(1970),並且在長遠的未來數字會用完,但由於其計時單位極精細的因素,常用來判斷程式執行時長。

2.1.2. 時間細節

那在同樣都是 Date 格式下,可以倚靠以下方法快速取得指定數值。

JavaScript
function getDateDetail()
{
  // Year
  console.log("Year:", now.getFullYear());
  // Month (0-11, where 0 = January and 11 = December)
  console.log("Month:", now.getMonth() + 1); // +1 because months are zero-indexed
  // Day of the Month
  console.log("Day of the Month:", now.getDate());
  // Day of the Week (0-6, where 0 = Sunday and 6 = Saturday)
  console.log("Day of the Week:", now.getDay());
  // Hours (0-23)
  console.log("Hours:", now.getHours());
  // Minutes (0-59)
  console.log("Minutes:", now.getMinutes());
  // Seconds (0-59)
  console.log("Seconds:", now.getSeconds());
  // Milliseconds (0-999)
  console.log("Milliseconds:", now.getMilliseconds());
  // Timezone Offset in Minutes
  console.log("Timezone Offset (in minutes):", now.getTimezoneOffset());
}

要注意是 “月份” 與 “星期幾” 是從 0 開始記錄,而時差也有些反常理,+8 時區回傳值是 -480 分鐘。

2.2. 檔案屬性

在 Drive 中點擊檔案後能在右側看到許多指標,而我們接著就要提取檔案的屬性。

JavaScript
// Get all attributes of file
function getFileAttribute() {
  const FILE_ID = 'FILE_ID';
  const file = DriveApp.getFileById(FILE_ID);

  // Basic Attribute
  const fileName = file.getName();
  const fileSize = file.getSize();
  const fileId = file.getId(); 
  const fileUrl = file.getUrl();
  const fileDescription = file.getDescription();
  const fileType = file.getMimeType();
  const fileCreatedDate = file.getDateCreated();
  const fileLastUpdated = file.getLastUpdated();
  const fileOwner = file.getOwner().getEmail();
  const fileEditors = file.getEditors().map(function(editor) {
    return editor.getEmail();
  }).join(', ');
  const fileViewers = file.getViewers().map(function(viewer) {
    return viewer.getEmail();
  }).join(', ');

  console.log('File Name: ' + fileName);
  console.log('File Size: ' + fileSize + ' bytes');
  console.log(`File ID: ${fileId}`); 
  console.log('File URL: ' + fileUrl);
  console.log('File Description: ' + fileDescription);
  console.log('File Type: ' + fileType);
  console.log('File Created Date: ' + fileCreatedDate);
  console.log('File Last Updated: ' + fileLastUpdated);
  console.log('File Owner: ' + fileOwner);
  console.log('File Editors: ' + fileEditors);
  console.log('File Viewers: ' + fileViewers);

  // File download URL
  const fileDownloadUrl = file.getDownloadUrl(); 
  console.log(`File Download URL: ${fileDownloadUrl}`); 

  // An data intercahnge object
  const fileBlob = file.getBlob(); 
  console.log(`File BLOB: ${fileBlob.getBytes()}`); 
}

其中的 getUrl 是獲取檔案在 Drive 的位置,而 getDownloadUrl 則是下載連結,但同理用戶需要至少 READ 權限才能夠下載檔案。

而 Blob 比較常用於資料傳輸的過程,主要是給機器閱覽而非人類能快速理解的資訊,通常比較少用到。

2.3. 日期比對

我們進入到今日的議題,假設我們準備一個資料夾安置檔案的每日備份,以 7 日座基底進行測試 。

那由於時間的特性,為方便計算我設為 00:00.000 的情況,另外需要判定時間長過 days * 24 hr * 60 min * 60 sec * 1000 milli-sec 。後續可以看到一系列操作並透過 sorting 檔案時間,避免迴圈做無謂的檢查。

JavaScript
// - Scan childs in the target folder
// -- Sort all childs by date created
// ---- Compare date created with date today if is |lifeTime| days ago
// ------ T
// -------- Delete the file
// ------ F
// -------- BREAK the loop for there's no more longer than max life-time
function scanLifeTime() {
  let folderId = 'FOLDER_ID';

  // Max lifetime in days
  let lifeTime = 7 * (24 * 3600 * 1000);

  console.warn('# RUN - scanLifeTime()');

  try {
    // Parent 
    let folder = DriveApp.getFolderById(folderId);
    // Childs
    let files = folder.getFiles();

    // List to store file info
    let fileList = [];

    // Timestamp to check lifetime
    let today = new Date().setHours(0, 0, 0, 0);

    // Gather all files into an array
    while (files.hasNext()) {
      let file = files.next();
      fileList.push({
        file: file,
        createdDate: file.getDateCreated()
      });
    }

    console.warn(`@ Sorting Files by Time Created`);

    // Sort files by their creation date
    fileList.sort((a, b) => a.createdDate - b.createdDate);

    console.warn(`@ Deleting Files over Lifetime`);

    // Iterate over the sorted array and delete files over lifetime
    for (let i = 0; i < fileList.length; i++) {
      let fileInfo = fileList[i];
      let createdDate = fileInfo.createdDate.setHours(0, 0, 0, 0);

      console.log(today - createdDate)

      if ((today - createdDate) >= lifeTime) {
        console.log(`(ID: ${fileInfo.file.getId()}) File ${fileInfo.file.getName()} removed for over lifetime`);
        // Move to trash can
        fileInfo.file.setTrashed(true);
      }
      // BREAK loop for no more longer than lifetime 
      else { console.log(`No files older than lifetime`); break; }
    }
  } catch (error) { console.error(error); }

  console.warn('# END - scanLifeTime()');
}

那前面提到我們需要針對每日進行檢查,就要另外設置 Trigger 的 Day Timer,可以選定個人偏好的時段。

3. 後話


到這邊我們已基本了解磁碟操作方式,並了解到常用的兩種定時 Trigger。 但各位應該覺得目前活用範圍偏少,這便要依靠 Google 編輯器進行擴增與資料保存。

在過後呢我們將進入到 Google Form 並結合其他服務,那我們下期再見囉 ~~

4. 參考


[1] Date — MDN Web Docs
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

[2] Class File — Official Doc
https://developers.google.com/apps-script/reference/drive/file

[3] Class Blob — Official Doc
https://developers.google.com/apps-script/reference/base/blob.html

5. 素材


[1] 圖片素材 by QuAn_
https://www.pixiv.net/users/6657532

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.