🎁 Sync 2026-08-28 19:05:48

This commit is contained in:
github-actions[bot]
2026-08-28 19:05:48 +08:00
parent 23a6a22cf3
commit 045d307bfe
15 changed files with 79 additions and 52 deletions
+2 -2
View File
@@ -2,8 +2,8 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_VERSION:=1.2.2-r20260804 PKG_VERSION:=1.2.3-r20260828
PKG_RELEASE:=5 PKG_RELEASE:=6
LUCI_TITLE:=LuCI support for jellyfin LUCI_TITLE:=LuCI support for jellyfin
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
@@ -130,7 +130,7 @@ do_install_detail() {
local tz="`uci get system.@system[0].zonename | sed 's/ /_/g'`" local tz="`uci get system.@system[0].zonename | sed 's/ /_/g'`"
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz" [ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
[ -z "$cache" ] || cmd="$cmd -v \"$cache:/config/transcodes\"" [ -z "$cache" ] || cmd="$cmd -v \"$cache:/config/transcodes\" -v \"$cache:/cache/transcodes\""
[ -z "$media" ] || cmd="$cmd -v \"$media:/media\"" [ -z "$media" ] || cmd="$cmd -v \"$media:/media\""
cmd="$cmd -v /mnt:/mnt" cmd="$cmd -v /mnt:/mnt"
+1 -1
View File
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall PKG_NAME:=luci-app-passwall
PKG_VERSION:=26.8.26 PKG_VERSION:=26.8.26
PKG_RELEASE:=249 PKG_RELEASE:=250
PKG_PO_VERSION:=$(PKG_VERSION) PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \ PKG_CONFIG_DEPENDS:= \
@@ -2098,7 +2098,7 @@ function gen_config(var)
query_type = dns_rule_query_type, query_type = dns_rule_query_type,
server = fakedns_tag, server = fakedns_tag,
disable_cache = true, disable_cache = true,
rewrite_ttl = tonumber(remote_rewrite_ttl) rewrite_ttl = 30
} }
table.insert(dns.rules, fakedns_dns_rule) table.insert(dns.rules, fakedns_dns_rule)
end end
+1 -1
View File
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall2 PKG_NAME:=luci-app-passwall2
PKG_VERSION:=26.8.27 PKG_VERSION:=26.8.27
PKG_RELEASE:=103 PKG_RELEASE:=104
PKG_PO_VERSION:=$(PKG_VERSION) PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \ PKG_CONFIG_DEPENDS:= \
+2 -2
View File
@@ -2098,10 +2098,10 @@ msgid "Access Control:"
msgstr "访问控制:" msgstr "访问控制:"
msgid "Add node to the load balancer is directly connected to %s[%s]." msgid "Add node to the load balancer is directly connected to %s[%s]."
msgstr "加入负载均衡节点到%s[%s]直连完成。" msgstr "加入负载均衡节点IP到%s[%s]直连豁免(防回环)完成。"
msgid "Add all %s nodes to %s[%s] direct connection complete." msgid "Add all %s nodes to %s[%s] direct connection complete."
msgstr "加入所有%s节点到%s[%s]直连完成。" msgstr "加入所有%s节点服务器IP到%s[%s]直连豁免(防回环)完成。"
msgid "Starting to load %s firewall rules..." msgid "Starting to load %s firewall rules..."
msgstr "开始加载 %s 防火墙规则..." msgstr "开始加载 %s 防火墙规则..."
@@ -557,6 +557,7 @@ load_acl() {
} }
filter_haproxy() { filter_haproxy() {
[ "$(config_n_get @global_haproxy[0] balancing_enable 0)" != "1" ] && return
for item in $(uci show $CONFIG | grep ".lbss=" | cut -d "'" -f 2); do for item in $(uci show $CONFIG | grep ".lbss=" | cut -d "'" -f 2); do
local ip=$(get_host_ip ipv4 $(echo $item | awk -F ":" '{print $1}') 1) local ip=$(get_host_ip ipv4 $(echo $item | awk -F ":" '{print $1}') 1)
[ -n "$ip" ] && ipset -q add $IPSET_VPS $ip [ -n "$ip" ] && ipset -q add $IPSET_VPS $ip
@@ -565,10 +566,16 @@ filter_haproxy() {
} }
filter_vpsip() { filter_vpsip() {
uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -v "^127\.0\.0\.1$" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPS &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R local ipv4_addrs=$(uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -v "^127\.0\.0\.1$")
#log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv4" "ipset" "${$IPSET_VPS}")" [ -n "$ipv4_addrs" ] && {
uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPS6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R echo "$ipv4_addrs" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPS &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R
#log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv6" "ipset" "${$IPSET_VPS6}")" log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv4" "ipset" "${IPSET_VPS}")"
}
local ipv6_addrs=$(uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}")
[ -n "$ipv6_addrs" ] && {
echo "$ipv6_addrs" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPS6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R
log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv6" "ipset" "${IPSET_VPS6}")"
}
} }
filter_server_port() { filter_server_port() {
@@ -585,6 +585,7 @@ load_acl() {
} }
filter_haproxy() { filter_haproxy() {
[ "$(config_n_get @global_haproxy[0] balancing_enable 0)" != "1" ] && return
for item in $(uci show $CONFIG | grep ".lbss=" | cut -d "'" -f 2); do for item in $(uci show $CONFIG | grep ".lbss=" | cut -d "'" -f 2); do
get_host_ip ipv4 $(echo $item | awk -F ":" '{print $1}') 1 get_host_ip ipv4 $(echo $item | awk -F ":" '{print $1}') 1
done | insert_nftset $NFTSET_VPS "-1" done | insert_nftset $NFTSET_VPS "-1"
@@ -602,10 +603,16 @@ filter_vps_addr() {
} }
filter_vpsip() { filter_vpsip() {
uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -v "^127\.0\.0\.1$" | insert_nftset $NFTSET_VPS "-1" local ipv4_addrs=$(uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -v "^127\.0\.0\.1$")
#log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv4" "nftset" "${$NFTSET_VPS}")" [ -n "$ipv4_addrs" ] && {
uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $NFTSET_VPS6 "-1" echo "$ipv4_addrs" | insert_nftset $NFTSET_VPS "-1"
#log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv6" "nftset" "${$NFTSET_VPS6}")" log_i18n 1 "Add all %s nodes to %s[%s] direct connection complete." "IPv4" "nftset" "${NFTSET_VPS}"
}
local ipv6_addrs=$(uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}")
[ -n "$ipv6_addrs" ] && {
echo "$ipv6_addrs" | insert_nftset $NFTSET_VPS6 "-1"
log_i18n 1 "Add all %s nodes to %s[%s] direct connection complete." "IPv6" "nftset" "${NFTSET_VPS6}"
}
} }
filter_server_port() { filter_server_port() {
+2 -2
View File
@@ -11,8 +11,8 @@ LUCI_DEPENDS:=+luci-lib-xterm +taskd
LUCI_EXTRA_DEPENDS:=taskd (>=1.0.3) LUCI_EXTRA_DEPENDS:=taskd (>=1.0.3)
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
PKG_VERSION:=1.0.25 PKG_VERSION:=1.0.26
PKG_RELEASE:=1 PKG_RELEASE:=2
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com> PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
include $(TOPDIR)/feeds/luci/luci.mk include $(TOPDIR)/feeds/luci/luci.mk
+3
View File
@@ -48,3 +48,6 @@ msgstr "任务执行失败!"
msgid "Click the button in the upper right corner of the dialog box to close it, or click here to view the log" msgid "Click the button in the upper right corner of the dialog box to close it, or click here to view the log"
msgstr "点击对话框右上角按钮关闭,或者点此查看日志" msgstr "点击对话框右上角按钮关闭,或者点此查看日志"
msgid "Upgrade"
msgstr "升级"
+1 -1
View File
@@ -17,7 +17,7 @@ LUCI_NAME:=luci-theme-footstrap
FOOTSTRAP_VERSION?= FOOTSTRAP_VERSION?=
ifneq ($(FOOTSTRAP_VERSION),) ifneq ($(FOOTSTRAP_VERSION),)
PKG_VERSION:=$(FOOTSTRAP_VERSION) PKG_VERSION:=$(FOOTSTRAP_VERSION)
PKG_RELEASE:=39 PKG_RELEASE:=40
endif endif
LUCI_TITLE:=Footstrap Theme LUCI_TITLE:=Footstrap Theme
@@ -774,14 +774,14 @@ const MARK = 'fs-ap'; /* the built form's class, and how mount() knows it is alr
const TAB_DEADLINE = 5000; const TAB_DEADLINE = 5000;
const TAB = 'fs-appearance'; /* the pane's data-tab, which ui.tabs' click handler matches on */ const TAB = 'fs-appearance'; /* the pane's data-tab, which ui.tabs' click handler matches on */
let _routeObserver = null, _viewObserver = null, _observedView = null, _building = false; let _routeObserver = null, _viewObserver = null, _observedRoot = null, _building = false;
function onPage() { return (document.body.getAttribute('data-page') || '') === PAGE; } function onPage() { return (document.body.getAttribute('data-page') || '') === PAGE; }
function stopWatch() { function stopWatch() {
if (_viewObserver) _viewObserver.disconnect(); if (_viewObserver) _viewObserver.disconnect();
_viewObserver = null; _viewObserver = null;
_observedView = null; _observedRoot = null;
} }
/* The stock tab GROUP: the element whose children are the panes, which ui.tabs marks /* The stock tab GROUP: the element whose children are the panes, which ui.tabs marks
@@ -831,24 +831,20 @@ function tabGroup(view) {
* *
* A map redraw (Save without Apply) rebuilds the group and `ui.tabs` stamps `data-initialized` as * A map redraw (Save without Apply) rebuilds the group and `ui.tabs` stamps `data-initialized` as
* an attribute change that can land after the last childList change, so the observer watches that * an attribute change that can land after the last childList change, so the observer watches that
* attribute too and a miss schedules retries on a widening delay otherwise the tab is missing * attribute too otherwise the tab is missing until the next navigation (openwrt/luci#8903).
* until the next navigation (openwrt/luci#8903). */ *
const RETRIES = [ 0, 60, 150, 300, 600, 1200 ]; * A ladder of retries on a widening delay shipped beside that watch and is gone: instrumented over
let _retryTimer = 0, _retryAt = 0; * ten sessions on both package managers a full load, an SPA return, a Save and a Save & Apply
function retryMount() { * it mounted the tab zero times, only ever arming a timer that woke to find the work done. The
if (_retryTimer) return; * deadline below could once be seen mounting it, but only because watch() was binding the observer
if (_retryAt >= RETRIES.length) return; * to a node the router was about to replace; with that fixed the deadline is a diagnostic again. */
const delay = RETRIES[_retryAt++];
_retryTimer = window.setTimeout(() => { _retryTimer = 0; mount(); }, delay);
}
function mount() { function mount() {
const view = document.getElementById('view'); const view = document.getElementById('view');
if (!view || !onPage()) return; if (!view || !onPage()) return;
if (view.querySelector('.' + MARK)) { _retryAt = 0; return; } if (view.querySelector('.' + MARK)) return;
if (_building) return; if (_building) return;
const tabs = tabGroup(view); const tabs = tabGroup(view);
if (!tabs) { retryMount(); return; } if (!tabs) return; /* not built yet; the observer calls again when it is */
_building = true; _building = true;
render() render()
.then((form) => { .then((form) => {
@@ -882,13 +878,23 @@ function mount() {
function watch() { function watch() {
const view = document.getElementById('view'); const view = document.getElementById('view');
if (_viewObserver && _observedView !== view) stopWatch(); /* The CONTAINER, by id not `#view`, which is not the same element for long. A client
* navigation builds a fresh one before it is in the document and swaps it in afterwards, while
* watch() runs on the `data-page` stamp, which comes first: the node bound here then reported
* `isConnected: false` while `#view` and `#maincontent` were both alive, and a Save's redraw
* produced four mutation batches that reached no callback at all. `#maincontent` outlives every
* swap, so the swap is itself a childList record. Save put the tab back in 250 ms after this,
* against 1,750-2,250 ms of waiting for the deadline before it. */
const root = document.getElementById('maincontent') || view;
if (_viewObserver && _observedRoot !== root) stopWatch();
if (_viewObserver || !view || !onPage()) return; if (_viewObserver || !view || !onPage()) return;
_observedView = view; _observedRoot = root;
_viewObserver = new MutationObserver(mount); _viewObserver = new MutationObserver(mount);
/* `data-initialized` is the moment the group becomes usable, and it does not always come with /* `data-initialized` is when the group becomes usable, and the filter is load-bearing proven
* a childList change (see retryMount above) */ * by staging openwrt/luci#8903 rather than waiting for it: tear the tab, the pane and the
_viewObserver.observe(view, { * attribute down in one task, restore the attribute ALONE 1,200 ms later, and the tab is back
* 4 ms after it. Without the filter it never comes back. No ordinary Save separates the two. */
_viewObserver.observe(root, {
childList: true, subtree: true, childList: true, subtree: true,
attributes: true, attributeFilter: [ 'data-initialized' ], attributes: true, attributeFilter: [ 'data-initialized' ],
}); });
@@ -900,13 +906,11 @@ function watch() {
* early on every mutation: the stock page renders, nothing throws, and every Appearance axis * early on every mutation: the stock page renders, nothing throws, and every Appearance axis
* is unreachable. */ * is unreachable. */
window.setTimeout(() => { window.setTimeout(() => {
/* It asks, it does not repair: with the observer on a node that survives a navigation the
* repair this used to attempt became unreachable, and the whole matrix passes without it.
* A group still found here means the observer is working, so there is nothing to report. */
const v = document.getElementById('view'); const v = document.getElementById('view');
if (!onPage() || !v || v.querySelector('.' + MARK) || _building) return; if (!onPage() || !v || v.querySelector('.' + MARK) || _building || tabGroup(v)) return;
/* one last attempt: the complaint below claims ui.tabs changed shape, which is only true
* if a fresh look still finds no group */
_retryAt = 0;
mount();
if (v.querySelector('.' + MARK) || _building || tabGroup(v)) return;
console.error('footstrap: the Appearance tab could not be attached — this page has tabs, but ' console.error('footstrap: the Appearance tab could not be attached — this page has tabs, but '
+ 'ui.tabs no longer marks them the way fs-appearance.js looks for. Every Appearance axis ' + 'ui.tabs no longer marks them the way fs-appearance.js looks for. Every Appearance axis '
+ 'is unreachable until that is updated.'); + 'is unreachable until that is updated.');
@@ -104,16 +104,22 @@ function arrange() {
* coalesced and one observer per #view node. The SPA router may replace #view between visits, so * coalesced and one observer per #view node. The SPA router may replace #view between visits, so
* re-attach when the observed node is no longer the current one a singleton bound to the first * re-attach when the observed node is no longer the current one a singleton bound to the first
* #view would watch a detached tree and the grid would never apply again. */ * #view would watch a detached tree and the grid would never apply again. */
let _observer = null, _observedView = null, _routeObserver = null; let _observer = null, _observedRoot = null, _routeObserver = null;
function stopWatch() { function stopWatch() {
if (_observer) _observer.disconnect(); if (_observer) _observer.disconnect();
_observer = null; _observer = null;
_observedView = null; _observedRoot = null;
_wrapEl = null; /* the grid belongs to the #view we are leaving */ _wrapEl = null; /* the grid belongs to the #view we are leaving */
} }
function watch() { function watch() {
const view = document.getElementById('view'); const view = document.getElementById('view');
if (_observer && _observedView !== view) /* `#maincontent`, not `#view`: a client navigation builds a fresh `#view` before it is in the
* document and swaps it in afterwards, and this runs on the `data-page` stamp, which comes
* first so the observer bound here read `isConnected: false` after one round trip and the
* grid stopped being re-arranged on every poll tick, silently, until the next full load. The
* shell's column outlives every swap. Same fault, same fix as fs-appearance.js. */
const root = document.getElementById('maincontent') || view;
if (_observer && _observedRoot !== root)
stopWatch(); stopWatch();
arrange(); arrange();
/* a chrome module is alive on every page, so without the route check an observer would attach /* a chrome module is alive on every page, so without the route check an observer would attach
@@ -121,11 +127,11 @@ function watch() {
if (_observer || !view || if (_observer || !view ||
(document.body.getAttribute('data-page') || '') !== 'admin-status-overview') (document.body.getAttribute('data-page') || '') !== 'admin-status-overview')
return; return;
_observedView = view; _observedRoot = root;
/* one arrange() per frame, however many mutations a poll tick delivers (fit.frame the /* one arrange() per frame, however many mutations a poll tick delivers (fit.frame the
* theme's shared coalescer, fs-fit.js) */ * theme's shared coalescer, fs-fit.js) */
_observer = new MutationObserver(fit.frame(arrange)); _observer = new MutationObserver(fit.frame(arrange));
_observer.observe(view, { childList: true, subtree: true }); _observer.observe(root, { childList: true, subtree: true });
} }
/* A chrome module is instantiated once per page load, so it has to notice SPA navigation itself. /* A chrome module is instantiated once per page load, so it has to notice SPA navigation itself.
+1 -1
View File
@@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=my-default-settings PKG_NAME:=my-default-settings
PKG_VERSION:=2 PKG_VERSION:=2
PKG_RELEASE:=9 PKG_RELEASE:=10
include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/package.mk
@@ -1,7 +1,7 @@
<% if luci.sys.exec("echo -n `uci -q get base_config.@status[0].links`") ~= "0" then %> <% if luci.sys.exec("echo -n `uci -q get base_config.@status[0].links`") ~= "0" then %>
<script> <script>
var links = document.createElement('div'); var links = document.createElement('div');
links.innerHTML ='<table class="table"><tr class="tr"><td class="td left"><a href="https://openwrt.ai/" target="_blank">固件下载与定制</a></td><td class="td left" width="25%"><a href="https://openwrt.ai/fadian/" target="_blank" style="color:orangered">赞助</a></td><td class="td left" width="25%"><a href="https://t.me/opwrt" target="_blank">TG频道</a></td><td class="td left" width="25%"><a href="https://github.com/kiddin9/OpenWrt_x86-r2s-r4s" target="_blank">源码与反馈</a></td></tr></table>'; links.innerHTML ='<table class="table"><tr class="tr"><td class="td left"><a href="https://openwrt.ai/" target="_blank">固件下载与定制</a></td><td class="td left" width="25%"><a href="https://openwrt.ai/fadian/" target="_blank" style="color:orangered">赞助</a></td><td class="td left" width="25%"><a href="https://github.com/kiddin9/Kwrt" target="_blank">源码与反馈</a></td><td class="td left" width="25%"><a href="https://t.me/opkwrt" target="_blank">TG交流</a></td></tr></table>';
setTimeout(function(){ setTimeout(function(){
var telegram = document.querySelectorAll(".cbi-section")[0]; var telegram = document.querySelectorAll(".cbi-section")[0];
telegram.appendChild(links); telegram.appendChild(links);