搞定中國安卓ICP備案號沒那麼難!有了「APP備案助手」,MD5、公鑰資訊一秒取得
隨著中國法律規定 APP 必須申請備案號碼,不管是 iOS 或是 Android 都必須申請,尤其是 Android 申請時候需要輸入 APP 的MD5 與 公鑰資料。
還好有「APP備案助手」,只要這個APP安裝在安卓上,就可以抓出手機上我們要上架的APP的MD5與公鑰,非常方便。


隨著中國法律規定 APP 必須申請備案號碼,不管是 iOS 或是 Android 都必須申請,尤其是 Android 申請時候需要輸入 APP 的MD5 與 公鑰資料。
還好有「APP備案助手」,只要這個APP安裝在安卓上,就可以抓出手機上我們要上架的APP的MD5與公鑰,非常方便。
在 ubuntu 24.04 上執行 ollama 很簡單按此,若需要修改預設模型存放地方,卻是有點困難,有必要將暫時解決方式記錄起來.
首先我們需了解兩個變數:OLLAMA_HOST,OLLAMA_MODELS 。
第一個變數預設值為 127.0.0.1:11434 這樣只能內部測試,若需要提供外部使用,需改為 0.0.0.0:11434 。
第二個變數用來變更下載的大語言模型路徑,這也是本篇文章重點。
我參考了這篇文章,實測多次真的無法在 ubuntu 24.04 下,使用 systemctl enale ollama 方式,套用以上修改過兩個變數,只能退而求其次,改成 shell script 的方式手動執行。
#!/bin/bash
export OLLAMA_HOST="0.0.0.0:11434"
export OLLAMA_MODELS="大語言模型目錄"
/usr/local/bin/ollama serve &
我會想要改的原因,是因為原本使用 docker 安裝 ollama ,但我發現常常不工作,只好直接安裝執行;但又想說哪一天 docker ollama 變正常了,因此保留原本 docker 裡面的大語言模型目錄,才需要改變預設目錄,這樣就能左右逢源解決困擾.
Obsidian 匯出 PDF 不含筆記屬性內容,本篇文章記錄如何解決此問題。
此方式可以把所有的屬性展現出來,匯出PDF就可以看見了,但無法選擇要展現那些屬性。
```dataview
TABLE WITHOUT ID file.frontmatter AS Properties
WHERE file.name = this.file.name
```
此方法可以自行決定那些欄位要呈現出來,比較有彈性。
```dataviewjs
// 檢索當前檔案的 Frontmatter
let frontmatter = dv.current().file.frontmatter;
// 定義要排除的欄位(視需要調整)
let excludeFields = ['tags', 'created']
// 根據排除列表提取並過濾鍵和值
let filtered_keys = Object.keys(frontmatter).filter(key => ! excludeFields.includes(key));
let filtered_values = filtered_keys.map(key => frontmatter[key]);
// 定義一個陣列來儲存表格的每一行
let rows = [];
// 使用鍵值對填充行陣列
for (let i = 0; i < filtered_keys.length; i++) {
// 將陣列值(例如標籤)轉換為以逗號分隔的單一字串
let value = Array.isArray(filtered_values[i]) ? filtered_values[i].join(', ') : filtered_values [i];
rows.push([filtered_keys[i], value])
}
// 生成一個包含兩列的表格並填充行
dv.table(['Properties', 'Values'], rows)
```
n8n 有很多好用的範本可以使用。如果我們也有很棒的流程要告訴大家,官方很貼心提供「n8n 流程預覽網頁元件」,可以在自己網站分享。我實作時遇到顯示失敗問題,也一併奉上解決方法。
wordpress 該如何安裝使用,有兩個方式:
方法(一):安裝外掛
我們可以借助外掛「WPCode Insert Headers and Footers 」,將 n8n 流程預覽網頁元件的 javascript 加上去,這樣以後發文,就可以直接引用該元件不用每次都加。
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2.0.0/webcomponents-loader.js"></script>
<script src="https://www.unpkg.com/lit@2.0.0-rc.2/polyfill-support.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@n8n_io/n8n-demo-component/n8n-demo.bundled.js"></script>
寫文章的時候,選擇自訂HTML
# 輸入 n8n 語法
<n8n-demo workflow='n8n的節點json字串' frame=true></n8n-demo>
方法(二):不安裝外掛,直接貼上 n8n javascript 與 n8n 語法
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2.0.0/webcomponents-loader.js"></script>
<script src="https://www.unpkg.com/lit@2.0.0-rc.2/polyfill-support.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@n8n_io/n8n-demo-component/n8n-demo.bundled.js"></script>
<n8n-demo workflow='n8n的節點json字串' frame=true></n8n-demo>
實際上我實作的時候,一直出現 json 錯誤
最後在 這個地方 發現有個神人做了一個 n8n 流程,其功能為:
將"流程 json 字串",轉化成一個可用的 "Encoded URL" 字串
我們將 Encoded URL 取代 json,這樣就可以解決 Invalid JSON 的問題了。
該神人做好的 n8n 流程,我放在下面,我們只要修改其第二節點的內容,改成自己的 json 字串,第三節點產出的就是我們要的 Encoded URL。
由於「n8n 流程預覽網頁元件」只能顯示出英文,因此我請 gemini pro 改寫能顯示中文的版本(檔案在這),只是我不懂 npm ,最後載入失敗。
我曾經看到一封 email ,內容寫得真爛,後來發現是我自己寫的,標點符號都亂標,XD 。最近又發現原來我寫中英文時,也很隨興,常事後看起來不對勁,但就是看不出所以然來。
後來我在脆上面,看到有人在推寫作時,應當要注意中、英文排版,建議參考「中文文案排版指北」,內容簡單,淺顯易懂,我也推薦大家發漏。
原本我在公司寫好的 Spring Boot 3.1.5+OpenAPI 3.1+selenium 4.21 都很正常,直到 Spring AI 1.0 橫空出世,我想 Spring Boot 也應該升級到Spring boot 3.5.0 ,才能用上 Spring AI 1.0 MCP 功能,也才能接上未來的 n8n。
但很可惜還沒來得及加上 Spring AI 1.0 外掛,就出現執行階段錯誤
02:29:19,730 |-INFO in ch.qos.logback.classic.util.ContextInitializer@4218d6a3 - ch.qos.logback.classic.util.DefaultJoranConfigurator.configure() call lasted 70 milliseconds. ExecutionStatus=DO_NOT_INVOKE_NEXT_IF_ANY
02:29:19,942 |-ERROR in ch.qos.logback.core.joran.spi.SaxEventInterpretationContext@663411de - No 'converterClass' attribute in <conversionRule>
02:29:19,942 |-ERROR in ch.qos.logback.core.joran.spi.SaxEventInterpretationContext@663411de - No 'converterClass' attribute in <conversionRule>
02:29:19,942 |-ERROR in ch.qos.logback.core.joran.spi.SaxEventInterpretationContext@663411de - No 'converterClass' attribute in <conversionRule>
02:29:19,942 |-ERROR in ch.qos.logback.core.joran.spi.SaxEventInterpretationContext@663411de - No 'converterClass' attribute in <conversionRule>
02:29:19,942 |-ERROR in ch.qos.logback.core.joran.spi.SaxEventInterpretationContext@663411de - No 'converterClass' attribute in <conversionRule>
02:29:19,942 |-ERROR in ch.qos.logback.core.joran.spi.SaxEventInterpretationContext@663411de - No 'converterClass' attribute in <conversionRule>
Logging system failed to initialize using configuration from 'null'
java.lang.NoSuchMethodError: 'void ch.qos.logback.core.model.processor.ModelInterpretationContext.setConfiguratorSupplier(java.util.function.Supplier)'
at org.springframework.boot.logging.logback.SpringBootJoranConfigurator.buildModelInterpretationContext(SpringBootJoranConfigurator.java:117)
踩坑好久好久,後來才發現原本 selenium 使用 webdrivermanager.jar (5.8.0) 內建的 logback,與 spring-boot 3.5.0 內建的 logback 函式庫相衝突,需要升級到最新的 webdrivermanager 6.1.0 才可以匹配,且我有額外排除 webdrivermanager 6.1.0 內建的 logback。
我的設定檔案是 build.gradle,非 maven,重點如下
plugins {
id 'java'
id 'org.springframework.boot' version '3.5.0'
id 'io.spring.dependency-management' version '1.1.7'
...
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web:3.5.0")
implementation 'org.seleniumhq.selenium:selenium-java:4.33.0'
implementation("io.github.bonigarcia:webdrivermanager:6.1.0"){
exclude group: 'ch.qos.logback', module: 'logback-classic'
}
...
}
當然 src/main/resources 目錄也要新增 logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%-4level] %msg%n</pattern>
</encoder>
</appender>
<logger name="io.github.bonigarcia" level="DEBUG" />
<logger name="io" level="WARN" />
<logger name="org" level="WARN" />
<logger name="com" level="WARN" />
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
這樣就能成功從 Spring Boot 3.1.5 升級到 Spring Boot 3.5.0 了
json字串有些特殊字元,需要跳脫後才能正常使用。因此有必要在n8n加上code節點寫javascript 跳脫。
const chars = {
"\"": "\\\"",
"\\": "\\\\",
"\/": "\\/",
"\u0000": "\\u0000",
"\u0001": "\\u0001",
"\u0002": "\\u0002",
"\u0003": "\\u0003",
"\u0004": "\\u0004",
"\u0005": "\\u0005",
"\u0006": "\\u0006",
"\u0007": "\\u0007",
"\u0008": "\\u0008",
"\u0009": "\\u0009",
"\u000A": "\\u000A",
"\u000B": "\\u000B",
"\u000C": "\\u000C",
"\u000D": "\\u000D",
"\u000E": "\\u000E",
"\u000F": "\\u000F",
"\u0010": "\\u0010",
"\u0011": "\\u0011",
"\u0012": "\\u0012",
"\u0013": "\\u0013",
"\u0014": "\\u0014",
"\u0015": "\\u0015",
"\u0016": "\\u0016",
"\u0017": "\\u0017",
"\u0018": "\\u0018",
"\u0019": "\\u0019",
"\u001A": "\\u001A",
"\u001B": "\\u001B",
"\u001C": "\\u001C",
"\u001D": "\\u001D",
"\u001E": "\\u001E",
"\u001F": "\\u001F",
"\u007F": "\\u007F",
"\u0080": "\\u0080",
"\u0081": "\\u0081",
"\u0082": "\\u0082",
"\u0083": "\\u0083",
"\u0084": "\\u0084",
"\u0085": "\\u0085",
"\u0086": "\\u0086",
"\u0087": "\\u0087",
"\u0088": "\\u0088",
"\u0089": "\\u0089",
"\u008A": "\\u008A",
"\u008B": "\\u008B",
"\u008C": "\\u008C",
"\u008D": "\\u008D",
"\u008E": "\\u008E",
"\u008F": "\\u008F",
"\u0090": "\\u0090",
"\u0091": "\\u0091",
"\u0092": "\\u0092",
"\u0093": "\\u0093",
"\u0094": "\\u0094",
"\u0095": "\\u0095",
"\u0096": "\\u0096",
"\u0097": "\\u0097",
"\u0098": "\\u0098",
"\u0099": "\\u0099",
"\u009A": "\\u009A",
"\u009B": "\\u009B",
"\u009C": "\\u009C",
"\u009D": "\\u009D",
"\u009E": "\\u009E",
"\u009F": "\\u009F"
};
$json.output = $input.first().json.output.replace(/[\"\\\/\u0000-\u001F\u007F\u0080-\u009F]/g, match=>chars[match]);
return $input.all();
現在主流文件辨識,應該都交由vision功能的AI模型處裡,辨識度高;若不想花錢使用AI,可以用apache tika頂著用。
docker 安裝 apache tika
docker run -d -p 9998:9998 --name tika-server-ocr apache/tika:latest-full
# 目前是3.1.0
安裝完畢,進入容器,安裝中文語言套件
docker exec -u root -it tika-server-ocr bash
###
apt update
apt-get install tesseract-ocr-chi-sim tesseract-ocr-chi-tra
###
測試
# Linux
# 中文圖檔 test.png
curl -T test.png http://127.0.0.1:9998/tika --header "X-Tika-OCRLanguage: eng+chi_tra+chi_sim"
N8N(nodemation)設定
前一個節點要把檔案準備好,再新增以下節點,丟給tika處理,回傳設定為text
安裝環境:
參考官方文件:Guacamole Docker
⚠️ 注意事項:以下步驟請務必注意 IP、Port、以及容器名稱,請記得調整。
docker run --restart always --name guacd -d -p 4822:4822 guacamole/guacd:1.6.0-RC1
docker run -d --restart=always --name postgres-17 -p 5432:5432 \
-e POSTGRES_USER=root \
-e POSTGRES_PASSWORD=密碼 \
-v postgres-17-data:/var/lib/postgresql/data postgres:17.4-bookworm
進入容器:
docker exec -it postgres-17 bash
進入 PostgreSQL 服務器:
psql -U root -p 5432 -h localhost -W
建立資料庫:
create database guacamole;
docker run --rm guacamole/guacamole:1.6.0-RC1 /opt/guacamole/bin/initdb.sh --postgresql > initdb.sql
apt-get install -y postgresql-client
psql -U root -p 5432 -h <容器IP> -W -d guacamole < initdb.sql
docker run --restart always --name guacamole \
-e GUACD_HOSTNAME=<guacd ip> \
-e GUACD_PORT=4822 \
-e POSTGRESQL_HOSTNAME=<postgres ip> \
-e POSTGRESQL_PORT=5432 \
-e POSTGRESQL_DATABASE=guacamole \
-e POSTGRESQL_USERNAME=root \
-e POSTGRESQL_PASSWORD=密碼 \
-d -p 8080:8080 guacamole/guacamole:1.6.0-RC1
location /guacamole/ {
proxy_pass http://ip:8081;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
client_max_body_size 1g;
#proxy_cookie_path /guacamole/ /new-path/; 若位置不一樣
access_log off;
}
才剛安裝nginx 反向代理程式容器,沒多久就忘了密碼 XD,我安裝時不綁定外部資料庫,內建的是sqlite。
要救回來原理:先進容器將所有使用者設定刪除,重開容器後,系統會以為初始化,此時就可以用預設帳密登入,然後再進容器把刪除的狀態回原,這樣就可以重設原使用者的密碼囉。
步驟如下:
docker exec -it 容器名稱 bash
apt update && apt install sqlite3 -y
sqlite3 /data/database.sqlite
UPDATE user SET is_deleted=1;
然後重開容器,接下來就可以用預設的帳號登入
帳號:admin@example.com
密碼:changeme
接下來再進一次容器,將剛剛設定刪除的管理者還原
這樣用預設帳號登入重新查看,原本管理者的帳號就出現了,改掉其密碼,這樣就救回來了