KDE Neon 使用心得與踩雷紀錄

前言 年初為了 arc browser 裝了一台 Hackintosh,因為原因又花了點時間裝了 KDE Neon,這邊紀錄一下使用心得與踩雷紀錄。時間線大概是 快快樂樂使用 wsl2 wsl 中踩了不少坑,想要嘗試 unix liked 的系統 好心人提供 arc browser 的邀請,萌生了裝 Hackintosh 的念頭 在 HP Z2 G4 上裝了 Hackintosh,但是沒有事前做足功課,內顯圖形記憶體(P630)始終是 7mb 買了張 amd WX4100 督上去,大幅提昇圖形性能,卻也沒再花時間繼續深入 嘗試在 windows 主機上雙系統 (windows + linux): 一開始直接選擇熟悉的 ubuntu,安裝了 ubuntu desktop 版本,由於是 nvidia 顯示卡,很快的遇到了硬體解碼問題 開始嘗試 nvidia-vaapi-driver,但是遇到了很多問題,最後放棄 想換到 amd 顯示卡,但是又不想花錢,於是想說看看其他發布版是否能解決 從 Linux Mint, Manjaro, KEO Neon 中選擇了同樣是 ubuntu 底,卻是 KDE 團隊維護團隊的 KDE Neon 不出意外的一樣遇到了 nvidia 驅動問題,雖然 firefox 已經可以順利硬體加速,但是 chromium 等仍然無法硬體加速 這時候已經花了不少時間在這個問題上,於是決定換到 amd 顯示卡(內顯) 在 Minisforum UM560 上安裝了 KDE Neon,一切順利,驅動毫無問題,硬體加速也正常 嘗試裝了 ventura theme,讓他稍微好看一點 持續與 wayland 相處,走一步是一步… ❯ neofetch `..---+/---..` raiven@um560 `---.`` `` `.---.` ------------ .--.` `` `-:-. OS: KDE neon 5.27 x86_64 `:/: `.----//----.` :/- Host: UM560 .:. `---` `--.` .:` Kernel: 5.19.0-43-generic .:` `--` .:- `:. Uptime: 1 hour, 2 mins `/ `:. `.-::-.` -:` `/` Packages: 1924 (dpkg), 4 (snap) /. /. `:++++++++:` .: .: Shell: zsh 5.8.1 `/ .: `+++++++++++/ /` `+` Resolution: 2560x1440 /+` -- .++++++++++++` :. .+: DE: Plasma 5.27.5 `/ .: `+++++++++++/ /` `+` WM: kwin /` /. `:++++++++:` .: .: Theme: [Plasma], Colloid-Dark [GTK2/3] ./ `:. `.:::-.` -:` `/` Icons: Cupertino-Ventura [Plasma], Cupertino-Ventura [GTK2/3] .:` `--` .:- `:. Terminal: konsole .:. `---` `--.` .:` CPU: AMD Ryzen 5 5625U with Radeon Graphics (12) @ 2.300GHz `:/: `.----//----.` :/- GPU: AMD ATI 04:00.0 Barcelo .-:.` `` `-:-. Memory: 6265MiB / 31519MiB `---.`` `` `.---.` `..---+/---..` Post Install KDE Neon 解決 key 過舊 當使用 sudo apt update 時可能會發生 ...

2023-06-04 · 4 min · 675 words

golang 樂觀鎖、悲觀鎖 學習筆記與實驗

介紹 改變數值的三個步驟 取出 修改 保存 但這三者間的時間差在不同 process、不同 thread、不同 corutine/goroutine 中會造成競爭危害(race condition)。 可以使用多種發法確保並行(concurrency)處理時保持資料的一致性,這裡介紹的是最常使用的悲觀鎖與樂觀鎖。 悲觀鎖: 總可能發生問題 lock (1) 取值 (2) 修改 (3) 保存 unlock 樂觀鎖: 不會總是發生問題 (1) 取值 if *addr == old { (2) 修改 (3) 保存 return true } return false 悲觀鎖 golang 中主要使用 sync.Mutex 作為悲觀鎖,看似會阻塞住其他 goroutines,但其實 sync.Mutex 中也使用到了 CAS。 sync.Mutex 中有一個 int32 的 state 與 uint32 的 sema(semaphore) type Mutex struct { state int32 sema uint32 } const ( mutexLocked = 1 << iota // mutex is locked mutexWoken mutexStarving mutexWaiterShift = iota starvationThresholdNs = 1e6 ) func (m *Mutex) Lock() { if atomic.CompareAndSwapInt32(&m.state, 0, mutexLocked) { if race.Enabled { race.Acquire(unsafe.Pointer(m)) } return } m.lockSlow() } state: ...

2023-05-14 · 3 min · 503 words

讓 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 ...

2023-05-04 · 2 min · 250 words

如何優雅地批次安裝 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 上的檔案來安裝 ...

2023-05-03 · 2 min · 310 words

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 用來驗證 ...

2023-04-22 · 3 min · 571 words

跟風寫了個使用 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。 ...

2023-03-17 · 2 min · 242 words

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),更省顯示卡資源。 ...

2023-02-24 · 2 min · 231 words

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 中查看 ...

2023-02-13 · 3 min · 507 words

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。 ...

2023-01-26 · 2 min · 344 words

後端工程師用 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 連線。 ...

2023-01-26 · 2 min · 306 words