2024年1月23日 星期二

Javascript 開發筆記 - 盡可能使用 npm 指令處理套件安全更新,此例升級 electron 和 electron-builder



之前寫的練習擺在 github 一直收到套件安全的升級通知信(這只是其中一條),以前在處理這個時,都是人工改掉 package.json ,這次來用指令試試:

% git clone https://github.com/changyy/node-electron-based
% cd node-electron-based
% source env_nvm.sh 
Now using node v16.20.2 (npm v8.19.4)
% npm install
npm WARN deprecated asar@3.2.0: Please use @electron/asar moving forward.  There is no API change, just a package name change
npm WARN deprecated electron-osx-sign@0.6.0: Please use @electron/osx-sign moving forward. Be aware the API is slightly different

added 557 packages, and audited 558 packages in 10s

69 packages are looking for funding
  run `npm fund` for details

11 vulnerabilities (4 moderate, 7 high)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

接著就如上述所言,用 npm audit fix 查看一下:

% npm audit fix

up to date, audited 558 packages in 860ms

69 packages are looking for funding
  run `npm fund` for details

# npm audit report

electron  <=22.3.24
Severity: high
Depends on vulnerable versions of @electron/get
Electron vulnerable to out-of-package code execution when launched with arbitrary cwd - https://github.com/advisories/GHSA-7x97-j373-85x5
Electron context isolation bypass via nested unserializable return value - https://github.com/advisories/GHSA-p7v2-p9m8-qqg7
Electron affected by libvpx's heap buffer overflow in vp8 encoding - https://github.com/advisories/GHSA-qqvq-6xgj-jw8g
ASAR Integrity bypass via filetype confusion in electron - https://github.com/advisories/GHSA-7m48-wc93-9g85
fix available via `npm audit fix --force`
Will install electron@28.1.4, which is a breaking change
node_modules/electron

got  <11.8.5
Severity: moderate
Got allows a redirect to a UNIX socket - https://github.com/advisories/GHSA-pfrx-2q88-qq97
fix available via `npm audit fix --force`
Will install electron@28.1.4, which is a breaking change
node_modules/got
  @electron/get  <=1.14.1
  Depends on vulnerable versions of got
  node_modules/@electron/get

minimatch  <3.0.5
Severity: high
minimatch ReDoS vulnerability - https://github.com/advisories/GHSA-f8q6-p94x-37v3
fix available via `npm audit fix`
node_modules/dir-compare/node_modules/minimatch
  dir-compare  <=2.4.0
  Depends on vulnerable versions of minimatch
  node_modules/dir-compare
    @electron/universal  1.0.1 - 1.3.3
    Depends on vulnerable versions of dir-compare
    node_modules/@electron/universal
      app-builder-lib  22.10.4 - 24.0.0-alpha.13
      Depends on vulnerable versions of @electron/universal
      node_modules/app-builder-lib
        dmg-builder  22.10.4 - 24.0.0-alpha.13
        Depends on vulnerable versions of app-builder-lib
        node_modules/dmg-builder
          electron-builder  19.25.0 || 22.10.4 - 24.6.0
          Depends on vulnerable versions of app-builder-lib
          Depends on vulnerable versions of dmg-builder
          Depends on vulnerable versions of simple-update-notifier
          node_modules/electron-builder

semver  7.0.0 - 7.5.1
Severity: moderate
semver vulnerable to Regular Expression Denial of Service - https://github.com/advisories/GHSA-c2qf-rxjj-qqgw
fix available via `npm audit fix`
node_modules/simple-update-notifier/node_modules/semver
  simple-update-notifier  1.0.7 - 1.1.0
  Depends on vulnerable versions of semver
  node_modules/simple-update-notifier

11 vulnerabilities (4 moderate, 7 high)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

使用 npm audit fix --force 處理:

% npm audit fix --force
npm WARN using --force Recommended protections disabled.
npm WARN audit Updating electron to 28.1.4, which is a SemVer major change.

added 10 packages, removed 13 packages, changed 15 packages, and audited 555 packages in 4s

76 packages are looking for funding
  run `npm fund` for details

# npm audit report

minimatch  <3.0.5
Severity: high
minimatch ReDoS vulnerability - https://github.com/advisories/GHSA-f8q6-p94x-37v3
fix available via `npm audit fix`
node_modules/dir-compare/node_modules/minimatch
  dir-compare  <=2.4.0
  Depends on vulnerable versions of minimatch
  node_modules/dir-compare
    @electron/universal  1.0.1 - 1.3.3
    Depends on vulnerable versions of dir-compare
    node_modules/@electron/universal
      app-builder-lib  22.10.4 - 24.0.0-alpha.13
      Depends on vulnerable versions of @electron/universal
      node_modules/app-builder-lib
        dmg-builder  22.10.4 - 24.0.0-alpha.13
        Depends on vulnerable versions of app-builder-lib
        node_modules/dmg-builder
          electron-builder  19.25.0 || 22.10.4 - 24.6.0
          Depends on vulnerable versions of app-builder-lib
          Depends on vulnerable versions of dmg-builder
          Depends on vulnerable versions of simple-update-notifier
          node_modules/electron-builder

semver  7.0.0 - 7.5.1
Severity: moderate
semver vulnerable to Regular Expression Denial of Service - https://github.com/advisories/GHSA-c2qf-rxjj-qqgw
fix available via `npm audit fix`
node_modules/simple-update-notifier/node_modules/semver
  simple-update-notifier  1.0.7 - 1.1.0
  Depends on vulnerable versions of semver
  node_modules/simple-update-notifier

8 vulnerabilities (2 moderate, 6 high)

To address all issues, run:
  npm audit fix

% git diff
diff --git a/package.json b/package.json
index f470e2b..4b7ac3d 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
     "concurrently": "^7.4.0",
     "copy-webpack-plugin": "^11.0.0",
     "cross-env": "^7.0.3",
-    "electron": "^20.1.1",
+    "electron": "^28.1.4",
     "electron-builder": "^23.3.3",
     "webpack-cli": "^4.10.0",
     "webpack-dev-server": "^4.11.0"

這樣應當算有處理到一個項目的更新,最後再看看之前的 build code 是否正常

% npm install
% npm run build

> simple-electron-app@1.0.0 build
> webpack-cli && electron-builder -mwl

assets by path ../../ 2.47 KiB
  assets by path ../../renderer/*.js 958 bytes
    asset ../../renderer/mainRenederer.js 910 bytes [emitted] [from: src/renderer/mainRenederer.js] [copied] [minimized]
    asset ../../renderer/index.js 48 bytes [emitted] [from: src/renderer/index.js] [copied] [minimized]
  asset ../../main/index.js 1.26 KiB [emitted] [from: src/main/index.js] [copied] [minimized]
  asset ../../preload/mainRenderer.js 289 bytes [emitted] [from: src/preload/mainRenderer.js] [copied] [minimized]
asset index.html 495 bytes [emitted] [from: src/html/mainRenderer/index.html] [copied]
asset index.js 253 bytes [emitted] [minimized] (name: mainRendererHTML)
./src/html/mainRenderer/index.js 380 bytes [built] [code generated]

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value.
Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

webpack 5.89.0 compiled with 1 warning in 146 ms
  • electron-builder  version=23.6.0 os=23.2.0
  • description is missed in the package.json  appPackageFile=/Volumes/Data/UserData/tmp/node-electron-based/package.json
  • writing effective config  file=dist/builder-effective-config.yaml
  • packaging       platform=darwin arch=arm64 electron=28.1.4 appOutDir=dist/mac-arm64
  • downloading     url=https://github.com/electron/electron/releases/download/v28.1.4/electron-v28.1.4-darwin-arm64.zip size=95 MB parts=8
  • downloaded      url=https://github.com/electron/electron/releases/download/v28.1.4/electron-v28.1.4-darwin-arm64.zip duration=36.971s
  • default Electron icon is used  reason=application icon is not set
  • skipped macOS application code signing  reason=cannot find valid "Developer ID Application" identity or custom non-Apple code signing certificate, it could cause some undefined behaviour, e.g. macOS localized description not visible, see https://electron.build/code-signing allIdentities=     0 identities found
                                                Valid identities only
     0 valid identities found
  • building        target=macOS zip arch=arm64 file=dist/simple-electron-app-1.0.0-arm64-mac.zip
  • building        target=DMG arch=arm64 file=dist/simple-electron-app-1.0.0-arm64.dmg
  • Detected arm64 process, HFS+ is unavailable. Creating dmg with APFS - supports Mac OSX 10.12+
  • packaging       platform=linux arch=x64 electron=28.1.4 appOutDir=dist/linux-unpacked
  • downloading     url=https://github.com/electron/electron/releases/download/v28.1.4/electron-v28.1.4-linux-x64.zip size=102 MB parts=8
  • building block map  blockMapFile=dist/simple-electron-app-1.0.0-arm64.dmg.blockmap
  • building block map  blockMapFile=dist/simple-electron-app-1.0.0-arm64-mac.zip.blockmap
  • downloaded      url=https://github.com/electron/electron/releases/download/v28.1.4/electron-v28.1.4-linux-x64.zip duration=30.749s
  • building        target=snap arch=x64 file=dist/simple-electron-app_1.0.0_amd64.snap
  • building        target=AppImage arch=x64 file=dist/simple-electron-app-1.0.0.AppImage
  • application Linux category is set to default "Utility"  reason=linux.category is not set and cannot map from macOS docs=https://www.electron.build/configuration/linux
  • default Electron icon is used  reason=application icon is not set
  • application Linux category is set to default "Utility"  reason=linux.category is not set and cannot map from macOS docs=https://www.electron.build/configuration/linux
  • packaging       platform=win32 arch=arm64 electron=28.1.4 appOutDir=dist/win-arm64-unpacked
  • downloading     url=https://github.com/electron/electron/releases/download/v28.1.4/electron-v28.1.4-win32-arm64.zip size=108 MB parts=8
  • downloading     url=https://github.com/electron-userland/electron-builder-binaries/releases/download/snap-template-4.0-2/snap-template-electron-4.0-2-amd64.tar.7z size=1.5 MB parts=1
  • downloading     url=https://github.com/electron-userland/electron-builder-binaries/releases/download/appimage-12.0.1/appimage-12.0.1.7z size=1.6 MB parts=1
  • downloaded      url=https://github.com/electron-userland/electron-builder-binaries/releases/download/appimage-12.0.1/appimage-12.0.1.7z duration=5.225s
  • downloaded      url=https://github.com/electron-userland/electron-builder-binaries/releases/download/snap-template-4.0-2/snap-template-electron-4.0-2-amd64.tar.7z duration=5.425s
  • downloaded      url=https://github.com/electron/electron/releases/download/v28.1.4/electron-v28.1.4-win32-arm64.zip duration=42.26s
  • default Electron icon is used  reason=application icon is not set
  • downloading     url=https://github.com/electron-userland/electron-builder-binaries/releases/download/winCodeSign-2.6.0/winCodeSign-2.6.0.7z size=5.6 MB parts=1
  • downloaded      url=https://github.com/electron-userland/electron-builder-binaries/releases/download/winCodeSign-2.6.0/winCodeSign-2.6.0.7z duration=4.001s
  • downloading     url=https://github.com/electron-userland/electron-builder-binaries/releases/download/wine-4.0.1-mac/wine-4.0.1-mac.7z size=19 MB parts=3
  • downloaded      url=https://github.com/electron-userland/electron-builder-binaries/releases/download/wine-4.0.1-mac/wine-4.0.1-mac.7z duration=13.249s
  • building        target=nsis file=dist/simple-electron-app Setup 1.0.0.exe archs=arm64 oneClick=true perMachine=false
  • downloading     url=https://github.com/electron-userland/electron-builder-binaries/releases/download/nsis-3.0.4.1/nsis-3.0.4.1.7z size=1.3 MB parts=1
  • downloaded      url=https://github.com/electron-userland/electron-builder-binaries/releases/download/nsis-3.0.4.1/nsis-3.0.4.1.7z duration=5.637s
  • downloading     url=https://github.com/electron-userland/electron-builder-binaries/releases/download/nsis-resources-3.4.1/nsis-resources-3.4.1.7z size=731 kB parts=1
  • downloaded      url=https://github.com/electron-userland/electron-builder-binaries/releases/download/nsis-resources-3.4.1/nsis-resources-3.4.1.7z duration=4.013s
  • building block map  blockMapFile=dist/simple-electron-app Setup 1.0.0.exe.blockmap

編譯正常,接下來再繼續處理 

% npm audit fix

up to date, audited 555 packages in 730ms

76 packages are looking for funding
  run `npm fund` for details

# npm audit report

minimatch  <3.0.5
Severity: high
minimatch ReDoS vulnerability - https://github.com/advisories/GHSA-f8q6-p94x-37v3
fix available via `npm audit fix`
node_modules/dir-compare/node_modules/minimatch
  dir-compare  <=2.4.0
  Depends on vulnerable versions of minimatch
  node_modules/dir-compare
    @electron/universal  1.0.1 - 1.3.3
    Depends on vulnerable versions of dir-compare
    node_modules/@electron/universal
      app-builder-lib  22.10.4 - 24.0.0-alpha.13
      Depends on vulnerable versions of @electron/universal
      node_modules/app-builder-lib
        dmg-builder  22.10.4 - 24.0.0-alpha.13
        Depends on vulnerable versions of app-builder-lib
        node_modules/dmg-builder
          electron-builder  19.25.0 || 22.10.4 - 24.6.0
          Depends on vulnerable versions of app-builder-lib
          Depends on vulnerable versions of dmg-builder
          Depends on vulnerable versions of simple-update-notifier
          node_modules/electron-builder

semver  7.0.0 - 7.5.1
Severity: moderate
semver vulnerable to Regular Expression Denial of Service - https://github.com/advisories/GHSA-c2qf-rxjj-qqgw
fix available via `npm audit fix`
node_modules/simple-update-notifier/node_modules/semver
  simple-update-notifier  1.0.7 - 1.1.0
  Depends on vulnerable versions of semver
  node_modules/simple-update-notifier

8 vulnerabilities (2 moderate, 6 high)

To address all issues, run:
  npm audit fix

故事大概起源於 electron-builder ,只好先把他升級看看

% cat package.json | jq '.devDependencies["electron-builder"]'
"^23.3.3"
% npm update --dev electron-builder
% cat package.json | jq '.devDependencies["electron-builder"]'
"^23.3.3"

看來只好靠這招了:

% npm install electron-builder@latest --save-dev
% cat package.json | jq '.devDependencies["electron-builder"]'
"^24.9.1"

如此也確認都沒事了:

% npm audit
found 0 vulnerabilities

最終,其實也只是改 package.json 兩行 XD

% git diff package.json 
diff --git a/package.json b/package.json
index f470e2b..4c830f1 100644
--- a/package.json
+++ b/package.json
@@ -19,8 +19,8 @@
     "concurrently": "^7.4.0",
     "copy-webpack-plugin": "^11.0.0",
     "cross-env": "^7.0.3",
-    "electron": "^20.1.1",
-    "electron-builder": "^23.3.3",
+    "electron": "^28.1.4",
+    "electron-builder": "^24.9.1",
     "webpack-cli": "^4.10.0",
     "webpack-dev-server": "^4.11.0"
   }

2024年1月11日 星期四

Synology NAS 使用 Private IP, 自訂網域 與 Wildcard SSL 來提供 HTTPS 服務並完成憑證定期更新與設定 @ DSM 7.2.1, DS723+

之前已經處理過 DS216play 的情況,撰寫過兩篇筆記:

這次在處理 DS723+ / DSM 7.2.1 時,有在追細一點,但整體上的流程 2022年的那篇只做了一半,他並沒有做到自動更新,而當時追的時候也沒追清楚。

簡略的流程:
  1. 參考 2022年的方式,先透過 acme.sh 產出憑證(例如用 Cloudflare 維護 DNS record 時,可以輕鬆呼叫 Cloudflare API 完成 txt record 更新),接著到 Synology 網頁管理 -> 控制台 -> 連線能力 -> 憑證 -> 新增 -> 新增憑證 -> 匯入憑證
  2. 這時匯入完畢後,其實在系統底層可以看到資訊,我原先在 2022年那篇誤認為 /usr/syno/etc/www/certificate/system_default/cert.conf 的描述位置(因為從 Nginx 設定檔有關),細追後,發現真正的位置在 /usr/syno/etc/certificate/_archive/ 某個目錄內
    • 用 cat /usr/syno/etc/certificate/_archive/INFO 可以看到你自己上傳的憑證,假設是在 /usr/syno/etc/certificate/MySelf 這目錄,內有 cert.pem, chain.pem, fullchain.pem, privkey.pem
  3. 這時若把 acme.sh 安置好,可以在 Synology NAS 內某個使用者的家目錄運行,那在他家目錄中就會有 ~/.acme.sh/*.YourDomain_ecc/ 這類位置,內有 ca.cer, '*.YourDomain.cer', '*.YourDomain.key', 'fullchain.cer' 和 '*.YourDomain.pkcs8',這時,就要把 /usr/syno/etc/certificate/MySelf 內的完成同步更新,例如使用 symbolic link 
  4. 後續,就回到 Synology 網頁介面 -> 控制台 -> 任務排程表 -> 新增一則任務並使用 root 權限 -> 設定每月執行一次 -> 在使用者定義指令碼那邊,可以直接呼叫 script (例如包裝成 renew-ssl.sh)在指定使用者家目錄完成憑證更新、接著在把 nginx reload
    • sudo -u YourNASUser bash /var/services/homes/YourNASUser/renew-ssl.sh
    • sudo nginx -t && sudo synopkg restart --service nginx && sudo synosystemctl reload nginx
目前看來,在 (2) 那邊找到的實際儲存位置時,透過 symbolic link 改到取 (3) 的資料,如此在控制台憑證列表可以立即觀看到 acme.sh renew 後的延長期限數字,這邊有提到 '*.YourDomain.pkcs8' 檔案格式,是跟 Synology NAS 使用的格式有關,他在呼叫 acme.sh renew 時,可以多添加 --to-pkcs8 參數來產生。


現況應當還有個隱憂,那就是 /usr/syno/etc/certificate/MySelf/*.pem 可完成自動更新,那 nginx 設定取得的憑證資訊是否也會更新?目前推猜好像不是同步的,且更新時機也還不明,只能等下個期週期後再來看看了。暫時推論是在設定憑證的系統預設時,才從 /usr/syno/etc/certificate/MySelf/*.pem 複製到 /usr/syno/etc/www/certificate/system_default/ 使用

2024年1月1日 星期一

使用 do-release-upgrade 把 Oracle Cloud - Ubuntu 18.04 升級至 20.04 再繼續升級到 22.04

在 2019年搶了一台 Ubuntu 18.04 後,一直在那邊做例行公事。應該近一年 apt upgrade 也沒法多升級什麼就涼在那邊,趁 2024-01-01 假期,來整理一下。

升級絕對有風險,請自行評估跟承擔,在此謹流水帳紀錄,適合我的 VM 情況不代表大家都能升。

由於之前有設定防火牆來做一些簡單的防護,這次升級時要打開 1022 port 來小心一下:

$ sudo iptables -I INPUT 1 -p tcp --dport 1022 -j ACCEPT
$ sudo service netfilter-persistent save

開始操作:

$ sudo do-release-upgrade 
...
Calculating the changes

Could not calculate the upgrade

An unresolvable problem occurred while calculating the upgrade.

This was likely caused by:
* Unofficial software packages not provided by Ubuntu
Please use the tool 'ppa-purge' from the ppa-purge
package to remove software from a Launchpad PPA and
try the upgrade again.

If none of this applies, then please report this bug using the
command 'ubuntu-bug ubuntu-release-upgrader-core' in a terminal. If
you want to investigate this yourself the log files in
'/var/log/dist-upgrade' will contain details about the upgrade.
Specifically, look at 'main.log' and 'apt.log'.

接著安裝一下:

$ sudo apt-get install ppa-purge
$ sudo do-release-upgrade 
...

又碰到問題,大概看了一下 bugs.launchpad.net/ubuntu/+source/llvm-toolchain-9/+bug/1886748 ,偷懶衝:

$ sudo apt install clang-9
$ sudo do-release-upgrade 
...
Do you want to start the upgrade? 


17 packages are going to be removed. 209 new packages are going to be 
installed. 759 packages are going to be upgraded. 

You have to download a total of 886 M. This download will take about 
1 hour 52 minutes with a 1Mbit DSL connection and about 1 day 10 
hours with a 56k modem. 

Fetching and installing the upgrade can take several hours. Once the 
download has finished, the process cannot be canceled. 

 Continue [yN]  Details [d]Y

...
System upgrade is complete.

Restart required 

To finish the upgrade, a restart is required. 
If you select 'y' the system will be restarted. 

Continue [yN] Y

所幸...連得上 XD 看來完成了 Ubuntu 20.04 了

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal

繼續升上去!

$ sudo do-release-upgrade 
...
Reading cache

Checking package manager

Continue running under SSH? 

This session appears to be running under ssh. It is not recommended 
to perform a upgrade over ssh currently because in case of failure it 
is harder to recover. 

If you continue, an additional ssh daemon will be started at port 
'1022'. 
Do you want to continue? 

Continue [yN] Y

Starting additional sshd 

To make recovery in case of failure easier, an additional sshd will 
be started on port '1022'. If anything goes wrong with the running 
ssh you can still connect to the additional one. 


To continue please press [ENTER]

Do you want to start the upgrade? 


12 packages are going to be removed. 128 new packages are going to be 
installed. 826 packages are going to be upgraded. 

You have to download a total of 746 M. This download will take about 
2 minutes with your connection. 

Installing the upgrade can take several hours. Once the download has 
finished, the process cannot be canceled. 

 Continue [yN]  Details [d] Y

done
Processing triggers for dbus (1.12.20-2ubuntu4.1) ...
Processing triggers for libgdk-pixbuf-2.0-0:amd64 (2.42.8+dfsg-1ubuntu0.2) ...
Reading package lists... Done    
Building dependency tree          
Reading state information... Done

Processing snap replacements

refreshing snap lxd

refreshing snap oracle-cloud-agent

Searching for obsolete software
Reading state information... Done

Remove obsolete packages? 


127 packages are going to be removed. 

Removing the packages can take several hours. 

 Continue [yN]  Details [d]Y

...

System upgrade is complete.

Restart required 

To finish the upgrade, a restart is required. 
If you select 'y' the system will be restarted. 

Continue [yN] Y

再次登入:

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.3 LTS
Release: 22.04
Codename: jammy

2023年12月31日 星期日

使用 Hugo 跟 Cloudflare 架設個人品牌網站 - changyy.app



買了 changyy.app 網域好一陣子,想說該用來經營一下個人品牌,然後一直偷懶 XD 目前用 Github private repository + Hugo + Cloudflare 維護 https://changyy.app 網站,最近來換一下 Hugo theme ,再重新複習一下。

目前架設個人品牌網站,主要著重在把一些網路足跡紀錄一下,雖說 linkedin 上也是整理足跡的方式,但目的是很正式的求職路線,一些有趣的小品反而不太適合。近三年嘗試了 golang、python 和 node.js 等等外,在工作上的程式語言有盡可能切換到 Python,也試著把一些小品工具包裝成 PyPi 安裝方式作為收尾,預計就可以用來充實個人品牌網站了?!

目前架設個人網站的需求如下:
  • 把相關網站靠 link 關聯著
  • 提供撰寫簡單的條列式記錄生活
就這樣,先挑了 hugo-PaperMod 樣版來試試。

連續動作:

% hugo version
hugo v0.121.1+extended Darwin/arm64 BuildDate=unknown VendorInfo=macports

% hugo new site MyWebsite --format yaml
Congratulations! Your new Hugo site was created in /path/MyWebsite.

Just a few more steps...

1. Change the current directory to /path/MyWebsite.
2. Create or install a theme:
   - Create a new theme with the command "hugo new theme <THEMENAME>"
   - Install a theme from https://themes.gohugo.io/
3. Edit hugo.yaml, setting the "theme" property to the theme name.
4. Create new content with the command "hugo new content <SECTIONNAME>/<FILENAME>.<FORMAT>".
5. Start the embedded web server with the command "hugo server --buildDrafts".

See documentation at https://gohugo.io/.

% cd MyWebsite
% hugo serve


接著套用一下 PaperMod 樣板,稍微從他的教學 github.com/adityatelange/hugo-PaperMod/wiki 小改:

% curl -L https://github.com/adityatelange/hugo-PaperMod/archive/v7.0.zip > /tmp/v7.0.zip
% unzip /tmp/v7.0.zip -d themes/
% mkdir -p config/_default/
% cat config/_default/config.yml 
theme: "hugo-PaperMod-7.0"
% tree -L 2
.
├── archetypes
│   └── default.md
├── assets
├── config
│   └── _default
├── content
├── data
├── hugo.yaml
├── i18n
├── layouts
├── static
└── themes
    └── hugo-PaperMod-7.0

12 directories, 2 files

% hugo serve

 


最後連續動作弄了些:

% cat config/_default/config.yml 
# https://gohugo.io/getting-started/configuration/
baseURL: https://your-domain
languageCode: en-us
title: YourWebsiteName
theme: hugo-PaperMod-7.0

# https://analytics.google.com/analytics/web/?#/xxxxx/reports/intelligenthome
googleAnalytics: G-XXXXXXX

minify:
  disableXML: true
  minifyOutput: true

# https://github.com/adityatelange/hugo-PaperMod/wiki/Installation
params:
  env: production
  # https://github.com/adityatelange/hugo-PaperMod/wiki/Features#profile-mode
  profileMode:
    enabled: true
    imageUrl: https://secure.gravatar.com/avatar/MD5_Of_EmailAddress?size=120
    imageWidth: 120
    imageHeight: 120
    buttons:
      - name: open source
        url: /projects

  socialIcons:
    - name: github
      url: https://github.com/id
    - name: linkedin
      url: https://linkedin.com/in/id
    - name: blogger
      url: https://your-blog-url
    
  assets:
    favicon: https://secure.gravatar.com/avatar/MD5_Of_EmailAddress?size=128
    favicon16x16: https://secure.gravatar.com/avatar/MD5_Of_EmailAddress?size=16
    favicon32x32: https://secure.gravatar.com/avatar/MD5_Of_EmailAddress?size=32
    apple_touch_icon: https://secure.gravatar.com/avatar/MD5_Of_EmailAddress?size=128
    safari_pinned_tab: https://secure.gravatar.com/avatar/MD5_Of_EmailAddress?size=128

% tree -L 2
.
├── archetypes
│   └── default.md
├── assets
├── config
│   └── _default
├── content
│   └── projects
├── data
├── hugo.yaml
├── i18n
├── layouts
├── static
└── themes
    └── hugo-PaperMod-7.0

13 directories, 2 files

下一刻則是 Cloudflare 那邊設定 Workers & Pages 項目,就長出了 changyy.app 啦,希望 2024年還有餘力繼續擴充足跡。

2023年12月25日 星期一

Python 開發筆記 - 開發 epub-image-helper 工具,批次將圖片目錄打包成 EPUB 格式,也支援 PDF to EPUB @ macos 14.2.1, Python 3.11

記得剛出社會沒多久,被派去研究電子書領域,那時就接觸了 EPUB 格式。當時在團隊中被分配到開發 EPUB READER,例如在 HTML5 環境中,在 Browser 讀進 epub 檔案、進行 unzip 、抽出目錄、呈現書的內容。後來也做過電子書相關的應用發想,而主管們相繼離開(?),也讓我接手和接觸了貢獻 webkit 的項目(C++),可惜很多狀態都不了了之。

大概兩三週前想到 EPUB 這格式,想嘗試把照片打包成單一 EPUB 檔案,方便收藏。但大概完成七八成後,才發現有很多限制,例如電子書閱讀器上要處理大檔案時,就會陷入到電子書閱讀器的硬體規格和處理能力,甚至它實作處理 EPUB 格式的方式等,我才發現當初想要把一堆照片合成一大本應當不是正道 XD 後來還是順手練習 python open source 工具,做了一些發布,在此就筆記一下。而能妥善處理大檔案的電子書閱讀器,大概就 iOS devices 而已,實際在 iPhone SE3 上處理 500MB 的電子書EPUB也都很 OK 的。

這次挑選 ebooklib 作為 EPUB 製作的核心函式庫,當初查看 github 專案上有破千的關注,跳下去使用時才發現有些限制,也順手發了兩次 pull requests ,查閱了該專案歷年的 pull requests 活躍狀態,還是自己弄了個 ebooklib.changyy 方便自己整合

最後產出的小專案:
安裝 epub-image-helper:

% pip install epub-image-helper
% epub-image-helper | jq -r '.version'
1.0.4

使用方式可以參考 README 或是 https://github.com/changyy/epub-image-helper/tree/main/example 內的小程式庫,主要可以用 epub-image-helper 將有階層式的照片打包起來,也可以自訂一個 input.json 格式,批次把許多目錄依照一些規則打包起來,如:

% cd example/01-batch-image-to-epub
% tree .
.
├── epub
├── image2epub.py
├── input.json
└── storage
    └── url 
        ├── 001 
        │   ├── 01.jpg
        │   ├── 02.jpg
        │   └── 03.jpg
        └── 002 
            ├── 01.jpg
            ├── 02.jpg
            ├── 03.jpg
            ├── 04.jpg
            └── 05.jpg

6 directories, 10 files
% cat input.json
[
  {   
    "name": "MyPhotosA",
    "author": ["Author"],
    "books": [
      "https://localhost/001/A", 
      "https://localhost/002/B", 
      "https://localhost/003/C"
    ]   
  },  
  {   
    "name": "MyPhotosB",
    "author": ["Author"],
    "books": [
      "https://localhost/004/A", 
      "https://localhost/005/B", 
      "https://localhost/006/C"
    ]   
  }
]
% python3 image2epub.py
...
% tree epub 
epub
└── MyPhotosA
    ├── MyPhotosA01.epub
    └── MyPhotosA02.epub

2 directories, 2 files

除此之外,也支援拿 pdf 作為處理,例如把一份 pdf 內所有的圖片都抽出來打包成 EPUB 格式。

估計就告一個段落吧!這個 epub-image-helper 工具發展過程中,發現自己原先想要做的(弄成一包很大的EPUB)並非主流,就漸漸失去熱情。趁熱情還沒散去之前,先弄成一個小 open source 紀念這段2023年12月初,斷斷續續兩個週末的小產出。