🍓 Sync 2022-06-14 16:41

This commit is contained in:
github-actions[bot] 2022-06-14 16:41:00 +08:00
parent f0a4f86014
commit 067e7d90df
78 changed files with 5411 additions and 6 deletions

View File

@ -0,0 +1,83 @@
# SPDX-Identifier-License: GPL-3.0-only
#
# Copyright (C) 2021 ImmortalWrt.org
include $(TOPDIR)/rules.mk
PKG_NAME:=UnblockNeteaseMusic-Go
PKG_VERSION:=0.2.13
PKG_RELEASE:=$(AUTORELEASE)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/cnsilvan/UnblockNeteaseMusic/tar.gz/$(PKG_VERSION)?
PKG_HASH:=92201b7f04ab1015c806c672b98a29b97d0f137d9b60e6d35d279c2064ed86a4
PKG_LICENSE:=GPL-3.0
PKG_LICENSE_FILE:=LICENSE
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
PKG_CONFIG_DEPENDS:= \
CONFIG_UNBLOCKNETEASEMUSIC_GO_COMPRESS_GOPROXY \
CONFIG_UNBLOCKNETEASEMUSIC_GO_COMPRESS_UPX
PKG_BUILD_DIR:=$(BUILD_DIR)/$(firstword $(subst -, ,$(PKG_NAME)))-$(PKG_VERSION)
PKG_BUILD_DEPENDS:=golang/host
PKG_BUILD_PARALLEL:=1
PKG_USE_MIPS16:=0
GO_PKG:=github.com/cnsilvan/UnblockNeteaseMusic
GO_PKG_BUILD_PKG:=$$(GO_PKG)
GO_PKG_LDFLAGS:=-s -w
COMPILE_TIME:= $(shell TZ=UTC-8 date '+%Y-%m-%d %H:%M:%S')
GO_PKG_LDFLAGS+= \
-X '$(GO_PKG)/version.Version=$(PKG_VERSION)' \
-X '$(GO_PKG)/version.BuildTime=$(COMPILE_TIME)' \
-X '$(GO_PKG)/version.ExGoVersionInfo=$(GO_ARM) $(GO_MIPS)$(GO_MIPS64)'
include $(INCLUDE_DIR)/package.mk
include ../../lang/golang/golang-package.mk
define Package/UnblockNeteaseMusic-Go/config
config UNBLOCKNETEASEMUSIC_GO_COMPRESS_GOPROXY
bool "Compiling with GOPROXY proxy"
default n
config UNBLOCKNETEASEMUSIC_GO_COMPRESS_UPX
bool "Compress executable files with UPX"
depends on !mips64
default n
endef
ifeq ($(CONFIG_UNBLOCKNETEASEMUSIC_GO_COMPRESS_GOPROXY),y)
export GO111MODULE=on
export GOPROXY=https://goproxy.io
endif
define Package/UnblockNeteaseMusic-Go
SECTION:=multimedia
CATEGORY:=Multimedia
TITLE:=Revive Netease Cloud Music (Golang)
URL:=https://github.com/cnsilvan/UnblockNeteaseMusic
DEPENDS:=$(GO_ARCH_DEPENDS)
endef
define Build/Compile
$(call GoPackage/Build/Compile)
ifeq ($(CONFIG_GOST_COMPRESS_UPX),y)
$(STAGING_DIR_HOST)/bin/upx --lzma --best $(GO_PKG_BUILD_BIN_DIR)/UnblockNeteaseMusic
endif
endef
define Package/UnblockNeteaseMusic-Go/install
$(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR))
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/UnblockNeteaseMusic $(1)/usr/bin/UnblockNeteaseMusic
$(INSTALL_DIR) $(1)/usr/share/UnblockNeteaseMusicGo
$(CP) ./files/* $(1)/usr/share/UnblockNeteaseMusicGo/
endef
$(eval $(call GoBinPackage,UnblockNeteaseMusic-Go))
$(eval $(call BuildPackage,UnblockNeteaseMusic-Go))

View File

@ -0,0 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICIjCCAaigAwIBAgIUTc9HQDej5hLCQ74u436a5yE4MDcwCgYIKoZIzj0EAwMw
SDELMAkGA1UEBhMCQ04xJDAiBgNVBAMMG1VuYmxvY2tOZXRlYXNlTXVzaWMgUm9v
dCBDQTETMBEGA1UECgwKMTcxNTE3MzMyOTAeFw0yMTA0MzAwNzIzMDJaFw0yNjA0
MjkwNzIzMDJaMEgxCzAJBgNVBAYTAkNOMSQwIgYDVQQDDBtVbmJsb2NrTmV0ZWFz
ZU11c2ljIFJvb3QgQ0ExEzARBgNVBAoMCjE3MTUxNzMzMjkwdjAQBgcqhkjOPQIB
BgUrgQQAIgNiAASIyI7lYgGlq49qWtY1O2/XNDeowYf7W/Z+l7C14bphxAJ9jSDo
tLwbFPWy5VPENc0rB0/yeHA2z7LU67POL2gGgp+17y7scLkkBk3Q7wRMETrtP44Z
ITBstZ0wzVyyQEKjUzBRMB0GA1UdDgQWBBQ2F7+t8cPHJaWuCD8RHTSdLugKYzAf
BgNVHSMEGDAWgBQ2F7+t8cPHJaWuCD8RHTSdLugKYzAPBgNVHRMBAf8EBTADAQH/
MAoGCCqGSM49BAMDA2gAMGUCMQDqaRX2e01e0U+f0As/KUKDhmG5ElkK5CjYK9jk
kXLNGFXJLGta6CDvjtMLBPc20qkCMBvDs+JnJKVBEJNZVsRBBs+v2YxNU/u2aYJa
dMwXuFveSDWOS7mBeRztX/geEggiSw==
-----END CERTIFICATE-----

View File

@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICRDCCAcqgAwIBAgIUeVqRrT2mHG5Mc8JD+ErphiAmlgkwCgYIKoZIzj0EAwMw
SDELMAkGA1UEBhMCQ04xJDAiBgNVBAMMG1VuYmxvY2tOZXRlYXNlTXVzaWMgUm9v
dCBDQTETMBEGA1UECgwKMTcxNTE3MzMyOTAeFw0yMTA0MzAwNzIzMDJaFw0yMjA0
MzAwNzIzMDJaMHsxCzAJBgNVBAYTAkNOMREwDwYDVQQHDAhIYW5nemhvdTEsMCoG
A1UECgwjTmV0RWFzZSAoSGFuZ3pob3UpIE5ldHdvcmsgQ28uLCBMdGQxETAPBgNV
BAsMCElUIERlcHQuMRgwFgYDVQQDDA8qLm11c2ljLjE2My5jb20wdjAQBgcqhkjO
PQIBBgUrgQQAIgNiAAQTPyU9RQ1pAFMLmozi+c4pEC1rrxAlPGwO9Em+qV+a5qLW
gQjjsJeabMqJ/UQ7hDtdKVxWuXiAjMiDcXwL63I71MZKPTAEKXdCmNQwb4kXvRUn
oOR4r7BMxEpGlf0CULWjQjBAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMCkGA1UdEQQi
MCCCDW11c2ljLjE2My5jb22CDyoubXVzaWMuMTYzLmNvbTAKBggqhkjOPQQDAwNo
ADBlAjEAs5bdgnNP/DiK919RiWscC0kyuY0ugG1C8m8F2Yod4MI3oTyrkVcag21o
NSzm802uAjBoPuKEbjjFP4ics0BQdICiVd6WCVAsE69FnlmqRteAJqxvdKGpVLi+
Qi3arfomrrc=
-----END CERTIFICATE-----

View File

@ -0,0 +1,9 @@
-----BEGIN EC PARAMETERS-----
BgUrgQQAIg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDBfW3twxGaQmMzP9p0/UU5EvHFVCbBw4piVFJ+pm/uFY6CKZkC5LGMa
Uc9vn/KiewGgBwYFK4EEACKhZANiAAQTPyU9RQ1pAFMLmozi+c4pEC1rrxAlPGwO
9Em+qV+a5qLWgQjjsJeabMqJ/UQ7hDtdKVxWuXiAjMiDcXwL63I71MZKPTAEKXdC
mNQwb4kXvRUnoOR4r7BMxEpGlf0CULU=
-----END EC PRIVATE KEY-----

View File

@ -0,0 +1,144 @@
From f4f5d11b578a1ab2c3d089bbe5453052b43892bb Mon Sep 17 00:00:00 2001
From: tofuliang <tofuliang@gmail.com>
Date: Mon, 24 Jan 2022 18:53:11 +0800
Subject: [PATCH] fix block ad,add web traffic logs
---
app.go | 1 +
config/config.go | 1 +
processor/processor.go | 55 +++++++++++++++++++++++++++++++++---------
3 files changed, 45 insertions(+), 12 deletions(-)
diff --git a/app.go b/app.go
index 73a6070..1018d75 100644
--- a/app.go
+++ b/app.go
@@ -45,6 +45,7 @@ func main() {
log.Println("EnableLocalVip=", *config.EnableLocalVip)
log.Println("UnlockSoundEffects=", *config.UnlockSoundEffects)
log.Println("QQCookieFile=", *config.QQCookieFile)
+ log.Println("LogWebTraffic=", *config.LogWebTraffic)
if host.InitHosts() == nil {
//go func() {
// // // terminal: $ go tool pprof -http=:8081 http://localhost:6060/debug/pprof/heap
diff --git a/config/config.go b/config/config.go
index 6c07873..a653cdf 100644
--- a/config/config.go
+++ b/config/config.go
@@ -31,6 +31,7 @@ var (
EnableLocalVip = flag.Bool("lv", false, "enable local vip")
UnlockSoundEffects = flag.Bool("sef", false, "unlock SoundEffects")
QQCookieFile = flag.String("qc", "./qq.cookie", "specify cookies file ,such as : \"qq.cookie\"")
+ LogWebTraffic = flag.Bool("wl", false, "log request url and response")
)
func ValidParams() bool {
diff --git a/processor/processor.go b/processor/processor.go
index 8d09dbf..d07b9d3 100644
--- a/processor/processor.go
+++ b/processor/processor.go
@@ -6,14 +6,6 @@ import (
"crypto/md5"
"encoding/hex"
"encoding/json"
- "github.com/cnsilvan/UnblockNeteaseMusic/cache"
- "github.com/cnsilvan/UnblockNeteaseMusic/common"
- "github.com/cnsilvan/UnblockNeteaseMusic/config"
- "github.com/cnsilvan/UnblockNeteaseMusic/network"
- "github.com/cnsilvan/UnblockNeteaseMusic/processor/crypto"
- "github.com/cnsilvan/UnblockNeteaseMusic/provider"
- "github.com/cnsilvan/UnblockNeteaseMusic/utils"
- "golang.org/x/text/width"
"io"
"io/ioutil"
"log"
@@ -22,6 +14,15 @@ import (
"regexp"
"strconv"
"strings"
+
+ "github.com/cnsilvan/UnblockNeteaseMusic/cache"
+ "github.com/cnsilvan/UnblockNeteaseMusic/common"
+ "github.com/cnsilvan/UnblockNeteaseMusic/config"
+ "github.com/cnsilvan/UnblockNeteaseMusic/network"
+ "github.com/cnsilvan/UnblockNeteaseMusic/processor/crypto"
+ "github.com/cnsilvan/UnblockNeteaseMusic/provider"
+ "github.com/cnsilvan/UnblockNeteaseMusic/utils"
+ "golang.org/x/text/width"
)
var (
@@ -188,6 +189,9 @@ func RequestAfter(request *http.Request, response *http.Response, netease *Netea
if ok {
code = codeN.String()
}
+
+ logResponse(netease)
+
if strings.EqualFold(netease.Path, "/api/osx/version") {
modified = disableUpdate(netease)
} else if strings.Contains(netease.Path, "/usertool/sound/") {
@@ -197,9 +201,24 @@ func RequestAfter(request *http.Request, response *http.Response, netease *Netea
for key, resp := range netease.JsonBody {
if strings.Contains(key, "/usertool/sound/") {
modified = unblockSoundEffects(resp.(map[string]interface{}))
- } else if *config.BlockAds && strings.Contains(netease.Path, "api/ad/") {
+ } else if *config.BlockAds && strings.Contains(key, "api/ad/") {
+ log.Println("block Ad has been triggered(" + key + ").")
resp = &common.MapType{}
modified = true
+ } else if *config.BlockAds && strings.EqualFold(key, "/api/v2/banner/get") {
+ newInfo := make(common.SliceType, 0)
+ info := netease.JsonBody[key]
+ for _, data := range info.(common.MapType)["banners"].(common.SliceType) {
+ if banner, ok := data.(common.MapType); ok {
+ if banner["adid"] == nil {
+ newInfo = append(newInfo, banner)
+ } else {
+ log.Println("block banner Ad has been triggered.")
+ modified = true
+ }
+ }
+ }
+ info.(common.MapType)["banners"] = newInfo
}
}
} else if !netease.Web && (code == "401" || code == "512") && strings.Contains(netease.Path, "manipulate") {
@@ -220,7 +239,9 @@ func RequestAfter(request *http.Request, response *http.Response, netease *Netea
// log.Println("NeedRepackage")
modifiedJson, _ := json.Marshal(netease.JsonBody)
// log.Println(netease)
- // log.Println(string(modifiedJson))
+ if *config.LogWebTraffic {
+ log.Println("modified =>\n" + string(modifiedJson))
+ }
if netease.Encrypted {
modifiedJson = crypto.AesEncryptECB(modifiedJson, []byte(aeskey))
}
@@ -258,14 +279,24 @@ func disableUpdate(netease *Netease) bool {
if len(value.(common.SliceType)) > 0 {
modified = true
jsonBody["updateFiles"] = make(common.SliceType, 0)
+ log.Println("disable update has been triggered.")
}
default:
}
}
- // modifiedJson, _ := json.Marshal(jsonBody)
- // log.Println(string(modifiedJson))
return modified
}
+
+func logResponse(netease *Netease) {
+ if *config.LogWebTraffic {
+ reqUrl := netease.Path
+ jsonBody := netease.JsonBody
+ modifiedJson, _ := json.Marshal(jsonBody)
+ sep := "===================================\n"
+ log.Println(sep + reqUrl + " => \n" + string(modifiedJson) + "\n")
+ }
+}
+
func localVIP(netease *Netease) bool {
if !*config.EnableLocalVip {
return false

View File

@ -0,0 +1,29 @@
From 6c009953d357d1cc03478cf65fc05701fb1966d6 Mon Sep 17 00:00:00 2001
From: ameansone <ameansone@outlook.com>
Date: Sun, 5 Dec 2021 19:18:20 +0800
Subject: [PATCH] fix(processor): avoid unnecessary decryption
---
processor/processor.go | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/processor/processor.go b/processor/processor.go
index 8d09dbf..011571b 100644
--- a/processor/processor.go
+++ b/processor/processor.go
@@ -177,9 +177,13 @@ func RequestAfter(request *http.Request, response *http.Response, netease *Netea
if netease.Forward {
aeskey = linuxApiKey
}
- decryptECBBytes, encrypted := crypto.AesDecryptECB(decryptECBBytes, []byte(aeskey))
- netease.Encrypted = encrypted
result := utils.ParseJson(decryptECBBytes)
+ netease.Encrypted = false;
+ if result == nil {
+ decryptECBBytes, encrypted := crypto.AesDecryptECB(decryptECBBytes, []byte(aeskey))
+ netease.Encrypted = encrypted
+ result = utils.ParseJson(decryptECBBytes)
+ }
netease.JsonBody = result
modified := false

View File

@ -0,0 +1,52 @@
# SPDX-Identifier-License: GPL-3.0-only
#
# Copyright (C) 2021 ImmortalWrt.org
include $(TOPDIR)/rules.mk
PKG_NAME:=UnblockNeteaseMusic
PKG_BASE_VERSION:=0.27.0-rc.6
PKG_RELEASE:=$(AUTORELEASE)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/UnblockNeteaseMusic/server.git
PKG_SOURCE_DATE:=2022-05-20
PKG_SOURCE_VERSION:=83e3467dc6b8e9bf1cc0feaabae834972aad3a64
PKG_MIRROR_HASH:=4214533b9bd28c67408f901461c10f239fdc3605db6477f043e45a0b7dd843b7
PKG_VERSION:=$(PKG_BASE_VERSION)-$(PKG_SOURCE_DATE)-$(call version_abbrev,$(PKG_SOURCE_VERSION))
PKG_LICENSE:=LGPL-3.0-only
PKG_LICENSE_FILE:=LICENSE
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
include $(INCLUDE_DIR)/package.mk
define Package/UnblockNeteaseMusic
SECTION:=multimedia
CATEGORY:=Multimedia
TITLE:=Revive Netease Cloud Music (NodeJS)
URL:=https://github.com/nondanee/UnblockNeteaseMusic
DEPENDS:=+node
PKGARCH:=all
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
xzcat $(DL_DIR)/$(PKG_SOURCE) | $(TAR) -C $(PKG_BUILD_DIR) $(TAR_OPTIONS)
endef
define Build/Configure
echo -e $(PKG_BASE_VERSION) > $(PKG_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/core_ver
echo -e $(PKG_SOURCE_VERSION) > $(PKG_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/local_ver
endef
define Build/Compile
endef
define Package/UnblockNeteaseMusic/install
$(INSTALL_DIR) $(1)/usr/share/UnblockNeteaseMusic
$(CP) $(PKG_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/* $(1)/usr/share/UnblockNeteaseMusic
endef
$(eval $(call BuildPackage,UnblockNeteaseMusic))

77
aliyundrive-fuse/Makefile Normal file
View File

@ -0,0 +1,77 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=aliyundrive-fuse
PKG_VERSION:=0.1.12
PKG_RELEASE:=$(AUTORELEASE)
PKG_LICENSE:=MIT
PKG_MAINTAINER:=messense <messense@icloud.com>
PKG_LIBC:=musl
ifeq ($(ARCH),arm)
PKG_LIBC:=musleabi
ARM_CPU_FEATURES:=$(word 2,$(subst +,$(space),$(call qstrip,$(CONFIG_CPU_TYPE))))
ifneq ($(filter $(ARM_CPU_FEATURES),vfp vfpv2),)
PKG_LIBC:=musleabihf
endif
endif
PKG_ARCH=$(ARCH)
ifeq ($(ARCH),i386)
PKG_ARCH:=i686
endif
PKG_SOURCE:=aliyundrive-fuse-v$(PKG_VERSION).$(PKG_ARCH)-unknown-linux-$(PKG_LIBC).tar.gz
PKG_SOURCE_URL:=https://github.com/messense/aliyundrive-fuse/releases/download/v$(PKG_VERSION)/
PKG_HASH:=skip
include $(INCLUDE_DIR)/package.mk
define Package/aliyundrive-fuse
SECTION:=multimedia
CATEGORY:=Multimedia
DEPENDS:=+fuse-utils
TITLE:=FUSE for AliyunDrive
URL:=https://github.com/messense/aliyundrive-fuse
endef
define Package/aliyundrive-fuse/description
FUSE for AliyunDrive.
endef
define Package/aliyundrive-fuse/conffiles
/etc/config/aliyundrive-fuse
endef
define Download/sha256sum
FILE:=$(PKG_SOURCE).sha256
URL_FILE:=$(FILE)
URL:=$(PKG_SOURCE_URL)
HASH:=skip
endef
$(eval $(call Download,sha256sum))
define Build/Prepare
mv $(DL_DIR)/$(PKG_SOURCE).sha256 .
cp $(DL_DIR)/$(PKG_SOURCE) .
shasum -a 256 -c $(PKG_SOURCE).sha256
rm $(PKG_SOURCE).sha256 $(PKG_SOURCE)
tar -C $(PKG_BUILD_DIR)/ -zxf $(DL_DIR)/$(PKG_SOURCE)
endef
define Build/Compile
echo "aliyundrive-fuse using precompiled binary."
endef
define Package/aliyundrive-fuse/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/aliyundrive-fuse $(1)/usr/bin/aliyundrive-fuse
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/aliyundrive-fuse.init $(1)/etc/init.d/aliyundrive-fuse
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./files/aliyundrive-fuse.config $(1)/etc/config/aliyundrive-fuse
endef
$(eval $(call BuildPackage,aliyundrive-fuse))

View File

@ -0,0 +1,8 @@
config default
option enable '0'
option debug '0'
option refresh_token ''
option domain_id ''
option mount_point '/mnt/aliyundrive'
option read_buffer_size '10485760'
option allow_other '1'

View File

@ -0,0 +1,53 @@
#!/bin/sh /etc/rc.common
USE_PROCD=1
START=99
STOP=15
NAME=aliyundrive-fuse
uci_get_by_type() {
local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null)
echo ${ret:=$3}
}
start_service() {
local enable=$(uci_get_by_type default enable)
case "$enable" in
1|on|true|yes|enabled)
local refresh_token=$(uci_get_by_type default refresh_token)
local domain_id=$(uci_get_by_type default domain_id)
local mount_point=$(uci_get_by_type default mount_point)
local read_buf_size=$(uci_get_by_type default read_buffer_size 10485760)
local allow_other=$(uci_get_by_type default allow_other 0)
local extra_options=""
if [[ ! -z "$domain_id" ]]; then
extra_options="$extra_options --domain-id $domain_id"
fi
if [ "$allow_other" = "1" ]; then
extra_options="$extra_options --allow-other"
fi
mkdir -p "$mount_point"
procd_open_instance
procd_set_param command /bin/sh -c "/usr/bin/$NAME $extra_options -S $read_buf_size --workdir /var/run/$NAME $mount_point >>/var/log/$NAME.log 2>&1"
procd_set_param pidfile /var/run/$NAME.pid
procd_set_param env REFRESH_TOKEN="$refresh_token"
case $(uci_get_by_type default debug) in
1|on|true|yes|enabled)
procd_append_param env RUST_LOG="aliyundrive_fuse=debug" ;;
*) ;;
esac
procd_close_instance ;;
*)
stop_service ;;
esac
}
service_triggers() {
procd_add_reload_trigger "aliyundrive-fuse"
}

View File

@ -0,0 +1,17 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-aliyundrive-fuse
PKG_VERSION:=0.1.12
PKG_RELEASE:=1
PKG_PO_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE)
PKG_LICENSE:=MIT
PKG_MAINTAINER:=messense <messense@icloud.com>
LUCI_TITLE:=LuCI Support for aliyundrive-fuse
LUCI_PKGARCH:=all
LUCI_DEPENDS:=+aliyundrive-fuse
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -0,0 +1,40 @@
module("luci.controller.aliyundrive-fuse", package.seeall)
function index()
if not nixio.fs.access("/etc/config/aliyundrive-fuse") then
return
end
local page
page = entry({"admin", "services", "aliyundrive-fuse"}, alias("admin", "services", "aliyundrive-fuse", "client"), _("AliyunDrive FUSE"), 10) -- 首页
page.dependent = true
page.acl_depends = { "luci-app-aliyundrive-fuse" }
entry({"admin", "services", "aliyundrive-fuse", "client"}, cbi("aliyundrive-fuse/client"), _("Settings"), 10).leaf = true -- 客户端配置
entry({"admin", "services", "aliyundrive-fuse", "log"}, form("aliyundrive-fuse/log"), _("Log"), 30).leaf = true -- 日志页面
entry({"admin", "services", "aliyundrive-fuse", "status"}, call("action_status")).leaf = true
entry({"admin", "services", "aliyundrive-fuse", "logtail"}, call("action_logtail")).leaf = true
end
function action_status()
local e = {}
e.running = luci.sys.call("pidof aliyundrive-fuse >/dev/null") == 0
e.application = luci.sys.exec("aliyundrive-fuse --version")
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function action_logtail()
local fs = require "nixio.fs"
local log_path = "/var/log/aliyundrive-fuse.log"
local e = {}
e.running = luci.sys.call("pidof aliyundrive-fuse >/dev/null") == 0
if fs.access(log_path) then
e.log = luci.sys.exec("tail -n 100 %s | sed 's/\\x1b\\[[0-9;]*m//g'" % log_path)
else
e.log = ""
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end

View File

@ -0,0 +1,33 @@
m = Map("aliyundrive-fuse")
m.title = translate("AliyunDrive FUSE")
m.description = translate("<a href=\"https://github.com/messense/aliyundrive-fuse\" target=\"_blank\">Project GitHub URL</a>")
m:section(SimpleSection).template = "aliyundrive-fuse/aliyundrive-fuse_status"
e = m:section(TypedSection, "default")
e.anonymous = true
enable = e:option(Flag, "enable", translate("Enable"))
enable.rmempty = false
refresh_token = e:option(Value, "refresh_token", translate("Refresh Token"))
refresh_token.description = translate("<a href=\"https://github.com/messense/aliyundrive-webdav#%E8%8E%B7%E5%8F%96-refresh_token\" target=\"_blank\">How to get refresh token</a>")
mount_point = e:option(Value, "mount_point", translate("Mount Point"))
mount_point.default = "/mnt/aliyundrive"
read_buffer_size = e:option(Value, "read_buffer_size", translate("Read Buffer Size"))
read_buffer_size.default = "10485760"
read_buffer_size.datatype = "uinteger"
domain_id = e:option(Value, "domain_id", translate("Domain ID"))
domain_id.description = translate("Input domain_id option will use <a href=\"https://www.aliyun.com/product/storage/pds\" target=\"_blank\">Aliyun PDS</a> instead of <a href=\"https://www.aliyundrive.com\" target=\"_blank\">AliyunDrive</a>")
allow_other = e:option(Flag, "allow_other", translate("Allow Other users Access"))
allow_other.description = translate("Allow other users to access the drive, enable this if you share with samba")
allow_other.rmempty = false
debug = e:option(Flag, "debug", translate("Debug Mode"))
debug.rmempty = false
return m

View File

@ -0,0 +1,9 @@
log = SimpleForm("logview")
log.submit = false
log.reset = false
t = log:field(DummyValue, '', '')
t.rawhtml = true
t.template = 'aliyundrive-fuse/aliyundrive-fuse_log'
return log

View File

@ -0,0 +1,15 @@
<%+cbi/valueheader%>
<textarea id="logview" class="cbi-input-textarea" style="width: 100%" rows="30" readonly="readonly"></textarea>
<script type="text/javascript">
const LOG_URL = '<%=luci.dispatcher.build_url("admin", "services", "aliyundrive-fuse", "logtail")%>';
XHR.poll(1, LOG_URL, null, (x, d) => {
let logview = document.getElementById("logview");
if (!d.running) {
XHR.halt();
}
logview.value = d.log;
logview.scrollTop = logview.scrollHeight;
});
</script>
<%+cbi/valuefooter%>

View File

@ -0,0 +1,21 @@
<script type="text/javascript">//<![CDATA[
XHR.poll(3, '<%=url([[admin]], [[services]], [[aliyundrive-fuse]], [[status]])%>', null,
function(x, data) {
var tb = document.getElementById('aliyundrive-fuse_status');
if (data && tb) {
if (data.running) {
tb.innerHTML = '<em><b style=color:green>' + data.application + '<%:RUNNING%></b></em>';
} else {
tb.innerHTML = '<em><b style=color:red>' + data.application + '<%:NOT RUNNING%></b></em>';
}
}
}
);
//]]>
</script>
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
<fieldset class="cbi-section">
<p id="aliyundrive-fuse_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>

View File

@ -0,0 +1,56 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8\n"
msgid "AliyunDrive"
msgstr "阿里云盘"
msgid "AliyunDrive FUSE"
msgstr "阿里云盘 FUSE"
msgid "Enable"
msgstr "启用"
msgid "Refresh Token"
msgstr "Refresh Token"
msgid "Mount Point"
msgstr "挂载点"
msgid "Read Buffer Size"
msgstr "下载缓冲大小(bytes)"
msgid "Collecting data..."
msgstr "获取数据中..."
msgid "RUNNING"
msgstr "运行中"
msgid "NOT RUNNING"
msgstr "未运行"
msgid "Settings"
msgstr "设置"
msgid "Log"
msgstr "日志"
msgid "Debug Mode"
msgstr "调试模式"
msgid "<a href=\"https://github.com/messense/aliyundrive-fuse\" target=\"_blank\">Project GitHub URL</a>"
msgstr "<a href=\"https://github.com/messense/aliyundrive-fuse\" target=\"_blank\">GitHub 项目地址</a>"
msgid "<a href=\"https://github.com/messense/aliyundrive-webdav#%E8%8E%B7%E5%8F%96-refresh_token\" target=\"_blank\">How to get refresh token</a>"
msgstr "<a href=\"https://github.com/messense/aliyundrive-webdav#%E8%8E%B7%E5%8F%96-refresh_token\" target=\"_blank\">查看获取 refresh token 的方法</a>"
msgid "Domain ID"
msgstr "阿里云相册与云盘服务 domainId"
msgid "Input domain_id option will use <a href=\"https://www.aliyun.com/product/storage/pds\" target=\"_blank\">Aliyun PDS</a> instead of <a href=\"https://www.aliyundrive.com\" target=\"_blank\">AliyunDrive</a>"
msgstr "填写此选项将使用<a href=\"https://www.aliyun.com/product/storage/pds\" target=\"_blank\">阿里云相册与网盘服务</a>而不是<a href=\"https://www.aliyundrive.com\" target=\"_blank\">阿里云盘</a>"
msgid "Allow Other users Access"
msgstr "允许其他用户访问"
msgid "Allow other users to access the drive, enable this if you share with samba"
msgstr "允许其他用户访问此驱动如果你想用Samba分享请开启此开关"

View File

@ -0,0 +1 @@
zh-cn

View File

@ -0,0 +1,11 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@aliyundrive-fuse[-1]
add ucitrack aliyundrive-fuse
set ucitrack.@aliyundrive-fuse[-1].init=aliyundrive-fuse
commit ucitrack
EOF
rm -f /tmp/luci-indexcache
exit 0

View File

@ -0,0 +1,11 @@
{
"luci-app-aliyundrive-fuse": {
"description": "Grant UCI access for luci-app-aliyundrive-fuse",
"read": {
"uci": [ "aliyundrive-fuse" ]
},
"write": {
"uci": [ "aliyundrive-fuse" ]
}
}
}

View File

@ -0,0 +1,17 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-aliyundrive-webdav
PKG_VERSION:=1.5.0
PKG_RELEASE:=1
PKG_PO_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE)
PKG_LICENSE:=MIT
PKG_MAINTAINER:=messense <messense@icloud.com>
LUCI_TITLE:=LuCI Support for aliyundrive-webdav
LUCI_PKGARCH:=all
LUCI_DEPENDS:=+aliyundrive-webdav
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -0,0 +1,40 @@
module("luci.controller.aliyundrive-webdav", package.seeall)
function index()
if not nixio.fs.access("/etc/config/aliyundrive-webdav") then
return
end
local page
page = entry({"admin", "services", "aliyundrive-webdav"}, alias("admin", "services", "aliyundrive-webdav", "client"), _("AliyunDrive WebDAV"), 10) -- 首页
page.dependent = true
page.acl_depends = { "luci-app-aliyundrive-webdav" }
entry({"admin", "services", "aliyundrive-webdav", "client"}, cbi("aliyundrive-webdav/client"), _("Settings"), 10).leaf = true -- 客户端配置
entry({"admin", "services", "aliyundrive-webdav", "log"}, form("aliyundrive-webdav/log"), _("Log"), 30).leaf = true -- 日志页面
entry({"admin", "services", "aliyundrive-webdav", "status"}, call("action_status")).leaf = true -- 运行状态
entry({"admin", "services", "aliyundrive-webdav", "logtail"}, call("action_logtail")).leaf = true -- 日志采集
end
function action_status()
local e = {}
e.running = luci.sys.call("pidof aliyundrive-webdav >/dev/null") == 0
e.application = luci.sys.exec("aliyundrive-webdav --version")
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function action_logtail()
local fs = require "nixio.fs"
local log_path = "/var/log/aliyundrive-webdav.log"
local e = {}
e.running = luci.sys.call("pidof aliyundrive-webdav >/dev/null") == 0
if fs.access(log_path) then
e.log = luci.sys.exec("tail -n 100 %s | sed 's/\\x1b\\[[0-9;]*m//g'" % log_path)
else
e.log = ""
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end

View File

@ -0,0 +1,60 @@
m = Map("aliyundrive-webdav")
m.title = translate("AliyunDrive WebDAV")
m.description = translate("<a href=\"https://github.com/messense/aliyundrive-webdav\" target=\"_blank\">Project GitHub URL</a>")
m:section(SimpleSection).template = "aliyundrive-webdav/aliyundrive-webdav_status"
e = m:section(TypedSection, "server")
e.anonymous = true
enable = e:option(Flag, "enable", translate("Enable"))
enable.rmempty = false
refresh_token = e:option(Value, "refresh_token", translate("Refresh Token"))
refresh_token.description = translate("<a href=\"https://github.com/messense/aliyundrive-webdav#%E8%8E%B7%E5%8F%96-refresh_token\" target=\"_blank\">How to get refresh token</a>")
root = e:option(Value, "root", translate("Root Directory"))
root.description = translate("Restrict access to a folder of aliyundrive, defaults to / which means no restrictions")
root.default = "/"
host = e:option(Value, "host", translate("Host"))
host.default = "0.0.0.0"
host.datatype = "ipaddr"
port = e:option(Value, "port", translate("Port"))
port.default = "8080"
port.datatype = "port"
tls_cert = e:option(Value, "tls_cert", translate("TLS certificate file path"))
tls_key = e:option(Value, "tls_key", translate("TLS private key file path"))
auth_user = e:option(Value, "auth_user", translate("Username"))
auth_password = e:option(Value, "auth_password", translate("Password"))
auth_password.password = true
read_buffer_size = e:option(Value, "read_buffer_size", translate("Read Buffer Size"))
read_buffer_size.default = "10485760"
read_buffer_size.datatype = "uinteger"
cache_size = e:option(Value, "cache_size", translate("Cache Size"))
cache_size.default = "1000"
cache_size.datatype = "uinteger"
cache_ttl = e:option(Value, "cache_ttl", translate("Cache Expiration Time (seconds)"))
cache_ttl.default = "600"
cache_ttl.datatype = "uinteger"
no_trash = e:option(Flag, "no_trash", translate("Delete file permanently instead of trashing"))
no_trash.rmempty = false
read_only = e:option(Flag, "read_only", translate("Enable read only mode"))
read_only.description = translate("Disallow upload, modify and delete file operations")
read_only.rmempty = false
domain_id = e:option(Value, "domain_id", translate("Domain ID"))
domain_id.description = translate("Input domain_id option will use <a href=\"https://www.aliyun.com/product/storage/pds\" target=\"_blank\">Aliyun PDS</a> instead of <a href=\"https://www.aliyundrive.com\" target=\"_blank\">AliyunDrive</a>")
debug = e:option(Flag, "debug", translate("Debug Mode"))
debug.rmempty = false
return m

View File

@ -0,0 +1,9 @@
log = SimpleForm("logview")
log.submit = false
log.reset = false
t = log:field(DummyValue, '', '')
t.rawhtml = true
t.template = 'aliyundrive-webdav/aliyundrive-webdav_log'
return log

View File

@ -0,0 +1,15 @@
<%+cbi/valueheader%>
<textarea id="logview" class="cbi-input-textarea" style="width: 100%" rows="30" readonly="readonly"></textarea>
<script type="text/javascript">
const LOG_URL = '<%=luci.dispatcher.build_url("admin", "services", "aliyundrive-webdav", "logtail")%>';
XHR.poll(1, LOG_URL, null, (x, d) => {
let logview = document.getElementById("logview");
if (!d.running) {
XHR.halt();
}
logview.value = d.log;
logview.scrollTop = logview.scrollHeight;
});
</script>
<%+cbi/valuefooter%>

View File

@ -0,0 +1,21 @@
<script type="text/javascript">//<![CDATA[
XHR.poll(3, '<%=url([[admin]], [[services]], [[aliyundrive-webdav]], [[status]])%>', null,
function(x, data) {
var tb = document.getElementById('aliyundrive-webdav_status');
if (data && tb) {
if (data.running) {
tb.innerHTML = '<em><b style=color:green>' + data.application + '<%:RUNNING%></b></em>';
} else {
tb.innerHTML = '<em><b style=color:red>' + data.application + '<%:NOT RUNNING%></b></em>';
}
}
}
);
//]]>
</script>
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
<fieldset class="cbi-section">
<p id="aliyundrive-webdav_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>

View File

@ -0,0 +1,86 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8\n"
msgid "AliyunDrive"
msgstr "阿里云盘"
msgid "AliyunDrive WebDAV"
msgstr "阿里云盘 WebDAV"
msgid "Enable"
msgstr "启用"
msgid "Refresh Token"
msgstr "Refresh Token"
msgid "Root Directory"
msgstr "云盘根目录"
msgid "Host"
msgstr "监听主机"
msgid "Port"
msgstr "监听端口"
msgid "TLS certificate file path"
msgstr "TLS 证书文件路径"
msgid "TLS private key file path"
msgstr "TLS 私钥文件路径"
msgid "Username"
msgstr "用户名"
msgid "Password"
msgstr "密码"
msgid "Read Buffer Size"
msgstr "下载缓冲大小(bytes)"
msgid "Cache Size"
msgstr "目录缓存大小"
msgid "Cache Expiration Time (seconds)"
msgstr "目录缓存过期时间(单位为秒)"
msgid "Collecting data..."
msgstr "获取数据中..."
msgid "RUNNING"
msgstr "运行中"
msgid "NOT RUNNING"
msgstr "未运行"
msgid "Settings"
msgstr "设置"
msgid "Log"
msgstr "日志"
msgid "Debug Mode"
msgstr "调试模式"
msgid "<a href=\"https://github.com/messense/aliyundrive-webdav\" target=\"_blank\">Project GitHub URL</a>"
msgstr "<a href=\"https://github.com/messense/aliyundrive-webdav\" target=\"_blank\">GitHub 项目地址</a>"
msgid "<a href=\"https://github.com/messense/aliyundrive-webdav#%E8%8E%B7%E5%8F%96-refresh_token\" target=\"_blank\">How to get refresh token</a>"
msgstr "<a href=\"https://github.com/messense/aliyundrive-webdav#%E8%8E%B7%E5%8F%96-refresh_token\" target=\"_blank\">查看获取 refresh token 的方法</a>"
msgid "Restrict access to a folder of aliyundrive, defaults to / which means no restrictions"
msgstr "限制只能访问该云盘目录,默认为 / 表示不限制,注意这个参数不是本地磁盘路径"
msgid "Delete file permanently instead of trashing"
msgstr "删除文件不放入回收站"
msgid "Enable read only mode"
msgstr "启用只读模式"
msgid "Disallow upload, modify and delete file operations"
msgstr "禁止上传、修改和删除文件操作"
msgid "Domain ID"
msgstr "阿里云相册与云盘服务 domainId"
msgid "Input domain_id option will use <a href=\"https://www.aliyun.com/product/storage/pds\" target=\"_blank\">Aliyun PDS</a> instead of <a href=\"https://www.aliyundrive.com\" target=\"_blank\">AliyunDrive</a>"
msgstr "填写此选项将使用<a href=\"https://www.aliyun.com/product/storage/pds\" target=\"_blank\">阿里云相册与网盘服务</a>而不是<a href=\"https://www.aliyundrive.com\" target=\"_blank\">阿里云盘</a>"

View File

@ -0,0 +1 @@
zh-cn

View File

@ -0,0 +1,11 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@aliyundrive-webdav[-1]
add ucitrack aliyundrive-webdav
set ucitrack.@aliyundrive-webdav[-1].init=aliyundrive-webdav
commit ucitrack
EOF
rm -f /tmp/luci-indexcache
exit 0

View File

@ -0,0 +1,11 @@
{
"luci-app-aliyundrive-webdav": {
"description": "Grant UCI access for luci-app-aliyundrive-webdav",
"read": {
"uci": [ "aliyundrive-webdav" ]
},
"write": {
"uci": [ "aliyundrive-webdav" ]
}
}
}

View File

@ -0,0 +1,21 @@
# Author: mingxiaoyu (fengying0347@163.com)
#
# Licensed to the public under the GNU General Public License v3.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-cloudflarespeedtest
LUCI_TITLE:=LuCI support for Cloudflares Speed Test
LUCI_DEPENDS:=+cdnspeedtest +openssl-util +curl
LUCI_PKGARCH:=all
PKG_VERSION:=1.4.6
PKG_RELEASE:=0
PKG_LICENSE:=AGPL-3.0
PKG_MAINTAINER:=mingxiaoyu <fengying0347@163.com>
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -0,0 +1,50 @@
-- Copyright (C) 2020 mingxiaoyu <fengying0347@163.com>
-- Licensed to the public under the GNU General Public License v3.
module("luci.controller.cloudflarespeedtest",package.seeall)
function index()
if not nixio.fs.access('/etc/config/cloudflarespeedtest') then
return
end
local page
page = entry({"admin", "services", "cloudflarespeedtest"}, firstchild(), _("Cloudflare Speed Test"), 99)
page.dependent = false
page.acl_depends = { "luci-app-cloudflarespeedtest" }
entry({"admin", "services", "cloudflarespeedtest", "general"}, cbi("cloudflarespeedtest/cloudflarespeedtest"), _("Base Setting"), 1)
entry({"admin", "services", "cloudflarespeedtest", "logread"}, form("cloudflarespeedtest/logread"), _("Logs"), 2)
entry({"admin", "services", "cloudflarespeedtest", "status"}, call("act_status")).leaf = true
entry({"admin", "services", "cloudflarespeedtest", "stop"}, call("act_stop"))
entry({"admin", "services", "cloudflarespeedtest", "start"}, call("act_start"))
entry({"admin", "services", "cloudflarespeedtest", "getlog"}, call("get_log"))
end
function act_status()
local e = {}
e.running = luci.sys.call("busybox ps -w | grep cdnspeedtest | grep -v grep >/dev/null") == 0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function act_stop()
luci.sys.call("busybox ps -w | grep cdnspeedtest | grep -v grep | xargs kill -9 >/dev/null")
luci.http.write('')
end
function act_start()
act_stop()
luci.sys.call("/usr/bin/cloudflarespeedtest/cloudflarespeedtest.sh start")
luci.http.write('')
end
function get_log()
local fs = require "nixio.fs"
local e = {}
e.running = luci.sys.call("busybox ps -w | grep cdnspeedtest | grep -v grep >/dev/null") == 0
e.log= fs.readfile("/var/log/cloudflarespeedtest.log") or ""
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end

View File

@ -0,0 +1,335 @@
require("luci.sys")
local uci = luci.model.uci.cursor()
m = Map('cloudflarespeedtest')
m.title = translate('Cloudflare Speed Test')
m.description = '<a href=\"https://github.com/mingxiaoyu/luci-app-cloudflarespeedtest\" target=\"_blank\">GitHub</a>'
-- [[ 基本设置 ]]--
s = m:section(NamedSection, 'global')
s.addremove = false
s.anonymous = true
o=s:option(Flag,"enabled",translate("Enabled"))
o.description = translate("Enabled scheduled task test Cloudflare IP")
o.rmempty=false
o.default = 0
o=s:option(Flag,"ipv6_enabled",translate("IPv6 Enabled"))
o.description = translate("Provides only one method, if IPv6 is enabled, IPv4 will not be tested")
o.default = 0
o.rmempty=false
o=s:option(Value,"speed",translate("Broadband speed"))
o.description =translate("100M broadband download speed is about 12M/s. It is not recommended to fill in an excessively large value, and it may run all the time.");
o.datatype ="uinteger"
o.rmempty=false
o=s:option(Value,"custome_url",translate("Custome Url"))
o.description = translate("<a href=\"https://github.com/XIU2/CloudflareSpeedTest/issues/168\" target=\"_blank\">How to create</a>")
o.rmempty=false
o=s:option(Flag,"custome_cors_enabled",translate("Custome Cron Enabled"))
o.default = 0
o.rmempty=false
o = s:option(Value, "custome_cron", translate("Custome Cron"))
o:depends("custome_cors_enabled", 1)
hour = s:option(Value, "hour", translate("Hour"))
hour.datatype = "range(0,23)"
hour:depends("custome_cors_enabled", 0)
minute = s:option(Value, "minute", translate("Minute"))
minute.datatype = "range(0,59)"
minute:depends("custome_cors_enabled", 0)
o = s:option(ListValue, "proxy_mode", translate("Proxy Mode"))
o:value("nil", translate("HOLD"))
o.description = translate("during the speed testing, swith to which mode")
o:value("gfw", translate("GFW List"))
o:value("close", translate("CLOSE"))
o.default = "gfw"
o=s:option(Flag,"advanced",translate("Advanced"))
o.description = translate("Not recommended")
o.default = 0
o.rmempty=false
o = s:option(Value, "threads", translate("Thread"))
o.datatype ="uinteger"
o.default = 200
o.rmempty=true
o:depends("advanced", 1)
o = s:option(Value, "tl", translate("Average Latency Cap"))
o.datatype ="uinteger"
o.default = 200
o.rmempty=true
o:depends("advanced", 1)
o = s:option(Value, "tll", translate("Average Latency Lower Bound"))
o.datatype ="uinteger"
o.default = 40
o.rmempty=true
o:depends("advanced", 1)
o = s:option(Value, "t", translate("Delayed speed measurement time"))
o.datatype ="uinteger"
o.default = 4
o.rmempty=true
o:depends("advanced", 1)
o = s:option(Value, "dt", translate("Download speed test time"))
o.datatype ="uinteger"
o.default = 10
o.rmempty=true
o:depends("advanced", 1)
o = s:option(Value, "dn", translate("Number of download speed tests"))
o.datatype ="uinteger"
o.default = 1
o.rmempty=true
o:depends("advanced", 1)
o = s:option(Flag, "dd", translate("Disable download speed test"))
o.default = 0
o.rmempty=true
o:depends("advanced", 1)
o = s:option(Value, "tp", translate("Port"))
o.rmempty=true
o.default = 443
o.datatype ="port"
o:depends("advanced", 1)
o = s:option(DummyValue, '', '')
o.rawhtml = true
o.template = "cloudflarespeedtest/actions"
s = m:section(NamedSection, "servers", "section", translate("Third party applications settings"))
if nixio.fs.access("/etc/config/shadowsocksr") then
s:tab("ssr", translate("Shadowsocksr Plus+"))
o=s:taboption("ssr", Flag, "ssr_enabled",translate("Shadowsocksr Plus+ Enabled"))
o.rmempty=true
local ssr_server_table = {}
uci:foreach("shadowsocksr", "servers", function(s)
if s.alias then
ssr_server_table[s[".name"]] = "[%s]:%s" % {string.upper(s.v2ray_protocol or s.type), s.alias}
elseif s.server and s.server_port then
ssr_server_table[s[".name"]] = "[%s]:%s:%s" % {string.upper(s.v2ray_protocol or s.type), s.server, s.server_port}
end
end)
local ssr_key_table = {}
for key, _ in pairs(ssr_server_table) do
table.insert(ssr_key_table, key)
end
table.sort(ssr_key_table)
o = s:taboption("ssr", DynamicList, "ssr_services",
translate("Shadowsocksr Servers"),
translate("Please select a service"))
for _, key in pairs(ssr_key_table) do
o:value(key, ssr_server_table[key])
end
o:depends("ssr_enabled", 1)
o.forcewrite = true
end
if nixio.fs.access("/etc/config/passwall") then
s:tab("passwalltab", translate("passwall"))
o=s:taboption("passwalltab", Flag, "passwall_enabled",translate("Passwall Enabled"))
o.rmempty=true
local passwall_server_table = {}
uci:foreach("passwall", "nodes", function(s)
if s.remarks then
passwall_server_table[s[".name"]] = "[%s]:%s" % {string.upper(s.protocol or s.type), s.remarks}
end
end)
local passwall_key_table = {}
for key, _ in pairs(passwall_server_table) do
table.insert(passwall_key_table, key)
end
table.sort(passwall_key_table)
o = s:taboption("passwalltab", DynamicList, "passwall_services",
translate("Passwall Servers"),
translate("Please select a service"))
for _, key in pairs(passwall_key_table) do
o:value(key, passwall_server_table[key])
end
o:depends("passwall_enabled", 1)
o.forcewrite = true
end
if nixio.fs.access("/etc/config/passwall2") then
s:tab("passwall2tab", translate("passwall2"))
o=s:taboption("passwall2tab", Flag, "passwall2_enabled",translate("PassWall2 Enabled"))
o.rmempty=true
local passwall2_server_table = {}
uci:foreach("passwall2", "nodes", function(s)
if s.remarks then
passwall2_server_table[s[".name"]] = "[%s]:%s" % {string.upper(s.protocol or s.type), s.remarks}
end
end)
local passwall2_key_table = {}
for key, _ in pairs(passwall2_server_table) do
table.insert(passwall2_key_table, key)
end
table.sort(passwall2_key_table)
o = s:taboption("passwall2tab", DynamicList, "passwall2_services",
translate("Passwall2 Servers"),
translate("Please select a service"))
for _, key in pairs(passwall2_key_table) do
o:value(key, passwall2_server_table[key])
end
o:depends("passwall2_enabled", 1)
o.forcewrite = true
end
s:tab("bypasstab", translate("Bypass"))
if nixio.fs.access("/etc/config/bypass") then
o=s:taboption("bypasstab", Flag, "bypass_enabled",translate("Bypass Enabled"))
o.rmempty=true
local bypass_server_table = {}
uci:foreach("bypass", "servers", function(s)
if s.alias then
bypass_server_table[s[".name"]] = "[%s]:%s" % {string.upper(s.protocol or s.type), s.alias}
elseif s.server and s.server_port then
bypass_server_table[s[".name"]] = "[%s]:%s:%s" % {string.upper(s.protocol or s.type), s.server, s.server_port}
end
end)
local bypass_key_table = {}
for key, _ in pairs(bypass_server_table) do
table.insert(bypass_key_table, key)
end
table.sort(bypass_key_table)
o = s:taboption("bypasstab", DynamicList, "bypass_services",
translate("Bypass Servers"),
translate("Please select a service"))
for _, key in pairs(bypass_key_table) do
o:value(key, bypass_server_table[key])
end
o:depends("bypass_enabled", 1)
o.forcewrite = true
end
s:tab("vssrtab", translate("Vssr"))
if nixio.fs.access("/etc/config/vssr") then
o=s:taboption("vssrtab", Flag, "vssr_enabled",translate("Vssr Enabled"))
o.rmempty=true
local vssr_server_table = {}
uci:foreach("vssr", "servers", function(s)
if s.alias then
vssr_server_table[s[".name"]] = "[%s]:%s" % {string.upper(s.protocol or s.type), s.alias}
elseif s.server and s.server_port then
vssr_server_table[s[".name"]] = "[%s]:%s:%s" % {string.upper(s.protocol or s.type), s.server, s.server_port}
end
end)
local vssr_key_table = {}
for key, _ in pairs(vssr_server_table) do
table.insert(vssr_key_table, key)
end
table.sort(vssr_key_table)
o = s:taboption("vssrtab", DynamicList, "vssr_services",
translate("Vssr Servers"),
translate("Please select a service"))
for _, key in pairs(vssr_key_table) do
o:value(key, vssr_server_table[key])
end
o:depends("vssr_enabled", 1)
o.forcewrite = true
end
s:tab("dnstab", translate("DNS"))
o=s:taboption("dnstab", Flag, "DNS_enabled",translate("DNS Enabled"))
o=s:taboption("dnstab", ListValue, "DNS_type", translate("DNS Type"))
o:value("aliyu", translate("AliyuDNS"))
o:depends("DNS_enabled", 1)
o=s:taboption("dnstab", Value,"app_key",translate("Access Key ID"))
o.rmempty=true
o:depends("DNS_enabled", 1)
o=s:taboption("dnstab", Value,"app_secret",translate("Access Key Secret"))
o.rmempty=true
o:depends("DNS_enabled", 1)
o=s:taboption("dnstab", Value,"main_domain",translate("Main Domain"),translate("For example: test.github.com -> github.com"))
o.rmempty=true
o:depends("DNS_enabled", 1)
o=s:taboption("dnstab", DynamicList,"sub_domain",translate("Sub Domain"),translate("For example: test.github.com -> test"))
o.rmempty=true
o:depends("DNS_enabled", 1)
o=s:taboption("dnstab", ListValue, "line", translate("Lines"))
o:value("default", translate("default"))
o:value("telecom", translate("telecom"))
o:value("unicom", translate("unicom"))
o:value("mobile", translate("mobile"))
o:depends("DNS_enabled", 1)
o.default ="telecom"
s:tab("dnshost", translate("HOST"))
o=s:taboption("dnshost", Flag, "HOST_enabled",translate("HOST Enabled"))
o=s:taboption("dnshost", Value,"host_domain",translate("Domain"))
o.rmempty=true
o:depends("HOST_enabled", 1)
e=m:section(TypedSection,"global",translate("Best IP"))
e.anonymous=true
local a="/usr/share/cloudflarespeedtestresult.txt"
tvIPs=e:option(TextValue,"syipstext")
tvIPs.rows=8
tvIPs.readonly="readonly"
tvIPs.wrap="off"
function tvIPs.cfgvalue(e,e)
sylogtext=""
if a and nixio.fs.access(a) then
sylogtext=luci.sys.exec("tail -n 100 %s"%a)
end
return sylogtext
end
tvIPs.write=function(e,e,e)
end
return m

View File

@ -0,0 +1,9 @@
log = SimpleForm("logview")
log.submit = false
log.reset = false
t = log:field(DummyValue, '', '')
t.rawhtml = true
t.template = 'cloudflarespeedtest/logread'
return log

View File

@ -0,0 +1,56 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
const STATUS_URL = '<%=luci.dispatcher.build_url("admin", "services", "cloudflarespeedtest","status")%>';
const RUN_URL = '<%=luci.dispatcher.build_url("admin", "services", "cloudflarespeedtest","start")%>';
const STOP_URL = '<%=luci.dispatcher.build_url("admin", "services", "cloudflarespeedtest","stop")%>';
const LOG_URL = '<%=luci.dispatcher.build_url("admin", "services", "cloudflarespeedtest","logread")%>';
XHR.poll(3, STATUS_URL, null,
function(x, data) {
var tb = document.getElementById('cloudflarespeedtest_status');
if (data && tb) {
if (data.running) {
buttonStatus(true)
tb.innerHTML = '<em><b><font color=green><%:RUNNING %></font></b></em>';
} else {
buttonStatus(false)
tb.innerHTML = '<em><b><font color=red> <%:NOT RUNNING %></font></b></em>';
}
}
}
);
function cloudflarespeedtest_act_start() {
buttonStatus(true)
XHR.get(RUN_URL, null, () => {
});
setTimeout(() => { window.location = LOG_URL }, 500);
return false;
}
function cloudflarespeedtest_act_stop(){
XHR.get(STOP_URL, null, () => {
buttonStatus(false)
});
return false;
}
function buttonStatus(running){
document.getElementById('cloudflarespeedtest_start').style.display = running ? "none" : "block"
document.getElementById('cloudflarespeedtest_stop').style.display = running ? "block" : "none"
}
//]]></script>
<label class="cbi-value-title"><%= translate("Status") %></label>
<div class="cbi-value-field">
<p id="cloudflarespeedtest_status"><em><%:Collecting data...%></em></p>
</div>
<label class="cbi-value-title"><%= translate("Speed Test") %></label>
<div class="cbi-value-field">
<input id="cloudflarespeedtest_start" type="button" style="display:block;" class="btn cbi-button cbi-button-apply" value="<%= translate('TEST AND APPLY') %>" onclick="cloudflarespeedtest_act_start()" />
<input id="cloudflarespeedtest_stop" type="button" style="display:none;" class="btn cbi-button cbi-button-apply" value="<%= translate('STOP') %>" onclick="cloudflarespeedtest_act_stop()" />
</div>
<%+cbi/valuefooter%>

View File

@ -0,0 +1,23 @@
<%+cbi/valueheader%>
<input type="checkbox" id="checkbox1" checked><%:Auto refresh%></input>
<textarea id="logview" class="cbi-input-textarea" style="width: 100%" rows="30" readonly="readonly"></textarea>
<script type="text/javascript">
const LOG_URL = '<%=luci.dispatcher.build_url("admin", "services", "cloudflarespeedtest","getlog")%>';
function getlog(){
XHR.get(LOG_URL, null, function(x, data) {
logview.value = data.log;
if(document.getElementById("checkbox1").checked == true){
logview.scrollTop = logview.scrollHeight;
}
});
}
getlog()
setInterval(() => {
if(document.getElementById("checkbox1").checked == true){
getlog()
}
}, 2000);
</script>
<%+cbi/valuefooter%>

View File

@ -0,0 +1 @@
zh_Hans

View File

@ -0,0 +1,221 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2022-02-10 20:44+0000\n"
"Last-Translator: mingxiaoyu <fengying0347@163.com>\n"
"Language: zh_Hans\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 4.8-dev\n"
msgid "<a href=\"https://github.com/mingxiaoyu/luci-app-cloudflarespeedtest\" target=\"_blank\">GitHub</a>"
msgstr "<a href=\"https://github.com/mingxiaoyu/luci-app-cloudflarespeedtest\" target=\"_blank\">GitHub项目地址</a>"
msgid "Cloudflare Speed Test"
msgstr "Cloudflare速度测试"
msgid "Base Setting"
msgstr "基本设置"
msgid "Logs"
msgstr "日志"
msgid "Enabled"
msgstr "启用"
msgid "Enabled scheduled task test Cloudflare IP"
msgstr "启用计划任务测试 Cloudflare IP"
msgid "Broadband speed"
msgstr "宽带速度"
msgid "Custome Url Enabled"
msgstr "启用自定义地址"
msgid "Custome Url"
msgstr "自定义地址"
msgid "Custome Cron Enabled"
msgstr "启用自定义Cron"
msgid "Custome Cron"
msgstr "自定义Cron"
msgid "Hour"
msgstr "小时"
msgid "Minute"
msgstr "分钟"
msgid "100M broadband download speed is about 12M/s. It is not recommended to fill in an excessively large value, and it may run all the time."
msgstr "100M的宽带下载大概为速度12M/s。不推荐填过大的值可能出现一直运行。"
msgid "Shadowsocksr Plus+ Enabled"
msgstr "启用ShadowSocksR Plus+"
msgid "Passwall Enabled"
msgstr "启用Passwall"
msgid "PassWall2 Enabled"
msgstr "启用PassWall2"
msgid "Bypass Enabled"
msgstr "启用Bypass"
msgid "Vssr Enabled"
msgstr "启用Vssr"
msgid "Shadowsocksr Servers"
msgstr "ShadowSocksR Plus+服务"
msgid "Passwall Servers"
msgstr "Passwall服务"
msgid "Passwall2 Servers"
msgstr "Passwall2服务"
msgid "Bypass Servers"
msgstr "Bypass服务"
msgid "Vssr Servers"
msgstr "Vssr服务"
msgid "Please select a service"
msgstr "请选择一项服务"
msgid "Speed Test"
msgstr "速度测试"
msgid "Best IP"
msgstr "最佳IP"
msgid "TEST AND APPLY"
msgstr "测试并应用"
msgid "STOP"
msgstr "停止"
msgid "Advanced"
msgstr "高级模式"
msgid "Thread"
msgid "线程数"
msgid "Average Latency Cap"
msgstr "平均延迟上限"
msgid "Average Latency Lower Bound"
msgstr "平均延迟下限"
msgid "IPv6 Enabled"
msgstr "启用IPv6"
msgid "Delayed speed measurement time"
msgstr "延迟测速次数"
msgid "Download speed test time"
msgstr "下载测速时间"
msgid "Number of download speed tests"
msgstr "下载测速数量"
msgid "Disable download speed test"
msgstr "禁用下载测速"
msgid "Port"
msgstr "端口"
msgid "Not recommended"
msgstr "不推荐"
msgid "Provides only one method, if IPv6 is enabled, IPv4 will not be tested"
msgstr "IPv4和IPv6只能选一个"
msgid "<a href=\"https://github.com/XIU2/CloudflareSpeedTest/issues/168\" target=\"_blank\">How to create</a>"
msgstr "<a href=\"https://github.com/XIU2/CloudflareSpeedTest/issues/168\" target=\"_blank\">如何创建</a>"
msgid "RUNNING"
msgstr "运行中"
msgid "NOT RUNNING"
msgstr "未运行"
msgid "Collecting data..."
msgstr "收集数据中..."
msgid "Third party applications settings"
msgstr "第三方应用设置"
msgid "Auto refresh"
msgstr "自动刷新"
msgid "Status"
msgstr "状态"
msgid "Proxy Mode"
msgstr "代理模式"
msgid "HOLD"
msgstr "保持"
msgid "GFW List"
msgid "GFW列表"
msgid "CLOSE"
msgstr "关闭"
msgid "during the speed testing, swith to which mode"
msgstr "在速度测试期间,切换到哪种模式"
msgid "DNS"
msgstr "DNS"
msgid "DNS Enabled"
msgstr "启用DNS"
msgid "DNS Type"
msgstr "DNS类型"
msgid "AliyuDNS"
msgstr "阿里云DNS"
msgid "Access Key ID"
msgstr "Access Key ID"
msgid "Access Key Secret"
msgstr "Access Key Secret"
msgid "Main Domain"
msgstr "主域名"
msgid "Sub Domain"
msgstr "子域名"
msgid "For example: test.github.com -> github.com"
msgstr "例如: test.github.com 则填: github.com"
msgid "For example: test.github.com -> test"
msgstr "例如: test.github.com, 则填: test"
msgid "Lines"
msgstr "解析线路"
msgid "default"
msgstr "默认"
msgid "telecom"
msgstr "电信"
msgid "unicom"
msgstr "联通"
msgid "mobile"
msgstr "移动"
msgid "HOST Enabled"
msgstr "启用HOST"
msgid "Domain"
msgstr "域名"

View File

@ -0,0 +1,21 @@
config global 'global'
option hour '5'
option minute '0'
option enabled '0'
option ipv6_enabled '0'
option advanced '0'
option tl '200'
option tll '40'
option custome_url 'https://speed.cloudflare.com/__down?bytes=300000000'
option threads '200'
option speed '100'
config servers 'servers'
option ssr_enabled '0'
option passwall_enabled '0'
option passwall2_enabled '0'
option bypass_enabled '0'
option vssr_enabled '0'
option DNS_enabled '0'

View File

@ -0,0 +1,59 @@
#!/bin/sh /etc/rc.common
START=99
USE_PROCD=1
CRON_FILE=/etc/crontabs/root
service_triggers() {
procd_add_reload_trigger "cloudflarespeedtest"
}
add_cron(){
local enabled
config_get_bool enabled $1 enabled
del_cron
if [ $enabled = 1 ] ; then
local minute
local hour
local custome_cors_enabled
local custome_cron
config_get minute $1 minute
config_get hour $1 hour
config_get_bool custome_cors_enabled $1 custome_cors_enabled
config_get custome_cron $1 custome_cron
if [ $custome_cors_enabled = 1 ] ; then
echo "$custome_cron /usr/bin/cloudflarespeedtest/cloudflarespeedtest.sh start" >> $CRON_FILE
else
echo "$minute $hour * * * /usr/bin/cloudflarespeedtest/cloudflarespeedtest.sh start" >> $CRON_FILE
fi
crontab $CRON_FILE
fi
}
del_cron(){
sed -i '/cloudflarespeedtest/d' $CRON_FILE
/etc/init.d/cron restart
}
stop_instance(){
del_cron
}
stop_service() {
config_load cloudflarespeedtest
config_foreach stop_instance global
}
start_service() {
config_load cloudflarespeedtest
config_foreach add_cron global
}
reload_service() {
stop
start
}

View File

@ -0,0 +1,81 @@
#!/bin/sh
LOG_FILE='/var/log/cloudflarespeedtest.log'
echolog() {
local d="$(date "+%Y-%m-%d %H:%M:%S")"
echo -e "$d: $*" >>$LOG_FILE
}
urlencode() {
# urlencode url<string>
out=''
for c in $(echo -n $1 | sed 's/[^\n]/&\n/g'); do
case $c in
[a-zA-Z0-9._-]) out="$out$c" ;;
*) out="$out$(printf '%%%02X' "'$c")" ;;
esac
done
echo -n $out
}
send_request() {
# send_request action<string> args<string>
local args="AccessKeyId=$ak_id&Action=$1&Format=json&$2&Version=2015-01-09"
local hash=$(urlencode $(echo -n "GET&%2F&$(urlencode $args)" | openssl dgst -sha1 -hmac "$ak_sec&" -binary | openssl base64))
curl -sSL --connect-timeout 5 "http://alidns.aliyuncs.com/?$args&Signature=$hash"
}
get_recordid() {
sed 's/RR/\n/g' | sed -n 's/.*RecordId[^0-9]*\([0-9]*\).*/\1\n/p' | sort -ru | sed /^$/d
}
query_recordid() {
send_request "DescribeSubDomainRecords" "SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&SubDomain=$sub_dm.$main_dm&Timestamp=$timestamp&Type=A"
}
update_record() {
send_request "UpdateDomainRecord" "Line=$line&RR=$sub_dm&RecordId=$1&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp&Type=$type&Value=$ip"
}
add_record() {
send_request "AddDomainRecord&DomainName=$main_dm" "Line=$line&RR=$sub_dm&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp&Type=$type&Value=$ip"
}
del_record() {
send_request "DeleteDomainRecord" "RecordId=$1&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp"
}
aliddns() {
ak_id=$1
ak_sec=$2
main_dm=$3
sub_dm=$4
line=$5
isIpv6=$6
ip=$7
type=A
if [ $isIpv6 -eq "1" ] ;then
type=AAAA
fi
echo $ip
echo $type
rrid=`query_recordid | get_recordid`
if [ -z "$rrid" ]; then
rrid=`add_record | get_recordid`
echolog "ADD record $rrid"
else
update_record $rrid
echolog "UPDATE record $rrid"
fi
if [ -z "$rrid" ]; then
# failed
echolog "# ERROR, Please Check Config/Time"
fi
}
timestamp=$(date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ")
aliddns "$@"

View File

@ -0,0 +1,296 @@
#!/bin/sh
LOG_FILE='/var/log/cloudflarespeedtest.log'
IP_FILE='/usr/share/cloudflarespeedtestresult.txt'
IPV4_TXT='/usr/share/CloudflareSpeedTest/ip.txt'
IPV6_TXT='/usr/share/CloudflareSpeedTest/ipv6.txt'
function get_global_config(){
while [[ "$*" != "" ]]; do
eval ${1}='`uci get cloudflarespeedtest.global.$1`' 2>/dev/null
shift
done
}
function get_servers_config(){
while [[ "$*" != "" ]]; do
eval ${1}='`uci get cloudflarespeedtest.servers.$1`' 2>/dev/null
shift
done
}
echolog() {
local d="$(date "+%Y-%m-%d %H:%M:%S")"
echo -e "$d: $*" >>$LOG_FILE
}
function read_config(){
get_global_config "enabled" "speed" "custome_url" "threads" "custome_cors_enabled" "custome_cron" "t" "tp" "dt" "dn" "dd" "tl" "tll" "ipv6_enabled" "advanced" "proxy_mode"
get_servers_config "ssr_services" "ssr_enabled" "passwall_enabled" "passwall_services" "passwall2_enabled" "passwall2_services" "bypass_enabled" "bypass_services" "vssr_enabled" "vssr_services" "DNS_enabled" "HOST_enabled"
}
function speed_test(){
rm -rf $LOG_FILE
command="/usr/bin/cdnspeedtest -sl $((speed*125/1000)) -url ${custome_url} -o ${IP_FILE}"
if [ $ipv6_enabled -eq "1" ] ;then
command="${command} -f ${IPV6_TXT} -ipv6"
else
command="${command} -f ${IPV4_TXT}"
fi
if [ $advanced -eq "1" ] ; then
command="${command} -tl ${tl} -tll ${tll} -n ${threads} -t ${t} -dt ${dt} -dn ${dn}"
if [ $dd -eq "1" ] ; then
command="${command} -dd"
fi
if [ $tp -ne "443" ] ; then
command="${command} -tp ${tp}"
fi
else
command="${command} -tl 200 -tll 40 -n 200 -t 4 -dt 10 -dn 1"
fi
ssr_original_server=$(uci get shadowsocksr.@global[0].global_server 2>/dev/null)
ssr_original_run_mode=$(uci get shadowsocksr.@global[0].run_mode 2>/dev/null)
if [ $ssr_original_server != "nil" ] ;then
if [ $proxy_mode == "close" ] ;then
uci set shadowsocksr.@global[0].global_server="nil"
elif [ $proxy_mode == "gfw" ] ;then
uci set shadowsocksr.@global[0].run_mode="gfw"
fi
uci commit shadowsocksr
/etc/init.d/shadowsocksr restart
fi
passwall_server_enabled=$(uci get passwall.@global[0].enabled 2>/dev/null)
passwall_original_run_mode=$(uci get passwall.@global[0].tcp_proxy_mode 2>/dev/null)
if [ $passwall_server_enabled -eq "1" ] ;then
if [ $proxy_mode == "close" ] ;then
uci set passwall.@global[0].enabled="0"
elif [ $proxy_mode == "gfw" ] ;then
uci set passwall.@global[0].tcp_proxy_mode="gfwlist"
fi
uci commit passwall
/etc/init.d/passwall restart 2>/dev/null
fi
passwall2_server_enabled=$(uci get passwall2.@global[0].enabled 2>/dev/null)
passwall2_original_run_mode=$(uci get passwall2.@global[0].tcp_proxy_mode 2>/dev/null)
if [ $passwall2_server_enabled -eq "1" ] ;then
if [ $proxy_mode == "close" ] ;then
uci set passwall2.@global[0].enabled="0"
elif [ $proxy_mode == "gfw" ] ;then
uci set passwall2.@global[0].tcp_proxy_mode="gfwlist"
uci set passwall2.@global[0].udp_proxy_mode="gfwlist"
fi
uci commit passwall2
/etc/init.d/passwall2 restart 2>/dev/null
fi
bypass_original_server=$(uci get bypass.@global[0].global_server 2>/dev/null)
bypass_original_run_mode=$(uci get bypass.@global[0].run_mode 2>/dev/null)
if [ $bypass_original_server != "$bypass_key_table" ] ;then
if [ $proxy_mode == "close" ] ;then
uci set bypass.@global[0].global_server="$bypass_key_table"
elif [ $proxy_mode == "gfw" ] ;then
uci set bypass.@global[0].run_mode="gfw"
fi
uci commit bypass
/etc/init.d/bypass restart
fi
vssr_original_server=$(uci get vssr.@global[0].global_server 2>/dev/null)
vssr_original_run_mode=$(uci get vssr.@global[0].run_mode 2>/dev/null)
if [ $vssr_original_server != "nil" ] ;then
if [ $proxy_mode == "close" ] ;then
uci set vssr.@global[0].global_server="nil"
elif [ $proxy_mode == "gfw" ] ;then
uci set vssr.@global[0].run_mode="gfw"
fi
uci commit vssr
/etc/init.d/vssr restart
fi
echo $command >> $LOG_FILE 2>&1
echolog "-----------start----------"
$command >> $LOG_FILE 2>&1
echolog "-----------end------------"
}
function ip_replace(){
# 获取最快 IP从 result.csv 结果文件中获取第一个 IP
bestip=$(sed -n "2,1p" $IP_FILE | awk -F, '{print $1}')
[[ -z "${bestip}" ]] && echo "CloudflareST 测速结果 IP 数量为 0跳过下面步骤..." && exit 0
alidns_ip
ssr_best_ip
vssr_best_ip
bypass_best_ip
passwall_best_ip
passwall2_best_ip
host_ip
}
function passwall_best_ip(){
if [ $passwall_server_enabled -eq '1' ] ; then
echolog "设置passwall代理模式"
if [ $proxy_mode == "close" ] ;then
uci set passwall.@global[0].enabled="${passwall_server_enabled}"
elif [ $proxy_mode == "gfw" ] ;then
uci set passwall.@global[0].tcp_proxy_mode="${passwall_original_run_mode}"
fi
uci commit passwall
fi
if [ $passwall_enabled -eq "1" ] ;then
echolog "设置passwall IP"
for ssrname in $passwall_services
do
echo $ssrname
uci set passwall.$ssrname.address="${bestip}"
done
uci commit passwall
if [ $passwall_server_enabled -eq "1" ] ;then
/etc/init.d/passwall restart 2>/dev/null
echolog "passwall重启完成"
fi
fi
}
function passwall2_best_ip(){
if [ $passwall2_server_enabled -eq '1' ] ; then
echolog "设置passwall2代理模式"
if [ $proxy_mode == "close" ] ;then
uci set passwall2.@global[0].enabled="${passwall2_server_enabled}"
elif [ $proxy_mode == "gfw" ] ;then
uci set passwall2.@global[0].tcp_proxy_mode="${passwall2_original_run_mode}"
uci set passwall2.@global[0].udp_proxy_mode="${passwall2_original_run_mode}"
fi
uci commit passwall2
fi
if [ $passwall2_enabled -eq "1" ] ;then
echolog "设置passwall2 IP"
for ssrname in $passwall2_services
do
echo $ssrname
uci set passwall2.$ssrname.address="${bestip}"
done
uci commit passwall2
if [ $passwall2_server_enabled -eq "1" ] ;then
/etc/init.d/passwall2 restart 2>/dev/null
echolog "passwall2重启完成"
fi
fi
}
function ssr_best_ip(){
if [ $ssr_enabled -eq "1" ] ;then
echolog "设置ssr IP"
for ssrname in $ssr_services
do
echo $ssrname
uci set shadowsocksr.$ssrname.server="${bestip}"
uci set shadowsocksr.$ssrname.ip="${bestip}"
done
if [ $ssr_original_server != 'nil' ] ; then
echolog "设置ssr代理模式"
if [ $proxy_mode == "close" ] ;then
uci set shadowsocksr.@global[0].global_server="${ssr_original_server}"
elif [ $proxy_mode == "gfw" ] ;then
uci set shadowsocksr.@global[0].run_mode="${ssr_original_run_mode}"
fi
fi
uci commit shadowsocksr
/etc/init.d/shadowsocksr restart &>/dev/null
echolog "ssr重启完成"
fi
}
function vssr_best_ip(){
if [ $vssr_enabled -eq "1" ] ;then
echolog "设置Vssr IP"
for ssrname in $vssr_services
do
echo $ssrname
uci set vssr.$ssrname.server="${bestip}"
done
if [ $vssr_original_server != 'nil' ] ; then
echolog "设置Vssr代理模式"
if [ $proxy_mode == "close" ] ;then
uci set vssr.@global[0].global_server="${vssr_original_server}"
elif [ $proxy_mode == "gfw" ] ;then
uci set vssr.@global[0].run_mode="${vssr_original_run_mode}"
fi
fi
uci commit vssr
/etc/init.d/vssr restart &>/dev/null
echolog "Vssr重启完成"
fi
}
function bypass_best_ip(){
if [ $bypass_enabled -eq "1" ] ;then
echolog "设置Bypass IP"
for ssrname in $bypass_services
do
echo $ssrname
uci set bypass.$ssrname.server="${bestip}"
done
if [ $bypass_original_server != '$bypass_key_table' ] ; then
echolog "设置Bypass代理模式"
if [ $proxy_mode == "close" ] ;then
uci set bypass.@global[0].global_server="${bypass_original_server}"
elif [ $proxy_mode == "gfw" ] ;then
uci set bypass.@global[0].run_mode="${bypass_original_run_mode}"
fi
fi
uci commit bypass
/etc/init.d/bypass restart &>/dev/null
echolog "Bypass重启完成"
fi
}
function alidns_ip(){
if [ $DNS_enabled -eq "1" ] ;then
get_servers_config "DNS_type" "app_key" "app_secret" "main_domain" "sub_domain" "line"
if [ $DNS_type == "aliyu" ] ;then
for sub in $sub_domain
do
echolog "更新域名$sub 阿里云DNS完成"
/usr/bin/cloudflarespeedtest/aliddns.sh $app_key $app_secret $main_domain $sub $line $ipv6_enabled $bestip
done
fi
fi
}
function host_ip() {
if [ $HOST_enabled -eq "1" ] ;then
get_servers_config "host_domain"
HOSTS_LINE="$bestip $host_domain"
if [ -n "$(grep $host_domain /etc/hosts)" ]
then
sed -i".bak" "/$host_domain/d" /etc/hosts
echo $HOSTS_LINE >> /etc/hosts;
else
echo $HOSTS_LINE >> /etc/hosts;
fi
/etc/init.d/dnsmasq reload &>/dev/null
echolog "HOST 完成"
fi
}
read_config
# 启动参数
if [ "$1" ] ;then
[ $1 == "start" ] && speed_test && ip_replace
[ $1 == "test" ] && speed_test
[ $1 == "replace" ] && ip_replace
exit
fi

View File

@ -0,0 +1,11 @@
{
"luci-app-cloudflarespeedtest": {
"description": "Grant UCI access for luci-app-cloudflarespeedtest",
"read": {
"uci": [ "cloudflarespeedtest" ]
},
"write": {
"uci": [ "cloudflarespeedtest" ]
}
}
}

View File

@ -0,0 +1,44 @@
#
# Copyright (C) 2020-2021 sirpdboy <herboy2008@gmail.com>
# The LuCI Network diagnosis and speed test <https://github.com/sirpdboy/NetSpeedTest>
# This is free software, licensed under the GNU General Public License v3.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-netspeedtest
PKG_VERSION:=1.7
PKG_RELEASE:=20220322
PKG_LICENSE:=GPLv2
PKG_MAINTAINER:=sirpdboy
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=luci
CATEGORY:=LuCI
SUBMENU:=3. Applications
TITLE:=LuCI Support for netspeedtest
DEPENDS:=+python3 +iperf3
PKGARCH:=all
endef
define Build/Compile
endef
define Package/$(PKG_NAME)/conffiles
/etc/config/netspeedtest
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/lib/lua/luci
cp -pR ./luasrc/* $(1)/usr/lib/lua/luci
$(INSTALL_DIR) $(1)/
cp -pR ./root/* $(1)/
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
po2lmo ./po/zh-cn/netspeedtest.po $(1)/usr/lib/lua/luci/i18n/netspeedtest.zh-cn.lmo
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@ -0,0 +1,121 @@
[![若部分图片无法正常显示,请挂上机场浏览或点这里到末尾看修复教程](https://visitor-badge.glitch.me/badge?page_id=sirpdboy-visitor-badge)](#解决-github-网页上图片显示失败的问题) [![](https://img.shields.io/badge/TG群-点击加入-FFFFFF.svg)](https://t.me/joinchat/AAAAAEpRF88NfOK5vBXGBQ)
<a href="#readme">
<img src="https://img.vim-cn.com/a1/8713845a4aa922ac96619b0d2fb3d6919d37fc.png" alt="图飞了😂" title="NetSpeedTest" align="right" height="180" />
</a>
欢迎来到sirpdboy的源码仓库
=
Welcome to sirpdboy's git source of packages
-
[luci-app-NetSpeedTest — 网络速度测试1.7完整版](https://github.com/sirpdboy/NetSpeedTest)
======================
[![](https://img.shields.io/badge/-目录:-696969.svg)](#readme) [![](https://img.shields.io/badge/-写在前面-F5F5F5.svg)](#写在前面-) [![](https://img.shields.io/badge/-编译说明-F5F5F5.svg)](#编译说明-) [![](https://img.shields.io/badge/-说明-F5F5F5.svg)](#说明-) [![](https://img.shields.io/badge/-捐助-F5F5F5.svg)](#捐助-)
**认真阅读完毕** 本页面,本页面包含注意事项和如何使用。
a new NetSpeedTest luci app bese luci-app-NetSpeedTest
-
## 写在前面:[![](https://img.shields.io/badge/-写在前面-F5F5F5.svg)](#写在前面-)
一直在找OPENWRT上测试速度的插件苦寻不到于是有了它!
此插件可进行内外和外网网络速度测试。
1.内网测速基于iperf3 插件服务端路由器如果没有安装请先安装此ipk插件。
2.测速的终端使用机器必须和测速服务器在同一个局域网络中!
3.客户端使用步骤:
启动测速服务器端-->下载测试客户端-->运行测速客户端-->输入服务端IP地址-->查看结果。
5.客户端运行国内端下载中有“iperf3测速客户端”运行它输入服务器IP即可。
国外原版,需要手动进入 CMD命令模式再输入命令iperf3.exe -c 服务器IP
6.网络测速iperf3客户端下载地址https://sipdboy.lanzoui.com/b01c3esih 密码:cpd6
8.外网测速使用speedtest.net测速内核需要依赖speedtest,另外感谢superspeed和user1121114685因为借用了你们的灵感
9.外网测速最后测试阶段感谢佐大:佐须之男 测试查问题!
10.新插件难免有bug 请不要大惊小怪。欢迎提交bug。
## 编译说明 [![](https://img.shields.io/badge/-编译说明-F5F5F5.svg)](#编译说明-)
将NetSpeedTest 主题添加至 LEDE/OpenWRT 源码的方法。
## 下载源码方法一:
编辑源码文件夹根目录feeds.conf.default并加入如下内容:
```Brach
# feeds获取源码
src-git NetSpeedTest https://github.com/sirpdboy/NetSpeedTest
```
```Brach
# 更新feeds并安装主题
scripts/feeds update NetSpeedTest
scripts/feeds install luci-app-NetSpeedTest
```
## 下载源码方法二:
```Brach
# 下载源码
git clone https://github.com/sirpdboy/NetSpeedTest package/NetSpeedTest
make menuconfig
```
## 配置菜单
```Brach
make menuconfig
# 找到 LuCI -> Applications, 选择 luci-app-NetSpeedTest, 保存后退出。
```
## 编译
```Brach
# 编译固件
make package/NetSpeedTest/luci-app-NetSpeedTest/{clean,compile} V=s
```
## 说明 [![](https://img.shields.io/badge/-说明-F5F5F5.svg)](#说明-)
源码来源https://github.com/sirpdboy/NetSpeedTest/luci-app-NetSpeedTest
你可以随意使用其中的源码,但请注明出处。
============================
# My other project
网络速度测试 https://github.com/sirpdboy/NetSpeedTest
定时关机重启 : https://github.com/sirpdboy/luci-app-autopoweroff
关机功能插件 : https://github.com/sirpdboy/luci-app-poweroffdevice
opentopd主题 : https://github.com/sirpdboy/luci-theme-opentopd
opentoks 主题: https://github.com/sirpdboy/luci-theme-opentoks [仿KOOLSAHRE主题]
btmob 主题: https://github.com/sirpdboy/luci-theme-btmob
系统高级设置 : https://github.com/sirpdboy/luci-app-advanced
## 捐助 [![](https://img.shields.io/badge/-捐助-F5F5F5.svg)](#捐助-)
**如果你觉得此项目对你有帮助,请捐助我们,以使项目能持续发展,更加完善。··请作者喝杯咖啡~~~**
**你们的支持就是我的动力!**
### 捐助方式
| <img src="https://img.shields.io/badge/-支付宝-F5F5F5.svg" href="#赞助支持本项目-" height="25" alt="图飞了😂"/> | <img src="https://img.shields.io/badge/-微信-F5F5F5.svg" height="25" alt="图飞了😂" href="#赞助支持本项目-"/> |
| :-----------------: | :-------------: |
|<img src="https://img.vim-cn.com/fd/8e2793362ac3510094961b04407beec569b2b4.png" width="150" height="150" alt="图飞了😂" href="#赞助支持本项目-"/>|<img src="https://img.vim-cn.com/c7/675730a88accebf37a97d9e84e33529322b6e9.png" width="150" height="150" alt="图飞了😂" href="#赞助支持本项目-"/>|
<a href="#readme">
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="图飞了😂" title="返回顶部" align="right"/>
</a>
###### [解决 Github 网页上图片显示失败的问题](https://blog.csdn.net/qq_38232598/article/details/91346392)
[![](https://img.shields.io/badge/TG群-点击加入-FFFFFF.svg)](https://t.me/joinchat/AAAAAEpRF88NfOK5vBXGBQ)

View File

@ -0,0 +1,76 @@
module("luci.controller.netspeedtest", package.seeall)
function index()
entry({"admin","network","netspeedtest"},cbi("netspeedtest/netspeedtest", {hideapplybtn=true, hidesavebtn=true, hideresetbtn=true}),_("Netspeedtest"),90).dependent=true
entry({"admin", "network", "netspeedtest", "status"}, call("act_status")).leaf = true
entry({"admin", "network","test_iperf0"}, post("test_iperf0"), nil).leaf = true
entry({"admin", "network","test_iperf1"}, post("test_iperf1"), nil).leaf = true
entry({"admin","network","netspeedtest", "run"}, call("run"))
entry({"admin", "network", "netspeedtest", "realtime_log"}, call("get_log"))
end
function act_status()
local e={}
e.status=luci.sys.call("pgrep iperf3 >/dev/null")==0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function testlan(cmd, addr)
luci.http.prepare_content("text/plain")
local util = io.popen(cmd)
if util then
while true do
local ln = util:read("*l")
if not ln then break end
luci.http.write(ln)
luci.http.write("\n")
end
util:close()
end
end
function testwan(cmd)
local util = io.popen(cmd)
util:close()
end
function test_iperf0(addr)
local netease
netease= luci.sys.call("ps |grep unblockneteasemusic |grep app.js |grep -v grep >/dev/null") == 0
if netease then
luci.sys.call("/etc/init.d/unblockneteasemusic stop ")
luci.sys.call("/etc/init.d/unblockmusic stop ")
end
testlan("iperf3 -s ", addr)
end
function test_iperf1(addr)
luci.sys.call("killall iperf3")
luci.sys.call("/etc/init.d/unblockneteasemusic restart ")
luci.sys.call("/etc/init.d/unblockmusic restart ")
end
function get_log()
local fs = require "nixio.fs"
local e = {}
e.running = luci.sys.call("busybox ps -w | grep netspeedtest | grep -v grep >/dev/null") == 0
e.log = fs.readfile("/var/log/netspeedtest.log") or ""
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function run()
testwan("/etc/init.d/netspeedtest nstest ")
luci.http.redirect(luci.dispatcher.build_url("admin","network","netspeedtest"))
end

View File

@ -0,0 +1,32 @@
-- Copyright 2018 sirpdboy (herboy2008@gmail.com)
require("luci.util")
local o,t,e
if luci.sys.call("pidof iperf3 >/dev/null") == 0 then
status = translate("<strong><font color=\"green\">iperf3 服务端运行中</font></strong>")
else
status = translate("<strong><font color=\"red\">iperf3 服务端未启动</font></strong>")
end
o = Map("netspeedtest", "<font color='green'>" .. translate("Netspeedtest") .."</font>",translate( "Network speed diagnosis test (including intranet and extranet)<br/>For specific usage, see:") ..translate("<a href=\'https://github.com/sirpdboy/netspeedtest.git' target=\'_blank\'>GitHub @netspeedtest/luci-app-netspeedtest</a>") )
t = o:section(TypedSection, "netspeedtest", translate('iperf3 lanspeedtest'))
t.anonymous = true
t.description = translate(string.format("%s<br />", status))
e = t:option(DummyValue, '', '')
e.rawhtml = true
e.template ='netspeedtest/netspeedtest'
t=o:section(TypedSection,"netspeedtest",translate("wanspeedtest"))
t.anonymous=true
e = t:option(DummyValue, '', '')
e.rawhtml = true
e.template ='netspeedtest/speedtest'
e =t:option(DummyValue, '', '')
e.rawhtml = true
e.template = 'netspeedtest/log'
return o

View File

@ -0,0 +1,16 @@
<%+cbi/valueheader%>
<textarea id="logview" class="cbi-input-textarea" style="width: 100%" rows="10" readonly="readonly"></textarea>
<script type="text/javascript">
const LOG_URL = '<%=luci.dispatcher.build_url("admin", "network", "netspeedtest","realtime_log")%>';
XHR.poll(1, LOG_URL, null, (x, d) => {
let logview = document.getElementById("logview");
if (!d.running) {
XHR.halt();
}
logview.value = d.log;
logview.scrollTop = logview.scrollHeight;
});
</script>
<%+cbi/valuefooter%>

View File

@ -0,0 +1,84 @@
<%
local fs = require "nixio.fs"
%>
<script type="text/javascript" src="<%=resource%>/cbi.js?v=1.1"></script>
<script type="text/javascript">//<![CDATA[
var stxhr = new XHR();
function update_status(field, proto)
{
var tool = field.name;
var addr = field.value;
var protocol = proto ;
var legend = document.getElementById('test-rc-legend');
var output = document.getElementById('test-rc-output');
if (legend && output)
{
output.innerHTML =
'<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> ' +
'<%:Waiting for command to complete...%>'
;
legend.parentNode.style.display = 'block';
legend.style.display = 'inline';
stxhr.post('<%=url('admin/network')%>/test_' + tool + protocol + '/' + addr, { token: '<%=token%>' },
function(x)
{
if (x.responseText)
{
legend.style.display = 'none';
output.innerHTML = String.format('<pre>%h</pre>', x.responseText);
}
else
{
legend.style.display = 'none';
output.innerHTML ='</p><%:Operation execution complete%></p>';
}
}
);
}
}
//]]></script>
<form method="post" action="<%=url('admin/network/netspeedtest')%>">
<div style="width:100%; float:left">
<table>
<tr><td class="cbi-value-title" ><input style="margin: 5px 0" type="hidden" value="" name="iperf" />
<select name="iperf_to" style="width:auto">
<option value="0" selected="selected"><%:iperfstart%></option>
<option value="1"><%:iperfstop%></option>
</select></td>
<td class="cbi-value-field" style="width:100%;" >
<input type="button" value="<%:Perform operation%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.iperf,this.form.iperf_to.selectedIndex)" /></td>
</tr>
<tr><td class="cbi-value-title" ><%:iperf3 instructions%></td>
<td class="cbi-value-field" ><%:The speed measurement terminal must be in the same LAN as the router that starts the speed measurement%><br /><%:Operation steps: start router speed measurement service download test client run speed measurement client input IP address of router speed measurement service%></td>
</tr>
<tr>
<td class="cbi-value-title"><%:Iperf3 speed measurement software download%></td>
<td class="cbi-value-field" >
<input type="button" class="cbi-button cbi-input-reload" value="<%:Domestic download password:%>cpd6" onclick="javascript:window.open('https://sipdboy.lanzoui.com/b01c3esih','target');" />
<input type="button" class="cbi-button cbi-input-reload" value="<%:Download from foreign official websites%>" onclick="javascript:window.open('https://iperf.fr/iperf-download.php','target');" /></td>
</tr>
</table>
<fieldset class="cbi-section" style="display:none">
<legend id="test-rc-legend">
<%:Collecting data...%>
</legend>
<span id="test-rc-output"></span>
</fieldset>
</div>
</form>

View File

@ -0,0 +1,31 @@
<%+cbi/valueheader%>
<label class="cbi-value-title"> </label>
<div class="cbi-value-field">
<input class="cbi-button cbi-button-apply" id="update_service" type="button" size="0" onclick="run()" value="<%= translate('Perform wanspeedtest') %>" />
</div>
<script type="text/javascript">
const RUN_URL = '<%=luci.dispatcher.build_url("admin", "network", "netspeedtest","run")%>';
const S_URL = '<%=luci.dispatcher.build_url("admin", "network", "netspeedtest")%>';
function run() {
var legend = document.getElementById('test-rc-legend');
var output = document.getElementById('test-rc-output');
output.innerHTML =
'<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> ' +
'<%:Network speed test, please wait for 1 minutes%>'
;
legend.parentNode.style.display = 'block';
legend.style.display = 'inline';
XHR.get(RUN_URL, null, () => {
setTimeout(() => { window.location = S_URL }, 3000);
});
return false;
}
</script>
<%+cbi/valuefooter%>

View File

@ -0,0 +1,70 @@
#
# Copyright (C) 2020-2021 sirpdboy herboy2008@gmail.com
# This is free software, licensed under the GNU General Public License v3.
#
msgid ""
msgstr ""
"Project-Id-Version: LuCi Chinese Translation\n"
"Report-Msgid-Bugs-To: \n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Pootle 2.0.6\n"
msgid "Netspeedtest"
msgstr "网速测试"
msgid "Network speed diagnosis test (including intranet and extranet)"
msgstr "网络速度诊断测试(包括内网和外网)"
msgid "iperf3 lanspeedtest"
msgstr "iperf3 内网测速"
msgid "Network speed diagnosis test (including intranet and extranet)<br/>For specific usage, see:"
msgstr "网络速度诊断测试(包括内网和外网)<br/>具体使用参见:"
msgid "iperfstart"
msgstr "iperf服务启动"
msgid "iperfstop"
msgstr "iperf服务停止"
msgid "Perform operation"
msgstr "执行操作"
msgid "iperf3 instructions"
msgstr "iperf3 使用说明"
msgid "Test speed service started"
msgstr "测试速度服务已经启动"
msgid "The speed measurement terminal must be in the same LAN as the router that starts the speed measurement"
msgstr "测速终端机必须与启动测速的路由器在同一局域网内"
msgid "Operation steps: start router speed measurement service download test client run speed measurement client input IP address of router speed measurement service"
msgstr "使用步骤A.启动路由器测速服务 B.下载测试客户端 C.运行测速客户端 D.输入路由器测速服务IP地址。 "
msgid "Domestic download password:"
msgstr "国内下密码:"
msgid "Iperf3 speed measurement software download"
msgstr "iperf3测速软件下载"
msgid "wanspeedtest"
msgstr "宽带速率测试"
msgid "Perform wanspeedtest"
msgstr "执行宽带测速"
msgid "Operation execution complete"
msgstr "操作执行完毕"
msgid "Network speed test, please wait for 1 minutes"
msgstr "网速测试中请稍等1分钟"
msgid "Download from foreign official websites"
msgstr "国外官网"

View File

@ -0,0 +1 @@
zh-cn

View File

@ -0,0 +1,8 @@
config netspeedtest
option enabled '0'
config wanspeedtest
option enabled '0'

View File

@ -0,0 +1,55 @@
#!/bin/sh /etc/rc.common
# Copyright 2020 -2021 sirpdboy (herboy2008@gmail.com)
START=95
STOP=10
. /lib/functions.sh
EXTRA_COMMANDS="nstest"
EXTRA_HELP=" netspeedtest"
NS_FILE=/usr/share/netspeedtest/netspeedtest.txt
TMP_T=/tmp/netspeedtest
LOG="/var/log/netspeedtest.log"
limit_log() {
local logf=$1
[ ! -f "$logf" ] && return
local sc=100
[ -n "$2" ] && sc=$2
local count=$(grep -c "" $logf)
if [ $count -gt $sc ];then
let count=count-$sc
sed -i "1,$count d" $logf
fi
}
init_env() {
[ ! -f "$LOG" ] && echo " " > $LOG
echo 1 > $NS_FILE
}
nstest() {
init_env
[ -f "$TMP_T" ] && return
echo 1 > $TMP_T
echo -ne "\n ————————————————————————————" | tee -a $LOG
/etc/init.d/speedtest | tee -a $NS_FILE
ns_server=`cat $NS_FILE | grep 'Hosted by' | cut -c10-`
ns_down=`cat $NS_FILE | grep 'Download:' |awk -F: '{printf $2}' `
ns_up=`cat $NS_FILE | grep 'Upload:' |awk -F: '{printf $2}' `
echo -ne "\n 测服信息:${ns_server} " | tee -a $LOG
echo -ne "\n 下行速率:${ns_down} ---- 上行速率:${ns_up} " | tee -a $LOG
echo -ne "\n 测试时间: " | tee -a $LOG
echo $(date +%Y-%m-%d" "%H:%M:%S) | tee -a $LOG
rm -rf $TMP_T
}
reload(){
start
}
start() {
limit_log $LOG 200
nstest
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
#!/bin/sh
chmod 755 /etc/init.d/netspeedtest /etc/init.d/speedtest >/dev/null 2>&1
rm -rf /tmp/luci-modulecache /tmp/luci-indexcache*
exit 0

View File

@ -0,0 +1,11 @@
{
"luci-app-netspeedtest": {
"description": "Grant UCI access for luci-app-netspeedtest",
"read": {
"uci": [ "netspeedtest" ]
},
"write": {
"uci": [ "netspeedtest" ]
}
}
}

View File

@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-ssr-plus
PKG_VERSION:=186
PKG_RELEASE:=3
PKG_RELEASE:=5
PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \
@ -35,6 +35,8 @@ LUCI_DEPENDS:= \
+PACKAGE_$(PKG_NAME)_INCLUDE_Redsocks2:redsocks2 \
+PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core:curl \
+PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core:sagernet-core \
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:curl \
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray-core \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client:shadowsocks-libev-ss-local \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client:shadowsocks-libev-ss-redir \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Server:shadowsocks-libev-ss-server \
@ -50,6 +52,18 @@ LUCI_DEPENDS:= \
define Package/$(PKG_NAME)/config
select PACKAGE_luci-lib-ipkg if PACKAGE_$(PKG_NAME)
choice
prompt "V2Ray Edition Selection"
default PACKAGE_$(PKG_NAME)_INCLUDE_Xray
config PACKAGE_$(PKG_NAME)_INCLUDE_Xray
bool "Include Xray Core"
config PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core
bool "Include sagernet-core (An enhanced edition of v2ray-core)"
endchoice
config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun
bool "Include Kcptun"
default n
@ -59,7 +73,7 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_IPT2Socks
bool "Include ipt2socks"
bool "Include Ipt2socks"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy
@ -71,10 +85,6 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Redsocks2
bool "Include Redsocks2"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core
bool "Include sagernet-core (An enhanced edition of v2ray-core)"
default y if aarch64||arm||i386||x86_64
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client
bool "Include Shadowsocks Libev Client"
default y if arm

View File

@ -0,0 +1,43 @@
# Copyright (C) 2020 Openwrt.org
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
#
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-unblockmusic
PKG_VERSION:=2.3.5
PKG_RELEASE:=21
PKG_LICENSE:=Apache-2.0
PKG_MAINTAINER:=lean
PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_UnblockNeteaseMusic_Go \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_UnblockNeteaseMusic_NodeJS
LUCI_TITLE:=LuCI support for Unblock NeteaseCloudMusic
LUCI_PKGARCH:=all
LUCI_DEPENDS:=+dnsmasq-full +ipset +uclient-fetch \
+PACKAGE_$(PKG_NAME)_INCLUDE_UnblockNeteaseMusic_Go:UnblockNeteaseMusic-Go \
+PACKAGE_$(PKG_NAME)_INCLUDE_UnblockNeteaseMusic_NodeJS:UnblockNeteaseMusic
define Package/$(PKG_NAME)/config
config PACKAGE_$(PKG_NAME)_INCLUDE_UnblockNeteaseMusic_Go
bool "UnblockNeteaseMusic Golang Version"
default y if i386||x86_64||arm||aarch64
config PACKAGE_$(PKG_NAME)_INCLUDE_UnblockNeteaseMusic_NodeJS
bool "UnblockNeteaseMusic NodeJS Version"
depends on HAS_FPU || KERNEL_MIPS_FPU_EMULATOR || SOFT_FLOAT
default n
endef
define Package/$(PKG_NAME)/conffiles
/etc/config/unblockmusic
endef
include ../../luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -0,0 +1,19 @@
module("luci.controller.unblockmusic", package.seeall)
function index()
if not nixio.fs.access("/etc/config/unblockmusic") then
return
end
entry({"admin", "services", "unblockmusic"}, alias("admin", "services", "unblockmusic", "general"), _("Unblock Netease Music"), 50).dependent = true
entry({"admin", "services", "unblockmusic", "general"}, cbi("unblockmusic/unblockmusic"), _("Base Setting"), 1).leaf = true
entry({"admin", "services", "unblockmusic", "log"}, form("unblockmusic/unblockmusic_log"), _("Log"), 2).leaf = true
entry({"admin", "services", "unblockmusic", "status"}, call("act_status")).leaf = true
end
function act_status()
local e = {}
e.running = luci.sys.call("busybox ps -w | grep UnblockNeteaseMusic | grep -v grep | grep -v logcheck.sh >/dev/null") == 0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end

View File

@ -0,0 +1,121 @@
local fs = require "nixio.fs"
mp = Map("unblockmusic")
mp.title = translate("解锁网易云灰色歌曲")
mp.description = translate("采用 [QQ/百度/酷狗/酷我/咪咕/JOOX]等音源,替换网易云变灰歌曲链接")
mp:section(SimpleSection).template = "unblockmusic/unblockmusic_status"
s = mp:section(TypedSection, "unblockmusic")
s.anonymous = true
s.addremove = false
enabled = s:option(Flag, "enabled", translate("启用"))
enabled.description = translate("启用后,路由器自动分流解锁,大部分设备无需设置代理")
enabled.default = 0
enabled.rmempty = false
apptype = s:option(ListValue, "apptype", translate("解锁程序选择"))
if nixio.fs.access("/usr/bin/UnblockNeteaseMusic") then
apptype:value("go", translate("Golang 版本"))
end
if nixio.fs.access("/usr/share/UnblockNeteaseMusic/app.js") then
apptype:value("nodejs", translate("NodeJS 版本"))
end
apptype:value("cloud", translate("云解锁( [CTCGFW] 云服务器)"))
speedtype = s:option(Value, "musicapptype", translate("音源选择"))
speedtype:value("default", translate("默认"))
speedtype:value("netease", translate("网易云音乐"))
speedtype:value("qq", translate("QQ音乐"))
speedtype:value("baidu", translate("百度音乐"))
speedtype:value("kugou", translate("酷狗音乐"))
speedtype:value("kuwo", translate("酷我音乐"))
speedtype:value("migu", translate("咪咕音乐"))
speedtype:value("joox", translate("JOOX音乐"))
speedtype.default = "kuwo"
speedtype:depends("apptype", "nodejs")
speedtype:depends("apptype", "go")
cloudserver = s:option(Value, "cloudserver", translate("服务器位置"))
cloudserver.description = translate("自定义服务器格式为 IP[域名]:HTTP端口:HTTPS端口<br />如果服务器为LAN内网IP需要将这个服务器IP放入例外客户端 (不代理HTTP和HTTPS)")
cloudserver.default = ""
cloudserver.rmempty = true
cloudserver:depends("apptype", "cloud")
search_limit = s:option(Value, "search_limit", translate("搜索结果限制"))
search_limit.description = translate("在搜索页面显示其他平台搜索结果个数可填0-3")
search_limit.default = "0"
search_limit:depends("apptype", "go")
flac = s:option(Flag, "flac_enabled", translate("启用无损音质"))
flac.description = translate("目前仅支持酷我、QQ、咪咕")
flac.default = "1"
flac.rmempty = false
flac:depends("apptype", "nodejs")
flac:depends("apptype", "go")
replace_music_source = s:option(ListValue, "replace_music_source", translate("强制音乐音源替换"))
replace_music_source:value("0", translate("不强制替换音乐音源"))
replace_music_source:value("192000", translate("当音质低于 192 Kbps"))
replace_music_source:value("320000", translate("当音质低于 320 Kbps"))
replace_music_source:value("600000", translate("当音质低于 999 Kbps无损"))
replace_music_source.description = translate("当音乐音质低于指定数值时,尝试强制使用其他平台的高音质版本进行替换")
replace_music_source.default = "0"
replace_music_source.rmempty = false
replace_music_source:depends("apptype", "nodejs")
local_vip = s:option(Flag, "local_vip", translate("启用本地 VIP"))
local_vip.description = translate("启用后,可以使用去广告、个性换肤、鲸云音效等本地功能")
local_vip.default = 0
local_vip.rmempty = false
local_vip:depends("apptype", "nodejs")
autoupdate = s:option(Flag, "autoupdate", translate("自动检查更新主程序"))
autoupdate.description = translate("每天自动检测并更新到最新版本")
autoupdate.default = "1"
autoupdate.rmempty = false
autoupdate:depends("apptype", "nodejs")
download_certificate = s:option(DummyValue, "opennewwindow", translate("HTTPS 证书"))
download_certificate.description = translate("<input type=\"button\" class=\"btn cbi-button cbi-button-apply\" value=\"下载CA根证书\" onclick=\"window.open('https://raw.githubusercontent.com/UnblockNeteaseMusic/server/enhanced/ca.crt')\" /><br />Mac/iOS客户端需要安装 CA根证书并信任<br />iOS系统需要在“设置 -> 通用 -> 关于本机 -> 证书信任设置”中,信任 UnblockNeteaseMusic Root CA <br />Linux 设备请在启用时加入 --ignore-certificate-errors 参数")
local ver = fs.readfile("/usr/share/UnblockNeteaseMusic/core_ver") or "0.00"
restart = s:option(Button, "restart", translate("手动更新"))
restart.inputtitle = translate("更新核心版本")
restart.description = string.format(translate("NodeJS 解锁主程序版本") .. "<strong><font color=\"green\">: %s </font></strong>", ver)
restart.inputstyle = "reload"
restart.write = function()
luci.sys.exec("/usr/share/UnblockNeteaseMusic/update_core.sh luci_update 2>&1")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "unblockmusic"))
end
restart:depends("apptype", "nodejs")
t = mp:section(TypedSection, "acl_rule")
t.title = translate("例外客户端规则")
t.description = translate("可以为局域网客户端分别设置不同的例外模式,默认无需设置")
t.template = "cbi/tblsection"
t.sortable = true
t.anonymous = true
t.addremove = true
ipaddr = t:option(Value, "ipaddr", translate("IP 地址"))
ipaddr.width = "40%"
ipaddr.datatype = "ip4addr"
ipaddr.placeholder = "0.0.0.0/0"
luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then
ipaddr:value(entry.dest:string())
end
end)
filter_mode = t:option(ListValue, "filter_mode", translate("例外协议"))
filter_mode.width = "40%"
filter_mode.default = "disable"
filter_mode.rmempty = false
filter_mode:value("disable", translate("不代理HTTP和HTTPS"))
filter_mode:value("http", translate("不代理HTTP"))
filter_mode:value("https", translate("不代理HTTPS"))
return mp

View File

@ -0,0 +1,15 @@
local fs = require "nixio.fs"
local conffile = "/tmp/music.log"
f = SimpleForm("logview")
t = f:field(TextValue, "conf")
t.rmempty = true
t.rows = 20
function t.cfgvalue()
luci.sys.exec("grep -B 1 'http' /tmp/unblockmusic.log | grep -v -e'running' -e'TLS' -e'Transport' -e'POST' -e'github' -e'consumed' -e'starting' -e'error' > /tmp/music.log")
return fs.readfile(conffile) or ""
end
t.readonly = "readonly"
return f

View File

@ -0,0 +1,22 @@
<script type="text/javascript">//<![CDATA[
XHR.poll(3, '<%=url([[admin]], [[services]], [[unblockmusic]], [[status]])%>', null,
function(x, data) {
var tb = document.getElementById('unblockmusic_status');
if (data && tb) {
if (data.running) {
var links = '<em><b><font color=green>UnblockNeteaseMusic <%:RUNNING%></font></b></em>';
tb.innerHTML = links;
} else {
tb.innerHTML = '<em><b><font color=red>UnblockNeteaseMusic <%:NOT RUNNING%></font></b></em>';
}
}
}
);
//]]>
</script>
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
<fieldset class="cbi-section">
<p id="unblockmusic_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>

View File

@ -0,0 +1,13 @@
msgid "Unblock Netease Music"
msgstr "解锁网易云灰色歌曲"
msgid "Base Setting"
msgstr "基本设置"
msgid "Log"
msgstr "日志"
msgid "Port"
msgstr "端口"

View File

@ -0,0 +1 @@
zh-cn

View File

@ -0,0 +1,8 @@
config unblockmusic
option musicapptype 'kuwo'
option autoupdate '1'
option endpoint 'http://music.163.com'
option enabled '0'
option apptype 'go'

View File

@ -0,0 +1,7 @@
#!/bin/sh
[ "$ACTION" = ifup ] || exit 0
sleep 10
ipset flush music 2>/dev/null
/usr/share/UnblockNeteaseMusic/getmusicip.sh

View File

@ -0,0 +1,223 @@
#!/bin/sh /etc/rc.common
. /lib/functions/network.sh
START=97
STOP=10
NAME=unblockmusic
uci_get_by_type() {
local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null)
echo ${ret:=$3}
}
uci_get_by_name() {
local index=0
if [ -n $4 ]; then
index=$4
fi
local ret=$(uci get $NAME.@$1[$index].$2 2>/dev/null)
echo ${ret:=$3}
}
check_host() {
local host=$1
if echo $host | grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/null; then
hostip=$host
elif [ "$host" != "${host#*:[0-9a-fA-F]}" ]; then
hostip=$host
else
hostip=$(ping $host -W 1 -s 1 -c 1 | grep PING | cut -d'(' -f 2 | cut -d')' -f1)
if echo $hostip | grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/null; then
hostip=$hostip
else
hostip="127.0.0.1"
fi
fi
echo -e $hostip
}
ip_rule()
{
local icount=$(uci show unblockmusic | grep 'filter_mode' | wc -l)
let icount=icount-1
for i in $(seq 0 $icount)
do
local ip=$(uci_get_by_name acl_rule ipaddr '' $i)
local mode=$(uci_get_by_name acl_rule filter_mode '' $i)
case "$mode" in
http)
ipset -! add music_http $ip
;;
https)
ipset -! add music_https $ip
;;
disable)
ipset -! add music_http $ip
ipset -! add music_https $ip
;;
esac
done
}
ENABLE=$(uci_get_by_type unblockmusic enabled 0)
TYPE=$(uci_get_by_type unblockmusic musicapptype default)
AUTOUPDATE=$(uci_get_by_type unblockmusic autoupdate 0)
APPTYPE=$(uci_get_by_type unblockmusic apptype go)
SEARCHLIMIT=$(uci_get_by_type unblockmusic search_limit 0)
FLAC=$(uci_get_by_type unblockmusic flac_enabled 0)
REPLACE_MUSIC_SOURCE=$(uci_get_by_type unblockmusic replace_music_source 0)
LOCAL_VIP=$(uci_get_by_type unblockmusic local_vip 0)
CLOUD=$(uci_get_by_type unblockmusic cloudserver "127.0.0.1:5200:5201")
cloudadd=$(echo "$CLOUD" | awk -F ':' '{print $1}')
cloudhttp=$(echo "$CLOUD" | awk -F ':' '{print $2}')
cloudhttps=$(echo "$CLOUD" | awk -F ':' '{print $3}')
cloudip=$(check_host $cloudadd)
network_flush_cache
network_get_ipaddr lanaddr "lan"
CRON_FILE=/etc/crontabs/root
ipt_n="iptables -t nat"
add_rule()
{
ipset -! -N music hash:ip
ipset -! -N music_http hash:ip
ipset -! -N music_https hash:ip
$ipt_n -N CLOUD_MUSIC
$ipt_n -A CLOUD_MUSIC -d 0.0.0.0/8 -j RETURN
$ipt_n -A CLOUD_MUSIC -d 10.0.0.0/8 -j RETURN
$ipt_n -A CLOUD_MUSIC -d 127.0.0.0/8 -j RETURN
$ipt_n -A CLOUD_MUSIC -d 169.254.0.0/16 -j RETURN
$ipt_n -A CLOUD_MUSIC -d 172.16.0.0/12 -j RETURN
$ipt_n -A CLOUD_MUSIC -d 192.168.0.0/16 -j RETURN
$ipt_n -A CLOUD_MUSIC -d 224.0.0.0/4 -j RETURN
$ipt_n -A CLOUD_MUSIC -d 240.0.0.0/4 -j RETURN
if [ "$APPTYPE" != "cloud" ]; then
$ipt_n -A CLOUD_MUSIC -p tcp -m set ! --match-set music_http src --dport 80 -j REDIRECT --to-ports 5200
$ipt_n -A CLOUD_MUSIC -p tcp -m set ! --match-set music_https src --dport 443 -j REDIRECT --to-ports 5201
else
$ipt_n -A CLOUD_MUSIC -p tcp -m set ! --match-set music_http src --dport 80 -j DNAT --to $cloudip:$cloudhttp
$ipt_n -A CLOUD_MUSIC -p tcp -m set ! --match-set music_https src --dport 443 -j DNAT --to $cloudip:$cloudhttps
$ipt_n -I POSTROUTING -p tcp -m multiport --dport $cloudhttp,$cloudhttps -d $cloudip -j SNAT --to-source $lanaddr
fi
$ipt_n -I PREROUTING -p tcp -m set --match-set music dst -j CLOUD_MUSIC
iptables -I OUTPUT -d 223.252.199.10 -j DROP
ip_rule
}
del_rule(){
$ipt_n -D PREROUTING -p tcp -m set --match-set music dst -j CLOUD_MUSIC 2>/dev/null
$ipt_n -D POSTROUTING -p tcp -m multiport --dport $cloudhttp,$cloudhttps -d $cloudip -j SNAT --to-source $lanaddr 2>/dev/null
$ipt_n -F CLOUD_MUSIC 2>/dev/null
$ipt_n -X CLOUD_MUSIC 2>/dev/null
iptables -D OUTPUT -d 223.252.199.10 -j DROP 2>/dev/null
ipset flush music 2>/dev/null
ipset -X music_http 2>/dev/null
ipset -X music_https 2>/dev/null
rm -f /tmp/dnsmasq.d/dnsmasq-163.conf
/etc/init.d/dnsmasq reload >/dev/null 2>&1
}
set_firewall(){
rm -f /tmp/dnsmasq.d/dnsmasq-163.conf
mkdir -p /tmp/dnsmasq.d
cat <<-EOF > "/tmp/dnsmasq.d/dnsmasq-163.conf"
ipset=/.music.163.com/music
ipset=/interface.music.163.com/music
ipset=/interface3.music.163.com/music
ipset=/apm.music.163.com/music
ipset=/apm3.music.163.com/music
ipset=/clientlog.music.163.com/music
ipset=/clientlog3.music.163.com/music
EOF
/etc/init.d/dnsmasq reload >/dev/null 2>&1
add_rule
mkdir -p /var/etc
echo -e "/etc/init.d/unblockmusic restart" > "/var/etc/unblockmusic.include"
}
add_cron()
{
if [ $AUTOUPDATE -eq 1 ]; then
sed -i '/update_core.sh/d' $CRON_FILE
echo '0 2 * * * /usr/share/UnblockNeteaseMusic/update_core.sh 2>&1' >> $CRON_FILE
crontab $CRON_FILE
fi
}
del_cron()
{
sed -i '/update_core.sh/d' $CRON_FILE
/etc/init.d/cron restart
}
start()
{
stop
[ $ENABLE -eq "0" ] && exit 0
rm -f /tmp/unblockmusic.log
echo "$(date -R) # Start UnblockNeteaseMusic" >/tmp/unblockmusic.log
if [ "$TYPE" = "default" ]; then
musictype=" "
else
musictype="-o $TYPE"
fi
if [ "$APPTYPE" == "nodejs" ]; then
if [ $FLAC -eq 1 ]; then
export ENABLE_FLAC=true
fi
if [ $REPLACE_MUSIC_SOURCE -ne 0 ]; then
export MIN_BR=$REPLACE_MUSIC_SOURCE
fi
if [ $LOCAL_VIP -eq 1 ]; then
export ENABLE_LOCAL_VIP=true
fi
node /usr/share/UnblockNeteaseMusic/app.js -p 5200 $musictype >>/tmp/unblockmusic.log 2>&1 &
node /usr/share/UnblockNeteaseMusic/app.js -e https://music.163.com -p 5203:5201 $musictype >>/tmp/unblockmusic.log 2>&1 &
add_cron
echo "$(date -R) # UnblockNeteaseMusic Nodejs Version (http:5200, https:5201)" >>/tmp/unblockmusic.log
elif [ "$APPTYPE" == "go" ]; then
if [ $FLAC -eq 1 ]; then
ENABLE_FLAC="-b "
fi
UnblockNeteaseMusic -o "kuwo:kugou" $ENABLE_FLAC -p 5200 -sp 5201 -c /usr/share/UnblockNeteaseMusicGo/server.crt -k /usr/share/UnblockNeteaseMusicGo/server.key -m 0 -e -sl ${SEARCHLIMIT} -l /tmp/unblockmusic.log &
echo "$(date -R) # UnblockNeteaseMusic Golang Version (http:5200, https:5201)" >>/tmp/unblockmusic.log
else
kill -9 $(busybox ps -w | grep 'sleep 60m' | grep -v grep | awk '{print $1}') >/dev/null 2>&1
/usr/bin/UnblockNeteaseMusicCloud >/dev/null 2>&1 &
echo "$(date -R) # UnblockNeteaseMusic Cloud Version - Server: $cloudip (http:$cloudhttp, https:$cloudhttps)" >>/tmp/unblockmusic.log
fi
set_firewall
if [ "$APPTYPE" != "cloud" ]; then
/usr/share/UnblockNeteaseMusic/logcheck.sh >/dev/null 2>&1 &
fi
}
stop()
{
kill -9 $(busybox ps -w | grep UnblockNeteaseMusic | grep -v grep | awk '{print $1}') >/dev/null 2>&1
kill -9 $(busybox ps -w | grep logcheck.sh | grep -v grep | awk '{print $1}') >/dev/null 2>&1
rm -f /tmp/unblockmusic.log
del_rule
del_cron
}

View File

@ -0,0 +1,17 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@unblockmusic[-1]
add ucitrack unblockmusic
set ucitrack.@unblockmusic[-1].init=unblockmusic
commit ucitrack
delete firewall.unblockmusic
set firewall.unblockmusic=include
set firewall.unblockmusic.type=script
set firewall.unblockmusic.path=/var/etc/unblockmusic.include
set firewall.unblockmusic.reload=1
commit firewall
EOF
rm -f /tmp/luci-indexcache
exit 0

View File

@ -0,0 +1,6 @@
/usr/share/UnblockNeteaseMusic/ca.crt
/usr/share/UnblockNeteaseMusic/server.crt
/usr/share/UnblockNeteaseMusic/server.key
/usr/share/UnblockNeteaseMusicGo/ca.crt
/usr/share/UnblockNeteaseMusicGo/server.crt
/usr/share/UnblockNeteaseMusicGo/server.key

View File

@ -0,0 +1,8 @@
#!/bin/sh
while true
do
ipset -! -N music hash:ip
uclient-fetch -q -T 10 http://httpdns.n.netease.com/httpdns/v2/d?domain=music.163.com,interface.music.163.com,interface3.music.163.com,apm.music.163.com,apm3.music.163.com,clientlog.music.163.com,clientlog3.music.163.com -O- | grep -Eo '[0-9]+?\.[0-9]+?\.[0-9]+?\.[0-9]+?' | sort | uniq | awk '{print "ipset -! add music "$1}' | sh
sleep 60m
done

View File

@ -0,0 +1,4 @@
#!/bin/sh
ipset -! -N music hash:ip
uclient-fetch -q -T 10 http://httpdns.n.netease.com/httpdns/v2/d?domain=music.163.com,interface.music.163.com,interface3.music.163.com,apm.music.163.com,apm3.music.163.com,clientlog.music.163.com,clientlog3.music.163.com -O- | grep -Eo '[0-9]+?\.[0-9]+?\.[0-9]+?\.[0-9]+?' | sort | uniq | awk '{print "ipset -! add music "$1}' | sh

View File

@ -0,0 +1,19 @@
#!/bin/sh
log_max_size=100
log_file="/tmp/unblockmusic.log"
log_size=0
/usr/share/UnblockNeteaseMusic/getmusicip.sh
sleep 29s
while true
do
icount=`busybox ps -w | grep UnblockNeteaseMusic | grep -v grep | grep -v logcheck.sh`
if [ -z "$icount" ]; then
/etc/init.d/unblockmusic restart
fi
log_size=$(expr $(ls -l $log_file | awk '{print $5}') / 1024)
[ $log_size -ge $log_max_size ] && echo "$(date -R) # Start UnblockNeteaseMusic" >/tmp/unblockmusic.log
sleep 29s
done

View File

@ -0,0 +1,68 @@
#!/bin/sh
function check_if_already_running(){
running_tasks="$(ps |grep "unblockneteasemusic" |grep "update_core" |grep -v "grep" |awk '{print $1}' |wc -l)"
[ "${running_tasks}" -gt "2" ] && echo -e "\nA task is already running." >>/tmp/unblockmusic_update.log && exit 2
}
function clean_log(){
echo "" > /tmp/unblockmusic_update.log
}
function check_latest_version(){
latest_ver="$(uclient-fetch --no-check-certificate -O- https://github.com/UnblockNeteaseMusic/server/commits/enhanced |tr -d '\n' |grep -Eo 'commit\/[0-9a-z]+' |sed -n 1p |sed 's#commit/##g')"
[ -z "${latest_ver}" ] && echo -e "\nFailed to check latest version, please try again later." >>/tmp/unblockmusic_update.log && exit 1
if [ ! -e "/usr/share/UnblockNeteaseMusic/local_ver" ]; then
clean_log
echo -e "Local version: NOT FOUND, cloud version: ${latest_ver}." >>/tmp/unblockmusic_update.log
update_core
else
if [ "$(cat /usr/share/UnblockNeteaseMusic/local_ver)" != "${latest_ver}" ]; then
clean_log
update_core
else
echo -e "\nLocal version: $(cat /usr/share/UnblockNeteaseMusic/local_ver 2>/dev/null), cloud version: ${latest_ver}." >>/tmp/unblockmusic_update.log
echo -e "You're already using the latest version." >>/tmp/unblockmusic_update.log
[ "${luci_update}" == "n" ] && /etc/init.d/unblockmusic restart
exit 3
fi
fi
}
function update_core(){
echo -e "Updating core..." >>/tmp/unblockmusic_update.log
mkdir -p "/tmp/unblockneteasemusic/core" >/dev/null 2>&1
rm -rf /tmp/unblockneteasemusic/core/* >/dev/null 2>&1
uclient-fetch --no-check-certificate -T 10 -O /tmp/unblockneteasemusic/core/core.tar.gz "https://github.com/UnblockNeteaseMusic/server/archive/enhanced.tar.gz" >/dev/null 2>&1
tar -zxf "/tmp/unblockneteasemusic/core/core.tar.gz" -C "/tmp/unblockneteasemusic/core/" >/dev/null 2>&1
if [ -e "/usr/share/UnblockNeteaseMusic/ca.crt" ] && [ -e "/usr/share/UnblockNeteaseMusic/server.crt" ] && [ -e "/usr/share/UnblockNeteaseMusic/server.key" ] ; then
rm -f /tmp/unblockneteasemusic/core/server-enhanced/ca.crt /tmp/unblockneteasemusic/core/server-enhanced/server.crt /tmp/unblockneteasemusic/core/server-enhanced/server.key
fi
cp -a /tmp/unblockneteasemusic/core/server-enhanced/* "/usr/share/UnblockNeteaseMusic/"
rm -rf "/tmp/unblockneteasemusic" >/dev/null 2>&1
if [ ! -e "/usr/share/UnblockNeteaseMusic/app.js" ]; then
echo -e "Failed to download core." >>/tmp/unblockmusic_update.log
exit 1
else
echo -e "${latest_ver}" > /usr/share/UnblockNeteaseMusic/local_ver
cat /usr/share/UnblockNeteaseMusic/package.json | grep version |awk -F ':' '{print $2}' | sed -r 's/.*"(.+)".*/\1/' > /usr/share/UnblockNeteaseMusic/core_ver
fi
echo -e "Succeeded in updating core." >>/tmp/unblockmusic_update.log
echo -e "Local version: $(cat /usr/share/UnblockNeteaseMusic/local_ver 2>/dev/null), cloud version: ${latest_ver}.\n" >>/tmp/unblockmusic_update.log
/etc/init.d/unblockmusic restart
}
function main(){
check_if_already_running
check_latest_version
}
luci_update="n"
[ "$1" == "luci_update" ] && luci_update="y"
main

View File

@ -0,0 +1,11 @@
{
"luci-app-unblockmusic": {
"description": "Grant UCI access for luci-app-unblockmusic",
"read": {
"uci": [ "unblockmusic" ]
},
"write": {
"uci": [ "unblockmusic" ]
}
}
}

59
smartdns/Makefile Normal file
View File

@ -0,0 +1,59 @@
#
# Copyright (c) 2018-2020 Nick Peng (pymumu@gmail.com)
# This is free software, licensed under the GNU General Public License v3.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=smartdns
PKG_VERSION:=1.2022.36
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://www.github.com/pymumu/smartdns.git
PKG_SOURCE_VERSION:=24661c2419a81e660b11a0e3d35a3bc269cd4bfa
PKG_MIRROR_HASH:=0835be621f0359bec24fe2ec112f455aef8d403167be33a8366630db9fdbdbaa
PKG_MAINTAINER:=Nick Peng <pymumu@gmail.com>
PKG_LICENSE:=GPL-3.0-or-later
PKG_LICENSE_FILES:=LICENSE
PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
MAKE_VARS += VER=$(PKG_VERSION)
MAKE_PATH:=src
define Package/smartdns
SECTION:=net
CATEGORY:=Network
TITLE:=smartdns server
DEPENDS:=+libpthread +libopenssl
URL:=https://www.github.com/pymumu/smartdns/
endef
define Package/smartdns/description
SmartDNS is a local DNS server which accepts DNS query requests from local network clients,
gets DNS query results from multiple upstream DNS servers concurrently, and returns the fastest IP to clients.
Unlike dnsmasq's all-servers, smartdns returns the fastest IP.
endef
define Package/smartdns/conffiles
/etc/config/smartdns
/etc/smartdns/address.conf
/etc/smartdns/blacklist-ip.conf
/etc/smartdns/custom.conf
endef
define Package/smartdns/install
$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/config $(1)/etc/init.d $(1)/etc/smartdns
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/smartdns $(1)/usr/sbin/smartdns
$(INSTALL_BIN) $(PKG_BUILD_DIR)/package/openwrt/files/etc/init.d/smartdns $(1)/etc/init.d/smartdns
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/address.conf $(1)/etc/smartdns/address.conf
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/blacklist-ip.conf $(1)/etc/smartdns/blacklist-ip.conf
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/custom.conf $(1)/etc/smartdns/custom.conf
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/files/etc/config/smartdns $(1)/etc/config/smartdns
endef
$(eval $(call BuildPackage,smartdns))

19
smartdns/Makefile.rej Normal file
View File

@ -0,0 +1,19 @@
--- smartdns/Makefile
+++ smartdns/Makefile
@@ -6,13 +6,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=smartdns
-PKG_VERSION:=1.2021.35
+PKG_VERSION:=2022.2.2
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://www.github.com/pymumu/smartdns.git
-PKG_SOURCE_VERSION:=f50e4dd0813da9300580f7188e44ed72a27ae79c
-PKG_MIRROR_HASH:=b4d825a48884101f647cd594f00b714a2d09ac419b958ee0317d302fd31b0038
+PKG_SOURCE_VERSION:=ba282c8c60df9b59deb420e5b3f5d177d2d87afa
+#PKG_MIRROR_HASH:=b4d825a48884101f647cd594f00b714a2d09ac419b958ee0317d302fd31b0038
PKG_MAINTAINER:=Nick Peng <pymumu@gmail.com>
PKG_LICENSE:=GPL-3.0-or-later