pretty code

2022年1月29日 星期六

Use Qt5 on Kobo

從 Qt 5開始,不像 Qt 4 擁有一個 Qt Windows System (QWS),取而代之的是 Qt Platform Abstraction (QPA),這是為了方便移植 Qt 去各個平台。

Kobo 為閱讀器軟體寫了一個 QPA,名稱是 kobo,故可以看到 Nickel 啟動時,會帶參數 "-platform kobo" 來啟動相關程式。


我們想要撰寫自己的 QPA,可以參考下面。

官方資料,目前資料不多,只能看 code


網友寫的


曾試著使用 Kobo 自己的 QPA,要設定變數 export QT_PLUGIN_PATH=/usr/local/Kobo,雖然有寫了一個簡單的 Hello World App,但啟動時看不到任何視窗,也許如國外網友所說,QPA 跟 Nickel 綁得太緊無法直接拿來使用。

看來還有很長一段路要走 ~~~

2022年1月25日 星期二

Shell Script 速成

記錄一下常用語法,懶得每次都要 Google 或是看 PDF 電子書。

變數篇

變數宣告
ABC=XXXXXXX
$ABC

要傳遞出去變環境變數
export ABC=XXXXXX

雙引號中的變數會被展開,單引號則是普通字串
"${ABC}/${DEF}"

上次指令結果
$?

將指令結果變成變數
ABC=$(ls | grep XX) or ABC=`ls | grep XX)

取得不含指令本身之目錄名稱,%表示從後面找最短匹配並丟掉
$(dirname $0)
${0%/*}

Array
$Ans=(1258 1414)

取 Array 第一個元素
${Ans[$i]}

取得 Array 元素個數
${#Logs[@]}


流程篇

[ ] 前後要留一個空格

隱形 if ~ then 語法
$ABC 存在則做某事,-d 則是表示目錄
[ -e $ABC ] && do something

if 語法,有特殊字元要跳脫,例如大於或小於
if [ "$? == "0" ]; then
    echo "ok"
else
    echo "error"
fi

不需跳脫 <
if [[ $ABC < $DEF ]]; then
    echo '$ABC < $DEF'
fi

for loop 使用
for ((i=0; i<$max; i=i+1))
do
     echo $i
done

Logs=("abc" "def")
for log in ${Logs[@]}
do
    echo $log
done

2022年1月23日 星期日

私密社團的必要性

一直以來都很討厭 FB 私密社團的設定,想要瀏覽討論,還得先加入社團,遇到這樣的限制,我連想要看的心情都沒有了。

如果是一般人就算了,明明是賣產品的,不知為何要設定私密?真心讓我想不通。

也許、應該、有機會讓我想要購買新機的,但就因為我看不到討論,故少了這麼一次機會。

當然我沒有怪公司,只是如果是我開公司,或是負責行銷方面的業務,我也會選擇私密社團嗎?

2022年1月22日 星期六

沒事還是少逛 PTT 八卦版

昨天中午在逛八卦版時,又看到一個心酸的個案,雖然我本人也是阮囊羞澀,想了想還是把電競筆電剩下的一半預算拿去做好事,不然個案年關難過呀!

再見了我的筆電,再見了我的暗黑 2 重製版,想要玩到購買的新遊戲,我看是沒機會了XD

順便檢視一下去年的費用支出,我應該要再省一點的,記帳完都沒在檢討的,這樣有跟沒有沒啥兩樣。

2022年1月19日 星期三

Kobo 字型顯示問題分析

今天在討論區看到有網友在發問為何 Kobo 無法顯示兩種字型?感覺這個問題很有意思,於是便分別在 Readmoo 和 Kobo 買了同樣的書,書名為《二人生活》。

初步分析結果,Readmoo 有分別針對不同句子指定字型,例如 body 是 gfont,特別的句子則是 kfont,而 kfont 我猜是楷體的意思,應該是 Readmoo 內部自己定義的。

至於 Kobo 其 CSS 檔案確實沒有指定第二種字型,只有單純指定顏色。

故我針對某句加了 Kobo 的內建字型來實驗,經實測還是無法指定字型。

網路查了一下,需使用 kobopatch 才能解決此問題。

使用 "Un-Force user font-family in KePubs:" 為關鍵字去查詢,終於在 kobopatch 的 yaml 檔案中看到註解。原來原本 Kobo 是可以使用兩種字型,但在開放使用者自訂字型後,Kobo 使用了一種簡單粗暴的方法來把原本電子書裡面的字型強制改成使用者的自訂字型,故才產生無法同時顯示兩種字型的問題。

長知識了,還好我對顯示多種字型沒什麼感覺,我只要可以顯示我的 Kindle 圓體就好了XD

2022/01/19 更新

本著實驗的精神,實際來試一下 kobopatch 的流程,雖然我是寫程式的,還是覺得有點複雜,跟我當初第一次閱讀 NickelMenu 的說明文件一樣XD

kobopatch 說明文件有提到,需要去該網站下載對應版本的韌體(kobo-update-4.30.18838.zip),並放入 src 資料夾內,但我進去該網站時,我的防毒軟體不知為何會跳出有毒的提醒?雖然我是相信那些開發者的,但既然我本來就有 telnet 進去機器的能力,簡單下個指令把我要的 .so 檔 tar 出來就好,再包成 kobopatch 程式要求檔名的 zip 檔(kobo-update-4.30.18838.zip)。

tar czvf KoboRoot.tgz -c /usr/local/Kobo libnickel.so.1.0.0

接著修改根目錄的 kobopatch.yaml,因為我想使用 override 的方式,避免去動原本 src 裡面的 yaml 檔案。


最後則是點擊 kobopatch.bat,如果沒有錯誤,在 out 資料夾便會出現我們常用的 KoboRoot.tgz,之後再用原本 patch 的方式更新系統即可。

patch 後的 libnickel.so.1.0.0 的差異如下:


接著修改 Kobo 原書的 CSS 檔案,簡單在原本顏色的 class 增加字型設定。


最後呈現出來的結果。

2022年1月15日 星期六

安裝 NickelMenu、KOReader、Plato

01. 安裝 NickelMenu

先去 NickelMenu 網址下載最新檔案,檔案名稱為 KoboRoot.tgz,將閱讀器接在電腦上,接著將檔案放在閱讀器磁碟機的 ".kobo" 資料夾下,然後退出閱讀器,閱讀器應該會重開機,重開機後就安裝完畢了。

然後將閱讀器再接上電腦,閱讀器磁碟機應該會多出一個 ".adds/nm" 的資料夾(注意 ".adds" 是一個隱藏資料夾,需要在檔案總管中設定顯示隱藏檔案才能看見),裡面有一個 doc 檔案,會列出一些 NickelMenu 支援的指令,可以參考它添加指令到自己的設定檔,並將設定檔放在同層目錄下,我的習慣是命名為 config。

為了之後方便,在退出磁碟機之前,先去 Kobo 自己的設定檔最後面(.kobo/Kobo/Kobo eReader.conf),使用記事本打開它並添加下面的設定,這樣會讓 Kobo 不去掃瞄某些資料夾,避免 Kobo 把第三方軟體當做檔案,顯示在我的書籍中。

[FeatureSettings]
ExcludeSyncFolders=(\\.(?!kobo|adobe).+|([^.][^/]*/)+\\..+)

02. 安裝 KOReader

KOReader 網址下載檔案,檔名為 koreader-kobo-v2021.12.1.zip,解壓縮後,裡面會有一個 koreader 的資料夾,整個複製到閱讀器的 ".adds" 資料夾裡。

03. 安裝 Plato

Plato 網址下載檔案,檔名為 plato-0.9.24.zip,解壓縮時選擇解壓縮到 "plato-0.9.24" 資料夾,將整個資料夾複製到閱讀器的 ".adds" 資料夾裡,我的習慣會重新命名為 "plato" 資料夾。

做完步驟 2 和步驟 3 後,整個目錄結構會如下所示。


04. 設定 NickelMenu 設定檔

所謂的設定檔其實就是一個沒有副檔名的純文字檔(沒看過作者的Code,最好還是用 ASCII 或是 UTF-8 編碼較保險),我們可以直接用記事本新增編輯,只要在設定檔案中增加下面指令,就可以在首頁分別啟動 KOReader 和 Plato 了。

menu_item :main    :KOReader                 :cmd_spawn          :quiet :exec /mnt/onboard/.adds/koreader/koreader.sh
menu_item :main    :Plato                    :cmd_spawn          :quiet :exec /mnt/onboard/.adds/plato/plato.sh

config 檔案應該如下圖所示。


或者也可以去此網站,按右鍵另存新檔,並選擇所有檔案類型,此時下載下來的便會是一個沒有副檔名的 "config" 檔案,接著把它放到 ".adds/nm" 資料夾中即可。


如何移除 NickelMenu

假設閱讀器插上電腦後,其磁碟機代號為 f:,則在 f:\.adds\nm 資料夾中新增一個檔案名稱為 "uninstall" 的檔案,注意沒有任何附檔名,接著讓閱讀器重開機,在開機的過程中,NickelMenu 看到 "uninstall" 的檔案,便會自己執行反安裝的動作。

2022年1月14日 星期五

懶惰不是病,但懶下去會要人命

可能是我螢幕有設定濾藍光的緣故,每次在終端機下要看目錄名稱都很吃力,反正有 tab 可以補完我也不以為意!

今天終於受不了了,上網查了一下如何更改設定,終於可以看清楚目錄名稱了XD

add LS_COLORS in $HOME/.bashrc

export LS_COLORS=$LS_COLORS:'di=0;92:'

2022年1月13日 星期四

絕世武功隨隨便便都要練個好幾十年

一直以為要成功了,沒想到還是不如所願,難過 >_<


Warning:想要在 Kobo 上使用 Qt,要使用 QPA。

2022年1月9日 星期日

KoboFileServer 開發記錄

上個星期在釐清了我的需求後,覺得自己比較需要的是 Wi-Fi 傳檔的軟體,而不是 GUI App for Google Drive,故利用了幾天晚上的時間,把 Wi-Fi 傳檔的軟體開發出來,也順利的執行在 Kobo Elipsa 上。

過程中有遇到一些問題,也看了很多國外討論網站,故已經把相關資訊都獨立寫成一篇文章了。但有些是針對 KoboFileServer 的注意事項,想了想還是另寫一篇專文,之後要增添新功能時就比較方便了。

01. 觸發 Import Book,目前是用 NickelMenu 的方法,雖然已經知道掛載 SD 會重複檔案的原因,但暫時是先用 NickelMenu 的方式解決,如果想要減少此操作步驟,可能是想辦法 command line 觸發 action,就像原本呼叫 refresh.sh 的方法一樣,應該是去參考 NickelDbus,似乎在安裝完後有一支 /usr/bin/qndb 可以被呼叫做一些事,我想這樣就可以解決了,可以參考 KoboMail 專案。

02. Form 上傳時,如果超過設定的 32M 會改用 disk 暫存,在 /tmp 下,會看到有一個類似 multipart-xxxxxxxxxx 的檔案。既然是 disk 速度就會慢,故可以考慮視情況微調,以 Elipsa 來說,我覺得可以使用到 200 MB。

03. 使用 Wi-Fi 雖然很方便,但網路速度影響很大,同樣一本 70 MB 的書,從 11 min 到 38 秒都有可能,後者的數據反而是用手機傳的(手機分享網路給 device),可見我家的無線基地台有點爛。


04. 原本已經架好 cross-compiler 的環境,以為可以比照辦理呼叫 libnickel.so 來 import books,沒想到該函數有用到其他 Qt Lib,除了設定 LD_LIBRARY_PATH 外,還必須寫成 QApplication 才行。不過至少確定 x-tools 可以跑在 Windows 10 的 Linux subsytem 裡。


後來發現,如果是寫成 QApplication,會遇到無法執行的問題,會缺少 xcb 的 PLUGIN,找了一下,不論是開發環境或者是 Kobo 系統裡面都找不到相關檔案,目前暫時無解。

Warning:想要在 Kobo 上使用 Qt,要使用 QPA。

2022年1月5日 星期三

開發或使用 Kobo 第三方軟體注意事項

陸續開發了兩套軟體,碰到了一些問題,記錄一下,以供後人參考。

Note:有新發現會不定期更新。

01. 如果是不需要 GUI 的程式,可以使用 Go 並設定跨平台編譯即可。

02. 如果需要 GUI,一些軟體的做法是先把東西畫到 framebuffer,再一次更新,就不會有閃爍的問題,可以參考 KOReader plugin 或是 application 的作法,另外,寫一個活在 KOReader 裡的軟體,就可以使用 KOReader API 開發 GUI App,開發語言是 Lua。

雖然沒有很懂架構,但寄生在雲端儲存 App 裡面,開啟一個對話盒看起來沒有問題。


03. 如果是透過程式將檔案加到 device,要觸發 device 重新掃瞄檔案系統,有兩種方式:

a. 掛載一個假的 SD,並通知 sd add event to /tmp/nickel-hardware-status。
b. 利用 /tmp/nickel-hardware-status,觸發 usb plug add event,不用真的插線,但使用者需按下連接,接著 sleep 幾秒,再觸發 usb plug remove event。這樣 device 就會重新掃瞄了。

Warning:掛載 SD 方法,之後如果插拔 USB,會讓書出現 2 次,原因是我們把 /mnt/onboard 下的資料夾掛載到 /mnt/sd,但插拔 USB 時,又會去掃 /mnt/onboard,故同樣的檔案才會出現 2 次。我們可以改用 NickelMenu 內建 action 去觸發,查了一下,KoboCloud 也有這種問題,但因為它把檔案下載到 .add 目錄,故用 ExcludeSyncFolders 的方式排除。


04. Kobo 只有在退出 USB 或是使用內建瀏覽器下載檔案時會觸發重新掃瞄檔案系統,也可以直接對 database 動手腳,我還看過有用 database trigger 的,但後者比較難,相容性也不好。

05. 英文網站常會看到 Nickel 這個單字,就是指 Kobo 的系統。

06. 以前的 Kobo 不會對隱藏目錄建立索引,但從版本 4.17 開始會處理隱藏目錄,故有用到 Kobo 支援格式檔案的第三方軟體的檔案就會被顯示在我的書籍中,當利用排除方式處理後,Kobo 會把不再索引的檔案砍掉,這會造成第三方軟體因為缺少檔案而無法啟動,故需要重新安裝軟體。

[FeatureSettings]
ExcludeSyncFolders=(\\.(?!kobo|adobe).+|([^.][^/]*/)+\\..+)

07. Kobo 設定檔在某些不知名情況下會被重設,故偶爾會造成系統異常,如果有看到似乎是重新設置系統的畫面,可以考慮直接關機,重開機後也許就不需重設帳號。

/mnt/onboard/.kobo/Kobo/Kobo eReader.conf

08. Kobo 不支援需要密碼的 PDF 檔案,故重新掃瞄檔案系統看不到檔案是正常的。

09. 下面這套軟體似乎是用 Qt 寫 App,也有提到跨平台編譯?


10. Send to Kobo app,該 app 會自動收信到 device。 


11. NickelDBus 是一個使用 Linux D-Bus(軟體訊息匯流排)協定的工具,可以觸發它去做一些事,比如重新掃瞄檔案系統,設定 Wi-Fi 等,以 Qt 和 C++ 開發。


12. NickelMenu 底層的原理,稍微 trace 一下,應該就是透過 NickelHook 去呼叫 libnickel.so 裡面的函數,來達到相關功能。也就是 Linux 的 dlopen and dlsym(使用動態連結函式庫的 c function),其實作可詳 NickelHook / nh.c,故要在 Golang 使用,可能只能走 cgo 模式了。


Warning:沒那麼簡單,libnickel 有用到 Qt Lib,以 import book 來說,還要寫成 QApplication 才能呼叫成功,但我最後還是沒試成功。



Warning:想要在 Kobo 上使用 Qt,要使用 QPA。


13. Cross-Compile C code.

a. git clone https://github.com/koreader/koxtoolchain
b. ./toxtoolchain/gen-tc.sh kobo
c. The tool is in /home/xxx/x-tools/arm-kobo-linux-gnueabihf
d. Before you compile your code, set up your env.

export PATH=/home/xxx/x-tools/arm-kobo-linux-gnueabihf/bin:$PATH
source /home/xxx/koxtoolchain/refs/x-compile.sh kobo env

e. Use arm-kobo-linux-gnueabihf-gcc to build your code.

f. 執行時如果需要外部動態函式庫,可以在編譯時指定路徑給 gcc,"-Wl" 是告知 gcc 後面 "-rpath" 是給 linker 用的,"," 代表空白好讓 linker 知道。

-Wl,-rpath,/usr/local/Kobo -Wl,-rpath,/usr/local/Qt-5.2.1-arm/lib

14. 如果要 compile Qt,可以用 NickelTC,高手已經把環境包好。

15. 判斷機器型號的方式,開啟 /mnt/onboard/.kobo/version,檢查最後 3 碼即可,比如說 387 就是 Elipsa,可以看 plato.sh 裡面的判斷方式。



大概就是這些吧 ...

2022年1月1日 星期六

手裡拿著一把槌子,看什麼都覺得是釘子

寫程式的時候很容易掉到思考陷阱中!

昨天想要測試在 Windows 下抓螢幕及模擬滑鼠點擊動作,雖然我 10 幾年前都是用 Win32 API 搞定,但時代在進步,既然多會了幾種語言,就是想要使用這幾年常用的語言來達到我的需求。

我的目標就是想要快速的實作出來,故才會掉入思考陷阱。

一開始就覺得 Node.js 應該有一堆套件可用,但在編譯時遇到問題,單看錯誤訊息也不是一下可以解決的事。

接著使用 Golang,也是遇到編譯問題,看來不管是 Node.js 還是 Golang,底層還是呼叫 Win32 API,故才會有這些編譯的問題(謎之音,那一開始用 C 不就好了,搞不好只要 15 分鐘)?還好作者有提示使用的 C Compiler,安裝了作者使用的 Compiler 後馬上就搞定。順便一提,這兩個功能我一開始是分兩次搜尋,其實最後一套就可以搞定這 2 個需求。


花了約 2 個小時完成概念,行數只有 86 行,大部份的時間都在找套件及解決編譯問題。雖然有達到我想要做的事,但好不好用那又是另外一個故事了XD

直到今早我才想到,我的目標是想要快速實作出來,為什麼要捨近求遠,一開始直接去抄我以前寫的 C code 不就搞定?

另外則是執著在想要使用 Node.js 和 Golang,明明我以前也用過 AutoIt 來解決一些 MIS 工作的痛點,但我昨天就是沒有想到該語言。

我想,寫程式前如果多想一點,應該可以少走很多冤枉路XD

世界上不存在完美的電子紙閱讀器,因為看書的人就是小眾市場

從以前對每台新出的電子書閱讀器都抱有滿腔的期待,到現在變成只是淡淡的喔了一聲,絲毫不以為意!原因無他,那就是不可能有一台完美的電子書閱讀器,因為看書的人就是那麼少!廠商不太可能為了這種沒賺錢的生意,花費心血設計一台 90 分的電子書閱讀器(是的你沒看錯,我不覺得現在的閱讀器有到 90 分的程度,但這是以一台什麼事都可以做的閱讀器的基準來評分),如果想要走精品路線,我也懷疑有多少人願意買單?

每個人對完美的閱讀器標準不同,我也降低了我的標準,故我希望擁有 3 種不同形式的閱讀器,來滿足我的個人需求:

01. 一台國產的電子紙閱讀器手機。

我希望是一台國產或是不要偷傳封包的機器,畢竟我真的是要當手機使用,轉帳什麼的對手機來說是家常便飯,故安全性很重要。另外效能也不能太差,故處理器至少要是聯發科等級,如果能是高通當然是更好,至於電量可以撐過一天即可。

海信 A5 雖然效能 OK,但因為不知名封包,故我也無法當手機使用。


02. 一台 6 吋的可上網電子書閱讀器(4:3 比例的螢幕,非手機狹長形的)。

6 吋是最適合手拿的尺寸,也是最適合看流式 EPUB 的尺寸,想要簡單看個 PTT,FB 或是其他網路文章也不會很吃力。

其實 1 和 2 的需求其實很像,重點就在安全性和效能。


03. 一台 10 吋的可上網電子書閱讀器。

10 吋加上裁邊功能,這樣 PDF 也可以擁有更好的閱讀體驗,看固定版面 EPUB 也還可以。某些時候上網用大螢幕還是比較方便。

----------------

因為我上網只是要查資料,故有沒有彩色我也沒有很介意。但就算已經分成 3 台電子書閱讀器了,我目前也找不到一台可以達到 90 分的閱讀器。

如果再把需求限縮,目前我覺得可以達到 90 分的電子書閱讀器只有 2 台:

6 吋看流式 EPUB - Kindle Paperwhite 3
10 吋看 PDF - Kobo Elipsa + 第三方軟體

前後買過 10 台機器的我,還得加上降低標準,這樣也才 2 台達到我的需求,你說無不無奈?