前言

臉書上偶爾會跳出多年前的貼文、相片、影片,每每看到都會湧上不少回憶。隨著日子一天一天過去,卻越來越不想公開自己的生活到社群平台。不過我有NAS耶,裡面存放了過去十多年的相片、影片。如果可以像臉書一樣,每天從去年同期的相片庫裡,隨機挑幾張相片來回憶就好了。

我的 NAS 是 Synology DS214Play,裡面有四十萬張相片,空間占用大約1.5T,一直在找適合的 Synology 套件,試用過 Memory,不過光轉檔就轉到昏天暗地了,更遑論要瀏覽相片了。找不到,乾脆動手做吧!

目標

程式每天從相片庫裡隨機找出過去幾年與今日同日期的相片,例如今天是 2020/6/2,往前找出 2019/6/2、2018/6/2、2017/6/2,以此類推。經由各種通訊平台傳送相片。

盤點

首先整理一下擁有的技能跟環境

環境

  • 一台有好多好多照片的 Synology NAS with DSM 6.2
  • 可以 SSH 登入系統
  • 可以 run python、bash

技能

  • 用過 ubuntu
  • 寫過 python、shell script
  • 建過 Line Bot、Telegram Bot,最常使用 Line Notify 發送通知訊息

運行架構

  1. 將所有相片進行索引、解析 Exif 資訊,進行時區轉換後並存放在資料庫裡。
  2. 隨機挑選同期相片,選擇通訊平台發送訊息。

部署到 NAS 上

  1. 先到 DSM 上將 SSH 登入開啟
    image alt <

  2. 透過 Putty 登入 NAS

  3. install pip in synology nas

  4. 從 github 將專案打包到 nas 上並解壓縮

    $ wget --no-check-certificate --content-disposition https://github.com/sporting/PhotoYourHistory/archive/v1.20.6.1.tar.gz
    $ tar -xvzf PhotoYourHistory-1.20.6.1.tar.gz
    $ mv PhotoYourHistory-1.20.6.1 PhotoYourHistory
    
  5. 設定環境

    • 建立 virtualenv 環境

      $ cd PhotoYourHistory
      $ python3 -m venv env
      $ source env/bin/activate
      
    • 設定要監控的目錄

      $ python init/SetRootDir.py /var/services/photo/
      
    • 設定通訊平台

      • 如果選定 Telegram Bot,請到 Telegram 平台找 @BotFather 申請新的 Bot,將取得的 Access Token 存入資料庫
      $ python init/SetBotToken.py [YOUR_TELEGRAM_BOT_ACCESS_TOKEN]
      
      • 再去找 @IDBot 要到你的 ID,將取得的 ID 存入資料庫,並設定你的代碼名稱 (ex: ERIC 艾力克)
       $ python init/SetUserData.py ERIC "TELEGRAM" [TELEGRAM_ID] 艾力克
      
      • 如果選定 LINE 平台,我們這邊選定免費的 Line Notify 發送訊息,請至 Line Notify Bot 申請 Token
      $ python init/SetUserData.py ERIC "LINE NOTIFY" [LINE_NOTIFY_TOKEN] 艾力克
      
    • 設定你想收到的相片分類,例如 ERIC 想收到關於 自己及ALICE、LINDA的相片訊息

      $ python init/SetCareCatagory.py ERIC ERIC ALICE LINDA
      
    • 在建立相片索引資料庫之前,請先建立相片分類引擎,請在 db 資料夾中建立一個檔案名稱為 MyCatalogEncoder.py 的檔案

      $ touch db/MyCatalogEncoder.py
      

      可以透過 vim 編輯或是回到 DSM 上編輯內容,請依據你的相片目錄管理原則,進行分類

      >>> from db.CatalogEncoder import CatalogEncoder
      >>> class MyCatalogEncoder(CatalogEncoder):
      >>> def default(self, dir):
            if dir.find('ERIC')>=0:
                return 'ERIC,ALICE,LINDA'        
      
            s = ''
            if dir.find('ERIC')>=0 or dir.find('mobile-eric')>=0:
                s = 'ERIC' if s=='' else s+',ERIC'
            if dir.find('ALICE')>=0 or dir.find('mobile-alice')>=0:
                s = 'ALICE' if s=='' else s+',ALICE'
            if dir.find('LINDA')>=0 or dir.find('mobile-linda'):
                s = 'LINDA' if s=='' else s+',LINDA'
      
            return 'ERIC,ALICE,LINDA' if s=='' else s
      
    • 可選功能,如果你想在手機平台上透過瀏覽器直接播放 Synology Nas 上面的影片,請將 Nas Domain、Port、登入 NAS 帳號密碼設定進資料庫,NAS 帳號密碼可以新增一個只有 photo 權限的帳號。程式會使用這個帳號取得登入 Nas 的 SID,並產生等同 DSFile 的觀看連結。

      $ # ex: python init/SetNasHostIPPort.py yourSynologyNas.dscloud.me 5001
      $ python init/SetNasHostIPPort.py [YOUR_NAS_DOMAIN_OR_IP] [YOUR_NAS_PORT]   
      $ python init/SetNasLoginAccountPwd.py [YOUR_NAS_LOGIN_ACCOUNT] [YOUR_NAS_LOGIN_PASSWORD]
      
    • 可選功能,有時候拍了相片卻忘掉這照片在哪裡拍的,可以透過 Google Map GeoLocation API 將地址夾帶在訊息之中。請至 google cloud 申請 API KEY,並設定進資料庫

      $ python init/SetGoogleMapApi.py [YOUR_GOOGLE_MAP_API_KEY]
      
    • 最後請在 DSM 控制台的任務排程表新增兩個排程,一個是更新相片資料庫索引,一個是發送相片到指定的通訊平台
      更新相片資料庫索引的排程請執行以下 command (YOUR_REPOSITORY_DIRECTORY 請設定剛才 PhotoYourHistory 的完整目錄,例如 /var/services/homes/eric/PhotoYourHistory/)
      我是設定在半夜 12:00 執行

      $ export LANG='en_US.UTF-8'
      $ export LC_ALL='en_US.UTF-8'
      $ cd [YOUR_REPOSITORY_DIRECTORY]
      $ source env/bin/activate
      $ PYTHONIOENCODING=utf-8 python DailyInsertMonitorDir.py
      $ PYTHONIOENCODING=utf-8 python DailyIndexingNewFiles.py
      

      發送相片到指定的通訊平台排程請執行以下 command
      我是設定在早上 6:00 執行,以便在起床後可以觀看

      $ export LANG='en_US.UTF-8'
      $ export LC_ALL='en_US.UTF-8'
      $ cd [YOUR_REPOSITORY_DIRECTORY]
      $ source env/bin/activate
      $ PYTHONIOENCODING=utf-8 python DailyPushPhotoThisDay.py
      
    • 預設每個日期隨機挑選三張相片,如果想調整隨機發送的相片數量,可逕行修改 DailyPushPhotoThisDay.py 裡的相片數,例如改成每天五張相片

      >>> # -*- coding: UTF-8 -*-
      >>> from datetime import datetime
      >>> from db.SaUsersDB import dbUsersHelper
      >>> import mysys.PushPhoto as PhotoService
      
      >>> if __name__ == "__main__":    
      >>>     duh = dbUsersHelper()
      >>>     users = duh.getSMSUsers()    
      >>>     PhotoService.Push(users,datetime.today(),5)
      
  6. 收到訊息如下

  • Telegram MediaGroup (將同一天的照片做一個 MediaGroup)

image alt <

  • Telegram MediaGroup 點開照片,可看到相片資訊

image alt <

  • Telegram Video Link,提供縮圖加連結

image alt <

  • Line Notify Photo

image alt <

  • Line Notify Video Link

image alt <

問題發想及回覆

  1. 如何決定相片的日期?
    Reply: 一般拍攝的相片裡會存放 Exif 資訊,以 Exif 資訊內的日期為主,而不參考檔案建檔、修改、存取日期。如果沒有 Exif 的檔案,需自行更新相片資料庫裡的 PHOTO_UTC_TS、PHOTO_UTC_DATE。

  2. 拍攝相片會有時區的問題?
    Reply: 因為要找出"與今日同期"的相片,需對相片時區的日期進行轉換。

  3. 在 NAS 裡進行相片管理,新增、修改、移動、刪除目錄後,如何更新相片資料庫?
    Reply: 監控指定目錄以進行檔案及目錄等索引。

  4. 發送訊息的成本?
    Reply: LINE 2.0 有 500 則免費訊息,超過就要收費。程式僅考慮最低成本,採用 Line Notify、Telegram Bot。

  5. 家庭影片能不能也當訊息發送?
    Reply: 可以,可是影片沒有 Exif 資訊,只能以建檔日期等資訊做為參考。

  6. 發送相片或是家庭影片檔案會不會很大?
    Reply: 考量瀏覽相片的順暢,以縮圖進行發送。考量影片的檔案大小,以發送 Synology Nas 連結的方式,在手機上直接觀賞串流影片。

  7. Nas 裡有很多 User 自己的相片,我並不想收到其他人的相片。
    Reply: 須將照片進行分類,本程式是以目錄名稱進行預分類,輔以每個 User 想觀看的不同分類進行通知提醒。例如目錄名稱有Eric、Alice字樣的,分類為ERIC, ALICE。而 Eric 想得到 Eric, Alice 相關的照片通知提醒。

  8. 可以像 Synology Package Memory 一樣有人臉辨識功能並進行分類嗎?或是只要發送有人像的照片即可?
    Reply: face-recognition 套件裝不起來,不然我也想做!有人有辦法安裝起來嗎?拜託告訴我!

完整的 Github 專案請參考: PhotoYourHistory


#synology #nas #photo #Python #PhotoThisDay #PhotoYourHistory #TelegramBot #LineNotify #我的這一天







Related Posts

CSS 的模組化(OOCSS、SMACSS、BEM)

CSS 的模組化(OOCSS、SMACSS、BEM)

用 Nest.js 開發 API 吧 (一)

用 Nest.js 開發 API 吧 (一)

SQL For Loop, Using Cursor

SQL For Loop, Using Cursor


Comments