讓 BOOX 也使用繁體中文辭典

由於最近讀原文書讀得挺辛苦,邊用電子閱讀器看書,騰不出手用手機查字典,內建的辭典又只有英文翻譯簡體中文,在網上衝浪也找不到繁體中文的 mdx 英漢辭典可以直接使用。 所需依賴 任何英漢辭典 文內以 BOOX 內下載的英漢辭典,參考教學。 python 環境,用以安裝 mdict-utils 經測試後 windows 與 wsl 中均能完成,文內 python 環境以 wsl 為主。 任何繁簡轉換軟體 文內以新發現的 ConvertZZ 最為 GUI 簡轉繁示例。 文末有使用 OpenCC 作為 CLI 示例。 主要流程 將 mdx 拆成 txt 簡轉繁 將 txt 包成 mdx 安裝 安裝 mdict-utils ❯ pip install mdict-utils Defaulting to user installation because normal site-packages is not writeable Collecting mdict-utils Downloading mdict_utils-1.3.12-py3-none-any.whl (36 kB) Collecting xxhash Downloading xxhash-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (212 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 212.5/212.5 KB 1.6 MB/s eta 0:00:00 Collecting tqdm Downloading tqdm-4.65.0-py3-none-any.whl (77 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 77.1/77.1 KB 7.4 MB/s eta 0:00:00 Installing collected packages: xxhash, tqdm, mdict-utils Successfully installed mdict-utils-1.3.12 tqdm-4.65.0 xxhash-3.2.0 unpack 將英漢辭典重新命名為 dict.mdx ...

如何優雅地批次安裝 Nerd font 字型

fonts repo 接觸 wsl/ubuntu 的這幾年,經常會需要安裝 zsh 以及字型,因此誕生了 cheat sheet,久而久之連下載->解壓縮->安裝這個過程,都懶了。 於是寫了一個批次下載並安裝最新版本的 Nerd Fond 字型的 shell script,讓 wsl 可以安裝 windows 的字型,linux 可以安裝 linux 字型。 #!/bin/bash declare target="linux" declare repo="ryanoasis/nerd-fonts" declare -a fonts=( BitstreamVeraSansMono CodeNewRoman DroidSansMono FiraCode FiraMono Go-Mono Hack Hermit JetBrainsMono Meslo Noto Overpass ProggyClean RobotoMono SourceCodePro SpaceMono Ubuntu UbuntuMono ) ARGS=`getopt -o p --long windows -- "$@"` if [ $? -ne 0 ]; then echo "getopt failed: " $ARGS exit 1 fi eval set -- "${ARGS}" while true do case "$1" in -p|--windows) target=windows shift ;; --) shift break ;; esac done get_latest_release() { echo $(curl --silent "https://api.github.com/repos/$@/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') } function install_linux_fonts() { local fonts_dir fonts_dir="${HOME}/.local/share/fonts" if [[ ! -d "$fonts_dir" ]]; then mkdir -p "$fonts_dir" fi mv $@/*.ttf $fonts_dir/ # fc-cache -fv } # Install font for the current user. It'll appear in "Font settings". function install_windows_fonts() { local dst_dir dst_dir=$(wslpath $(cmd.exe /c "echo %LOCALAPPDATA%\Microsoft\\Windows\\Fonts" 2>/dev/null | sed 's/\r$//')) mkdir -p "$dst_dir" local src for src in "$@"; do local file=$(basename "$src") test -f "$dst_dir/$file" || cp -f "$src" "$dst_dir/" local win_path win_path=$(wslpath -w "$dst_dir/$file") echo $win_path reg.exe add \ "HKCU\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts" \ /v "${file%.*} (TrueType)" /t REG_SZ /d "$win_path" /f 2>/dev/null done } function main() { local version version=$( get_latest_release $repo ) local tmp_dir tmp_dir="$(mktemp -d)" trap "rm -rf ${tmp_dir@Q}" INT TERM EXIT for font in "${fonts[@]}"; do zip_file="${font}.zip" download_url="https://github.com/$repo/releases/download/${version}/${zip_file}" echo "Downloading $download_url" wget -q --show-progress -P "$tmp_dir" "$download_url" # unzip -o means replace file without asking. unzip -o "$tmp_dir/$zip_file" -d "$tmp_dir" rm "$tmp_dir/$zip_file" done find "$tmp_dir" -name '*Windows Compatible*' -delete if [ "$target" = "linux" ] then install_linux_fonts $tmp_dir elif [ "$target" = "windows" ] then install_windows_fonts $tmp_dir/*.ttf fi } main echo -e '\033[0;32m' echo 'Fonts successfully installed.' echo -e '\033[0m' 若沒有要改目標字型也可以直接透過 github 上的檔案來安裝 ...

golang 中使用 Line LIFF 實作 Single Sign-On

文章中的程式碼放在https://github.com/omegaatt36/line-verify-id-token中。 Requirements Line Login Channel channel id channel secret Line LIFF APP 用 liff.getIDToken() 獲取 ID Token 在現代網站中,單一登錄 (Single Sign-On, SSO) 已經成為了一個普遍存在的功能,它能夠讓使用者在不同的應用程式和服務之間自動地登錄,而不需要再輸入帳號和密碼。這樣可以方便使用者的使用,並且也能夠增加安全性,減少帳號密碼被盜用的風險。 我們將使用 Golang 語言來實作單一登錄功能,並且使用 Line LIFF 來進行身份驗證。在此之前,我們需要先了解幾個概念。 Line LIFF (Line Front-end Framework) 是一個由 Line 提供的 Web 應用程式框架,開發者可以使用它來建立 Line 的客戶端應用程式。使用 Line LIFF 開發的應用程式可以在 Line 客戶端中被直接執行,而不需要額外安裝或下載。此外,Line LIFF 還提供了一些功能,例如使用者的身份驗證、分享資料等等。 JWT (JSON Web Token) 則是一種開放標準,用於在不同系統之間安全地傳輸訊息。它通常用於認證和授權,因為它可以確保傳輸的訊息是可信的,而且在傳輸過程中不會被竄改。 我們可以使用 Line 的 Verify API,同時也可以選擇後端自己驗證,解出 jwt 中的資訊。 我們的目的是拿到每個使用者在 Line 的 UserID,做為身分識別。於是根據 Line 提供的 JWT 欄位對應,定義一個結構用來存放驗證後的資訊。 // DecodedIDToken defines decoded payload by id token. type DecodedIDToken struct { Amr []string ChannelID string Email string ExpiredAt int64 IssuedAt int64 Issuer string Name string Picture string UserID string } 接著撰寫一個驗證 ID Token 的 function 用來驗證 ...

跟風寫了個使用 OpenAI API 的 Telegram Chat Bot

前言 放在最前面 Github repo 原本打算使用別人寫好的 bot,免費的版本均是透過儲存 cookies 的方式,直接透過 ChatGPT 網頁建立新的 「Chat」。好景不常,OpenAI 馬上把登入頁面到聊天頁面中間安插了類似 reCaptcha,來驗證是否為真人。看到有好心人提供了 go 版本的 OpenAi API,就打算自己寫一寫,順便當作 《Clean Architecture》 的讀後作業。 依賴注入 架構圖待補 我需要對 OpenAI 詢問,並用 stream(逐字)的方式回給我,也需要對 Telegram 逐字回答。 在這個 8931bf 版本中,很明確定義對於 OpenAI 與 Telegram 的 usecase chatgpt_usecase.go // ChatGPTUseCase defines ChatGPT send question use case. type ChatGPTUseCase interface { Stream(ctx context.Context, question string) (<-chan string, <-chan error) } telegram_usecase.go // TelegramUseCase defines telegram send message use case. type TelegramUseCase interface { SendAsLiveOutput(chatID int64, feed <-chan string) error } 在 *_repository.go 進行實作。並在 main.go 中依賴反轉,將實作注入近 bot service。 ...

Logitech Media Server 遷移紀錄:從 Bare Metal 到 Docker 再到 Podman

2021 年公司開始實施 322 WFH,少了通勤的時間,在家的時間也多了,就想在上班時也能好好對待自己,雖然是木耳但始終會想知道,網路上說的獨立訊源減少雜訊是有多重要,亦或只是玄學?於是誕生了Raspberry pi 4 + piCorePlayer 7.0.0 折騰筆記這篇筆記,到現在這個部落格的累積曝光最高的也是因為這篇吧。 雖然說現在已經出到 8.2.0,但也已經是 2022 年六月的版本了,起初因為 raspberry pi 4b 便宜而使用 piCorePlayer,後來也因 raspberry pi 4b 漲價(漲幅超過 100%)進而不使用 piCorePlayer,不知道官方後來沒更新了是因為樹莓派太穩定,還是真的太貴了…。 從 Bare Metal 到 Docker 當時在學習 HomeLab,首先是從 portainer 開始玩,也因此誕生了 logitech media server 搭配 docker 實現雙機分離。後來也用著同樣的 image 將 lms 建在 k8s cluster 內,遇到的比較髒的問題是 nginx 的 port 用非正式的方式解決。 這時候其實已經不在乎 logitech media server 是否帶來更好的音質了,也沒有連動 NAS 的音樂,主要是使用 Youtube Plugin 播放 Youtube 上的內容(即便有訂閱 Youtube Premium)。以及使用 Podcast Plugin 收聽 podcast。 使用 docker 的好處不外乎一個字,省,於是我把 raspberry pi 4b 也給賣了。 從 Docker 到 Podman 與 LXC 2022 年台灣疫情大爆發,公司也從 322 變成全遠端,但也在 2022 下半年恢復 322,於 2023 年正式恢復正常進辦公室。在這期間發現 logitech media server 使用 docker 做為執行環境,除了省物理機的錢(相較 bare metal),更省顯示卡資源。 ...

WSL2 中使用 systemd 管理 podman 的 container

原本使用 wsl-distrod 來作為 wsl 中 systemd 的實現方式,後來 microsoft 宣布 wsl 支持 systemd 後,distrod 等等 repo 就沒有在更新了呢,是巧合嗎?我不這麼認為。 這篇簡略紀錄 wsl2 中啟用 systemd 作為 process 管理工具以及配合紅帽推出的 podman 來取代(斷捨離)docker desktop。 環境 wsl2 + ubuntu 22.04 ❯ neofetch .-/+oossssoo+/-. raiven@raiven `:+ssssssssssssssssss+:` ------------- -+ssssssssssssssssssyyssss+- OS: Ubuntu 22.04.1 LTS on Windows 10 x86_64 .ossssssssssssssssssdMMMNysssso. Kernel: 5.10.43.3-microsoft-standard-WSL2 /ssssssssssshdmmNNmmyNMMMMhssssss/ Uptime: 3 hours, 10 mins +ssssssssshmydMMMMMMMNddddyssssssss+ Packages: 2005 (dpkg), 4 (snap) /sssssssshNMMMyhhyyyyhmNMMMNhssssssss/ Shell: zsh 5.8.1 .ssssssssdMMMNhsssssssssshNMMMdssssssss. Theme: Adwaita [GTK3] +sssshhhyNMMNyssssssssssssyNMMMysssssss+ Icons: Adwaita [GTK3] ossyNMMMNyMMhsssssssssssssshmmmhssssssso Terminal: Windows Terminal ossyNMMMNyMMhsssssssssssssshmmmhssssssso CPU: AMD Ryzen 9 5900X (24) @ 3.700GHz +sssshhhyNMMNyssssssssssssyNMMMysssssss+ GPU: dbac:00:00.0 Microsoft Corporation Device 008e .ssssssssdMMMNhsssssssssshNMMMdssssssss. Memory: 1427MiB / 15966MiB /sssssssshNMMMyhhyyyyhdNMMMNhssssssss/ +sssssssssdmydMMMMMMMMddddyssssssss+ /ssssssssssshdmNNNNmyNMMMMhssssss/ .ossssssssssssssssssdMMMNysssso. -+sssssssssssssssssyyyssss+- `:+ssssssssssssssssss+:` .-/+oossssoo+/-. wsl2 中啟用 systemd 請確保 wsl2 的版本是 version 2,可以在 cmd/powershell 中查看 ...

gin 搭配 html/template 包實現動態生成 HTML 文件

起因 在網站註冊流程中,若是用信箱驗證,網站會寄送一封驗證信到指定的電子信箱。信中可能含有 verify token 或是直接是寫好的 verify URL。至於實作方面我們可以透過 Go 1.16 推出的 Embedding Files 搭配 html/template,實現動態生成 HTML 信件,用以寄送至指定信箱。 本篇內容的詳細程式碼可以到 github 頁面查看。 實作 資料夾結構: project/ ├─ templates/ │ ├─ template.go │ ├─ success.tmpl │ ├─ verify.tmpl ├─ main.go templates project/templates/template.go 在包內宣告私有變數,透過 Embedding Files 讀出目錄內的所有檔案。 package template //go:embed * var f embed.FS 宣告需要被轉換成 HTML 模板的檔案名 TemplateName,可以用 go-enum 來自動生成變數。並將其註冊進陣列 _TemplateNameNames 內。 package template // ENUM( // success.tmpl // verify.tmpl // ) type TemplateName string func (x TemplateName) String() string { return string(x) } var _TemplateNameNames = []string{ string(TemplateNameVerifyTmpl), string(TemplateNameSuccessTmpl), } // TemplateNameNames returns a list of possible string values of TemplateName. func TemplateNameNames() []string { tmp := make([]string, len(_TemplateNameNames)) copy(tmp, _TemplateNameNames) return tmp } const ( TemplateNameVerifyTmpl TemplateName = "verify.tmpl" TemplateNameSuccessTmpl TemplateName = "success.tmpl" ) 最終將 embed files 與檔案名丟給 html/template 包請他們我們轉換成 template。 ...

後端工程師用 Golang 在 WSL 中寫 GUI 是不是搞錯了甚麼 - 安裝篇

由於先前將 raspberry pi 4b 給賣掉了,bmx280 中基於 bme280 而產生的 exporter 因此失去戰鬥能力,藉此玩玩 tinygo,透過 serial port 透過 raspberry pi pico 對 bme280 讀取溫溼度。在開發過程中發現,WSL 中,command line 輸入: GOOS=windows go run main.go 這樣會吃 windows 的環境,比如讀 serial port 需要 COM port,這樣就不是去讀 /dev/ttyS4 而是讀 COM4,這 cross compile 也太方便了吧…。 後續在工作上接收了需要寫一個 websocket server/client,而 client 需要: 有圖形化最好 (TUI or GUI) 跑在 windows 桌面上 ,開發過程中再次感受到 cross compile 的方便,有點慶幸是在這個一個方便的時代學習敲鍵盤(? Requirement Golang 1.16+ () Docker or Podman 在 WSL 中建立 X Window System 環境 因為我的 Golang 環境是基於 WSL,於是我需要先準備在 WSL 中能跑的 GUI 環境。 在 Unix like 使用的 GUI 被稱之為 X Window System 或 X11 或 X,以所需的情形來說即是需要在 Windows 中啟動 X server,來與 WSL 中的 X client 連線。 ...

解決 VM 關機時等待容器關閉

[ *] A stop job is running for libcontainer container xxxxxxxx (10s / 1m30s)_ 過去 kubernetes 還跟 docker-shim 手牽手時,在關閉 k8s node vm 時常常出現等待 docker-shim 關閉,直到一分三十秒被 time out 才正確關機。若是開發機就當作去尿尿的時間就好,但若是重要的環境停機備份,或是斷電時靠 UPS 提供電源等待系統關機,那浪費時間就不好了。 這次在 home lab 中採取省電措施,不用 1 master + 1 node 的組合,直接使用 k3s 作為家用 kubernetes 的實驗環境。但依然在關機時會需要等待 containerd-shim 等等被 time out kill 才會完成關機。 若是沒有做特別的設定,或是沒有過分的 stateful pod,找到了 k3s issue #2400 中的解決方法 Stopping K3s To allow high availability during upgrades, the K3s containers continue running when the K3s service is stopped. ...

在 AWS 上使用 EC2 建立 FRP 玩玩內網穿透

前言 TL;DR 2022 年上旬熱衷於軟路由,在 Raspberry Pi 4b 上裝了 openWRT 來玩,使用 USB 網卡作為 LAN NIC,雖然使用上完全沒有問題,但透過 USB 始終有個芥蒂,「就不能多個 pci-e 來接網卡嗎」,於是衝動順勢買了 Mikrotik RB5009UG+S+IN。 RB5009G 為 arm64(ARMv8),系統為 RouterOS v7,透過 ZeroTier 插件可以實現內網穿透以及 VPN,一直以來可在外連回家裡做事,連 Jellyfin 使用起來都很順。 事出必有因,ZeroTier 的服務器在未知的地方,VPN 的設定也是在網頁上設定,即便不需要太過擔心,但若是 ZeroTier 被攻擊,那自己的內網也危險了。後來又遇到一次,在某處透過 Windows rdp 連回家開 VScode 做事,但敲鍵盤會有一到兩秒的延遲,加劇了需要替換掉 ZeroTier 的想法。 frp 是一個由 golang 寫出來的 reverse proxy…,其他的到 github 看比較清楚 XD。 這篇文章主要是透過 frp 建立內網穿透,雖然大部分都在建立 AWS EC2 instance,frp 的建立實在是非常簡單,VPN (maybe WireGuard?)的實現會另外再寫一篇。 事前準備 一個 AWS 帳號 一台 linux 主機作為 frp client 建立 Amazon EC2 建立執行個體 建立好帳號後,進入 AWS console,點擊 EC2。 點擊啟動執行個體 取名為 frp-tunnel 選用自己習慣的 linux distro,這邊我習慣使用 ubuntu,故選 ubuntu 22.04。 執行個體類型選 t2.micro,金鑰由於安全因素,請建立新的金鑰對(key pair) 由於我使用 ubuntu 22.04,故使用 ED25519 來加密(RSA 已被淘汰)。下載下來的 pem or ppk 需要好好保存,未來不能再下載。 網路設定的部分,ssh 的 source 使用我的IP,不要一開機就被陌生人打穿。 設定存儲的部分,若是使用 AWS Linux 的話可以預設 8GB 沒問題,我自己的 ubuntu vm 習慣 20GB,所以設成 20GB。 最後確認一下右邊的摘要,就可以點擊啟動執行個體。 建立完成後就會轉跳至完成頁面。 ssh 連線至 EC2 在 console 頁可以看到剛剛建立的 EC2 instance,點擊可以進入 instance 頁面。 ...