🍕 Sync 2026-09-28 20:03:36

This commit is contained in:
github-actions[bot] committed 2026-09-28 20:03:36 +08:00
1 parent 3970936ab8
commit 416e0193a9
18 files changed
+113 -104

No files matched your search

+1 -1
View File
@@ -4,7 +4,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=honk PKG_NAME:=honk
PKG_VERSION:=0.0.1_beta82 PKG_VERSION:=0.0.1_beta82
PKG_RELEASE:=3 PKG_RELEASE:=4
# Raw upstream release tag. It keeps the dots in qualifiers (e.g. v0.0.1.beta.49) # Raw upstream release tag. It keeps the dots in qualifiers (e.g. v0.0.1.beta.49)
# because that is what the GitHub release asset name uses. # because that is what the GitHub release asset name uses.
-14
View File
@@ -1,14 +0,0 @@
# api.dae
# Configure API access for HONK dashboards and controllers.
experimental {
native_api {
enabled: true
listen: '0.0.0.0:9527'
secret: 'honk114514'
ui: '/etc/honk/doona'
config_write: true
geosite_download_url: 'https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/release/geosite.dat'
geoip_download_url: 'https://raw.githubusercontent.com/QiuSimons/geoip-moedove/refs/heads/main/geoip.dat'
}
}
+1 -1
View File
@@ -2,6 +2,6 @@
config honk 'config' config honk 'config'
option enabled '0' option enabled '0'
option advanced '0' option advanced '0'
option dashboard 'doona' option dashboard 'none'
option config_file '/etc/honk/config.dae' option config_file '/etc/honk/config.dae'
+2 -2
View File
@@ -6,8 +6,8 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-honk PKG_NAME:=luci-app-honk
PKG_VERSION:=1.1.2 PKG_VERSION:=1.1.3
PKG_RELEASE:=4 PKG_RELEASE:=5
LUCI_TITLE:=LuCI support for honk LUCI_TITLE:=LuCI support for honk
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
+9
View File
@@ -315,3 +315,12 @@ msgstr "API 配置"
msgid "API configuration saved and service restarted." msgid "API configuration saved and service restarted."
msgstr "API 配置已保存并重启服务。" msgstr "API 配置已保存并重启服务。"
msgid "None"
msgstr "无"
msgid "Dashboard Disabled"
msgstr "面板未启用"
msgid "Dashboard type is currently set to \"None\". Web dashboard and API listener are disabled."
msgstr "当前面板类型为“无”,Web 管理面板和 Native API 监听已禁用。"
+4 -17
View File
@@ -4,23 +4,10 @@
[ -f /usr/share/honk/download_zashboard.sh ] && rm -f /usr/share/honk/download_zashboard.sh [ -f /usr/share/honk/download_zashboard.sh ] && rm -f /usr/share/honk/download_zashboard.sh
mkdir -p /etc/honk/config.d /etc/honk/state mkdir -p /etc/honk/config.d /etc/honk/state
if [ ! -f /etc/honk/config.d/api.dae ]; then [ -f /etc/honk/config.d/api.dae ] || touch /etc/honk/config.d/api.dae
cat << 'EOF' > /etc/honk/config.d/api.dae dash=$(uci -q get honk.config.dashboard || uci -q get honk.@honk[0].dashboard || echo "")
# api.dae if [ "$dash" = "none" ]; then
# Configure API access for HONK dashboards and controllers. : > /etc/honk/config.d/api.dae
experimental {
native_api {
enabled: true
listen: '0.0.0.0:9527'
secret: 'honk114514'
ui: '/etc/honk/doona'
config_write: true
geosite_download_url: 'https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/release/geosite.dat'
geoip_download_url: 'https://raw.githubusercontent.com/QiuSimons/geoip-moedove/refs/heads/main/geoip.dat'
}
}
EOF
fi fi
# Smooth migration from legacy /etc/honk/dashboard to /etc/honk/doona # Smooth migration from legacy /etc/honk/dashboard to /etc/honk/doona
@@ -233,7 +233,7 @@ function get_dashboard_info(req) {
}); });
} }
} }
if (!requested_type) requested_type = "doona"; if (!requested_type) requested_type = "none";
let api_cfg = get_api_config(); let api_cfg = get_api_config();
if (!api_cfg.is_legacy) { if (!api_cfg.is_legacy) {
@@ -265,6 +265,10 @@ function get_dashboard_info(req) {
has_native_api: !!(parsed_native && parsed_native.enabled) has_native_api: !!(parsed_native && parsed_native.enabled)
}; };
if (requested_type == "none") {
return res;
}
let target_default_ui = (requested_type == "zashboard") ? "/etc/honk/zashboard" : "/etc/honk/doona"; let target_default_ui = (requested_type == "zashboard") ? "/etc/honk/zashboard" : "/etc/honk/doona";
let other_default_ui = (requested_type == "zashboard") ? "/etc/honk/doona" : "/etc/honk/zashboard"; let other_default_ui = (requested_type == "zashboard") ? "/etc/honk/doona" : "/etc/honk/zashboard";
@@ -350,6 +354,17 @@ function switch_dashboard_api(target_type) {
system("mkdir -p /etc/honk/config.d"); system("mkdir -p /etc/honk/config.d");
if (target_type == "none" || !target_type) {
let cur = readfile(api_file);
if (cur && trim(cur) != "") {
writefile(api_file, "");
system("/etc/init.d/honk restart >/dev/null 2>&1 &");
return { success: true, type: "none" };
}
writefile(api_file, "");
return { success: true, type: "none", noop: true };
}
let api_cfg = get_api_config(); let api_cfg = get_api_config();
let parsed_clash = api_cfg.parsed_clash; let parsed_clash = api_cfg.parsed_clash;
let parsed_native = api_cfg.parsed_native; let parsed_native = api_cfg.parsed_native;
@@ -508,7 +523,7 @@ return {
switch_dashboard_api: { switch_dashboard_api: {
args: { type: "string" }, args: { type: "string" },
call: function(req) { call: function(req) {
let t = req.args ? req.args.type : "doona"; let t = req.args ? req.args.type : "none";
return switch_dashboard_api(t); return switch_dashboard_api(t);
} }
} }
@@ -420,25 +420,7 @@ function createConfigFileView(filePath, mapTitle, mapDesc, fieldTitle, successMs
o.wrap = 'off'; o.wrap = 'off';
o.load = function(section_id) { o.load = function(section_id) {
return readFile(filePath).then(function(content) { return readFile(filePath).then(function(content) {
if ((!content || !content.trim()) && filePath.endsWith('/api.dae')) { return content || '';
return [
'# api.dae',
'# Configure API access for HONK dashboards and controllers.',
'',
'experimental {',
' native_api {',
' enabled: true',
" listen: '0.0.0.0:9527'",
" secret: 'honk114514'",
" ui: '/etc/honk/doona'",
" config_write: true",
" geosite_download_url: 'https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/release/geosite.dat'",
" geoip_download_url: 'https://raw.githubusercontent.com/QiuSimons/geoip-moedove/refs/heads/main/geoip.dat'",
' }',
'}'
].join('\n') + '\n';
}
return content;
}); });
}; };
o.write = function(section_id, formvalue) { o.write = function(section_id, formvalue) {
@@ -22,7 +22,7 @@ return view.extend({
} }
var sec = (uci.sections('honk', 'honk')[0] || {}); var sec = (uci.sections('honk', 'honk')[0] || {});
var sid = sec['.name'] || 'config'; var sid = sec['.name'] || 'config';
var dashType = uci.get('honk', sid, 'dashboard') || 'doona'; var dashType = uci.get('honk', sid, 'dashboard') || 'none';
var DASHBOARD_PROFILES = { var DASHBOARD_PROFILES = {
zashboard: { zashboard: {
@@ -95,6 +95,9 @@ return view.extend({
}); });
} }
}); });
var optNone = E('option', { 'value': 'none' }, _('None'));
if (dashType === 'none') optNone.selected = true;
sel.appendChild(optNone);
Object.keys(DASHBOARD_PROFILES).forEach(function(k) { Object.keys(DASHBOARD_PROFILES).forEach(function(k) {
var opt = E('option', { 'value': k }, DASHBOARD_PROFILES[k].label || DASHBOARD_PROFILES[k].name); var opt = E('option', { 'value': k }, DASHBOARD_PROFILES[k].label || DASHBOARD_PROFILES[k].name);
if (k === dashType) opt.selected = true; if (k === dashType) opt.selected = true;
@@ -210,13 +213,29 @@ return view.extend({
profile.exampleConfig || '' profile.exampleConfig || ''
) )
]), ]),
E('div', { 'style': 'margin-top: 16px; display: flex; gap: 10px; align-items: center;' }, [ E('div', { 'style': 'margin-top: 16px; display: flex; gap: 10px; align-items: center; flex-wrap: wrap;' }, [
createDashboardSelect(),
E('a', { 'href': L.url('admin/services/honk/api'), 'class': 'cbi-button' }, _('Configure in API Settings')), E('a', { 'href': L.url('admin/services/honk/api'), 'class': 'cbi-button' }, _('Configure in API Settings')),
btnQuickEnable, btnQuickEnable,
quickEnableMsg quickEnableMsg
]) ])
]); ]);
// State: None
var selectDashboardNone = createDashboardSelect();
var stateNone = E('div', { 'class': 'cbi-section', 'style': 'display: none;' }, [
E('h3', {}, _('Dashboard Disabled')),
E('div', { 'class': 'cbi-section-descr' },
_('Dashboard type is currently set to "None". Web dashboard and API listener are disabled.')
),
E('table', { 'class': 'table', 'style': 'margin: 14px 0;' }, [
E('tr', {}, [
E('th', { 'style': 'width: 25%; vertical-align: middle;' }, _('Dashboard Type')),
E('td', {}, selectDashboardNone)
])
])
]);
// State 2: Missing UI // State 2: Missing UI
var metaUiDir = E('td', {}, profile.defaultDir); var metaUiDir = E('td', {}, profile.defaultDir);
var metaController = E('td', {}, '0.0.0.0:9527'); var metaController = E('td', {}, '0.0.0.0:9527');
@@ -515,6 +534,7 @@ return view.extend({
function showState(name) { function showState(name) {
stateLoading.style.display = (name === 'loading') ? 'block' : 'none'; stateLoading.style.display = (name === 'loading') ? 'block' : 'none';
stateNone.style.display = (name === 'none') ? 'block' : 'none';
stateUnconfigured.style.display = (name === 'unconfigured') ? 'block' : 'none'; stateUnconfigured.style.display = (name === 'unconfigured') ? 'block' : 'none';
stateMissingUi.style.display = (name === 'missing_ui') ? 'block' : 'none'; stateMissingUi.style.display = (name === 'missing_ui') ? 'block' : 'none';
stateReady.style.display = (name === 'ready') ? 'block' : 'none'; stateReady.style.display = (name === 'ready') ? 'block' : 'none';
@@ -579,6 +599,10 @@ return view.extend({
} }
function loadInfo(forceReload) { function loadInfo(forceReload) {
if (dashType === 'none') {
showState('none');
return;
}
honk.callHonkDashboardInfo(dashType).then(function(data) { honk.callHonkDashboardInfo(dashType).then(function(data) {
if (!data || !data.configured) { if (!data || !data.configured) {
showState('unconfigured'); showState('unconfigured');
@@ -648,6 +672,7 @@ return view.extend({
return E('div', { 'class': 'dash-wrap' }, [ return E('div', { 'class': 'dash-wrap' }, [
style, style,
stateLoading, stateLoading,
stateNone,
stateUnconfigured, stateUnconfigured,
stateMissingUi, stateMissingUi,
stateReady stateReady
@@ -32,9 +32,10 @@ return view.extend({
o.default = '0'; o.default = '0';
o = s.option(form.ListValue, 'dashboard', _('Dashboard Type'), _('Select the active web dashboard.')); o = s.option(form.ListValue, 'dashboard', _('Dashboard Type'), _('Select the active web dashboard.'));
o.value('none', _('None'));
o.value('zashboard', 'Zashboard'); o.value('zashboard', 'Zashboard');
o.value('doona', _('Doona')); o.value('doona', _('Doona'));
o.default = 'doona'; o.default = 'none';
o = s.option(form.TextValue, '_config', _('Global Configuration'), _('Correctly configure the include field for separate-config to work, or enter complete configuration here.')); o = s.option(form.TextValue, '_config', _('Global Configuration'), _('Correctly configure the include field for separate-config to work, or enter complete configuration here.'));
o.depends('advanced', '1'); o.depends('advanced', '1');
@@ -55,10 +56,10 @@ return view.extend({
handleSaveApply: function(ev, mode) { handleSaveApply: function(ev, mode) {
var sections = uci.sections('honk', 'honk'); var sections = uci.sections('honk', 'honk');
var sid = (sections && sections[0]) ? sections[0]['.name'] : '@honk[0]'; var sid = (sections && sections[0]) ? sections[0]['.name'] : '@honk[0]';
var oldDash = uci.get('honk', sid, 'dashboard') || 'doona'; var oldDash = uci.get('honk', sid, 'dashboard') || 'none';
return this.handleSave(ev).then(function() { return this.handleSave(ev).then(function() {
var newDash = uci.get('honk', sid, 'dashboard') || 'doona'; var newDash = uci.get('honk', sid, 'dashboard') || 'none';
if (newDash !== oldDash) { if (newDash !== oldDash) {
return honk.callHonkSwitchDashboardApi(newDash); return honk.callHonkSwitchDashboardApi(newDash);
} }
+4
View File
@@ -2,6 +2,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## [2.2.0-r3] - 节点表单导入字段语言混合优化
- 「添加本地订阅」表单导入 /「编辑节点」页:名称 / 分组 / 协议保持系统语言(中/英切换),其余技术参数字段固定为英文(Server / Port / Password / Cipher / Method / Security / Network / Header Type / Path / Obfs / Obfs Param / Obfs Password / Protocol Param / Skip Cert Verify / Private Key / Peer Public Key),与 Clash YAML / 分享链接字段名保持一致,提升可对照性
## [2.2.0-r2] - 节点页按钮顺序调整 ## [2.2.0-r2] - 节点页按钮顺序调整
- 「节点」页「筛选」后的「刷新」「删除」按钮位置互换(现为:筛选 | 删除 | 刷新) - 「节点」页「筛选」后的「刷新」「删除」按钮位置互换(现为:筛选 | 删除 | 刷新)
+1 -1
View File
@@ -10,7 +10,7 @@ PKG_NAME:=luci-app-substore
# 版本约定:每次提交 PKG_RELEASE +1(2.1.2-r1 ~ r9); # 版本约定:每次提交 PKG_RELEASE +1(2.1.2-r1 ~ r9);
# 达到 r10 时 PKG_VERSION 末位 +1(2.1.2 -> 2.1.3),PKG_RELEASE 重置为 1。 # 达到 r10 时 PKG_VERSION 末位 +1(2.1.2 -> 2.1.3),PKG_RELEASE 重置为 1。
PKG_VERSION:=2.2.0 PKG_VERSION:=2.2.0
PKG_RELEASE:=3 PKG_RELEASE:=4
LUCI_DEPENDS:=+luci-lua-runtime +luci-compat LUCI_DEPENDS:=+luci-lua-runtime +luci-compat
+3 -3
View File
@@ -69,18 +69,18 @@ group them, then re-emit them in a format your client can consume.
## Installation ## Installation
> The version in the package name must match `PKG_VERSION` / `PKG_RELEASE` in the > The version in the package name must match `PKG_VERSION` / `PKG_RELEASE` in the
> [Makefile](Makefile) (currently `2.2.0-r2`). > [Makefile](Makefile) (currently `2.2.0-r3`).
opkg (OpenWrt / ImmortalWrt 24.10 and earlier): opkg (OpenWrt / ImmortalWrt 24.10 and earlier):
```bash ```bash
opkg install luci-app-substore-2.2.0-r2.ipk opkg install luci-app-substore-2.2.0-r3.ipk
``` ```
apk (OpenWrt / ImmortalWrt 25.12+): apk (OpenWrt / ImmortalWrt 25.12+):
```bash ```bash
apk add --allow-untrusted luci-app-substore-2.2.0-r2.apk apk add --allow-untrusted luci-app-substore-2.2.0-r3.apk
``` ```
Then open LuCI: **Services → Subscriptions**. Then open LuCI: **Services → Subscriptions**.
+3 -3
View File
@@ -61,18 +61,18 @@
## 安装 ## 安装
> 包名中的版本号必须与 [Makefile](Makefile) 的 `PKG_VERSION` / `PKG_RELEASE` 保持一致 > 包名中的版本号必须与 [Makefile](Makefile) 的 `PKG_VERSION` / `PKG_RELEASE` 保持一致
> (当前 `2.2.0-r2`)。 > (当前 `2.2.0-r3`)。
opkg(OpenWrt / ImmortalWrt 24.10 及更早): opkg(OpenWrt / ImmortalWrt 24.10 及更早):
```bash ```bash
opkg install luci-app-substore-2.2.0-r2.ipk opkg install luci-app-substore-2.2.0-r3.ipk
``` ```
apk(OpenWrt / ImmortalWrt 25.12+): apk(OpenWrt / ImmortalWrt 25.12+):
```bash ```bash
apk add --allow-untrusted luci-app-substore-2.2.0-r2.apk apk add --allow-untrusted luci-app-substore-2.2.0-r3.apk
``` ```
然后在 LuCI 菜单打开:**服务 → 订阅**。 然后在 LuCI 菜单打开:**服务 → 订阅**。
+3 -3
View File
@@ -3,18 +3,18 @@
> NOTE: stage-0 skeleton has not yet been installed/verified on a target device. > NOTE: stage-0 skeleton has not yet been installed/verified on a target device.
> This document will be updated once installation is validated. > This document will be updated once installation is validated.
> >
> 包名中的版本号需与 Makefile 的 `PKG_VERSION` / `PKG_RELEASE` 保持同步(当前 2.2.0-r2)。 > 包名中的版本号需与 Makefile 的 `PKG_VERSION` / `PKG_RELEASE` 保持同步(当前 2.2.0-r3)。
## Install (opkg — OpenWrt / ImmortalWrt 24.10 及更早) ## Install (opkg — OpenWrt / ImmortalWrt 24.10 及更早)
```bash ```bash
opkg install luci-app-substore-2.2.0-r2.ipk opkg install luci-app-substore-2.2.0-r3.ipk
``` ```
## Install (apk — OpenWrt / ImmortalWrt 25.12+) ## Install (apk — OpenWrt / ImmortalWrt 25.12+)
```bash ```bash
apk add --allow-untrusted luci-app-substore-2.2.0-r2.apk apk add --allow-untrusted luci-app-substore-2.2.0-r3.apk
``` ```
Refresh LuCI: Refresh LuCI:
@@ -96,29 +96,29 @@ var FIELD_LABELS = {
"name": "<%:Name%>", "name": "<%:Name%>",
"group": "<%:Group%>", "group": "<%:Group%>",
"protocol": "<%:Protocol%>", "protocol": "<%:Protocol%>",
"server": "<%:Server%>", "server": "Server",
"port": "<%:Port%>", "port": "Port",
"password": "<%:Password%>", "password": "Password",
"uuid": "UUID", "uuid": "UUID",
"alterId": "Alter ID", "alterId": "Alter ID",
"cipher": "<%:Cipher%>", "cipher": "Cipher",
"method": "<%:Encryption method%>", "method": "Method",
"security": "<%:Security%>", "security": "Security",
"net": "<%:Network%>", "net": "Network",
"headerType": "<%:Camouflage type%>", "headerType": "Header Type",
"flow": "Flow", "flow": "Flow",
"path": "<%:Path%>", "path": "Path",
"host": "Host", "host": "Host",
"sni": "SNI", "sni": "SNI",
"tls": "TLS", "tls": "TLS",
"obfs": "<%:Obfs%>", "obfs": "Obfs",
"obfs-param": "<%:Obfs param%>", "obfs-param": "Obfs Param",
"obfs-password": "<%:Obfs password%>", "obfs-password": "Obfs Password",
"protocol-param": "<%:Protocol param%>", "protocol-param": "Protocol Param",
"udp": "UDP", "udp": "UDP",
"skip-cert-verify": "<%:Skip cert verify%>", "skip-cert-verify": "Skip Cert Verify",
"private-key": "<%:Private key%>", "private-key": "Private Key",
"peer-public-key": "<%:Peer public key%>" "peer-public-key": "Peer Public Key"
}; };
var NODEFORM_I18N = { var NODEFORM_I18N = {
"node": "<%:Node%>", "node": "<%:Node%>",
@@ -43,29 +43,29 @@ var FIELD_LABELS = {
"name": "<%:Name%>", "name": "<%:Name%>",
"group": "<%:Group%>", "group": "<%:Group%>",
"protocol": "<%:Protocol%>", "protocol": "<%:Protocol%>",
"server": "<%:Server%>", "server": "Server",
"port": "<%:Port%>", "port": "Port",
"password": "<%:Password%>", "password": "Password",
"uuid": "UUID", "uuid": "UUID",
"alterId": "Alter ID", "alterId": "Alter ID",
"cipher": "<%:Cipher%>", "cipher": "Cipher",
"method": "<%:Encryption method%>", "method": "Method",
"security": "<%:Security%>", "security": "Security",
"net": "<%:Network%>", "net": "Network",
"headerType": "<%:Camouflage type%>", "headerType": "Header Type",
"flow": "Flow", "flow": "Flow",
"path": "<%:Path%>", "path": "Path",
"host": "Host", "host": "Host",
"sni": "SNI", "sni": "SNI",
"tls": "TLS", "tls": "TLS",
"obfs": "<%:Obfs%>", "obfs": "Obfs",
"obfs-param": "<%:Obfs param%>", "obfs-param": "Obfs Param",
"obfs-password": "<%:Obfs password%>", "obfs-password": "Obfs Password",
"protocol-param": "<%:Protocol param%>", "protocol-param": "Protocol Param",
"udp": "UDP", "udp": "UDP",
"skip-cert-verify": "<%:Skip cert verify%>", "skip-cert-verify": "Skip Cert Verify",
"private-key": "<%:Private key%>", "private-key": "Private Key",
"peer-public-key": "<%:Peer public key%>" "peer-public-key": "Peer Public Key"
}; };
var NODEFORM_I18N = { var NODEFORM_I18N = {
"node": "<%:Node%>", "node": "<%:Node%>",
+1 -1
View File
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI Status Pages LUCI_TITLE:=LuCI Status Pages
LUCI_DEPENDS:=+luci-base +luci-app-oui +luci-mod-dashboard +libiwinfo +rpcd-mod-iwinfo +rpcd-mod-rrdns +ucode +ucode-mod-fs +ucode-mod-ubus +ucode-mod-socket LUCI_DEPENDS:=+luci-base +luci-app-oui +luci-mod-dashboard +libiwinfo +rpcd-mod-iwinfo +rpcd-mod-rrdns +ucode +ucode-mod-fs +ucode-mod-ubus +ucode-mod-socket
PKG_RELEASE:=16 PKG_RELEASE:=18
PKG_BUILD_DEPENDS:=iwinfo PKG_BUILD_DEPENDS:=iwinfo
PKG_LICENSE:=Apache-2.0 PKG_LICENSE:=Apache-2.0