diff --git a/clashoo/Makefile b/clashoo/Makefile index 3c4069b4..80b448fc 100644 --- a/clashoo/Makefile +++ b/clashoo/Makefile @@ -1,19 +1,20 @@ include $(TOPDIR)/rules.mk PKG_NAME:=clashoo -PKG_SHORT_SHA:=6780eee -PKG_COMMIT_DATE:=2026.10.25 +PKG_UPSTREAM_VERSION:=1.19.33 +PKG_UPSTREAM_TAG:=v$(PKG_UPSTREAM_VERSION) +PKG_SHORT_SHA:=3f27ef3 -PKG_VERSION:=$(PKG_COMMIT_DATE)~$(PKG_SHORT_SHA) -PKG_RELEASE:=3 +PKG_VERSION:=2026.10.25.$(PKG_UPSTREAM_VERSION) +PKG_RELEASE:=1 -PKG_SOURCE:=$(PKG_NAME)-alpha-$(PKG_SHORT_SHA).tar.gz -PKG_SOURCE_SUBDIR:=$(PKG_NAME)-alpha-$(PKG_SHORT_SHA) -PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-alpha-$(PKG_SHORT_SHA) +PKG_SOURCE:=$(PKG_NAME)-stable-$(PKG_UPSTREAM_TAG)-$(PKG_SHORT_SHA).tar.gz +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-stable-$(PKG_UPSTREAM_TAG)-$(PKG_SHORT_SHA) +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_SUBDIR) PKG_SOURCE_URL:=https://github.com/kenzok8/openwrt-clashoo/releases/download/mihomo-src -PKG_SOURCE_VERSION:=6780eeeb27c7eda5e79a6310a4f7f91ba7cb725d -PKG_HASH:=affb9e916e750c6bd4385c6718660a02cc213936063141fd1c2422011e408b47 -PKG_BUILD_VERSION:=alpha-$(PKG_SHORT_SHA) +PKG_SOURCE_VERSION:=3f27ef39f8c96bbfbc8b0b9bb10f5c9ef60149d8 +PKG_HASH:=1ef7a4087f3805bd2624a940e2e43a0bc23719a25465c9f503aa6c11572f1321 +PKG_BUILD_VERSION:=$(PKG_UPSTREAM_TAG) PKG_LICENSE:=GPL3.0+ PKG_MAINTAINER:=kenzok8 @@ -50,8 +51,11 @@ endef define Package/clashoo/install $(call GoPackage/Package/Install/Bin,$(1)) + $(INSTALL_DIR) $(1)/usr/libexec/clashoo $(INSTALL_DIR) $(1)/usr/bin - ln -sf /usr/bin/mihomo $(1)/usr/bin/clash-meta + mv -f $(1)/usr/bin/mihomo $(1)/usr/libexec/clashoo/mihomo-stable + ln -sf /usr/libexec/clashoo/mihomo-stable $(1)/usr/bin/mihomo + ln -sf /usr/libexec/clashoo/mihomo-stable $(1)/usr/bin/clash-meta $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_DIR) $(1)/etc/config @@ -82,10 +86,44 @@ define Package/clashoo/install $(RM) $(1)/usr/share/clashoo/core_down_complete endef +define Package/clashoo/preinst +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + save_core() { + src="$$1" + dst="$$2" + [ -f "$$src" ] && [ ! -L "$$src" ] || return 0 + if [ -e "$$dst" ] || [ -L "$$dst" ]; then return 0; fi + mkdir -p "$$(dirname "$$dst")" || return 1 + tmp="$$dst.tmp.$$$$" + cp "$$src" "$$tmp" && chmod 0755 "$$tmp" && cmp -s "$$src" "$$tmp" || { + rm -f "$$tmp" + return 1 + } + if command -v sha256sum >/dev/null 2>&1; then + old_hash="$$(sha256sum "$$src" | awk '{print $$1}')" + new_hash="$$(sha256sum "$$tmp" | awk '{print $$1}')" + [ "$$old_hash" = "$$new_hash" ] || { + rm -f "$$tmp" + return 1 + } + fi + mv -f "$$tmp" "$$dst" + } + save_core /usr/bin/mihomo /usr/share/clashoo/bin/mihomo-alpha || exit 1 + save_core /usr/bin/mihomo-stable /usr/share/clashoo/bin/mihomo-stable || exit 1 + if [ -x /usr/bin/clash-meta ] && [ ! -L /usr/bin/clash-meta ] && [ ! -e /usr/share/clashoo/bin/mihomo-stable ]; then + if ! /usr/bin/clash-meta -v 2>/dev/null | grep -Eiq '(alpha|beta|rc|pre|smart)'; then + save_core /usr/bin/clash-meta /usr/share/clashoo/bin/mihomo-stable || exit 1 + fi + fi +fi +exit 0 +endef + define Package/clashoo/postinst #!/bin/sh if [ -z "$${IPKG_INSTROOT}" ]; then - [ -x /usr/bin/mihomo ] && [ ! -x /usr/bin/clash-meta ] && ln -sf /usr/bin/mihomo /usr/bin/clash-meta rm -f /usr/share/clashoo/check_luci_version.sh /usr/share/clashoo/check_clash_meta_version.sh /usr/share/clashoo/check_mihomo_core_version.sh rm -f /usr/share/clashoo/cuslist.sh /usr/share/clashoo/groups.sh /usr/share/clashoo/load_groups.sh /usr/share/clashoo/panel_diag.sh rm -f /usr/share/clashoo/rmlist.sh /usr/share/clashoo/uplist.sh /usr/share/clashoo/rpc_restart_async.sh /usr/share/clashoo/rpc_update_china_ip_async.sh diff --git a/clashoo/files/etc/config/clashoo b/clashoo/files/etc/config/clashoo index 1b0e2392..d744fb10 100644 --- a/clashoo/files/etc/config/clashoo +++ b/clashoo/files/etc/config/clashoo @@ -9,7 +9,7 @@ config clashoo 'config' option dash_port '9090' option dashboard_panel 'zashboard' option level 'info' - option core '3' + option core '2' option allow_lan '1' option dnsforwader '1' option subcri 'meta' @@ -28,7 +28,7 @@ config clashoo 'config' option listen_port '1053' option interf '0' option download_core 'amd64-compatible' - option dcore '3' + option dcore '2' option same_tag '1' option geoip_source '3' option geoip_format 'mmdb' diff --git a/clashoo/files/etc/init.d/clashoo b/clashoo/files/etc/init.d/clashoo index 13e25189..f926fe63 100755 --- a/clashoo/files/etc/init.d/clashoo +++ b/clashoo/files/etc/init.d/clashoo @@ -169,43 +169,54 @@ cleanup_stale_core_nft() { } _core_candidates() { - echo "/usr/bin/mihomo-stable /usr/bin/mihomo /usr/bin/clash-meta /etc/clashoo/clash" + echo "/usr/share/clashoo/bin/mihomo-stable /usr/libexec/clashoo/mihomo-stable /usr/share/clashoo/bin/mihomo-alpha /usr/bin/mihomo /usr/bin/clash-meta /etc/clashoo/clash" } _migrate_legacy_mihomo_stable() { - local legacy=/usr/bin/clash-meta version - [ -x /usr/bin/mihomo-stable ] && return 0 + local legacy=/usr/bin/clash-meta target=/usr/share/clashoo/bin/mihomo-stable version staged + [ -x "$target" ] && return 0 [ -x "$legacy" ] && [ ! -L "$legacy" ] || return 0 version=$("$legacy" -v 2>/dev/null | head -n 1) [ -n "$version" ] || return 0 echo "$version" | grep -Eiq '(alpha|beta|rc|pre|smart)' && return 0 - cp -f "$legacy" /usr/bin/mihomo-stable 2>/dev/null && chmod 0755 /usr/bin/mihomo-stable + mkdir -p "$(dirname "$target")" || return 1 + staged="${target}.$$" + cp -f "$legacy" "$staged" 2>/dev/null && chmod 0755 "$staged" && mv -f "$staged" "$target" } -_fallback_missing_mihomo_core() { - local selected fallback - is_singbox_selected && return 0 - selected="$(uci -q get clashoo.config.core 2>/dev/null)" - case "$selected" in - 2) - [ -x /usr/bin/mihomo-stable ] && return 0 - [ -x /usr/bin/mihomo ] || return 0 - fallback=3 - ;; - 3) - [ -x /usr/bin/mihomo ] && return 0 - [ -x /usr/bin/mihomo-stable ] || return 0 - fallback=2 - ;; - *) return 0 ;; - esac - uci -q set clashoo.config.core="$fallback" - uci -q set clashoo.config.dcore="$fallback" - uci -q commit clashoo >/dev/null 2>&1 - if [ "$fallback" = "3" ]; then - log_msg "Stable core missing, falling back to Alpha" "稳定版内核缺失,自动回退到 Alpha" +_mihomo_stable_binary() { + local bundled=/usr/libexec/clashoo/mihomo-stable manual=/usr/share/clashoo/bin/mihomo-stable bundled_ver manual_ver + # A successful custom download is an explicit override, even if its version is older. + if [ -x "$manual" ] && + [ "$(sed -n '1{s/^[[:space:]]*//;s/[[:space:]]*$//;p;}' /usr/share/clashoo/clash_meta_version 2>/dev/null)" = "custom-url" ]; then + echo "$manual" + return 0 + fi + [ -x "$bundled" ] || { [ -x "$manual" ] && { echo "$manual"; return 0; }; return 1; } + [ -x "$manual" ] || { echo "$bundled"; return; } + bundled_ver="$("$bundled" -v 2>/dev/null | awk '{for (i = 1; i < NF; i++) if ($i == "Meta") {print $(i + 1); exit}}')" + manual_ver="$("$manual" -v 2>/dev/null | awk '{for (i = 1; i < NF; i++) if ($i == "Meta") {print $(i + 1); exit}}')" + bundled_ver="${bundled_ver#v}" + manual_ver="${manual_ver#v}" + printf '%s\n' "$bundled_ver" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$' || bundled_ver="" + printf '%s\n' "$manual_ver" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$' || manual_ver="" + if [ -n "$bundled_ver" ] && [ -n "$manual_ver" ]; then + if awk -v manual="$manual_ver" -v bundled="$bundled_ver" 'BEGIN { + split(manual, m, "."); split(bundled, b, "."); + for (i = 1; i <= 3; i++) { + if (m[i] + 0 > b[i] + 0) exit 0; + if (m[i] + 0 < b[i] + 0) exit 1; + } + exit 0; + }'; then + echo "$manual" + else + echo "$bundled" + fi + elif [ -n "$manual_ver" ]; then + echo "$manual" else - log_msg "Alpha core missing, falling back to stable" "Alpha 内核缺失,自动回退到稳定版" + echo "$bundled" fi } @@ -220,11 +231,11 @@ _detect_selected_core() { return 1 ;; 2|mihomo) - [ -x /usr/bin/mihomo-stable ] && echo /usr/bin/mihomo-stable && return - return 1 + _mihomo_stable_binary + return $? ;; 3|mihomo-alpha) - [ -x /usr/bin/mihomo ] && echo /usr/bin/mihomo && return + [ -x /usr/share/clashoo/bin/mihomo-alpha ] && echo /usr/share/clashoo/bin/mihomo-alpha && return return 1 ;; esac @@ -233,7 +244,7 @@ _detect_selected_core() { core_supports_advanced_features() { case "$CLASH" in - */mihomo|*/mihomo-stable|*/clash-meta|*/smart) + */mihomo|*/mihomo-stable|*/mihomo-alpha|*/clash-meta|*/smart) return 0 ;; *) @@ -2126,12 +2137,12 @@ _start_validate_core() { echo "Clashoo" > "$REAL_LOG" return 1 elif [ "${core:-0}" -eq 2 ] && [ ! -x "$CLASH" ]; then - log_msg "mihomo core not found, detected binary is unavailable: $CLASH" "找不到可用的 mihomo 内核: $CLASH" + log_msg "mihomo stable core not found, detected binary is unavailable: $CLASH" "找不到可用的 mihomo 稳定版内核: $CLASH" sleep 1 echo "Clashoo" > "$REAL_LOG" return 1 elif [ "${core:-0}" -eq 3 ] && [ ! -x "$CLASH" ]; then - log_msg "mihomo core not found, detected binary is unavailable: $CLASH" "找不到可用的 mihomo 内核: $CLASH" + log_msg "mihomo Alpha core not found, detected binary is unavailable: $CLASH" "找不到可用的 mihomo Alpha 内核,请在组件更新中安装: $CLASH" sleep 1 echo "Clashoo" > "$REAL_LOG" return 1 @@ -2167,10 +2178,10 @@ _start_prepare_config() { if { egrep -q '^ {0,}rule-providers:' "$CONFIG_YAML" || egrep -q '^ {0,}script:' "$CONFIG_YAML"; } && ! core_supports_advanced_features; then [ "$_reload_candidate" = "1" ] && return 1 - if [ -x /usr/bin/mihomo ]; then - uci set clashoo.config.core="3" && uci commit clashoo - elif [ -x /usr/bin/mihomo-stable ]; then + if [ -n "$(_mihomo_stable_binary)" ]; then uci set clashoo.config.core="2" && uci commit clashoo + elif [ -x /usr/share/clashoo/bin/mihomo-alpha ]; then + uci set clashoo.config.core="3" && uci commit clashoo else log_msg "Current config requires mihomo/clash-meta core" "当前配置需要 mihomo 或 clash-meta 内核" backend_remove_rules >/dev/null 2>&1 @@ -2407,7 +2418,6 @@ start_service(){ sync_legacy_core_field _migrate_legacy_mihomo_stable - _fallback_missing_mihomo_core CLASH="$(_detect_selected_core)" cleanup_legacy_startup_backups diff --git a/clashoo/files/usr/share/clashoo/nftables/geoip6_cn.nft b/clashoo/files/usr/share/clashoo/nftables/geoip6_cn.nft index 69367b5b..5cd2612d 100644 --- a/clashoo/files/usr/share/clashoo/nftables/geoip6_cn.nft +++ b/clashoo/files/usr/share/clashoo/nftables/geoip6_cn.nft @@ -120,7 +120,6 @@ set clashoo_china6 { 2400:5280:1400::/38, 2400:5280:1c00::/38, 2400:5280:3400::/38, - 2400:5280:4c00::/38, 2400:5280:5000::/36, 2400:5280:6000::/35, 2400:5280:8000::/34, @@ -962,6 +961,7 @@ set clashoo_china6 { 2402:7d80::/32, 2402:7da0::/32, 2402:7e20::/32, + 2402:7ee0::/32, 2402:8180::/32, 2402:8300::/32, 2402:8380::/32, @@ -1791,7 +1791,11 @@ set clashoo_china6 { 2405:84c0:8050::/48, 2405:84c0:8053::/48, 2405:84c0:8058::/45, - 2405:84c0:8060::/43, + 2405:84c0:8061::/48, + 2405:84c0:8062::/47, + 2405:84c0:8064::/46, + 2405:84c0:8068::/45, + 2405:84c0:8070::/44, 2405:84c0:8080::/41, 2405:84c0:8100::/40, 2405:84c0:8200::/39, @@ -2050,7 +2054,10 @@ set clashoo_china6 { 2406:840:8a0::/43, 2406:840:8c0::/42, 2406:840:900::/40, - 2406:840:a00::/44, + 2406:840:a01::/48, + 2406:840:a02::/47, + 2406:840:a04::/46, + 2406:840:a08::/45, 2406:840:a12::/47, 2406:840:a14::/46, 2406:840:a18::/45, @@ -2248,7 +2255,8 @@ set clashoo_china6 { 2406:840:9610::/44, 2406:840:9630::/44, 2406:840:9640::/43, - 2406:840:9660::/46, + 2406:840:9660::/48, + 2406:840:9662::/47, 2406:840:9664::/47, 2406:840:9667::/48, 2406:840:9668::/45, @@ -2272,6 +2280,7 @@ set clashoo_china6 { 2406:840:9900::/42, 2406:840:9940::/43, 2406:840:9960::/47, + 2406:840:9963::/48, 2406:840:9965::/48, 2406:840:9968::/46, 2406:840:996d::/48, @@ -3144,8 +3153,7 @@ set clashoo_china6 { 240b:4006::/48, 240b:4006:1000::/43, 240b:4006:1020::/44, - 240b:4006:1100::/45, - 240b:4006:110c::/46, + 240b:4006:1100::/44, 240b:4006:1110::/45, 240b:4006:1118::/46, 240b:4007::/32, @@ -3261,8 +3269,6 @@ set clashoo_china6 { 2605:9d80:9042::/48, 2605:9d80:9071::/48, 2605:9d80:9092::/48, - 2620:57:4004::/47, - 2804:1e48:9002::/48, 2a03:f900::/29, 2a04:3e00::/48, 2a04:3e00:2::/47, diff --git a/clashoo/files/usr/share/clashoo/nftables/geoip_cn.nft b/clashoo/files/usr/share/clashoo/nftables/geoip_cn.nft index 7661766e..26ac0cf7 100644 --- a/clashoo/files/usr/share/clashoo/nftables/geoip_cn.nft +++ b/clashoo/files/usr/share/clashoo/nftables/geoip_cn.nft @@ -394,16 +394,13 @@ set clashoo_china { 43.92.0.0/15, 43.94.0.0/18, 43.96.0.0/23, - 43.96.2.130/32, 43.96.3.0/24, 43.96.4.0/22, 43.96.8.0/22, - 43.96.16.130/32, 43.96.18.0/24, 43.96.20.0/22, 43.96.24.0/22, 43.96.32.0/22, - 43.96.36.130/32, 43.96.40.0/24, 43.96.42.0/24, 43.96.44.0/23, @@ -414,7 +411,6 @@ set clashoo_china { 43.96.62.0/23, 43.96.64.0/21, 43.96.72.0/22, - 43.96.77.131/32, 43.96.78.0/24, 43.96.80.0/23, 43.96.85.0/24, @@ -459,8 +455,7 @@ set clashoo_china { 43.123.0.0/17, 43.123.128.0/18, 43.124.0.0/16, - 43.125.0.0/20, - 43.125.24.0/21, + 43.125.0.0/19, 43.125.32.0/20, 43.125.48.0/21, 43.126.0.0/17, @@ -805,6 +800,7 @@ set clashoo_china { 45.117.68.0/22, 45.117.124.0/22, 45.117.252.0/22, + 45.119.42.0/23, 45.119.60.0/22, 45.119.64.0/21, 45.119.72.0/22, @@ -1124,6 +1120,7 @@ set clashoo_china { 47.246.192.0/20, 47.246.208.0/23, 47.246.212.0/22, + 47.246.216.0/22, 47.250.0.0/18, 47.250.68.0/22, 47.250.72.0/21, @@ -1478,8 +1475,7 @@ set clashoo_china { 103.8.108.0/22, 103.8.156.0/22, 103.8.200.0/21, - 103.8.221.0/24, - 103.8.222.0/23, + 103.8.220.0/22, 103.9.8.0/22, 103.9.24.0/22, 103.9.108.0/22, @@ -2113,7 +2109,6 @@ set clashoo_china { 103.89.184.0/21, 103.89.192.0/19, 103.89.224.0/21, - 103.90.51.0/24, 103.90.52.0/22, 103.90.56.0/23, 103.90.92.0/22, @@ -2683,6 +2678,7 @@ set clashoo_china { 103.186.228.0/23, 103.189.92.0/23, 103.189.152.0/22, + 103.189.197.0/24, 103.190.20.0/23, 103.190.71.0/24, 103.190.104.0/23, @@ -4062,10 +4058,6 @@ set clashoo_china { 124.67.0.0/16, 124.68.16.0/20, 124.68.64.0/18, - 124.68.176.0/20, - 124.68.224.0/20, - 124.68.244.0/22, - 124.68.248.0/21, 124.69.0.0/16, 124.70.0.0/16, 124.71.0.0/17, @@ -4445,6 +4437,7 @@ set clashoo_china { 160.202.62.0/24, 160.202.148.0/22, 160.202.152.0/22, + 160.202.210.0/23, 160.202.212.0/22, 160.202.216.0/21, 160.202.224.0/19, @@ -4741,6 +4734,7 @@ set clashoo_china { 192.140.160.0/19, 192.140.192.0/20, 192.140.208.0/21, + 192.140.244.0/23, 192.144.128.0/17, 192.163.11.0/24, 192.232.34.0/23, @@ -6497,12 +6491,14 @@ set clashoo_china { 223.112.0.0/14, 223.116.0.0/15, 223.121.128.0/17, - 223.122.4.0/22, - 223.122.12.0/22, + 223.122.5.0/24, + 223.122.6.0/23, + 223.122.13.0/24, + 223.122.14.0/23, 223.122.18.0/23, 223.122.20.0/22, 223.122.26.0/23, - 223.122.28.0/22, + 223.122.28.0/23, 223.123.196.0/22, 223.123.204.0/22, 223.123.208.0/20, diff --git a/clashoo/files/usr/share/clashoo/ruleset/cn-ip.srs b/clashoo/files/usr/share/clashoo/ruleset/cn-ip.srs index d0b0b745..ef9118fa 100644 Binary files a/clashoo/files/usr/share/clashoo/ruleset/cn-ip.srs and b/clashoo/files/usr/share/clashoo/ruleset/cn-ip.srs differ diff --git a/clashoo/files/usr/share/clashoo/ruleset/cn.mrs b/clashoo/files/usr/share/clashoo/ruleset/cn.mrs index 536c85a7..610f2d2d 100644 Binary files a/clashoo/files/usr/share/clashoo/ruleset/cn.mrs and b/clashoo/files/usr/share/clashoo/ruleset/cn.mrs differ diff --git a/clashoo/files/usr/share/clashoo/ruleset/geolocation-!cn.srs b/clashoo/files/usr/share/clashoo/ruleset/geolocation-!cn.srs index e3c6a513..6f26b898 100644 Binary files a/clashoo/files/usr/share/clashoo/ruleset/geolocation-!cn.srs and b/clashoo/files/usr/share/clashoo/ruleset/geolocation-!cn.srs differ diff --git a/clashoo/files/usr/share/clashoo/ruleset/geosite-cn.srs b/clashoo/files/usr/share/clashoo/ruleset/geosite-cn.srs index db4f38eb..216609fe 100644 Binary files a/clashoo/files/usr/share/clashoo/ruleset/geosite-cn.srs and b/clashoo/files/usr/share/clashoo/ruleset/geosite-cn.srs differ diff --git a/clashoo/files/usr/share/clashoo/ruleset/private-ip.srs b/clashoo/files/usr/share/clashoo/ruleset/private-ip.srs index 7fa17b9a..f825d93c 100644 Binary files a/clashoo/files/usr/share/clashoo/ruleset/private-ip.srs and b/clashoo/files/usr/share/clashoo/ruleset/private-ip.srs differ diff --git a/clashoo/files/usr/share/clashoo/update/core_download.sh b/clashoo/files/usr/share/clashoo/update/core_download.sh index f5aec7ac..9407fd1a 100755 --- a/clashoo/files/usr/share/clashoo/update/core_download.sh +++ b/clashoo/files/usr/share/clashoo/update/core_download.sh @@ -1062,10 +1062,10 @@ if [ -n "$CUSTOM_CORE_URL" ]; then write_log "使用自定义内核下载链接" URL="$CUSTOM_CORE_URL" if [ "$CORETYPE" = "3" ]; then - TARGET="/usr/bin/mihomo" + TARGET="/usr/share/clashoo/bin/mihomo-alpha" VERSION_FILE="/usr/share/clashoo/mihomo_version" else - TARGET="/usr/bin/mihomo-stable" + TARGET="/usr/share/clashoo/bin/mihomo-stable" VERSION_FILE="/usr/share/clashoo/clash_meta_version" fi TAG="custom" @@ -1175,7 +1175,7 @@ elif [ "$CORETYPE" = "2" ]; then [ -z "$TAG" ] && write_log "获取稳定版版本号失败" && exit 1 ASSET=$(pick_mihomo_asset "MetaCubeX/mihomo" "$TAG" "$(map_mihomo_arch "$MODELTYPE")" "stable") URL="https://github.com/MetaCubeX/mihomo/releases/download/${TAG}/${ASSET}" - TARGET="/usr/bin/mihomo-stable" + TARGET="/usr/share/clashoo/bin/mihomo-stable" VERSION_FILE="/usr/share/clashoo/clash_meta_version" VERSION_VALUE="$TAG" else @@ -1189,7 +1189,7 @@ else [ -z "$ASSET" ] && ASSET=$(pick_mihomo_asset "MetaCubeX/mihomo" "$TAG" "$(map_mihomo_arch "$MODELTYPE")" "alpha") [ -z "$ASSET" ] && ASSET=$(pick_mihomo_asset "MetaCubeX/mihomo" "$TAG" "$(map_mihomo_arch "$MODELTYPE")" "stable") URL="https://github.com/MetaCubeX/mihomo/releases/download/${TAG}/${ASSET}" - TARGET="/usr/bin/mihomo" + TARGET="/usr/share/clashoo/bin/mihomo-alpha" VERSION_FILE="/usr/share/clashoo/mihomo_version" VERSION_VALUE="$(printf '%s\n' "$ASSET" | sed -n 's#^mihomo-.*-alpha-\([0-9a-fA-F]\{7,\}\)\.gz$#\1#p' | head -n 1)" [ -z "$VERSION_VALUE" ] && VERSION_VALUE="$TAG" diff --git a/luci-app-bandix/Makefile b/luci-app-bandix/Makefile index 0467f134..85eda9c1 100644 --- a/luci-app-bandix/Makefile +++ b/luci-app-bandix/Makefile @@ -11,8 +11,10 @@ LUCI_DEPENDS:=+luci-base +luci-lib-jsonc +curl +bandix PKG_MAINTAINER:=timsaya PKG_VERSION:=0.12.12 -PKG_RELEASE:=1 +PKG_RELEASE:=3 +# Rebuild language packages when a package revision changes without a PO commit. +PKG_PO_VERSION=$(if $(DUMP),x,$(strip $(call findrev)))-r$(PKG_RELEASE) include $(TOPDIR)/feeds/luci/luci.mk -# call BuildPackage - OpenWrt buildroot signature \ No newline at end of file +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-bandix/htdocs/luci-static/resources/bandix/geoip.js b/luci-app-bandix/htdocs/luci-static/resources/bandix/geoip.js new file mode 100644 index 00000000..c4876b50 --- /dev/null +++ b/luci-app-bandix/htdocs/luci-static/resources/bandix/geoip.js @@ -0,0 +1,227 @@ +'use strict'; +'require baseclass'; +'require rpc'; +'require ui'; +'require poll'; +'require request'; + +var callStatus = rpc.declare({ object: 'luci.bandix', method: 'getGeoipStatus', expect: {} }); +var callManage = rpc.declare({ object: 'luci.bandix', method: 'manageGeoip', params: ['action', 'profile', 'enabled'], expect: {} }); + +function size(bytes) { + if (bytes == null) return '—'; + if (bytes < 1024) return bytes + ' B'; + if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KiB'; + return (bytes / 1048576).toFixed(1) + ' MiB'; +} +function unwrap(reply) { + if (!reply || reply.status !== 'success' || !reply.data) throw new Error(reply && (reply.message || reply.error) || _('GeoIP service is unavailable. Enable connection monitoring and apply settings, or update Bandix.')); + return reply.data; +} +function localized(names) { + var language = (L.env.lang || document.documentElement.lang || 'en').replace(/_/g, '-'); + var key = /^zh/i.test(language) ? 'zh-CN' : language.split('-')[0]; + return names && (names[key] || names.en) || ''; +} +function countryName(info) { + if (info.country_code && typeof Intl !== 'undefined' && Intl.DisplayNames) { + try { return new Intl.DisplayNames([(L.env.lang || 'en').replace(/_/g, '-')], { type: 'region' }).of(info.country_code); } catch (e) { /* use database names */ } + } + return localized(info.country_names) || info.country_code || ''; +} +var scopes = { + local: _('Local network'), private: _('Private address'), loopback: _('Loopback'), + link_local: _('Link-local address'), shared: _('Shared address (CGNAT)'), + multicast: _('Multicast'), unspecified: _('Unspecified address'), + documentation: _('Documentation address'), reserved: _('Reserved address'), unknown: _('Unknown location') +}; +var phases = { + preparing: _('Checking database version…'), checking_space: _('Checking storage…'), + downloading: _('Downloading database…'), verifying: _('Verifying database…'), + activating: _('Loading database…'), importing: _('Importing database…'), + completed: _('Database ready'), up_to_date: _('Database is up to date'), + cancelled: _('Download cancelled'), failed: _('Database operation failed') +}; + +return baseclass.extend({ + describe: function (info) { + if (!info) return null; + if (info.scope !== 'public') return { summary: scopes[info.scope] || scopes.unknown, details: scopes[info.scope] || scopes.unknown }; + var country = countryName(info), region = localized(info.region_names), city = localized(info.city_names); + var location = [country, region, city].filter(function (value, index, all) { return value && all.indexOf(value) === index; }).join(' · '); + return { + summary: [location, info.organization].filter(Boolean).join(' · ') || scopes.unknown, + details: [location, info.asn ? 'AS' + info.asn : '', info.organization].filter(Boolean).join('\n') + }; + }, + + render: function () { + if (this._root) return this._root; + var root, current = null, pending = false, refreshing = false, dirtyProfile = false; + var badge = E('strong', {}, _('Loading…')); + var enabled = E('input', { type: 'checkbox', disabled: true }); + var profile = E('select', { 'class': 'cbi-input-select', 'aria-label': _('Database contents') }, [ + E('option', { value: 'country' }, _('Country/region — approximately 3.3 MiB')), + E('option', { value: 'country_asn' }, _('Country/region + network organization — approximately 12 MiB')), + E('option', { value: 'city_asn' }, _('Province/city + network organization — approximately 57 MiB')) + ]); + var importedCity = null; + var details = E('div', { style: 'color:var(--text-color-secondary,#888);font-size:0.9em;line-height:1.6;overflow-wrap:anywhere' }); + var message = E('div', { role: 'status', 'aria-live': 'polite', style: 'font-size:0.9em;overflow-wrap:anywhere' }); + var progressFill = E('div', { style: 'width:0%' }); + var progress = E('div', { 'class': 'cbi-progressbar', style: 'display:none;margin:8px 0', role: 'progressbar', 'aria-valuemin': 0, 'aria-valuemax': 100 }, progressFill); + var download = E('button', { type: 'button', 'class': 'btn cbi-button cbi-button-apply' }, _('Download and enable')); + var upload = E('button', { type: 'button', 'class': 'btn cbi-button' }, _('Upload database')); + var cancel = E('button', { type: 'button', 'class': 'btn cbi-button', style: 'display:none' }, _('Cancel')); + var remove = E('button', { type: 'button', 'class': 'btn cbi-button cbi-button-negative', style: 'display:none' }, _('Delete')); + + function display(status) { + var wasBusy = current && current.job && current.job.busy; + if (wasBusy && status.job && !status.job.busy && status.job.phase === 'completed') dirtyProfile = false; + current = status; + var job = status.job || {}, databases = status.databases || [], busy = pending || job.busy; + badge.style.color = status.enabled ? 'var(--success-color,#2f9e44)' : ''; + badge.textContent = status.enabled ? _('Enabled') : databases.length ? _('Disabled') : _('Not installed'); + enabled.checked = !!status.enabled; enabled.disabled = busy || !databases.length; + if (!dirtyProfile && status.profile) { + if (status.profile === 'city' && !importedCity) { + importedCity = E('option', { value: 'city' }, _('Province/city (uploaded database)')); profile.appendChild(importedCity); + } + profile.value = status.profile; + } + if (job.busy && job.profile) profile.value = job.profile; + profile.disabled = busy; + download.disabled = busy; upload.disabled = busy; + download.textContent = databases.length ? _('Update database') : _('Download and enable'); + remove.style.display = databases.length || status.load_error ? '' : 'none'; remove.disabled = busy; + cancel.style.display = job.busy && job.phase !== 'activating' ? '' : 'none'; cancel.disabled = pending; + var builds = databases.map(function (db) { + var name = { country: _('Country/region'), city: _('Province/city'), asn: _('Network organization') }[db.kind] || db.kind; + var date = '—'; + if (db.build_epoch) { + try { date = new Date(db.build_epoch * 1000).toLocaleDateString((L.env.lang || 'en').replace(/_/g, '-')); } + catch (e) { date = new Date(db.build_epoch * 1000).toLocaleDateString(); } + } + return name + ' ' + date; + }); + details.textContent = [ + builds.length ? _('Version') + ': ' + builds.join(' · ') : '', + _('Storage used') + ': ' + size(status.installed_bytes) + ' · ' + _('Available space') + ': ' + size(status.free_bytes), + _('Database directory') + ': ' + status.directory + ].filter(Boolean).join('\n'); details.style.whiteSpace = 'pre-line'; + var total = job.total_bytes; + var percent = total > 0 ? Math.min(100, Math.floor((job.downloaded_bytes || 0) * 100 / total)) : null; + progress.style.display = job.busy && total > 0 ? '' : 'none'; + progressFill.style.width = (percent || 0) + '%'; + progress.title = percent == null ? '' : percent + '%'; + if (percent != null) progress.setAttribute('aria-valuenow', percent); + message.style.color = job.phase === 'failed' || status.load_error ? 'var(--error-color,#c0392b)' : ''; + if (status.load_error && !job.busy) { + message.textContent = _('The installed database could not be loaded. Download or upload it again.'); + message.title = status.load_error; + } else if (job.phase === 'failed') { + var errorMessage = job.error_phase === 'checking_space' + ? _('Cannot prepare storage. Check free space and directory permissions.') + : job.error_phase === 'verifying' + ? _('Database validation failed. The previous database is unchanged.') + : _('Database operation failed. Retry or upload a local database.'); + if (job.error_phase === 'checking_space' && status.free_bytes != null && job.required_bytes > status.free_bytes) { + errorMessage = _('Not enough free space for this database.') + ' ' + _('Required space') + ': ' + size(job.required_bytes) + ' · ' + _('Available space') + ': ' + size(status.free_bytes); + } + message.textContent = errorMessage; message.title = job.error || ''; + } else { + message.textContent = (phases[job.phase] || '') + (job.busy && total > 0 ? ' ' + size(job.downloaded_bytes || 0) + ' / ' + size(total) + ' (' + percent + '%)' : ''); + message.title = job.current_file || ''; + } + } + function refresh() { + if (refreshing || (root && !root.isConnected)) return Promise.resolve(); + refreshing = true; + return callStatus().then(unwrap).then(display).catch(function (error) { + message.textContent = _('GeoIP service is unavailable. Enable connection monitoring and apply settings, or update Bandix.'); + message.title = error.message || String(error); + download.disabled = true; upload.disabled = true; enabled.disabled = true; + }).finally(function () { refreshing = false; }); + } + function manage(action, selected, checked) { + pending = true; if (current) display(current); + return callManage(action, selected || '', checked ? '1' : '0').then(unwrap).then(function (status) { + if (action === 'download') dirtyProfile = true; + display(status); + }).catch(function (error) { + ui.addNotification(null, E('p', _('Database operation failed') + ': ' + (error.message || error)), 'error'); + }).finally(function () { pending = false; if (current) display(current); }); + } + profile.addEventListener('change', function () { dirtyProfile = true; }); + enabled.addEventListener('change', function () { manage('enable', null, enabled.checked); }); + download.addEventListener('click', function () { manage('download', profile.value); }); + cancel.addEventListener('click', function () { manage('cancel'); }); + remove.addEventListener('click', function () { + ui.showModal(_('Delete GeoIP databases'), [ + E('p', _('Remove installed databases and disable IP location lookup?')), + E('div', { 'class': 'right' }, [ + E('button', { type: 'button', 'class': 'btn', click: ui.hideModal }, _('Cancel')), ' ', + E('button', { type: 'button', 'class': 'btn cbi-button-negative', click: function () { ui.hideModal(); dirtyProfile = false; manage('delete'); } }, _('Delete')) + ]) + ]); + }); + upload.addEventListener('click', function () { + if (!current) return; + var limit = typeof current.upload_max_bytes === 'number' ? current.upload_max_bytes : 8 * 1048576; + var selection = E('input', { type: 'file', accept: '.mmdb', 'aria-label': _('Upload database') }); + var uploadError = E('p', { style: 'color:var(--error-color,#c0392b)', role: 'alert' }); + var uploadAction = E('button', { type: 'button', 'class': 'btn cbi-button-action important', disabled: true }, _('Upload and enable')); + selection.addEventListener('change', function () { + var file = selection.files[0]; + uploadAction.disabled = !file || !/\.mmdb$/i.test(file.name) || file.size === 0 || file.size > limit; + uploadError.textContent = uploadAction.disabled && file ? _('Choose an uncompressed .mmdb file within the upload size limit.') : ''; + }); + uploadAction.addEventListener('click', function () { + var file = selection.files[0]; if (!file || uploadAction.disabled) return; + pending = true; display(current); + var fill = E('div', { style: 'width:0%' }); + var bar = E('div', { 'class': 'cbi-progressbar' }, fill); + ui.showModal(_('Uploading database…'), [bar]); + var data = new FormData(); + data.append('sessionid', rpc.getSessionID()); + data.append('filename', '/tmp/bandix-geoip-upload.mmdb'); + data.append('filedata', file); + request.post(L.env.cgi_base + '/cgi-upload', data, { + timeout: 0, + progress: function (event) { + if (!event.total) return; + var percent = Math.min(100, Math.round(event.loaded * 100 / event.total)); + fill.style.width = percent + '%'; bar.title = percent + '%'; + } + }).then(function (response) { + var reply = response.json(); + if (!response.ok || reply.failure) throw new Error(reply.message || _('Database upload failed')); + ui.hideModal(); return manage('import'); + }).catch(function (error) { + ui.hideModal(); ui.addNotification(null, E('p', _('Database upload failed') + ': ' + (error.message || error)), 'error'); + }).finally(function () { pending = false; if (current) display(current); }); + }); + ui.showModal(_('Upload database'), [ + E('p', {}, _('Maximum upload size') + ': ' + size(limit)), selection, uploadError, + E('div', { 'class': 'right' }, [E('button', { type: 'button', 'class': 'btn', click: ui.hideModal }, _('Cancel')), ' ', uploadAction]) + ]); + }); + root = E('div', { style: 'max-width:780px' }, [ + E('div', { style: 'display:flex;flex-wrap:wrap;align-items:center;gap:16px;margin-bottom:12px' }, [ + E('label', { style: 'display:flex;align-items:center;gap:8px' }, [enabled, _('Enable IP location lookup')]), badge + ]), + E('div', { style: 'display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:10px' }, [profile, download, upload, cancel, remove]), + details, progress, message, + E('div', { style: 'font-size:0.85em;opacity:0.75;margin-top:8px' }, [ + _('Data source') + ': ', E('a', { href: 'https://github.com/P3TERX/GeoLite.mmdb', target: '_blank', rel: 'noopener noreferrer' }, 'P3TERX / MaxMind GeoLite2'), + ' · ', E('a', { href: 'https://www.maxmind.com/en/geolite2/eula', target: '_blank', rel: 'noopener noreferrer' }, _('Data terms')), + E('div', {}, _('Upload an uncompressed Country, City or ASN .mmdb file. To add ASN, install a Country or City database first.')) + ]) + ]); + this._root = root; + poll.add(refresh, 2); + // renderWidget returns before LuCI attaches the form to the document. + setTimeout(refresh, 0); + return root; + } +}); diff --git a/luci-app-bandix/htdocs/luci-static/resources/view/bandix/connection.js b/luci-app-bandix/htdocs/luci-static/resources/view/bandix/connection.js index 4a3be0d1..24852fb8 100644 --- a/luci-app-bandix/htdocs/luci-static/resources/view/bandix/connection.js +++ b/luci-app-bandix/htdocs/luci-static/resources/view/bandix/connection.js @@ -4,6 +4,7 @@ 'require uci'; 'require rpc'; 'require poll'; +'require bandix.geoip as geoip'; var BANDIX_MODAL_BG_OPENWRT2020_LIGHT = '#ffffff'; var BANDIX_MODAL_BG_OPENWRT2020_DARK = '#2a2a2a'; @@ -136,15 +137,21 @@ function formatSize(bytes) { // IPv6 地址按 RFC 3986 用方括号包起来,一是避免 '2600:...:8000::' + ':' + '80' 拼出 // ':::80' 这种分不清边界的写法,二是选中复制出来就是 [addr]:port,可以直接粘去用。 // 地址和端口是行内元素,复制时不会被拆成两行;端口自身 nowrap,不会被折断 -function flowEndpointCell(addr, port) { +function flowEndpointCell(addr, port, information) { var text = addr || '-'; if (text.indexOf(':') >= 0) { text = '[' + text + ']'; } - return E('td', { 'class': 'flows-addr-cell' }, [ + var description = geoip.describe(information); + var children = [E('div', {}, [ E('span', { 'class': 'flows-addr' }, text), E('span', { 'class': 'flows-port' }, port ? ':' + port : '') - ]); + ])]; + if (description) children.push(E('div', { + 'class': 'flows-geoip', title: description.details, + style: 'font-size:0.8rem;opacity:0.75;margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:240px' + }, description.summary)); + return E('td', { 'class': 'flows-addr-cell' }, children); } function formatDeviceName(device) { @@ -1211,7 +1218,8 @@ return view.extend({ total: res.data.total || 0, page: res.data.page || currentPage, page_size: res.data.page_size || currentPageSize, - total_pages: res.data.total_pages || 1 + total_pages: res.data.total_pages || 1, + geoip: res.data.geoip || {} }; } @@ -1233,6 +1241,7 @@ return view.extend({ tableBody.innerHTML = ''; var normalized = normalizeFlowsResponse(res); var flows = normalized.items; + var information = normalized.geoip || {}; totalItems = normalized.total; currentPage = normalized.page; totalPages = Math.max(1, normalized.total_pages); @@ -1258,11 +1267,11 @@ return view.extend({ tableBody.appendChild(E('tr', {}, [ E('td', { 'class': protoCls }, (f.protocol || '-').toUpperCase()), E('td', { 'class': 'flows-state-cell ' + stateCls }, f.state || '-'), - flowEndpointCell(f.orig && f.orig.src, f.orig && f.orig.sport), - flowEndpointCell(f.orig && f.orig.dst, f.orig && f.orig.dport), + flowEndpointCell(f.orig && f.orig.src, f.orig && f.orig.sport, information[f.orig && f.orig.src]), + flowEndpointCell(f.orig && f.orig.dst, f.orig && f.orig.dport, information[f.orig && f.orig.dst]), E('td', {}, sendStr), - flowEndpointCell(f.repl && f.repl.src, f.repl && f.repl.sport), - flowEndpointCell(f.repl && f.repl.dst, f.repl && f.repl.dport), + flowEndpointCell(f.repl && f.repl.src, f.repl && f.repl.sport, information[f.repl && f.repl.src]), + flowEndpointCell(f.repl && f.repl.dst, f.repl && f.repl.dport, information[f.repl && f.repl.dst]), E('td', {}, replyStr), E('td', { 'style': 'font-size: 0.8rem;' }, flagsStr) ])); diff --git a/luci-app-bandix/htdocs/luci-static/resources/view/bandix/settings.js b/luci-app-bandix/htdocs/luci-static/resources/view/bandix/settings.js index 70659560..5b472cc5 100644 --- a/luci-app-bandix/htdocs/luci-static/resources/view/bandix/settings.js +++ b/luci-app-bandix/htdocs/luci-static/resources/view/bandix/settings.js @@ -4,6 +4,7 @@ 'require ui'; 'require uci'; 'require rpc'; +'require bandix.geoip as geoip'; 'require tools.widgets as widgets'; @@ -231,6 +232,13 @@ return view.extend({ s.description = _('Configure basic parameters for Bandix service'); s.addremove = false; + o = s.option(form.Value, 'host', _('Listen Address'), + _('IP address for Bandix to listen on. Use 127.0.0.1 for local access or 0.0.0.0 / :: for all interfaces.')); + o.default = '127.0.0.1'; + o.datatype = 'ipaddr("nomask")'; + o.placeholder = '127.0.0.1'; + o.rmempty = false; + // 添加端口设置选项 o = s.option(form.Value, 'port', _('Port'), _('Port for Bandix service to listen on')); @@ -785,6 +793,16 @@ return view.extend({ o.default = '0'; o.rmempty = false; + o = s.option(form.DummyValue, '_geoip_manager', _('IP location database')); + o.renderWidget = function () { return geoip.render(); }; + + o = s.option(form.Value, 'geoip_dir', _('Database directory'), + _('Use persistent storage or an external drive. Save and apply directory changes before downloading.')); + o.default = '/usr/share/bandix-geoip'; + o.placeholder = '/usr/share/bandix-geoip'; + o.datatype = 'directory'; + o.rmempty = false; + // 4. DNS监控设置部分 (dns) s = m.section(form.NamedSection, 'dns', 'dns', _('DNS Monitor Settings')); s.description = _('Configure DNS monitoring related parameters'); diff --git a/luci-app-bandix/po/es/bandix.po b/luci-app-bandix/po/es/bandix.po index 0f89e6c6..ac2ce1fc 100644 --- a/luci-app-bandix/po/es/bandix.po +++ b/luci-app-bandix/po/es/bandix.po @@ -221,12 +221,6 @@ msgstr "WAN cargado" msgid "WAN Downloaded" msgstr "WAN descargado" -msgid "Total Upload" -msgstr "Carga total" - -msgid "Total Download" -msgstr "Descarga total" - msgid "LAN Upload" msgstr "Carga LAN" @@ -422,18 +416,12 @@ msgstr "Página" msgid "of" msgstr "de" -msgid "Total" -msgstr "Total" - msgid "records" msgstr "registros" msgid "Per Page" msgstr "Por página" -msgid "" -msgstr "" - msgid "Total Queries" msgstr "Total de consultas" @@ -938,18 +926,6 @@ msgstr "Máximo" msgid "Minimum" msgstr "Mínimo" -msgid "WAN Upload" -msgstr "Subida WAN" - -msgid "WAN Download" -msgstr "Descarga WAN" - -msgid "WAN Uploaded" -msgstr "Subido WAN" - -msgid "WAN Downloaded" -msgstr "Descargado WAN" - msgid "Clear Traffic Data" msgstr "Borrar datos de tráfico" @@ -1082,9 +1058,6 @@ msgstr "Descargar e Instalar" msgid "Manual Download" msgstr "Descarga Manual" -msgid "Close" -msgstr "Cerrar" - msgid "Starting installation... The page will refresh automatically in 30 seconds." msgstr "Iniciando instalación... La página se actualizará automáticamente en 30 segundos." @@ -1094,9 +1067,6 @@ msgstr "Por favor, borre manualmente la caché del navegador después de actuali msgid "Traffic Statistics" msgstr "Estadísticas de Tráfico" -msgid "Traffic Statistics" -msgstr "Estadísticas de Tráfico" - msgid "Device Usage Ranking" msgstr "Clasificación de Uso de Dispositivos" @@ -1351,3 +1321,192 @@ msgstr "No disponible" msgid "Show reply direction" msgstr "Mostrar la dirección de respuesta" + +msgid "Available space" +msgstr "Espacio disponible" + +msgid "Cannot prepare storage. Check free space and directory permissions." +msgstr "No se pudo preparar el almacenamiento. Compruebe el espacio y los permisos." + +msgid "Checking database version…" +msgstr "Comprobando la versión…" + +msgid "Checking storage…" +msgstr "Comprobando el almacenamiento…" + +msgid "Choose an uncompressed .mmdb file within the upload size limit." +msgstr "Seleccione un archivo .mmdb sin comprimir dentro del límite de tamaño." + +msgid "Country/region + network organization — approximately 12 MiB" +msgstr "País/región + organización de red · unos 12 MiB" + +msgid "Country/region — approximately 3.3 MiB" +msgstr "País/región · unos 3,3 MiB" + +msgid "Data source" +msgstr "Fuente de datos" + +msgid "Data terms" +msgstr "Condiciones de uso" + +msgid "Database contents" +msgstr "Contenido de la base" + +msgid "Database directory" +msgstr "Directorio de la base" + +msgid "Database enabled" +msgstr "Base de datos activada" + +msgid "Database is up to date" +msgstr "La base está actualizada" + +msgid "Database operation failed" +msgstr "Error en la operación de la base" + +msgid "Database operation failed. Retry or upload a local database." +msgstr "Error en la operación. Reintente o cargue una base local." + +msgid "Database upload failed" +msgstr "Error al cargar la base" + +msgid "Database validation failed. The previous database is unchanged." +msgstr "Error de validación. Se conserva la base anterior." + +msgid "Delete" +msgstr "Eliminar" + +msgid "Delete GeoIP databases" +msgstr "Eliminar bases GeoIP" + +msgid "Disabled" +msgstr "Desactivado" + +msgid "Documentation address" +msgstr "Dirección de documentación" + +msgid "Download and enable" +msgstr "Descargar y activar" + +msgid "Download cancelled" +msgstr "Descarga cancelada" + +msgid "Downloading database…" +msgstr "Descargando la base…" + +msgid "Enable IP location lookup" +msgstr "Activar ubicación de IP" + +msgid "Enabled" +msgstr "Activado" + +msgid "GeoIP service is unavailable. Enable connection monitoring and apply settings, or update Bandix." +msgstr "GeoIP no está disponible. Active la monitorización de conexiones y aplique los ajustes, o actualice Bandix." + +msgid "IP location database" +msgstr "Base de ubicación de IP" + +msgid "Importing database…" +msgstr "Importando la base…" + +msgid "Link-local address" +msgstr "Dirección de enlace local" + +msgid "Loading database…" +msgstr "Cargando la base…" + +msgid "Local network" +msgstr "Red local" + +msgid "Loopback" +msgstr "Bucle local" + +msgid "Maximum upload size" +msgstr "Tamaño máximo de carga" + +msgid "Multicast" +msgstr "Multidifusión" + +msgid "Not installed" +msgstr "Sin instalar" + +msgid "Private address" +msgstr "Dirección privada" + +msgid "Province/city (uploaded database)" +msgstr "Provincia/ciudad (base cargada)" + +msgid "Province/city + network organization — approximately 57 MiB" +msgstr "Provincia/ciudad + organización de red · unos 57 MiB" + +msgid "Remove installed databases and disable IP location lookup?" +msgstr "¿Eliminar las bases y desactivar la ubicación de IP?" + +msgid "Reserved address" +msgstr "Dirección reservada" + +msgid "Shared address (CGNAT)" +msgstr "Dirección compartida (CGNAT)" + +msgid "Storage used" +msgstr "Espacio utilizado" + +msgid "The installed database could not be loaded. Download or upload it again." +msgstr "No se pudo cargar la base. Descárguela o cárguela de nuevo." + +msgid "Unknown" +msgstr "Desconocido" + +msgid "Unknown location" +msgstr "Ubicación desconocida" + +msgid "Unspecified address" +msgstr "Dirección sin especificar" + +msgid "Update database" +msgstr "Actualizar base" + +msgid "Upload an uncompressed Country, City or ASN .mmdb file. To add ASN, install a Country or City database first." +msgstr "Cargue un archivo Country, City o ASN .mmdb sin comprimir. Instale Country o City antes de añadir ASN." + +msgid "Upload and enable" +msgstr "Cargar y activar" + +msgid "Upload database" +msgstr "Cargar base" + +msgid "Uploading database…" +msgstr "Subiendo la base…" + +msgid "Use persistent storage or an external drive. Save and apply directory changes before downloading." +msgstr "Use almacenamiento persistente o externo. Guarde y aplique los cambios de directorio antes de descargar." + +msgid "Verifying database…" +msgstr "Verificando la base…" + +msgid "Version" +msgstr "Versión" + +msgid "Country/region" +msgstr "País/región" + +msgid "Province/city" +msgstr "Provincia/ciudad" + +msgid "Network organization" +msgstr "Organización de red" + +msgid "Not enough free space for this database." +msgstr "No hay espacio suficiente para esta base." + +msgid "Required space" +msgstr "Espacio necesario" + +msgid "Database ready" +msgstr "Base lista" + +msgid "Listen Address" +msgstr "Dirección de escucha" + +msgid "IP address for Bandix to listen on. Use 127.0.0.1 for local access or 0.0.0.0 / :: for all interfaces." +msgstr "Dirección IP de escucha de Bandix. Use 127.0.0.1 para acceso local o 0.0.0.0 / :: para todas las interfaces." diff --git a/luci-app-bandix/po/fr/bandix.po b/luci-app-bandix/po/fr/bandix.po index 11c212dd..5bdbad4c 100644 --- a/luci-app-bandix/po/fr/bandix.po +++ b/luci-app-bandix/po/fr/bandix.po @@ -221,12 +221,6 @@ msgstr "WAN envoyé" msgid "WAN Downloaded" msgstr "WAN téléchargé" -msgid "Total Upload" -msgstr "Téléversement total" - -msgid "Total Download" -msgstr "Téléchargement total" - msgid "LAN Upload" msgstr "Débit envoi LAN" @@ -422,18 +416,12 @@ msgstr "Page" msgid "of" msgstr "sur" -msgid "Total" -msgstr "Total" - msgid "records" msgstr "enregistrements" msgid "Per Page" msgstr "Par page" -msgid "" -msgstr "" - msgid "Total Queries" msgstr "Total des requêtes" @@ -938,18 +926,6 @@ msgstr "Maximum" msgid "Minimum" msgstr "Minimum" -msgid "WAN Upload" -msgstr "Envoi WAN" - -msgid "WAN Download" -msgstr "Téléchargement WAN" - -msgid "WAN Uploaded" -msgstr "Envoyé WAN" - -msgid "WAN Downloaded" -msgstr "Téléchargé WAN" - msgid "Clear Traffic Data" msgstr "Effacer les données de trafic" @@ -1082,9 +1058,6 @@ msgstr "Télécharger et Installer" msgid "Manual Download" msgstr "Téléchargement Manuel" -msgid "Close" -msgstr "Fermer" - msgid "Starting installation... The page will refresh automatically in 30 seconds." msgstr "Démarrage de l'installation... La page sera actualisée automatiquement dans 30 secondes." @@ -1094,9 +1067,6 @@ msgstr "Veuillez vider manuellement le cache du navigateur après la mise à jou msgid "Traffic Statistics" msgstr "Statistiques de Trafic" -msgid "Traffic Statistics" -msgstr "Statistiques de Trafic" - msgid "Device Usage Ranking" msgstr "Classement d'Utilisation des Appareils" @@ -1351,3 +1321,192 @@ msgstr "Indisponible" msgid "Show reply direction" msgstr "Afficher la direction de réponse" + +msgid "Available space" +msgstr "Espace disponible" + +msgid "Cannot prepare storage. Check free space and directory permissions." +msgstr "Impossible de préparer le stockage. Vérifiez l’espace libre et les permissions." + +msgid "Checking database version…" +msgstr "Vérification de la version…" + +msgid "Checking storage…" +msgstr "Vérification du stockage…" + +msgid "Choose an uncompressed .mmdb file within the upload size limit." +msgstr "Choisissez un fichier .mmdb non compressé respectant la taille limite." + +msgid "Country/region + network organization — approximately 12 MiB" +msgstr "Pays/région + organisation réseau · environ 12 MiB" + +msgid "Country/region — approximately 3.3 MiB" +msgstr "Pays/région · environ 3,3 MiB" + +msgid "Data source" +msgstr "Source des données" + +msgid "Data terms" +msgstr "Conditions d’utilisation" + +msgid "Database contents" +msgstr "Contenu de la base" + +msgid "Database directory" +msgstr "Répertoire de la base" + +msgid "Database enabled" +msgstr "Base activée" + +msgid "Database is up to date" +msgstr "La base est à jour" + +msgid "Database operation failed" +msgstr "Échec de l’opération" + +msgid "Database operation failed. Retry or upload a local database." +msgstr "Échec de l’opération. Réessayez ou importez une base locale." + +msgid "Database upload failed" +msgstr "Échec de l’envoi de la base" + +msgid "Database validation failed. The previous database is unchanged." +msgstr "Échec de validation. La base précédente est conservée." + +msgid "Delete" +msgstr "Supprimer" + +msgid "Delete GeoIP databases" +msgstr "Supprimer les bases GeoIP" + +msgid "Disabled" +msgstr "Désactivé" + +msgid "Documentation address" +msgstr "Adresse de documentation" + +msgid "Download and enable" +msgstr "Télécharger et activer" + +msgid "Download cancelled" +msgstr "Téléchargement annulé" + +msgid "Downloading database…" +msgstr "Téléchargement de la base…" + +msgid "Enable IP location lookup" +msgstr "Activer la géolocalisation IP" + +msgid "Enabled" +msgstr "Activé" + +msgid "GeoIP service is unavailable. Enable connection monitoring and apply settings, or update Bandix." +msgstr "GeoIP indisponible. Activez le suivi des connexions et appliquez les paramètres, ou mettez Bandix à jour." + +msgid "IP location database" +msgstr "Base de géolocalisation IP" + +msgid "Importing database…" +msgstr "Importation de la base…" + +msgid "Link-local address" +msgstr "Adresse de lien local" + +msgid "Loading database…" +msgstr "Chargement de la base…" + +msgid "Local network" +msgstr "Réseau local" + +msgid "Loopback" +msgstr "Bouclage" + +msgid "Maximum upload size" +msgstr "Taille maximale d’envoi" + +msgid "Multicast" +msgstr "Multidiffusion" + +msgid "Not installed" +msgstr "Non installé" + +msgid "Private address" +msgstr "Adresse privée" + +msgid "Province/city (uploaded database)" +msgstr "Région/ville (base importée)" + +msgid "Province/city + network organization — approximately 57 MiB" +msgstr "Région/ville + organisation réseau · environ 57 MiB" + +msgid "Remove installed databases and disable IP location lookup?" +msgstr "Supprimer les bases et désactiver la géolocalisation IP ?" + +msgid "Reserved address" +msgstr "Adresse réservée" + +msgid "Shared address (CGNAT)" +msgstr "Adresse partagée (CGNAT)" + +msgid "Storage used" +msgstr "Espace utilisé" + +msgid "The installed database could not be loaded. Download or upload it again." +msgstr "Impossible de charger la base. Téléchargez-la ou importez-la à nouveau." + +msgid "Unknown" +msgstr "Inconnu" + +msgid "Unknown location" +msgstr "Localisation inconnue" + +msgid "Unspecified address" +msgstr "Adresse non spécifiée" + +msgid "Update database" +msgstr "Mettre à jour la base" + +msgid "Upload an uncompressed Country, City or ASN .mmdb file. To add ASN, install a Country or City database first." +msgstr "Importez un fichier Country, City ou ASN .mmdb non compressé. Installez Country ou City avant d’ajouter ASN." + +msgid "Upload and enable" +msgstr "Importer et activer" + +msgid "Upload database" +msgstr "Importer une base" + +msgid "Uploading database…" +msgstr "Envoi de la base…" + +msgid "Use persistent storage or an external drive. Save and apply directory changes before downloading." +msgstr "Utilisez un stockage persistant ou externe. Enregistrez et appliquez le changement de répertoire avant de télécharger." + +msgid "Verifying database…" +msgstr "Vérification de la base…" + +msgid "Version" +msgstr "Version" + +msgid "Country/region" +msgstr "Pays/région" + +msgid "Province/city" +msgstr "Région/ville" + +msgid "Network organization" +msgstr "Organisation réseau" + +msgid "Not enough free space for this database." +msgstr "Espace insuffisant pour cette base." + +msgid "Required space" +msgstr "Espace nécessaire" + +msgid "Database ready" +msgstr "Base prête" + +msgid "Listen Address" +msgstr "Adresse d’écoute" + +msgid "IP address for Bandix to listen on. Use 127.0.0.1 for local access or 0.0.0.0 / :: for all interfaces." +msgstr "Adresse IP d’écoute de Bandix. Utilisez 127.0.0.1 pour un accès local ou 0.0.0.0 / :: pour toutes les interfaces." diff --git a/luci-app-bandix/po/ja/bandix.po b/luci-app-bandix/po/ja/bandix.po index f5fb03d3..f3c1f4c7 100644 --- a/luci-app-bandix/po/ja/bandix.po +++ b/luci-app-bandix/po/ja/bandix.po @@ -221,12 +221,6 @@ msgstr "WAN アップロード済み" msgid "WAN Downloaded" msgstr "WAN ダウンロード済み" -msgid "Total Upload" -msgstr "総アップロード速度" - -msgid "Total Download" -msgstr "総ダウンロード速度" - msgid "LAN Upload" msgstr "LAN アップロード速度" @@ -422,18 +416,12 @@ msgstr "ページ" msgid "of" msgstr "の" -msgid "Total" -msgstr "合計" - msgid "records" msgstr "件の記録" msgid "Per Page" msgstr "ページあたり" -msgid "" -msgstr "件" - msgid "Total Queries" msgstr "総クエリ数" @@ -938,18 +926,6 @@ msgstr "最大" msgid "Minimum" msgstr "最小" -msgid "WAN Upload" -msgstr "WAN アップロード" - -msgid "WAN Download" -msgstr "WAN ダウンロード" - -msgid "WAN Uploaded" -msgstr "WAN アップロード量" - -msgid "WAN Downloaded" -msgstr "WAN ダウンロード量" - msgid "Clear Traffic Data" msgstr "トラフィックデータを削除" @@ -1082,9 +1058,6 @@ msgstr "ダウンロードしてインストール" msgid "Manual Download" msgstr "手動ダウンロード" -msgid "Close" -msgstr "閉じる" - msgid "Starting installation... The page will refresh automatically in 30 seconds." msgstr "インストールを開始しています... ページは30秒後に自動的に更新されます。" @@ -1094,9 +1067,6 @@ msgstr "更新後、ブラウザのキャッシュを手動でクリアしてく msgid "Traffic Statistics" msgstr "トラフィック統計" -msgid "Traffic Statistics" -msgstr "トラフィック統計" - msgid "Device Usage Ranking" msgstr "デバイス使用量ランキング" @@ -1351,3 +1321,192 @@ msgstr "利用不可" msgid "Show reply direction" msgstr "応答方向を表示" + +msgid "Available space" +msgstr "空き容量" + +msgid "Cannot prepare storage. Check free space and directory permissions." +msgstr "保存先を準備できません。空き容量と権限を確認してください。" + +msgid "Checking database version…" +msgstr "データベースのバージョンを確認中…" + +msgid "Checking storage…" +msgstr "空き容量を確認中…" + +msgid "Choose an uncompressed .mmdb file within the upload size limit." +msgstr "上限サイズ以内の未圧縮 .mmdb ファイルを選択してください。" + +msgid "Country/region + network organization — approximately 12 MiB" +msgstr "国・地域 + ネットワーク組織 · 約 12 MiB" + +msgid "Country/region — approximately 3.3 MiB" +msgstr "国・地域 · 約 3.3 MiB" + +msgid "Data source" +msgstr "データ提供元" + +msgid "Data terms" +msgstr "データ利用規約" + +msgid "Database contents" +msgstr "データベースの内容" + +msgid "Database directory" +msgstr "データベース保存先" + +msgid "Database enabled" +msgstr "データベースを有効にしました" + +msgid "Database is up to date" +msgstr "データベースは最新です" + +msgid "Database operation failed" +msgstr "データベース操作に失敗しました" + +msgid "Database operation failed. Retry or upload a local database." +msgstr "操作に失敗しました。再試行するかローカルのデータベースをアップロードしてください。" + +msgid "Database upload failed" +msgstr "データベースのアップロードに失敗しました" + +msgid "Database validation failed. The previous database is unchanged." +msgstr "検証に失敗しました。既存のデータベースは保持されています。" + +msgid "Delete" +msgstr "削除" + +msgid "Delete GeoIP databases" +msgstr "GeoIP データベースを削除" + +msgid "Disabled" +msgstr "無効" + +msgid "Documentation address" +msgstr "文書用アドレス" + +msgid "Download and enable" +msgstr "ダウンロードして有効化" + +msgid "Download cancelled" +msgstr "ダウンロードを中止しました" + +msgid "Downloading database…" +msgstr "データベースをダウンロード中…" + +msgid "Enable IP location lookup" +msgstr "IP 位置情報の検索を有効化" + +msgid "Enabled" +msgstr "有効" + +msgid "GeoIP service is unavailable. Enable connection monitoring and apply settings, or update Bandix." +msgstr "GeoIP を利用できません。接続監視を有効にして設定を適用するか、Bandix を更新してください。" + +msgid "IP location database" +msgstr "IP 位置情報データベース" + +msgid "Importing database…" +msgstr "データベースをインポート中…" + +msgid "Link-local address" +msgstr "リンクローカルアドレス" + +msgid "Loading database…" +msgstr "データベースを読み込み中…" + +msgid "Local network" +msgstr "ローカルネットワーク" + +msgid "Loopback" +msgstr "ループバック" + +msgid "Maximum upload size" +msgstr "最大アップロードサイズ" + +msgid "Multicast" +msgstr "マルチキャスト" + +msgid "Not installed" +msgstr "未インストール" + +msgid "Private address" +msgstr "プライベートアドレス" + +msgid "Province/city (uploaded database)" +msgstr "都道府県・都市(アップロード済み)" + +msgid "Province/city + network organization — approximately 57 MiB" +msgstr "都道府県・都市 + ネットワーク組織 · 約 57 MiB" + +msgid "Remove installed databases and disable IP location lookup?" +msgstr "データベースを削除し、IP 位置情報の検索を無効にしますか?" + +msgid "Reserved address" +msgstr "予約済みアドレス" + +msgid "Shared address (CGNAT)" +msgstr "共有アドレス(CGNAT)" + +msgid "Storage used" +msgstr "使用容量" + +msgid "The installed database could not be loaded. Download or upload it again." +msgstr "データベースを読み込めません。再度ダウンロードまたはアップロードしてください。" + +msgid "Unknown" +msgstr "不明" + +msgid "Unknown location" +msgstr "位置情報不明" + +msgid "Unspecified address" +msgstr "未指定アドレス" + +msgid "Update database" +msgstr "データベースを更新" + +msgid "Upload an uncompressed Country, City or ASN .mmdb file. To add ASN, install a Country or City database first." +msgstr "未圧縮の Country、City、ASN の .mmdb ファイルをアップロードできます。ASN の追加前に Country または City をインストールしてください。" + +msgid "Upload and enable" +msgstr "アップロードして有効化" + +msgid "Upload database" +msgstr "データベースをアップロード" + +msgid "Uploading database…" +msgstr "データベースをアップロード中…" + +msgid "Use persistent storage or an external drive. Save and apply directory changes before downloading." +msgstr "永続ストレージまたは外付けドライブを使用してください。保存先の変更を保存・適用してからダウンロードしてください。" + +msgid "Verifying database…" +msgstr "データベースを検証中…" + +msgid "Version" +msgstr "バージョン" + +msgid "Country/region" +msgstr "国・地域" + +msgid "Province/city" +msgstr "都道府県・都市" + +msgid "Network organization" +msgstr "ネットワーク組織" + +msgid "Not enough free space for this database." +msgstr "このデータベースを保存する空き容量が不足しています。" + +msgid "Required space" +msgstr "必要な容量" + +msgid "Database ready" +msgstr "データベースの準備完了" + +msgid "Listen Address" +msgstr "待ち受けアドレス" + +msgid "IP address for Bandix to listen on. Use 127.0.0.1 for local access or 0.0.0.0 / :: for all interfaces." +msgstr "Bandix が待ち受ける IP アドレス。ローカルアクセスには 127.0.0.1、すべてのインターフェースには 0.0.0.0 / :: を指定します。" diff --git a/luci-app-bandix/po/pl/bandix.po b/luci-app-bandix/po/pl/bandix.po index 223ec195..5401ef15 100644 --- a/luci-app-bandix/po/pl/bandix.po +++ b/luci-app-bandix/po/pl/bandix.po @@ -221,12 +221,6 @@ msgstr "WAN wysłane" msgid "WAN Downloaded" msgstr "WAN pobrane" -msgid "Total Upload" -msgstr "Całkowite wysyłanie" - -msgid "Total Download" -msgstr "Całkowite pobieranie" - msgid "LAN Upload" msgstr "Wysyłanie LAN" @@ -422,18 +416,12 @@ msgstr "Strona" msgid "of" msgstr "z" -msgid "Total" -msgstr "Całkowity" - msgid "records" msgstr "rekordów" msgid "Per Page" msgstr "Na stronę" -msgid "" -msgstr "" - msgid "Total Queries" msgstr "Całkowite zapytania" @@ -938,18 +926,6 @@ msgstr "Maksimum" msgid "Minimum" msgstr "Minimum" -msgid "WAN Upload" -msgstr "Wysyłanie WAN" - -msgid "WAN Download" -msgstr "Pobieranie WAN" - -msgid "WAN Uploaded" -msgstr "Wysłano WAN" - -msgid "WAN Downloaded" -msgstr "Pobrano WAN" - msgid "Clear Traffic Data" msgstr "Wyczyść dane ruchu" @@ -1082,9 +1058,6 @@ msgstr "Pobierz i Zainstaluj" msgid "Manual Download" msgstr "Pobieranie Ręczne" -msgid "Close" -msgstr "Zamknij" - msgid "Starting installation... The page will refresh automatically in 30 seconds." msgstr "Rozpoczynanie instalacji... Strona odświeży się automatycznie za 30 sekund." @@ -1094,9 +1067,6 @@ msgstr "Po aktualizacji należy ręcznie wyczyścić pamięć podręczną przegl msgid "Traffic Statistics" msgstr "Statystyki ruchu" -msgid "Traffic Statistics" -msgstr "Statystyki ruchu" - msgid "Device Usage Ranking" msgstr "Ranking Użycia Urządzeń" @@ -1351,3 +1321,192 @@ msgstr "Niedostępne" msgid "Show reply direction" msgstr "Pokaż kierunek odpowiedzi" + +msgid "Available space" +msgstr "Wolne miejsce" + +msgid "Cannot prepare storage. Check free space and directory permissions." +msgstr "Nie można przygotować pamięci. Sprawdź wolne miejsce i uprawnienia katalogu." + +msgid "Checking database version…" +msgstr "Sprawdzanie wersji bazy…" + +msgid "Checking storage…" +msgstr "Sprawdzanie pamięci…" + +msgid "Choose an uncompressed .mmdb file within the upload size limit." +msgstr "Wybierz nieskompresowany plik .mmdb mieszczący się w limicie rozmiaru." + +msgid "Country/region + network organization — approximately 12 MiB" +msgstr "Kraj/region + organizacja sieciowa · ok. 12 MiB" + +msgid "Country/region — approximately 3.3 MiB" +msgstr "Kraj/region · ok. 3,3 MiB" + +msgid "Data source" +msgstr "Źródło danych" + +msgid "Data terms" +msgstr "Warunki korzystania" + +msgid "Database contents" +msgstr "Zawartość bazy" + +msgid "Database directory" +msgstr "Katalog bazy" + +msgid "Database enabled" +msgstr "Baza danych włączona" + +msgid "Database is up to date" +msgstr "Baza danych jest aktualna" + +msgid "Database operation failed" +msgstr "Operacja na bazie nie powiodła się" + +msgid "Database operation failed. Retry or upload a local database." +msgstr "Operacja nie powiodła się. Spróbuj ponownie lub prześlij lokalną bazę." + +msgid "Database upload failed" +msgstr "Przesyłanie bazy nie powiodło się" + +msgid "Database validation failed. The previous database is unchanged." +msgstr "Weryfikacja nie powiodła się. Poprzednia baza pozostaje bez zmian." + +msgid "Delete" +msgstr "Usuń" + +msgid "Delete GeoIP databases" +msgstr "Usuń bazy GeoIP" + +msgid "Disabled" +msgstr "Wyłączone" + +msgid "Documentation address" +msgstr "Adres dokumentacyjny" + +msgid "Download and enable" +msgstr "Pobierz i włącz" + +msgid "Download cancelled" +msgstr "Pobieranie anulowane" + +msgid "Downloading database…" +msgstr "Pobieranie bazy…" + +msgid "Enable IP location lookup" +msgstr "Włącz geolokalizację IP" + +msgid "Enabled" +msgstr "Włączone" + +msgid "GeoIP service is unavailable. Enable connection monitoring and apply settings, or update Bandix." +msgstr "GeoIP jest niedostępne. Włącz monitorowanie połączeń i zastosuj ustawienia lub zaktualizuj Bandix." + +msgid "IP location database" +msgstr "Baza geolokalizacji IP" + +msgid "Importing database…" +msgstr "Importowanie bazy…" + +msgid "Link-local address" +msgstr "Adres lokalny łącza" + +msgid "Loading database…" +msgstr "Wczytywanie bazy…" + +msgid "Local network" +msgstr "Sieć lokalna" + +msgid "Loopback" +msgstr "Pętla zwrotna" + +msgid "Maximum upload size" +msgstr "Maksymalny rozmiar pliku" + +msgid "Multicast" +msgstr "Multicast" + +msgid "Not installed" +msgstr "Niezainstalowane" + +msgid "Private address" +msgstr "Adres prywatny" + +msgid "Province/city (uploaded database)" +msgstr "Region/miasto (przesłana baza)" + +msgid "Province/city + network organization — approximately 57 MiB" +msgstr "Region/miasto + organizacja sieciowa · ok. 57 MiB" + +msgid "Remove installed databases and disable IP location lookup?" +msgstr "Usunąć bazy i wyłączyć geolokalizację IP?" + +msgid "Reserved address" +msgstr "Adres zarezerwowany" + +msgid "Shared address (CGNAT)" +msgstr "Adres współdzielony (CGNAT)" + +msgid "Storage used" +msgstr "Zajęte miejsce" + +msgid "The installed database could not be loaded. Download or upload it again." +msgstr "Nie można wczytać bazy. Pobierz lub prześlij ją ponownie." + +msgid "Unknown" +msgstr "Nieznane" + +msgid "Unknown location" +msgstr "Nieznana lokalizacja" + +msgid "Unspecified address" +msgstr "Adres nieokreślony" + +msgid "Update database" +msgstr "Aktualizuj bazę" + +msgid "Upload an uncompressed Country, City or ASN .mmdb file. To add ASN, install a Country or City database first." +msgstr "Prześlij nieskompresowany plik Country, City lub ASN .mmdb. Przed ASN zainstaluj Country lub City." + +msgid "Upload and enable" +msgstr "Prześlij i włącz" + +msgid "Upload database" +msgstr "Prześlij bazę" + +msgid "Uploading database…" +msgstr "Przesyłanie bazy…" + +msgid "Use persistent storage or an external drive. Save and apply directory changes before downloading." +msgstr "Użyj pamięci trwałej lub dysku zewnętrznego. Zapisz i zastosuj zmianę katalogu przed pobieraniem." + +msgid "Verifying database…" +msgstr "Weryfikacja bazy…" + +msgid "Version" +msgstr "Wersja" + +msgid "Country/region" +msgstr "Kraj/region" + +msgid "Province/city" +msgstr "Region/miasto" + +msgid "Network organization" +msgstr "Organizacja sieciowa" + +msgid "Not enough free space for this database." +msgstr "Brak miejsca na tę bazę danych." + +msgid "Required space" +msgstr "Wymagane miejsce" + +msgid "Database ready" +msgstr "Baza gotowa" + +msgid "Listen Address" +msgstr "Adres nasłuchiwania" + +msgid "IP address for Bandix to listen on. Use 127.0.0.1 for local access or 0.0.0.0 / :: for all interfaces." +msgstr "Adres IP nasłuchiwania Bandix. Użyj 127.0.0.1 dla dostępu lokalnego lub 0.0.0.0 / :: dla wszystkich interfejsów." diff --git a/luci-app-bandix/po/ru/bandix.po b/luci-app-bandix/po/ru/bandix.po index 725837d2..62ed7228 100644 --- a/luci-app-bandix/po/ru/bandix.po +++ b/luci-app-bandix/po/ru/bandix.po @@ -221,12 +221,6 @@ msgstr "WAN отправлено" msgid "WAN Downloaded" msgstr "WAN загружено" -msgid "Total Upload" -msgstr "Всего выгружено" - -msgid "Total Download" -msgstr "Всего загружено" - msgid "LAN Upload" msgstr "Скорость отправки LAN" @@ -422,18 +416,12 @@ msgstr "Страница" msgid "of" msgstr "из" -msgid "Total" -msgstr "Всего" - msgid "records" msgstr "записей" msgid "Per Page" msgstr "На странице" -msgid "" -msgstr "" - msgid "Total Queries" msgstr "Всего запросов" @@ -938,18 +926,6 @@ msgstr "Максимум" msgid "Minimum" msgstr "Минимум" -msgid "WAN Upload" -msgstr "Отправка WAN" - -msgid "WAN Download" -msgstr "Загрузка WAN" - -msgid "WAN Uploaded" -msgstr "Отправлено WAN" - -msgid "WAN Downloaded" -msgstr "Загружено WAN" - msgid "Clear Traffic Data" msgstr "Очистить данные трафика" @@ -1082,9 +1058,6 @@ msgstr "Скачать и Установить" msgid "Manual Download" msgstr "Ручная Загрузка" -msgid "Close" -msgstr "Закрыть" - msgid "Starting installation... The page will refresh automatically in 30 seconds." msgstr "Начало установки... Страница автоматически обновится через 30 секунд." @@ -1094,9 +1067,6 @@ msgstr "Пожалуйста, вручную очистите кеш брауз msgid "Traffic Statistics" msgstr "Статистика трафика" -msgid "Traffic Statistics" -msgstr "Статистика трафика" - msgid "Device Usage Ranking" msgstr "Рейтинг использования устройств" @@ -1351,3 +1321,192 @@ msgstr "Недоступно" msgid "Show reply direction" msgstr "Показывать обратное направление" + +msgid "Available space" +msgstr "Свободное место" + +msgid "Cannot prepare storage. Check free space and directory permissions." +msgstr "Не удалось подготовить хранилище. Проверьте свободное место и права доступа." + +msgid "Checking database version…" +msgstr "Проверка версии базы…" + +msgid "Checking storage…" +msgstr "Проверка хранилища…" + +msgid "Choose an uncompressed .mmdb file within the upload size limit." +msgstr "Выберите несжатый файл .mmdb, не превышающий ограничение размера." + +msgid "Country/region + network organization — approximately 12 MiB" +msgstr "Страна/регион + сетевая организация · около 12 MiB" + +msgid "Country/region — approximately 3.3 MiB" +msgstr "Страна/регион · около 3,3 MiB" + +msgid "Data source" +msgstr "Источник данных" + +msgid "Data terms" +msgstr "Условия использования" + +msgid "Database contents" +msgstr "Содержимое базы" + +msgid "Database directory" +msgstr "Каталог базы" + +msgid "Database enabled" +msgstr "База данных включена" + +msgid "Database is up to date" +msgstr "База данных актуальна" + +msgid "Database operation failed" +msgstr "Ошибка операции с базой" + +msgid "Database operation failed. Retry or upload a local database." +msgstr "Операция не удалась. Повторите попытку или загрузите локальную базу." + +msgid "Database upload failed" +msgstr "Не удалось загрузить базу" + +msgid "Database validation failed. The previous database is unchanged." +msgstr "Проверка не пройдена. Предыдущая база сохранена." + +msgid "Delete" +msgstr "Удалить" + +msgid "Delete GeoIP databases" +msgstr "Удалить базы GeoIP" + +msgid "Disabled" +msgstr "Отключено" + +msgid "Documentation address" +msgstr "Адрес для документации" + +msgid "Download and enable" +msgstr "Скачать и включить" + +msgid "Download cancelled" +msgstr "Загрузка отменена" + +msgid "Downloading database…" +msgstr "Скачивание базы…" + +msgid "Enable IP location lookup" +msgstr "Включить геолокацию IP" + +msgid "Enabled" +msgstr "Включено" + +msgid "GeoIP service is unavailable. Enable connection monitoring and apply settings, or update Bandix." +msgstr "GeoIP недоступен. Включите мониторинг соединений и примените настройки либо обновите Bandix." + +msgid "IP location database" +msgstr "База геолокации IP" + +msgid "Importing database…" +msgstr "Импорт базы…" + +msgid "Link-local address" +msgstr "Локальный адрес канала" + +msgid "Loading database…" +msgstr "Подключение базы…" + +msgid "Local network" +msgstr "Локальная сеть" + +msgid "Loopback" +msgstr "Петлевой адрес" + +msgid "Maximum upload size" +msgstr "Максимальный размер загрузки" + +msgid "Multicast" +msgstr "Многоадресная рассылка" + +msgid "Not installed" +msgstr "Не установлено" + +msgid "Private address" +msgstr "Частный адрес" + +msgid "Province/city (uploaded database)" +msgstr "Регион/город (загруженная база)" + +msgid "Province/city + network organization — approximately 57 MiB" +msgstr "Регион/город + сетевая организация · около 57 MiB" + +msgid "Remove installed databases and disable IP location lookup?" +msgstr "Удалить базы и отключить геолокацию IP?" + +msgid "Reserved address" +msgstr "Зарезервированный адрес" + +msgid "Shared address (CGNAT)" +msgstr "Общий адрес (CGNAT)" + +msgid "Storage used" +msgstr "Занято места" + +msgid "The installed database could not be loaded. Download or upload it again." +msgstr "Не удалось открыть базу. Скачайте или загрузите её повторно." + +msgid "Unknown" +msgstr "Неизвестно" + +msgid "Unknown location" +msgstr "Местоположение неизвестно" + +msgid "Unspecified address" +msgstr "Неуказанный адрес" + +msgid "Update database" +msgstr "Обновить базу" + +msgid "Upload an uncompressed Country, City or ASN .mmdb file. To add ASN, install a Country or City database first." +msgstr "Можно загрузить несжатый файл Country, City или ASN .mmdb. Перед ASN установите Country или City." + +msgid "Upload and enable" +msgstr "Загрузить и включить" + +msgid "Upload database" +msgstr "Загрузить базу" + +msgid "Uploading database…" +msgstr "Загрузка базы…" + +msgid "Use persistent storage or an external drive. Save and apply directory changes before downloading." +msgstr "Используйте постоянное хранилище или внешний диск. Перед скачиванием сохраните и примените изменение каталога." + +msgid "Verifying database…" +msgstr "Проверка базы…" + +msgid "Version" +msgstr "Версия" + +msgid "Country/region" +msgstr "Страна/регион" + +msgid "Province/city" +msgstr "Регион/город" + +msgid "Network organization" +msgstr "Сетевая организация" + +msgid "Not enough free space for this database." +msgstr "Недостаточно места для этой базы." + +msgid "Required space" +msgstr "Требуемое место" + +msgid "Database ready" +msgstr "База готова" + +msgid "Listen Address" +msgstr "Адрес прослушивания" + +msgid "IP address for Bandix to listen on. Use 127.0.0.1 for local access or 0.0.0.0 / :: for all interfaces." +msgstr "IP-адрес прослушивания Bandix. Используйте 127.0.0.1 для локального доступа или 0.0.0.0 / :: для всех интерфейсов." diff --git a/luci-app-bandix/po/zh_Hans/bandix.po b/luci-app-bandix/po/zh_Hans/bandix.po index 1b70bbab..65379d5b 100644 --- a/luci-app-bandix/po/zh_Hans/bandix.po +++ b/luci-app-bandix/po/zh_Hans/bandix.po @@ -221,12 +221,6 @@ msgstr "WAN 已上传" msgid "WAN Downloaded" msgstr "WAN 已下载" -msgid "Total Upload" -msgstr "总上传速率" - -msgid "Total Download" -msgstr "总下载速率" - msgid "LAN Upload" msgstr "LAN 上传速率" @@ -419,18 +413,12 @@ msgstr "第" msgid "of" msgstr "页,共" -msgid "Total" -msgstr "全部" - msgid "records" msgstr "条记录" msgid "Per Page" msgstr "每页显示" -msgid "" -msgstr "条" - msgid "Total Queries" msgstr "总查询数" @@ -852,7 +840,7 @@ msgid "Please select at least one day" msgstr "请至少选择一天" msgid "No scheduled rules yet, click \"Add Rule\" to start setting" -msgstr "还没有定时限速规则,点击"添加规则"开始设置" +msgstr "还没有定时限速规则,点击\"添加规则\"开始设置" msgid "Loading..." msgstr "加载中..." @@ -935,18 +923,6 @@ msgstr "最大值" msgid "Minimum" msgstr "最小值" -msgid "WAN Upload" -msgstr "WAN 上传" - -msgid "WAN Download" -msgstr "WAN 下载" - -msgid "WAN Uploaded" -msgstr "WAN 上传量" - -msgid "WAN Downloaded" -msgstr "WAN 下载量" - msgid "Clear Traffic Data" msgstr "删除流量数据" @@ -1079,9 +1055,6 @@ msgstr "下载并安装" msgid "Manual Download" msgstr "手动下载" -msgid "Close" -msgstr "关闭" - msgid "Starting installation... The page will refresh automatically in 30 seconds." msgstr "开始安装... 页面将在30秒后自动刷新。" @@ -1097,9 +1070,6 @@ msgstr "有更新,点击前往设置" msgid "Traffic Statistics" msgstr "流量统计" -msgid "Traffic Statistics" -msgstr "流量统计" - msgid "Device Usage Ranking" msgstr "设备用量排行" @@ -1378,3 +1348,192 @@ msgstr "每分钟" msgid "Show reply direction" msgstr "显示回复方向" + +msgid "Available space" +msgstr "可用空间" + +msgid "Cannot prepare storage. Check free space and directory permissions." +msgstr "无法准备存储,请检查剩余空间和目录权限。" + +msgid "Checking database version…" +msgstr "正在检查数据库版本…" + +msgid "Checking storage…" +msgstr "正在检查存储空间…" + +msgid "Choose an uncompressed .mmdb file within the upload size limit." +msgstr "请选择未压缩且未超过上传大小限制的 .mmdb 文件。" + +msgid "Country/region + network organization — approximately 12 MiB" +msgstr "国家/地区 + 网络组织 · 约 12 MiB" + +msgid "Country/region — approximately 3.3 MiB" +msgstr "国家/地区 · 约 3.3 MiB" + +msgid "Data source" +msgstr "数据来源" + +msgid "Data terms" +msgstr "数据使用条款" + +msgid "Database contents" +msgstr "数据库内容" + +msgid "Database directory" +msgstr "数据库目录" + +msgid "Database enabled" +msgstr "数据库已启用" + +msgid "Database is up to date" +msgstr "数据库已是最新版本" + +msgid "Database operation failed" +msgstr "数据库操作失败" + +msgid "Database operation failed. Retry or upload a local database." +msgstr "数据库操作失败,请重试或上传本地数据库。" + +msgid "Database upload failed" +msgstr "数据库上传失败" + +msgid "Database validation failed. The previous database is unchanged." +msgstr "数据库校验失败,原数据库未更改。" + +msgid "Delete" +msgstr "删除" + +msgid "Delete GeoIP databases" +msgstr "删除 IP 归属地数据库" + +msgid "Disabled" +msgstr "已停用" + +msgid "Documentation address" +msgstr "文档示例地址" + +msgid "Download and enable" +msgstr "下载并启用" + +msgid "Download cancelled" +msgstr "下载已取消" + +msgid "Downloading database…" +msgstr "正在下载数据库…" + +msgid "Enable IP location lookup" +msgstr "启用 IP 归属地查询" + +msgid "Enabled" +msgstr "已启用" + +msgid "GeoIP service is unavailable. Enable connection monitoring and apply settings, or update Bandix." +msgstr "IP 归属地服务不可用,请启用连接监控并应用设置,或更新 Bandix。" + +msgid "IP location database" +msgstr "IP 归属地数据库" + +msgid "Importing database…" +msgstr "正在导入数据库…" + +msgid "Link-local address" +msgstr "链路本地地址" + +msgid "Loading database…" +msgstr "正在加载数据库…" + +msgid "Local network" +msgstr "局域网" + +msgid "Loopback" +msgstr "回环地址" + +msgid "Maximum upload size" +msgstr "上传大小上限" + +msgid "Multicast" +msgstr "组播地址" + +msgid "Not installed" +msgstr "未安装" + +msgid "Private address" +msgstr "私有地址" + +msgid "Province/city (uploaded database)" +msgstr "省市(已上传的数据库)" + +msgid "Province/city + network organization — approximately 57 MiB" +msgstr "省市 + 网络组织 · 约 57 MiB" + +msgid "Remove installed databases and disable IP location lookup?" +msgstr "删除已安装的数据库并停用 IP 归属地查询?" + +msgid "Reserved address" +msgstr "保留地址" + +msgid "Shared address (CGNAT)" +msgstr "共享地址(CGNAT)" + +msgid "Storage used" +msgstr "存储占用" + +msgid "The installed database could not be loaded. Download or upload it again." +msgstr "无法加载已安装的数据库,请重新下载或上传。" + +msgid "Unknown" +msgstr "未知" + +msgid "Unknown location" +msgstr "归属地未知" + +msgid "Unspecified address" +msgstr "未指定地址" + +msgid "Update database" +msgstr "更新数据库" + +msgid "Upload an uncompressed Country, City or ASN .mmdb file. To add ASN, install a Country or City database first." +msgstr "可上传未压缩的 Country、City 或 ASN .mmdb 文件。添加 ASN 前,请先安装 Country 或 City 数据库。" + +msgid "Upload and enable" +msgstr "上传并启用" + +msgid "Upload database" +msgstr "上传数据库" + +msgid "Uploading database…" +msgstr "正在上传数据库…" + +msgid "Use persistent storage or an external drive. Save and apply directory changes before downloading." +msgstr "请使用持久存储或外接磁盘。更改目录后,请先保存并应用,再下载数据库。" + +msgid "Verifying database…" +msgstr "正在校验数据库…" + +msgid "Version" +msgstr "版本" + +msgid "Country/region" +msgstr "国家/地区" + +msgid "Province/city" +msgstr "省市" + +msgid "Network organization" +msgstr "网络组织" + +msgid "Not enough free space for this database." +msgstr "没有足够空间安装此数据库。" + +msgid "Required space" +msgstr "所需空间" + +msgid "Database ready" +msgstr "数据库已就绪" + +msgid "Listen Address" +msgstr "监听地址" + +msgid "IP address for Bandix to listen on. Use 127.0.0.1 for local access or 0.0.0.0 / :: for all interfaces." +msgstr "Bandix 监听的 IP 地址。127.0.0.1 仅供本机访问,0.0.0.0 / :: 监听所有接口。" diff --git a/luci-app-bandix/po/zh_Hant/bandix.po b/luci-app-bandix/po/zh_Hant/bandix.po index b8555bdd..e1246472 100644 --- a/luci-app-bandix/po/zh_Hant/bandix.po +++ b/luci-app-bandix/po/zh_Hant/bandix.po @@ -221,12 +221,6 @@ msgstr "WAN 已上傳" msgid "WAN Downloaded" msgstr "WAN 已下載" -msgid "Total Upload" -msgstr "總上傳速率" - -msgid "Total Download" -msgstr "總下載速率" - msgid "LAN Upload" msgstr "LAN 上傳速率" @@ -422,18 +416,12 @@ msgstr "第" msgid "of" msgstr "頁,共" -msgid "Total" -msgstr "全部" - msgid "records" msgstr "筆記錄" msgid "Per Page" msgstr "每頁顯示" -msgid "" -msgstr "筆" - msgid "Total Queries" msgstr "總查詢數" @@ -855,7 +843,7 @@ msgid "Please select at least one day" msgstr "請至少選擇一天" msgid "No scheduled rules yet, click \"Add Rule\" to start setting" -msgstr "還沒有定時限速規則,點擊"新增規則"開始設定" +msgstr "還沒有定時限速規則,點擊\"新增規則\"開始設定" msgid "Loading..." msgstr "載入中..." @@ -938,18 +926,6 @@ msgstr "最大值" msgid "Minimum" msgstr "最小值" -msgid "WAN Upload" -msgstr "WAN 上傳" - -msgid "WAN Download" -msgstr "WAN 下載" - -msgid "WAN Uploaded" -msgstr "WAN 上傳量" - -msgid "WAN Downloaded" -msgstr "WAN 下載量" - msgid "Clear Traffic Data" msgstr "刪除流量數據" @@ -1082,9 +1058,6 @@ msgstr "下載並安裝" msgid "Manual Download" msgstr "手動下載" -msgid "Close" -msgstr "關閉" - msgid "Starting installation... The page will refresh automatically in 30 seconds." msgstr "開始安裝... 頁面將在30秒後自動重新整理。" @@ -1094,9 +1067,6 @@ msgstr "更新後請手動清空瀏覽器快取。" msgid "Traffic Statistics" msgstr "流量統計" -msgid "Traffic Statistics" -msgstr "流量統計" - msgid "Device Usage Ranking" msgstr "設備用量排行" @@ -1351,3 +1321,192 @@ msgstr "無法使用" msgid "Show reply direction" msgstr "顯示回覆方向" + +msgid "Available space" +msgstr "可用空間" + +msgid "Cannot prepare storage. Check free space and directory permissions." +msgstr "無法準備儲存空間,請檢查剩餘空間和目錄權限。" + +msgid "Checking database version…" +msgstr "正在檢查資料庫版本…" + +msgid "Checking storage…" +msgstr "正在檢查儲存空間…" + +msgid "Choose an uncompressed .mmdb file within the upload size limit." +msgstr "請選擇未壓縮且未超過上傳大小限制的 .mmdb 檔案。" + +msgid "Country/region + network organization — approximately 12 MiB" +msgstr "國家/地區 + 網路組織 · 約 12 MiB" + +msgid "Country/region — approximately 3.3 MiB" +msgstr "國家/地區 · 約 3.3 MiB" + +msgid "Data source" +msgstr "資料來源" + +msgid "Data terms" +msgstr "資料使用條款" + +msgid "Database contents" +msgstr "資料庫內容" + +msgid "Database directory" +msgstr "資料庫目錄" + +msgid "Database enabled" +msgstr "資料庫已啟用" + +msgid "Database is up to date" +msgstr "資料庫已是最新版本" + +msgid "Database operation failed" +msgstr "資料庫操作失敗" + +msgid "Database operation failed. Retry or upload a local database." +msgstr "資料庫操作失敗,請重試或上傳本機資料庫。" + +msgid "Database upload failed" +msgstr "資料庫上傳失敗" + +msgid "Database validation failed. The previous database is unchanged." +msgstr "資料庫驗證失敗,原資料庫未變更。" + +msgid "Delete" +msgstr "刪除" + +msgid "Delete GeoIP databases" +msgstr "刪除 IP 歸屬地資料庫" + +msgid "Disabled" +msgstr "已停用" + +msgid "Documentation address" +msgstr "文件範例位址" + +msgid "Download and enable" +msgstr "下載並啟用" + +msgid "Download cancelled" +msgstr "下載已取消" + +msgid "Downloading database…" +msgstr "正在下載資料庫…" + +msgid "Enable IP location lookup" +msgstr "啟用 IP 歸屬地查詢" + +msgid "Enabled" +msgstr "已啟用" + +msgid "GeoIP service is unavailable. Enable connection monitoring and apply settings, or update Bandix." +msgstr "IP 歸屬地服務無法使用,請啟用連線監控並套用設定,或更新 Bandix。" + +msgid "IP location database" +msgstr "IP 歸屬地資料庫" + +msgid "Importing database…" +msgstr "正在匯入資料庫…" + +msgid "Link-local address" +msgstr "鏈路本機位址" + +msgid "Loading database…" +msgstr "正在載入資料庫…" + +msgid "Local network" +msgstr "區域網路" + +msgid "Loopback" +msgstr "回送位址" + +msgid "Maximum upload size" +msgstr "上傳大小上限" + +msgid "Multicast" +msgstr "多點傳送位址" + +msgid "Not installed" +msgstr "未安裝" + +msgid "Private address" +msgstr "私有位址" + +msgid "Province/city (uploaded database)" +msgstr "省市(已上傳的資料庫)" + +msgid "Province/city + network organization — approximately 57 MiB" +msgstr "省市 + 網路組織 · 約 57 MiB" + +msgid "Remove installed databases and disable IP location lookup?" +msgstr "刪除已安裝的資料庫並停用 IP 歸屬地查詢?" + +msgid "Reserved address" +msgstr "保留位址" + +msgid "Shared address (CGNAT)" +msgstr "共用位址(CGNAT)" + +msgid "Storage used" +msgstr "儲存用量" + +msgid "The installed database could not be loaded. Download or upload it again." +msgstr "無法載入已安裝的資料庫,請重新下載或上傳。" + +msgid "Unknown" +msgstr "未知" + +msgid "Unknown location" +msgstr "歸屬地未知" + +msgid "Unspecified address" +msgstr "未指定位址" + +msgid "Update database" +msgstr "更新資料庫" + +msgid "Upload an uncompressed Country, City or ASN .mmdb file. To add ASN, install a Country or City database first." +msgstr "可上傳未壓縮的 Country、City 或 ASN .mmdb 檔案。新增 ASN 前,請先安裝 Country 或 City 資料庫。" + +msgid "Upload and enable" +msgstr "上傳並啟用" + +msgid "Upload database" +msgstr "上傳資料庫" + +msgid "Uploading database…" +msgstr "正在上傳資料庫…" + +msgid "Use persistent storage or an external drive. Save and apply directory changes before downloading." +msgstr "請使用持續性儲存或外接磁碟。變更目錄後,請先儲存並套用,再下載資料庫。" + +msgid "Verifying database…" +msgstr "正在驗證資料庫…" + +msgid "Version" +msgstr "版本" + +msgid "Country/region" +msgstr "國家/地區" + +msgid "Province/city" +msgstr "省市" + +msgid "Network organization" +msgstr "網路組織" + +msgid "Not enough free space for this database." +msgstr "沒有足夠空間安裝此資料庫。" + +msgid "Required space" +msgstr "所需空間" + +msgid "Database ready" +msgstr "資料庫已就緒" + +msgid "Listen Address" +msgstr "監聽位址" + +msgid "IP address for Bandix to listen on. Use 127.0.0.1 for local access or 0.0.0.0 / :: for all interfaces." +msgstr "Bandix 監聽的 IP 位址。127.0.0.1 僅供本機存取,0.0.0.0 / :: 監聽所有介面。" diff --git a/luci-app-bandix/root/usr/libexec/rpcd/luci.bandix b/luci-app-bandix/root/usr/libexec/rpcd/luci.bandix index f6a5677e..d00115a7 100755 --- a/luci-app-bandix/root/usr/libexec/rpcd/luci.bandix +++ b/luci-app-bandix/root/usr/libexec/rpcd/luci.bandix @@ -3,9 +3,16 @@ . /usr/share/libubox/jshn.sh -# 从UCI配置读取端口号,如果读取失败则使用默认端口8686 -BANDIX_PORT=$(uci get bandix.general.port 2>/dev/null || echo "8686") -readonly BANDIX_API_BASE="http://127.0.0.1:$BANDIX_PORT" +# Wildcard listening addresses must be reached through loopback on the router. +BANDIX_HOST=$(uci -q get bandix.general.host) +BANDIX_PORT=$(uci -q get bandix.general.port) +BANDIX_PORT=${BANDIX_PORT:-8686} +case "$BANDIX_HOST" in + ''|0.0.0.0) BANDIX_HOST='127.0.0.1' ;; + ::) BANDIX_HOST='[::1]' ;; + *:*) BANDIX_HOST="[$BANDIX_HOST]" ;; +esac +readonly BANDIX_API_BASE="http://$BANDIX_HOST:$BANDIX_PORT" readonly BANDIX_DEVICES_API="$BANDIX_API_BASE/api/traffic/devices" readonly BANDIX_LIMITS_API="$BANDIX_API_BASE/api/traffic/limits" readonly BANDIX_METRICS_API="$BANDIX_API_BASE/api/traffic/metrics" @@ -421,12 +428,13 @@ get_connection_flows() { [ -n "$state" ] && query_params="${query_params}state=$(printf '%s' "$state" | sed 's/ /%20/g')&" [ -n "$page" ] && query_params="${query_params}page=$page&" [ -n "$page_size" ] && query_params="${query_params}page_size=$page_size&" + if [ -n "$page" ] || [ -n "$page_size" ]; then query_params="${query_params}geoip=1&"; fi query_params=$(echo "$query_params" | sed 's/&$//') local url="$BANDIX_CONNECTION_FLOWS_API" [ -n "$query_params" ] && url="${url}?${query_params}" - local response=$(curl -s --connect-timeout 2 --max-time 5 -X GET "$url" 2>/dev/null) + local response=$(curl -s --connect-timeout 2 --max-time 15 -X GET "$url" 2>/dev/null) if [ $? -ne 0 ] || [ -z "$response" ]; then make_error "Failed to connect to Bandix service" return @@ -434,6 +442,44 @@ get_connection_flows() { echo "$response" } +# GeoIP management is proxied to the router itself; writes require the LuCI +# write ACL. Accept only action/profile identifiers, never arbitrary URLs/paths. +get_geoip_status() { + local response + response=$(curl -s --connect-timeout 2 --max-time 8 "$BANDIX_API_BASE/api/geoip/status" 2>/dev/null) + if [ $? -ne 0 ] || [ -z "$response" ]; then + make_error "GeoIP service is unavailable" + return + fi + printf '%s\n' "$response" +} + +manage_geoip() { + local action="$1" profile="$2" enabled="$3" payload response + json_init + case "$action" in + download) + case "$profile" in country|country_asn|city|city_asn) ;; *) make_error "Invalid database profile"; return ;; esac + json_add_string "action" "download" + json_add_string "profile" "$profile" + ;; + enable) + json_add_string "action" "enable" + case "$enabled" in 1|true) json_add_boolean "enabled" 1 ;; 0|false) json_add_boolean "enabled" 0 ;; *) make_error "Invalid enabled value"; return ;; esac + ;; + cancel|delete|import) json_add_string "action" "$action" ;; + *) make_error "Invalid GeoIP action"; return ;; + esac + payload=$(json_dump) + json_cleanup + response=$(curl -s --connect-timeout 2 --max-time 8 -X POST -H 'Content-Type: application/json' --data-binary "$payload" "$BANDIX_API_BASE/api/geoip/manage" 2>/dev/null) + if [ $? -ne 0 ] || [ -z "$response" ]; then + make_error "GeoIP service is unavailable" + return + fi + printf '%s\n' "$response" +} + # 获取 DNS 查询记录 get_dns_queries() { # 检查 DNS 监控是否启用 @@ -1311,6 +1357,14 @@ case "$1" in json_add_string "mac" json_close_object + json_add_object "getGeoipStatus" + json_close_object + json_add_object "manageGeoip" + json_add_string "action" + json_add_string "profile" + json_add_string "enabled" + json_close_object + json_add_object "getConnection" json_close_object @@ -1525,6 +1579,20 @@ case "$1" in fi delete_device "$mac" ;; + getGeoipStatus) + get_geoip_status + ;; + manageGeoip) + input="" + read -r input + action="$(printf '%s' "$input" | jsonfilter -e '$.action' 2>/dev/null)" + [ -z "$action" ] && action="$(printf '%s' "$input" | jsonfilter -e '$[0]' 2>/dev/null)" + profile="$(printf '%s' "$input" | jsonfilter -e '$.profile' 2>/dev/null)" + [ -z "$profile" ] && profile="$(printf '%s' "$input" | jsonfilter -e '$[1]' 2>/dev/null)" + enabled="$(printf '%s' "$input" | jsonfilter -e '$.enabled' 2>/dev/null)" + [ -z "$enabled" ] && enabled="$(printf '%s' "$input" | jsonfilter -e '$[2]' 2>/dev/null)" + manage_geoip "$action" "$profile" "$enabled" + ;; getConnection) # logger "luci.bandix: getConnection called" get_connection_devices diff --git a/luci-app-bandix/root/usr/share/rpcd/acl.d/luci-app-bandix.json b/luci-app-bandix/root/usr/share/rpcd/acl.d/luci-app-bandix.json index 7c8ea354..573f9d0c 100644 --- a/luci-app-bandix/root/usr/share/rpcd/acl.d/luci-app-bandix.json +++ b/luci-app-bandix/root/usr/share/rpcd/acl.d/luci-app-bandix.json @@ -27,7 +27,8 @@ "getTrafficUsageRanking", "getTrafficUsageIncrements", "getRateLimitWhitelist", - "getTrafficQuotas" + "getTrafficQuotas", + "getGeoipStatus" ] }, "uci": [ @@ -68,12 +69,19 @@ "updateScheduleLimit", "getTrafficQuotas", "setTrafficQuota", - "deleteTrafficQuota" + "deleteTrafficQuota", + "getGeoipStatus", + "manageGeoip" ] }, "uci": [ "bandix" - ] + ], + "file": { + "/tmp/bandix-geoip-upload.mmdb": [ + "write" + ] + } } } } diff --git a/luci-app-clashoo/Makefile b/luci-app-clashoo/Makefile index 4873fc40..700cc308 100644 --- a/luci-app-clashoo/Makefile +++ b/luci-app-clashoo/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-clashoo PKG_VERSION:=1.31.0 -PKG_RELEASE:=6 +PKG_RELEASE:=7 PKG_MAINTAINER:=kenzok8 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) @@ -91,7 +91,7 @@ define Package/luci-i18n-clashoo-zh-cn/postinst if [ -z "$${IPKG_INSTROOT}" ]; then # just clear the LuCI cache so the new translations load on next request; # no service restart needed (and none that would drop the login session). - rm -rf /tmp/luci* + rm -rf /tmp/luci-indexcache /tmp/luci-modulecache fi exit 0 endef diff --git a/luci-app-clashoo/root/usr/share/rpcd/ucode/luci.clashoo b/luci-app-clashoo/root/usr/share/rpcd/ucode/luci.clashoo index 52a2ceae..73ba1c98 100755 --- a/luci-app-clashoo/root/usr/share/rpcd/ucode/luci.clashoo +++ b/luci-app-clashoo/root/usr/share/rpcd/ucode/luci.clashoo @@ -15,7 +15,9 @@ function mkdtemp(tpl) { } const BINARY_PATHS = [ -'/usr/bin/mihomo-stable', +'/usr/share/clashoo/bin/mihomo-stable', +'/usr/libexec/clashoo/mihomo-stable', +'/usr/share/clashoo/bin/mihomo-alpha', '/usr/bin/mihomo', '/usr/bin/clash-meta', '/usr/bin/clash', @@ -283,8 +285,8 @@ if (family === 'mihomo') { } } let channel = get_core_channel('mihomo'); - if (channel == 'stable' && access('/usr/bin/mihomo-stable', 'x')) return '/usr/bin/mihomo-stable'; - if (channel == 'alpha' && access('/usr/bin/mihomo', 'x')) return '/usr/bin/mihomo'; + if (channel == 'stable') return selected_mihomo_stable(); + if (channel == 'alpha') return access('/usr/share/clashoo/bin/mihomo-alpha', 'x') ? '/usr/share/clashoo/bin/mihomo-alpha' : ''; if (channel == 'smart') { for (let path in SMART_BINARY_PATHS) if (access(path, 'x')) return path; @@ -371,7 +373,7 @@ c.set('clashoo', 'config', 'core', legacy); } function has_mihomo_stable() { -if (access('/usr/bin/mihomo-stable', 'x')) return true; +if (selected_mihomo_stable()) return true; if (system("[ -x /usr/bin/clash-meta ] && [ ! -L /usr/bin/clash-meta ]") != 0) return false; let version = get_core_version('/usr/bin/clash-meta'); return !!version && !match(version, /(alpha|beta|rc|pre|smart)/i); @@ -387,7 +389,7 @@ if (core == 'mihomo' && dcore == '2') { return { error: 'mihomo_stable_missing', message: '未检测到 mihomo 稳定版,请先在“组件更新”中更新稳定版' }; } if (core == 'mihomo' && dcore == '3') { - if (access('/usr/bin/mihomo', 'x')) return null; + if (access('/usr/share/clashoo/bin/mihomo-alpha', 'x')) return null; return { error: 'mihomo_alpha_missing', message: '未检测到 mihomo Alpha,请先在“组件更新”中更新 Alpha' }; } if (core == 'singbox' && dcore == '4') { @@ -887,6 +889,23 @@ if (m) return m[1]; return full; } +function selected_mihomo_stable() { +let bundled = '/usr/libexec/clashoo/mihomo-stable'; +let manual = '/usr/share/clashoo/bin/mihomo-stable'; +if (access(manual, 'x') && read_first_line('/usr/share/clashoo/clash_meta_version') == 'custom-url') return manual; +if (!access(bundled, 'x')) return access(manual, 'x') ? manual : ''; +if (!access(manual, 'x')) return bundled; +let bv = match(core_short_version(bundled), /^v?([0-9]+)\.([0-9]+)\.([0-9]+)$/); +let mv = match(core_short_version(manual), /^v?([0-9]+)\.([0-9]+)\.([0-9]+)$/); +if (!bv) return mv ? manual : bundled; +if (!mv) return bundled; +for (let i = 1; i <= 3; i++) { + if (int(mv[i]) > int(bv[i])) return manual; + if (int(mv[i]) < int(bv[i])) return bundled; +} +return manual; +} + function component_installed_label(id) { if (id == 'clashoo') return pkg_version('clashoo') || '未安装'; if (id == 'luci') return pkg_version('luci-app-clashoo') || '未安装'; @@ -923,12 +942,11 @@ return !!match(ver || '', /(alpha|beta|rc|pre|smart)/i); function component_installed_versions(id) { let out = {}; if (id == 'mihomo') { - let stable = access('/usr/bin/mihomo-stable', 'x') ? read_first_line('/usr/share/clashoo/clash_meta_version') : ''; - if (!stable && access('/usr/bin/mihomo-stable', 'x')) stable = core_short_version('/usr/bin/mihomo-stable'); + let stable_bin = selected_mihomo_stable(); + let stable = stable_bin ? core_short_version(stable_bin) : ''; if (is_prerelease_label(stable)) stable = ''; - let alpha = read_first_line('/usr/share/clashoo/mihomo_version'); + let alpha = access('/usr/share/clashoo/bin/mihomo-alpha', 'x') ? core_short_version('/usr/share/clashoo/bin/mihomo-alpha') : ''; if (match(alpha, /^smart-/)) alpha = ''; - if (!alpha && access('/usr/bin/mihomo', 'x')) alpha = core_short_version('/usr/bin/mihomo'); out.stable = stable || ''; out.alpha = mihomo_alpha_label(alpha); return out; @@ -2815,7 +2833,7 @@ let api = get_clash_api_auth(); health_status, health_detail, has_tun_device, core_type: configured_core, dcore, local_ip, has_mihomo_stable: has_mihomo_stable(), - has_mihomo_alpha: !!access('/usr/bin/mihomo', 'x'), + has_mihomo_alpha: !!access('/usr/share/clashoo/bin/mihomo-alpha', 'x'), has_singbox_stable: !!access(SINGBOX_BINARY_PATHS[0], 'x'), has_singbox_alpha: !!access(SINGBOX_BINARY_PATHS[1], 'x'), has_smart: !!find_smart_binary() }; diff --git a/luci-app-kai/Makefile b/luci-app-kai/Makefile deleted file mode 100755 index 9ad52b4e..00000000 --- a/luci-app-kai/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright (C) 2008-2014 The LuCI Team -# -# This is free software, licensed under the Apache License, Version 2.0 . -# - -include $(TOPDIR)/rules.mk - -LUCI_TITLE:=kai -PKG_VERSION:=1.0.2-r5 -PKG_RELEASE:= -LUCI_DEPENDS:=+kai +luci-compat +luci-lib-linkeaseauth +linkease-app-entry -LUCI_MINIFY_CSS:=0 -LUCI_MINIFY_JS:=0 - -define Package/luci-app-kai/conffiles -/etc/config/kai -endef - -define Package/luci-app-kai/postrm -#!/bin/sh -rm -f /tmp/luci-indexcache -exit 0 -endef - -include $(TOPDIR)/feeds/luci/luci.mk - -# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-kai/luasrc/controller/kai.lua b/luci-app-kai/luasrc/controller/kai.lua deleted file mode 100644 index 128d247a..00000000 --- a/luci-app-kai/luasrc/controller/kai.lua +++ /dev/null @@ -1,29 +0,0 @@ -local http = require "luci.http" - -module("luci.controller.kai", package.seeall) - -function index() - if not nixio.fs.access("/etc/config/kai") then - return - end - local page - page = entry({"admin", "services","kai"}, cbi("kai"), _("KAI"), 100) - page.dependent = true - entry({"admin", "services", "kai_status"}, call("kai_status")) - -end - -function kai_status() - local sys = require "luci.sys" - local uci = require "luci.model.uci".cursor() - local port = tonumber(uci:get_first("kai", "kai", "port")) or 8197 - if port < 1 or port > 65535 or port % 1 ~= 0 then - port = 8197 - end - local status = { - running = (sys.call("pidof kai_bin >/dev/null") == 0), - port = port - } - http.prepare_content("application/json") - http.write_json(status) -end diff --git a/luci-app-kai/luasrc/model/cbi/kai.lua b/luci-app-kai/luasrc/model/cbi/kai.lua deleted file mode 100644 index 8c8fb48a..00000000 --- a/luci-app-kai/luasrc/model/cbi/kai.lua +++ /dev/null @@ -1,32 +0,0 @@ -local m, s - -m = Map("kai", translate("KAI"), translate("KAI is an efficient AI tool.")) -m:section(SimpleSection).template = "kai/kai_status" - -s=m:section(TypedSection, "kai", translate("Global settings")) -s.addremove=false -s.anonymous=true - -s:option(Flag, "enabled", translate("Enable")).rmempty=false - -local kai_model = require "luci.model.kai" -local blocks = kai_model.blocks() -local home = kai_model.home() - -local data_dir = s:option(Value, "data_dir", translate("Data directory")) -data_dir.rmempty = false -data_dir.description = translate("Required. KAI session will store cwd/cache/data/config/state under this directory (subfolders: cwd, cache, data, config, state).") - -local paths, default_path = kai_model.find_paths(blocks, home, "Configs") -for _, val in pairs(paths) do - data_dir:value(val, val) -end -data_dir.default = default_path - -local port = s:option(Value, "port", translate("API port")) -port.default = "8197" -port.rmempty = false -port.datatype = "port" -port.description = translate("Port for KAI HTTP server (kai_bin). kai_session will read OPENCODE_CONFIG via 127.0.0.1:.") - -return m diff --git a/luci-app-kai/luasrc/model/kai.lua b/luci-app-kai/luasrc/model/kai.lua deleted file mode 100644 index b4ef8499..00000000 --- a/luci-app-kai/luasrc/model/kai.lua +++ /dev/null @@ -1,54 +0,0 @@ -local jsonc = require "luci.jsonc" - -local kai = {} - -kai.blocks = function() - local f = io.popen("lsblk -s -f -b -o NAME,FSSIZE,MOUNTPOINT --json", "r") - local vals = {} - if f then - local ret = f:read("*all") - f:close() - local obj = jsonc.parse(ret) - for _, val in pairs(obj and obj["blockdevices"] or {}) do - local fsize = val["fssize"] - if fsize ~= nil and string.len(fsize) > 10 and val["mountpoint"] then - vals[#vals + 1] = val["mountpoint"] - end - end - end - return vals -end - -kai.home = function() - local uci = require "luci.model.uci".cursor() - local home_dirs = {} - home_dirs["main_dir"] = uci:get_first("quickstart", "main", "main_dir", "/root") - home_dirs["Configs"] = uci:get_first("quickstart", "main", "conf_dir", home_dirs["main_dir"] .. "/Configs") - home_dirs["Public"] = uci:get_first("quickstart", "main", "pub_dir", home_dirs["main_dir"] .. "/Public") - home_dirs["Downloads"] = uci:get_first("quickstart", "main", "dl_dir", home_dirs["Public"] .. "/Downloads") - home_dirs["Caches"] = uci:get_first("quickstart", "main", "tmp_dir", home_dirs["main_dir"] .. "/Caches") - return home_dirs -end - -kai.find_paths = function(blocks, home_dirs, path_name) - local default_path = "" - local paths = {} - - default_path = home_dirs[path_name] .. "/KAI" - if #blocks == 0 then - table.insert(paths, default_path) - else - for _, val in pairs(blocks) do - table.insert(paths, val .. "/" .. path_name .. "/KAI") - end - local without_conf_dir = "/root/" .. path_name .. "/KAI" - if default_path == without_conf_dir then - default_path = paths[1] - end - end - - return paths, default_path -end - -return kai - diff --git a/luci-app-kai/luasrc/view/kai/kai_status.htm b/luci-app-kai/luasrc/view/kai/kai_status.htm deleted file mode 100644 index 43c2c0e3..00000000 --- a/luci-app-kai/luasrc/view/kai/kai_status.htm +++ /dev/null @@ -1,23 +0,0 @@ - - -
- <%:Status%> -

- <%:Collecting data...%> -

-