Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the ultimate-addons-for-gutenberg domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /opt/bitnami/wordpress/wp-includes/functions.php on line 6114
G-Drive 智慧工坊 – 磁碟檔案 002 – 檔案屬性與日期比對 - 八寶周的研究小屋

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

Comments

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.