mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-10-29 19:55:13 +08:00
update 2026-07-03 01:41:07
This commit is contained in:
1 parent
287b2370e9
commit
fc84ee6995
5 files changed
+353
-16
No files matched your search
@@ -835,7 +835,7 @@ Xray.outbounds = {
|
|||||||
tcpcongestion = server.custom_tcpcongestion, -- 连接服务器节点的 TCP 拥塞控制算法
|
tcpcongestion = server.custom_tcpcongestion, -- 连接服务器节点的 TCP 拥塞控制算法
|
||||||
-- 出站的 dialerProxy(与 fragment 中的 tag 保持一致)
|
-- 出站的 dialerProxy(与 fragment 中的 tag 保持一致)
|
||||||
dialerProxy = (xray_fragment.fragment == "1" or xray_fragment.noise == "1") and
|
dialerProxy = (xray_fragment.fragment == "1" or xray_fragment.noise == "1") and
|
||||||
((remarks ~= nil and remarks ~= "") and (node_id .. "." .. remarks) or node_id) or nil
|
((remarks and remarks ~= "") and (node_id .. "." .. remarks) or ("direct" .. "." .. node_id)) or nil
|
||||||
}
|
}
|
||||||
} or nil,
|
} or nil,
|
||||||
mux = (server.v2ray_protocol ~= "hysteria2" and server.v2ray_protocol ~= "wireguard") and {
|
mux = (server.v2ray_protocol ~= "hysteria2" and server.v2ray_protocol ~= "wireguard") and {
|
||||||
@@ -872,7 +872,7 @@ if xray_fragment.fragment ~= "0" or (xray_fragment.noise ~= "0" and xray_noise.e
|
|||||||
local n_domainstrategy = xray_noise.domainStrategy
|
local n_domainstrategy = xray_noise.domainStrategy
|
||||||
table.insert(Xray.outbounds, {
|
table.insert(Xray.outbounds, {
|
||||||
protocol = "freedom",
|
protocol = "freedom",
|
||||||
tag = (remarks ~= nil and remarks ~= "") and (node_id .. "." .. remarks) or node_id,
|
tag = (remarks and remarks ~= "") and (node_id .. "." .. remarks) or ("direct" .. "." .. node_id),
|
||||||
settings = (xray_fragment.noise == "1" and xray_noise.enabled == "1") and n_domainstrategy and n_domainstrategy ~= "" and {
|
settings = (xray_fragment.noise == "1" and xray_noise.enabled == "1") and n_domainstrategy and n_domainstrategy ~= "" and {
|
||||||
domainStrategy = n_domainstrategy
|
domainStrategy = n_domainstrategy
|
||||||
} or nil,
|
} or nil,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ local b64decode = nixio.bin.b64decode
|
|||||||
local b64encode = nixio.bin.b64encode
|
local b64encode = nixio.bin.b64encode
|
||||||
local URL = require "url"
|
local URL = require "url"
|
||||||
local cache = {}
|
local cache = {}
|
||||||
|
local old_groupHash_cache = {}
|
||||||
local nodeResult = setmetatable({}, {__index = cache}) -- update result
|
local nodeResult = setmetatable({}, {__index = cache}) -- update result
|
||||||
local name = 'shadowsocksr'
|
local name = 'shadowsocksr'
|
||||||
local uciType = 'servers'
|
local uciType = 'servers'
|
||||||
@@ -378,14 +379,14 @@ local function isClashYAML(str)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local function processClashSubscription(url)
|
local function processClashSubscription(url, groupHash)
|
||||||
local ok, parsed = pcall(URL.parse, url)
|
local ok, parsed = pcall(URL.parse, url)
|
||||||
if not ok or not parsed or not parsed.host then
|
if not ok or not parsed or not parsed.host then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local url_hash = string.sub(md5(url), 1, 8)
|
local groupHash_short = string.sub(groupHash, 1, 8)
|
||||||
local alias = "Clash_" .. parsed.host .. "_" .. url_hash
|
local alias = "Clash_" .. parsed.host .. "_" .. groupHash_short
|
||||||
local server_port = parsed.port or ((parsed.scheme == "http") and "80" or "443")
|
local server_port = parsed.port or ((parsed.scheme == "http") and "80" or "443")
|
||||||
local result = {
|
local result = {
|
||||||
type = "clash",
|
type = "clash",
|
||||||
@@ -2005,14 +2006,55 @@ end
|
|||||||
local function read_old_md5(groupHash)
|
local function read_old_md5(groupHash)
|
||||||
local path = get_md5_path(groupHash)
|
local path = get_md5_path(groupHash)
|
||||||
if nixio.fs.access(path) then
|
if nixio.fs.access(path) then
|
||||||
return trim(nixio.fs.readfile(path) or "")
|
local content = trim(nixio.fs.readfile(path) or "")
|
||||||
|
if content ~= "" then
|
||||||
|
-- 尝试解析 JSON 格式
|
||||||
|
local ok, data = pcall(jsonParse, content)
|
||||||
|
if ok and data and data.md5 then
|
||||||
|
return data.md5
|
||||||
|
end
|
||||||
|
-- 兼容旧格式(纯 MD5 值)
|
||||||
|
return content
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return ""
|
return ""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- 读取上次保存的 groupHash(扫描所有 sub_md5_* 文件,通过 url 匹配)
|
||||||
|
local function read_old_groupHash(url)
|
||||||
|
-- 检查缓存
|
||||||
|
if old_groupHash_cache[url] then
|
||||||
|
return old_groupHash_cache[url]
|
||||||
|
end
|
||||||
|
|
||||||
|
local files = nixio.fs.dir("/tmp/") or {}
|
||||||
|
for file in files do
|
||||||
|
if file:match("^sub_md5_") then
|
||||||
|
local full_path = "/tmp/" .. file
|
||||||
|
if nixio.fs.access(full_path) then
|
||||||
|
local content = trim(nixio.fs.readfile(full_path) or "")
|
||||||
|
if content ~= "" then
|
||||||
|
local ok, data = pcall(jsonParse, content)
|
||||||
|
if ok and data and data.url and data.url == url then
|
||||||
|
return data.hash, data.url
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
-- 将订阅分组最新内容的 MD5 值保存到对应的临时文件中,以便下次更新时进行对比。
|
-- 将订阅分组最新内容的 MD5 值保存到对应的临时文件中,以便下次更新时进行对比。
|
||||||
local function write_new_md5(groupHash, md5)
|
-- 同时保存 groupHash 和 url,用于检测 groupHash 的值变化
|
||||||
nixio.fs.writefile(get_md5_path(groupHash), md5)
|
local function write_new_md5(groupHash, md5, url)
|
||||||
|
local path = get_md5_path(groupHash)
|
||||||
|
local data = {
|
||||||
|
md5 = md5,
|
||||||
|
hash = groupHash,
|
||||||
|
url = url
|
||||||
|
}
|
||||||
|
nixio.fs.writefile(path, jsonStringify(data))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- curl
|
-- curl
|
||||||
@@ -2511,6 +2553,7 @@ end
|
|||||||
local execute = function()
|
local execute = function()
|
||||||
local updated = false
|
local updated = false
|
||||||
local selected_hashes = {}
|
local selected_hashes = {}
|
||||||
|
local old_groupHash = nil
|
||||||
|
|
||||||
for _, item in ipairs(subscribe_items) do
|
for _, item in ipairs(subscribe_items) do
|
||||||
local fetch_url = build_convert_url(item.url)
|
local fetch_url = build_convert_url(item.url)
|
||||||
@@ -2531,7 +2574,11 @@ local execute = function()
|
|||||||
local raw, new_md5
|
local raw, new_md5
|
||||||
local groupHash
|
local groupHash
|
||||||
local yaml_removed_count = 0
|
local yaml_removed_count = 0
|
||||||
|
|
||||||
|
-- 读取旧的 groupHash
|
||||||
|
old_groupHash = read_old_groupHash(url)
|
||||||
|
log("读取到旧的 groupHash: " .. tostring(old_groupHash))
|
||||||
|
|
||||||
if should_use_mihomo_mode() then
|
if should_use_mihomo_mode() then
|
||||||
raw, new_md5 = curl(fetch_url, user_agent)
|
raw, new_md5 = curl(fetch_url, user_agent)
|
||||||
if isClashYAML(raw) then
|
if isClashYAML(raw) then
|
||||||
@@ -2557,7 +2604,7 @@ local execute = function()
|
|||||||
if should_use_mihomo_mode() and yaml_removed_count and yaml_removed_count > 0 then
|
if should_use_mihomo_mode() and yaml_removed_count and yaml_removed_count > 0 then
|
||||||
log("Clash/Mihomo YAML 已按订阅过滤关键词移除节点数量: " .. tostring(yaml_removed_count))
|
log("Clash/Mihomo YAML 已按订阅过滤关键词移除节点数量: " .. tostring(yaml_removed_count))
|
||||||
end
|
end
|
||||||
log("groupHash: " .. groupHash)
|
log("groupHash: " .. tostring(groupHash))
|
||||||
log("old_md5: " .. tostring(old_md5))
|
log("old_md5: " .. tostring(old_md5))
|
||||||
log("new_md5: " .. tostring(new_md5))
|
log("new_md5: " .. tostring(new_md5))
|
||||||
|
|
||||||
@@ -2589,8 +2636,18 @@ local execute = function()
|
|||||||
log("订阅内容未变化但本地节点不存在,强制重建订阅节点: " .. url)
|
log("订阅内容未变化但本地节点不存在,强制重建订阅节点: " .. url)
|
||||||
end
|
end
|
||||||
updated = true
|
updated = true
|
||||||
-- 保存更新后的 MD5 值到以 groupHash 为标识的临时文件中,用于下次订阅更新时进行对比
|
|
||||||
write_new_md5(groupHash, new_md5)
|
-- 当 groupHash 变化时,删除旧的 MD5 文件
|
||||||
|
if old_groupHash and old_groupHash ~= groupHash then
|
||||||
|
local old_path = get_md5_path(old_groupHash)
|
||||||
|
if nixio.fs.access(old_path) then
|
||||||
|
nixio.fs.remove(old_path)
|
||||||
|
log("groupHash 已变化,删除旧 MD5 文件: " .. old_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 保存更新后的 groupHash、MD5 和 URL 值
|
||||||
|
write_new_md5(groupHash, new_md5, url)
|
||||||
|
|
||||||
cache[groupHash] = {}
|
cache[groupHash] = {}
|
||||||
tinsert(nodeResult, {})
|
tinsert(nodeResult, {})
|
||||||
@@ -2600,7 +2657,7 @@ local execute = function()
|
|||||||
|
|
||||||
if isClashYAML(raw) then
|
if isClashYAML(raw) then
|
||||||
is_clash_subscription = true
|
is_clash_subscription = true
|
||||||
local result = processClashSubscription(fetch_url)
|
local result = processClashSubscription(fetch_url, groupHash)
|
||||||
if result and check_filer(result) then
|
if result and check_filer(result) then
|
||||||
log('过滤 Clash 总节点: ' .. result.alias)
|
log('过滤 Clash 总节点: ' .. result.alias)
|
||||||
elseif result and not cache[groupHash][result.hashkey] then
|
elseif result and not cache[groupHash][result.hashkey] then
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
|
|||||||
|
|
||||||
PKG_NAME:=mosdns
|
PKG_NAME:=mosdns
|
||||||
PKG_VERSION:=5.3.4
|
PKG_VERSION:=5.3.4
|
||||||
PKG_RELEASE:=5
|
PKG_RELEASE:=6
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://codeload.github.com/IrineSistiana/mosdns/tar.gz/v$(PKG_VERSION)?
|
PKG_SOURCE_URL:=https://codeload.github.com/IrineSistiana/mosdns/tar.gz/v$(PKG_VERSION)?
|
||||||
|
|||||||
@@ -0,0 +1,280 @@
|
|||||||
|
From e2a50186add36064f78015b163d725f1fe9821d0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: sbwml <admin@cooluc.com>
|
||||||
|
Date: Thu, 2 Jul 2026 22:37:40 +0800
|
||||||
|
Subject: [PATCH] feat: add size and backups config for log file rotation
|
||||||
|
|
||||||
|
- `log.size`: limits active log file size, supports K/M/G/T (default 1M)
|
||||||
|
- `log.backups`: limits max retained backup files (default 3)
|
||||||
|
|
||||||
|
Signed-off-by: sbwml <admin@cooluc.com>
|
||||||
|
---
|
||||||
|
mlog/logger.go | 25 +++++-
|
||||||
|
mlog/rotator.go | 219 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 241 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100644 mlog/rotator.go
|
||||||
|
|
||||||
|
--- a/mlog/logger.go
|
||||||
|
+++ b/mlog/logger.go
|
||||||
|
@@ -38,6 +38,14 @@ type LogConfig struct {
|
||||||
|
|
||||||
|
// Production enables json output.
|
||||||
|
Production bool `yaml:"production"`
|
||||||
|
+
|
||||||
|
+ // Size of log file limit. Default is 1M.
|
||||||
|
+ // Supported units: K, M, G, T. If no unit, defaults to M.
|
||||||
|
+ Size string `yaml:"size"`
|
||||||
|
+
|
||||||
|
+ // Max number of old log files to retain. Default is 3.
|
||||||
|
+ // Set to a negative number to retain all files.
|
||||||
|
+ Backups int `yaml:"backups"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
@@ -57,11 +65,22 @@ func NewLogger(lc LogConfig) (*zap.Logge
|
||||||
|
|
||||||
|
var out zapcore.WriteSyncer
|
||||||
|
if lf := lc.File; len(lf) > 0 {
|
||||||
|
- f, _, err := zap.Open(lf)
|
||||||
|
+ maxSize, err := ParseSize(lc.Size)
|
||||||
|
if err != nil {
|
||||||
|
- return nil, fmt.Errorf("open log file: %w", err)
|
||||||
|
+ return nil, fmt.Errorf("invalid log size limit: %w", err)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ backups := lc.Backups
|
||||||
|
+ if backups == 0 {
|
||||||
|
+ backups = 3
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rotator := &Rotator{
|
||||||
|
+ Filename: lf,
|
||||||
|
+ MaxSize: maxSize,
|
||||||
|
+ MaxBackups: backups,
|
||||||
|
}
|
||||||
|
- out = zapcore.Lock(f)
|
||||||
|
+ out = zapcore.AddSync(rotator)
|
||||||
|
} else {
|
||||||
|
out = stderr
|
||||||
|
}
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/mlog/rotator.go
|
||||||
|
@@ -0,0 +1,219 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2020-2022, IrineSistiana
|
||||||
|
+ *
|
||||||
|
+ * This file is part of mosdns.
|
||||||
|
+ *
|
||||||
|
+ * mosdns is free software: you can redistribute it and/or modify
|
||||||
|
+ * it under the terms of the GNU General Public License as published by
|
||||||
|
+ * the Free Software Foundation, either version 3 of the License, or
|
||||||
|
+ * (at your option) any later version.
|
||||||
|
+ *
|
||||||
|
+ * mosdns is distributed in the hope that it will be useful,
|
||||||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
+ * GNU General Public License for more details.
|
||||||
|
+ *
|
||||||
|
+ * You should have received a copy of the GNU General Public License
|
||||||
|
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+package mlog
|
||||||
|
+
|
||||||
|
+import (
|
||||||
|
+ "fmt"
|
||||||
|
+ "os"
|
||||||
|
+ "path/filepath"
|
||||||
|
+ "sort"
|
||||||
|
+ "strconv"
|
||||||
|
+ "strings"
|
||||||
|
+ "sync"
|
||||||
|
+ "time"
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
+type Rotator struct {
|
||||||
|
+ Filename string
|
||||||
|
+ MaxSize int64
|
||||||
|
+ MaxBackups int
|
||||||
|
+
|
||||||
|
+ size int64
|
||||||
|
+ f *os.File
|
||||||
|
+ mu sync.Mutex
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (r *Rotator) Write(p []byte) (n int, err error) {
|
||||||
|
+ r.mu.Lock()
|
||||||
|
+ defer r.mu.Unlock()
|
||||||
|
+
|
||||||
|
+ if r.f == nil {
|
||||||
|
+ if err := r.open(); err != nil {
|
||||||
|
+ return 0, err
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ writeLen := int64(len(p))
|
||||||
|
+ if r.MaxSize > 0 && r.size+writeLen > r.MaxSize {
|
||||||
|
+ if err := r.rotate(); err != nil {
|
||||||
|
+ return 0, err
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ n, err = r.f.Write(p)
|
||||||
|
+ r.size += int64(n)
|
||||||
|
+ return n, err
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (r *Rotator) open() error {
|
||||||
|
+ info, err := os.Stat(r.Filename)
|
||||||
|
+ if os.IsNotExist(err) {
|
||||||
|
+ return r.openNew()
|
||||||
|
+ }
|
||||||
|
+ if err != nil {
|
||||||
|
+ return err
|
||||||
|
+ }
|
||||||
|
+ r.size = info.Size()
|
||||||
|
+ f, err := os.OpenFile(r.Filename, os.O_APPEND|os.O_WRONLY, 0644)
|
||||||
|
+ if err != nil {
|
||||||
|
+ return r.openNew()
|
||||||
|
+ }
|
||||||
|
+ r.f = f
|
||||||
|
+ return nil
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (r *Rotator) openNew() error {
|
||||||
|
+ err := os.MkdirAll(filepath.Dir(r.Filename), 0755)
|
||||||
|
+ if err != nil {
|
||||||
|
+ return err
|
||||||
|
+ }
|
||||||
|
+ f, err := os.OpenFile(r.Filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||||
|
+ if err != nil {
|
||||||
|
+ return err
|
||||||
|
+ }
|
||||||
|
+ r.f = f
|
||||||
|
+ r.size = 0
|
||||||
|
+ return nil
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (r *Rotator) rotate() error {
|
||||||
|
+ if r.f != nil {
|
||||||
|
+ r.f.Close()
|
||||||
|
+ r.f = nil
|
||||||
|
+ }
|
||||||
|
+ _, err := os.Stat(r.Filename)
|
||||||
|
+ if err == nil {
|
||||||
|
+ ext := filepath.Ext(r.Filename)
|
||||||
|
+ name := strings.TrimSuffix(r.Filename, ext)
|
||||||
|
+ // Windows doesn't allow colons in filenames, so use dashes for time
|
||||||
|
+ newName := fmt.Sprintf("%s-%s%s", name, time.Now().Format("2006-01-02T15-04-05.000"), ext)
|
||||||
|
+ os.Rename(r.Filename, newName)
|
||||||
|
+ }
|
||||||
|
+ err = r.openNew()
|
||||||
|
+ if err == nil {
|
||||||
|
+ r.cleanupBackups()
|
||||||
|
+ }
|
||||||
|
+ return err
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (r *Rotator) cleanupBackups() {
|
||||||
|
+ if r.MaxBackups < 0 {
|
||||||
|
+ return // < 0 means keep all
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dir := filepath.Dir(r.Filename)
|
||||||
|
+ ext := filepath.Ext(r.Filename)
|
||||||
|
+ name := strings.TrimSuffix(filepath.Base(r.Filename), ext)
|
||||||
|
+
|
||||||
|
+ entries, err := os.ReadDir(dir)
|
||||||
|
+ if err != nil {
|
||||||
|
+ return
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ var backups []string
|
||||||
|
+ prefix := name + "-"
|
||||||
|
+ for _, entry := range entries {
|
||||||
|
+ if entry.IsDir() {
|
||||||
|
+ continue
|
||||||
|
+ }
|
||||||
|
+ n := entry.Name()
|
||||||
|
+ if strings.HasPrefix(n, prefix) && strings.HasSuffix(n, ext) {
|
||||||
|
+ // Basic validation of the timestamp length
|
||||||
|
+ timestamp := n[len(prefix) : len(n)-len(ext)]
|
||||||
|
+ if len(timestamp) == 23 {
|
||||||
|
+ backups = append(backups, filepath.Join(dir, n))
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if len(backups) <= r.MaxBackups {
|
||||||
|
+ return
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Sort alphabetically, which sorts by time since format is 2006-01-02T15-04-05.000
|
||||||
|
+ sort.Strings(backups)
|
||||||
|
+
|
||||||
|
+ toDelete := len(backups) - r.MaxBackups
|
||||||
|
+ for i := 0; i < toDelete; i++ {
|
||||||
|
+ os.Remove(backups[i])
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (r *Rotator) Sync() error {
|
||||||
|
+ r.mu.Lock()
|
||||||
|
+ defer r.mu.Unlock()
|
||||||
|
+ if r.f != nil {
|
||||||
|
+ return r.f.Sync()
|
||||||
|
+ }
|
||||||
|
+ return nil
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (r *Rotator) Close() error {
|
||||||
|
+ r.mu.Lock()
|
||||||
|
+ defer r.mu.Unlock()
|
||||||
|
+ if r.f != nil {
|
||||||
|
+ err := r.f.Close()
|
||||||
|
+ r.f = nil
|
||||||
|
+ return err
|
||||||
|
+ }
|
||||||
|
+ return nil
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// ParseSize parses the size string and returns bytes.
|
||||||
|
+// Supports K, M, G, T units. If no unit, defaults to M.
|
||||||
|
+func ParseSize(s string) (int64, error) {
|
||||||
|
+ if s == "" {
|
||||||
|
+ return 1024 * 1024, nil // Default 1M
|
||||||
|
+ }
|
||||||
|
+ s = strings.ToUpper(strings.TrimSpace(s))
|
||||||
|
+
|
||||||
|
+ var unit string
|
||||||
|
+ var valStr string
|
||||||
|
+ for i, c := range s {
|
||||||
|
+ if c >= 'A' && c <= 'Z' {
|
||||||
|
+ valStr = s[:i]
|
||||||
|
+ unit = s[i:]
|
||||||
|
+ break
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if unit == "" {
|
||||||
|
+ valStr = s
|
||||||
|
+ unit = "M" // default to M
|
||||||
|
+ }
|
||||||
|
+ valStr = strings.TrimSpace(valStr)
|
||||||
|
+
|
||||||
|
+ val, err := strconv.ParseInt(valStr, 10, 64)
|
||||||
|
+ if err != nil {
|
||||||
|
+ return 0, err
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ switch unit {
|
||||||
|
+ case "K", "KB":
|
||||||
|
+ return val * 1024, nil
|
||||||
|
+ case "M", "MB":
|
||||||
|
+ return val * 1024 * 1024, nil
|
||||||
|
+ case "G", "GB":
|
||||||
|
+ return val * 1024 * 1024 * 1024, nil
|
||||||
|
+ case "T", "TB":
|
||||||
|
+ return val * 1024 * 1024 * 1024 * 1024, nil
|
||||||
|
+ default:
|
||||||
|
+ return 0, fmt.Errorf("invalid size unit: %s", unit)
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
@@ -21,13 +21,13 @@ define Download/geoip
|
|||||||
HASH:=b71d1999439dde2de2d2b6844a2befa50c50211ff739785c005ca7c230a17d6a
|
HASH:=b71d1999439dde2de2d2b6844a2befa50c50211ff739785c005ca7c230a17d6a
|
||||||
endef
|
endef
|
||||||
|
|
||||||
GEOSITE_VER:=20260701035519
|
GEOSITE_VER:=20260702133809
|
||||||
GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER)
|
GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER)
|
||||||
define Download/geosite
|
define Download/geosite
|
||||||
URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/
|
URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/
|
||||||
URL_FILE:=dlc.dat
|
URL_FILE:=dlc.dat
|
||||||
FILE:=$(GEOSITE_FILE)
|
FILE:=$(GEOSITE_FILE)
|
||||||
HASH:=76902d5531d1036277d5663ff37d2c60403b16913ebfa82235fbd7139825d3b7
|
HASH:=f2ec0b9dc07c03af30d61f84d0d07210235fcc226a9c2b6682717bada6e58c12
|
||||||
endef
|
endef
|
||||||
|
|
||||||
GEOSITE_IRAN_VER:=202606290159
|
GEOSITE_IRAN_VER:=202606290159
|
||||||
|
|||||||
Reference in new issue
Block a user