update 2025-05-14 04:25:50
This commit is contained in:
parent
310e9dd234
commit
445f0b7a67
|
@ -9,8 +9,8 @@ include $(TOPDIR)/rules.mk
|
|||
|
||||
PKG_NAME:=luci-app-netspeedtest
|
||||
|
||||
PKG_VERSION:=5.0.1
|
||||
PKG_RELEASE:=20250512
|
||||
PKG_VERSION:=5.0.2
|
||||
PKG_RELEASE:=20250513
|
||||
|
||||
LUCI_TITLE:=LuCI Support for netspeedtest
|
||||
LUCI_DEPENDS:=+speedtest-cli +homebox +iperf3-ssl
|
||||
|
|
|
@ -30,7 +30,7 @@ return view.extend({
|
|||
|
||||
var iframe = E('iframe', {
|
||||
src: window.location.origin + ':' + state.port,
|
||||
style: 'width: 100%; min-height: 80vh; border: none; border-radius: 3px;'
|
||||
style: 'border:none;width: 100%; min-height: 80vh; border: none; border-radius: 3px;overflow:hidden !important;'
|
||||
});
|
||||
|
||||
function checkProcess() {
|
||||
|
@ -42,7 +42,7 @@ return view.extend({
|
|||
|
||||
function controlService(action) {
|
||||
var command = action === 'start'
|
||||
? 'nohup /usr/bin/homebox > /tmp/homebox.log 2>&1 &'
|
||||
? 'nohup /usr/bin/homebox > /tmp/netspeedtest.log 2>&1 &'
|
||||
: '/usr/bin/killall homebox';
|
||||
return fs.exec('/bin/sh', ['-c', command]);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ var state = {
|
|||
port: null
|
||||
};
|
||||
|
||||
const logPath = '/var/log/iperf3.log';
|
||||
const logPath = '/tmp/netspeedtest.log';
|
||||
|
||||
function checkProcess() {
|
||||
return fs.exec('/bin/pidof', ['iperf3']).then(res => ({
|
||||
|
@ -172,7 +172,7 @@ const statusSection = E('div', { 'class': 'cbi-section' }, [
|
|||
return E('div', [
|
||||
statusSection,
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('h3', {}, _('Iperf3 Run Log')),
|
||||
E('h3', {}, _('Run Log')),
|
||||
logTextarea,
|
||||
E('div', { 'style': 'text-align: right; font-size: small; margin-top: 5px;' },
|
||||
_('Refresh every 5 seconds.')
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* Copyright (C) 2021-2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-netspeedtest */
|
||||
'use strict';
|
||||
'require dom';
|
||||
'require fs';
|
||||
|
@ -11,76 +12,87 @@ var logTextarea;
|
|||
var log_path;
|
||||
|
||||
uci.load('netspeedtest').then(function() {
|
||||
log_path = '/var/log/netspeedtest.log';
|
||||
log_path = '/tmp/netspeedtest.log';
|
||||
});
|
||||
|
||||
function pollLog() {
|
||||
return Promise.all([
|
||||
fs.read_direct(log_path, 'text').then(function (res) {
|
||||
return res.trim().split(/\n/).join('\n').replace(/\u001b\[33mWARN\u001b\[0m/g, '').replace(/\u001b\[36mINFO\u001b\[0m/g, '').replace(/\u001b\[31mERRO\u001b\[0m/g, '');
|
||||
}),
|
||||
]).then(function (data) {
|
||||
logTextarea.value = data[0] || _('No log data.');
|
||||
return Promise.all([
|
||||
fs.read_direct(log_path, 'text').then(function(res) {
|
||||
return res.trim()
|
||||
.split(/\n/).join('\n')
|
||||
.replace(/\u001b\[33mWARN\u001b\[0m/g, '')
|
||||
.replace(/\u001b\[36mINFO\u001b\[0m/g, '')
|
||||
.replace(/\u001b\[31mERRO\u001b\[0m/g, '');
|
||||
}),
|
||||
]).then(function(data) {
|
||||
logTextarea.value = data[0] || _('No log data.');
|
||||
|
||||
if (!userScrolled) {
|
||||
logTextarea.scrollTop = logTextarea.scrollHeight;
|
||||
} else {
|
||||
logTextarea.scrollTop = scrollPosition;
|
||||
}
|
||||
});
|
||||
};
|
||||
if (!userScrolled) {
|
||||
logTextarea.scrollTop = logTextarea.scrollHeight;
|
||||
} else {
|
||||
logTextarea.scrollTop = scrollPosition;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return view.extend({
|
||||
handleCleanLogs: function () {
|
||||
return fs.write(log_path, '')
|
||||
.catch(function (e) { ui.addNotification(null, E('p', e.message)) });
|
||||
},
|
||||
handleCleanLogs: function() {
|
||||
return fs.write(log_path, '')
|
||||
.catch(function(e) {
|
||||
ui.addNotification(null, E('p', e.message))
|
||||
});
|
||||
},
|
||||
|
||||
render: function () {
|
||||
logTextarea = E('textarea', {
|
||||
'class': 'cbi-input-textarea',
|
||||
'wrap': 'off',
|
||||
'readonly': 'readonly',
|
||||
'style': 'width: calc(100% - 20px);height: 535px;margin: 10px;overflow-y: scroll;',
|
||||
});
|
||||
render: function() {
|
||||
logTextarea = E('textarea', {
|
||||
'class': 'cbi-input-textarea',
|
||||
'wrap': 'off',
|
||||
'readonly': 'readonly',
|
||||
'style': 'width: calc(100% - 20px); height: 535px; margin: 10px; overflow-y: scroll;'
|
||||
});
|
||||
|
||||
logTextarea.addEventListener('scroll', function () {
|
||||
userScrolled = true;
|
||||
scrollPosition = logTextarea.scrollTop;
|
||||
});
|
||||
logTextarea.addEventListener('scroll', function() {
|
||||
userScrolled = true;
|
||||
scrollPosition = logTextarea.scrollTop;
|
||||
});
|
||||
|
||||
var log_textarea_wrapper = E('div', { 'id': 'log_textarea' }, logTextarea);
|
||||
var log_textarea_wrapper = E('div', { 'id': 'log_textarea' }, logTextarea);
|
||||
|
||||
setTimeout(function () {
|
||||
poll.add(pollLog);
|
||||
}, 100);
|
||||
setTimeout(function() {
|
||||
poll.add(pollLog);
|
||||
}, 100);
|
||||
|
||||
var clear_logs_button = E('input', { 'class': 'btn cbi-button-action', 'type': 'button', 'style': 'margin-left: 10px; margin-top: 10px;', 'value': _('Clear logs') });
|
||||
clear_logs_button.addEventListener('click', this.handleCleanLogs.bind(this));
|
||||
var clear_logs_button = E('input', {
|
||||
'class': 'btn cbi-button-action',
|
||||
'type': 'button',
|
||||
'style': 'margin-left: 20px; margin-top: 10px;',
|
||||
'value': _('Clear logs')
|
||||
});
|
||||
clear_logs_button.addEventListener('click', this.handleCleanLogs.bind(this));
|
||||
|
||||
return E([
|
||||
E('div', { 'class': 'cbi-map' }, [
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
clear_logs_button,
|
||||
log_textarea_wrapper,
|
||||
E('div', { 'style': 'text-align:right' },
|
||||
E('small', {}, _('Refresh every %s seconds.').format(L.env.pollinterval)),
|
||||
E('div', { 'class': 'cbi-section-actions cbi-section-actions-right' })
|
||||
]),
|
||||
E('div', { 'style': 'text-align: right; font-style: italic;' }, [
|
||||
return E('div', { 'class': 'cbi-map' }, [
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
clear_logs_button,
|
||||
log_textarea_wrapper,
|
||||
E('div', { 'style': 'text-align: right' }, [
|
||||
E('small', {}, _('Refresh every %s seconds.').format(L.env.pollinterval))
|
||||
]),
|
||||
E('div', { 'class': 'cbi-section-actions cbi-section-actions-right' })
|
||||
]),
|
||||
E('div', { 'style': 'text-align: right; font-style: italic; margin-top: 10px;' }, [
|
||||
E('span', {}, [
|
||||
_('© github '),
|
||||
E('a', {
|
||||
'href': 'https://github.com/sirpdboy',
|
||||
E('a', {
|
||||
'href': 'https://github.com/sirpdboy',
|
||||
'target': '_blank',
|
||||
'style': 'text-decoration: none;'
|
||||
}, 'by sirpdboy')
|
||||
])
|
||||
])
|
||||
]);
|
||||
}
|
||||
])
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
// handleSaveApply: null,
|
||||
// handleSave: null,
|
||||
// handleSave: null,
|
||||
// handleReset: null
|
||||
});
|
||||
});
|
|
@ -1,3 +1,4 @@
|
|||
/* Copyright (C) 2021-2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-netspeedtest */
|
||||
'use strict';
|
||||
'require view';
|
||||
'require uci';
|
||||
|
@ -22,7 +23,7 @@ return view.extend({
|
|||
s.render = function (section_id) {
|
||||
return E('iframe', {
|
||||
src: '//openspeedtest.com/speedtest',
|
||||
style: 'border:none;width:100%;height:100%;min-height:360px;border:none;overflow:hidden !important;'
|
||||
style: 'width:100%;height:100%;min-height:360px;border:none;overflow:hidden !important;'
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* Copyright (C) 2021-2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-netspeedtest */
|
||||
'use strict';
|
||||
'require view';
|
||||
'require poll';
|
||||
|
@ -17,7 +18,7 @@ return view.extend({
|
|||
// handleSaveApply: null,
|
||||
// handleSave: null,
|
||||
// handleReset: null,
|
||||
load: function () {
|
||||
load() {
|
||||
return Promise.all([
|
||||
L.resolveDefault(fs.stat(SpeedtestCli), {}),
|
||||
L.resolveDefault(fs.read(ResultFile), null),
|
||||
|
@ -26,76 +27,94 @@ return view.extend({
|
|||
]);
|
||||
},
|
||||
|
||||
poll_status: function (nodes, res) {
|
||||
var has_ookla = res[0].path,
|
||||
poll_status(nodes, res) {
|
||||
var has_ookla = res[0].path,
|
||||
result_content = res[1] ? res[1].trim().split("\n") : [];
|
||||
var ookla_stat = nodes.querySelector('#ookla_status'),
|
||||
var ookla_stat = nodes.querySelector('#ookla_status'),
|
||||
result_stat = nodes.querySelector('#speedtest_result');
|
||||
|
||||
// Update status indicators
|
||||
ookla_stat.style.color = has_ookla ? 'green' : 'red';
|
||||
dom.content(ookla_stat, [_(has_ookla ? 'Installed' : 'Not Installed')]);
|
||||
|
||||
// Update result display
|
||||
if (result_content.length) {
|
||||
if (result_content[0] == 'Testing') {
|
||||
result_stat.innerHTML = "<span style='color:green;font-weight:bold'>" +
|
||||
"<img src='/luci-static/resources/icons/loading.gif' height='17' style='vertical-align:middle'/> " +
|
||||
_('Testing in progress...') +
|
||||
"</span>";
|
||||
} else if (result_content[0].match(/https?:\S+/)) {
|
||||
result_stat.innerHTML = "<div style='max-width:500px'><a href='" +
|
||||
result_content[0] + "' target='_blank'><img src='" +
|
||||
result_content[0] + '.png' + "' style='max-width:100%'></a></div>";
|
||||
} else if (result_content[0] == 'Test failed') {
|
||||
result_stat.innerHTML = "<span style='color:red;font-weight:bold'>" +
|
||||
_('Test failed.') + "</span>";
|
||||
}
|
||||
} else {
|
||||
result_stat.innerHTML = "<span style='color:gray'>" +
|
||||
_('No test results yet.') + "</span>";
|
||||
// 获取版本号(新增部分)
|
||||
var version_info = '';
|
||||
if (has_ookla) {
|
||||
fs.exec_direct('/usr/bin/speedtest', ['--version'])
|
||||
.then(function(res) {
|
||||
if (res.stdout) {
|
||||
var version_match = res.stdout.match(/Speedtest (\d+\.\d+\.\d+)/);
|
||||
if (version_match) {
|
||||
version_info = ' ver:' + version_match[1];
|
||||
}
|
||||
}
|
||||
// 更新状态显示(包含版本号)
|
||||
ookla_stat.style.color = 'green';
|
||||
dom.content(ookla_stat, [_(has_ookla ? 'Installed' + version_info : 'Not Installed')]);
|
||||
})
|
||||
.catch(function() {
|
||||
// 如果获取版本失败,仍显示基本状态
|
||||
ookla_stat.style.color = has_ookla ? 'green' : 'red';
|
||||
dom.content(ookla_stat, [_(has_ookla ? 'Installed' : 'Not Installed')]);
|
||||
});
|
||||
} else {
|
||||
// 未安装时的显示保持不变
|
||||
ookla_stat.style.color = 'red';
|
||||
dom.content(ookla_stat, [_('Not Installed')]);
|
||||
}
|
||||
if (result_content.length) {
|
||||
if (result_content[0] == 'Testing') {
|
||||
result_stat.innerHTML = "<span style='color:green;font-weight:bold'>" +
|
||||
"<img src='/luci-static/resources/icons/loading.gif' height='17' style='vertical-align:middle ;margin-left:20px'/> " +
|
||||
_('SpeedTesting in progress...') +
|
||||
"</span>";
|
||||
} else if (result_content[0].match(/https?:\S+/)) {
|
||||
result_stat.innerHTML = "<div style='max-width:500px'><a href='" +
|
||||
result_content[0] + "' target='_blank'><img src='" +
|
||||
result_content[0] + '.png' + "' style='max-width:100%;margin-left:20px'></a></div>";
|
||||
} else if (result_content[0] == 'Test failed') {
|
||||
result_stat.innerHTML = "<span style='color:red;font-weight:bold;margin-left:20px'>" +
|
||||
_('Test failed.') + "</span>";
|
||||
}
|
||||
},
|
||||
} else {
|
||||
result_stat.innerHTML = "<span style='color:gray;margin-left:20px'>" +
|
||||
_('No test results yet.') + "</span>";
|
||||
}
|
||||
},
|
||||
|
||||
render: function (res) {
|
||||
render(res) {
|
||||
var has_ookla = res[0].path,
|
||||
result_content = res[1] ? res[1].trim().split("\n") : [],
|
||||
result_mtime = res[2] ? res[2].mtime * 1000 : 0,
|
||||
date = new Date();
|
||||
|
||||
var m, s, o;
|
||||
m = new form.Map('netspeedtest', _('WAN Ookla SpeedTest'));
|
||||
m = new form.Map('netspeedtest', _('Wan Ookla SpeedTest'));
|
||||
|
||||
// Result display section
|
||||
s = m.section(form.TypedSection, '_result');
|
||||
s.anonymous = true;
|
||||
s.render = function () {
|
||||
var content;
|
||||
if (result_content.length) {
|
||||
if (result_content[0] == 'Testing') {
|
||||
content = E('span', { style: 'color:green;font-weight:bold' }, [
|
||||
E('img', { src: '/luci-static/resources/icons/loading.gif', height: '20' }),
|
||||
' ', _('Testing in progress...')
|
||||
]);
|
||||
} else if (result_content[0].match(/https?:\S+/)) {
|
||||
content = E('div', { style: 'max-width:500px' }, [
|
||||
E('a', { href: result_content[0], target: '_blank' }, [
|
||||
E('img', { src: result_content[0] + '.png', style: 'max-width:100%' })
|
||||
])
|
||||
]);
|
||||
} else {
|
||||
content = E('span', { style: 'color:red;font-weight:bold' },
|
||||
_('Test failed.'));
|
||||
}
|
||||
} else {
|
||||
content = E('span', { style: 'color:gray' },
|
||||
_('No test results yet.'));
|
||||
}
|
||||
return E('div', { id: 'speedtest_result' }, content);
|
||||
};
|
||||
s.render = function (section_id) {
|
||||
if (result_content.length) {
|
||||
if (result_content[0] == 'Testing') {
|
||||
return E('div', { 'id': 'speedtest_result' }, [ E('span', { 'style': 'color:yellow;font-weight:bold' }, [
|
||||
E('img', { 'src': L.resource(['icons/loading.gif']), 'height': '20', 'style': 'vertical-align:middle' }, []),
|
||||
_('Testing in progress...')
|
||||
]) ])
|
||||
};
|
||||
if (result_content[0].match(/https?:\S+/)) {
|
||||
return E('div', { 'id': 'speedtest_result' }, [ E('div', { 'style': 'max-width:500px' }, [
|
||||
E('a', { 'href': result_content[0], 'target': '_blank' }, [
|
||||
E('img', { 'src': result_content[0] + '.png', 'style': 'max-width:100%;max-height:100%;vertical-align:middle' }, [])
|
||||
]) ]) ])
|
||||
};
|
||||
if (result_content[0] == 'Test failed') {
|
||||
return E('div', { 'id': 'speedtest_result' }, [ E('span', { 'style': 'color:red;font-weight:bold' }, [ _('Test failed.') ]) ])
|
||||
}
|
||||
} else {
|
||||
return E('div', { 'id': 'speedtest_result' }, [ E('span', { 'style': 'color:red;font-weight:bold;display:none' }, [ _('No result.') ]) ])
|
||||
}
|
||||
};
|
||||
|
||||
// Configuration section
|
||||
s = m.section(form.NamedSection, 'config', 'netspeedtest');
|
||||
s.anonymous = true;
|
||||
|
||||
// Start test button
|
||||
o = s.option(form.Button, '_start', _('Start Ookla SpeedTest'));
|
||||
|
|
|
@ -17,7 +17,7 @@ msgid "NetSpeedtest"
|
|||
msgstr "网速测试"
|
||||
|
||||
msgid "A tool for testing network speed in multiple aspects"
|
||||
msgstr "一个用于从多方面测试本地和宽带网络速度的工具"
|
||||
msgstr "一个用于从多方面测试本地和宽带网络速度的测速工具"
|
||||
|
||||
msgid "Lan Speedtest Iperf3"
|
||||
msgstr "本地iperf3吞吐测速"
|
||||
|
@ -26,7 +26,7 @@ msgid "Lan Speedtest Homebox"
|
|||
msgstr "本地homebox网页测速"
|
||||
|
||||
msgid "Wan Ookla SpeedTest"
|
||||
msgstr "宽带Ookla网速测速"
|
||||
msgstr "宽带Ookla网速测试"
|
||||
|
||||
msgid "Wan OpenSpeedTest"
|
||||
msgstr "宽带OpenSpeedTest测速"
|
||||
|
@ -79,8 +79,8 @@ msgstr "开启日志显示"
|
|||
msgid "Download iperf3 client"
|
||||
msgstr "下载iperf3客户端"
|
||||
|
||||
msgid "Iperf3 Run Log"
|
||||
msgstr "Iperf3运行日志"
|
||||
msgid "Run Log"
|
||||
msgstr "运行日志"
|
||||
|
||||
msgid "Refresh Log"
|
||||
msgstr "刷新日志"
|
||||
|
@ -109,8 +109,8 @@ msgstr "开始宽带测速"
|
|||
msgid "Click to execute"
|
||||
msgstr "点击执行"
|
||||
|
||||
msgid "Testing in progress..."
|
||||
msgstr "测试正在进行中..."
|
||||
msgid "SpeedTesting in progress..."
|
||||
msgstr "测速中,请稍候..."
|
||||
|
||||
msgid "Test failed."
|
||||
msgstr "测速失败"
|
||||
|
|
|
@ -6,67 +6,72 @@
|
|||
START=99
|
||||
USE_PROCD=1
|
||||
|
||||
EXTRA_COMMANDS="download_ookla ookla_verify"
|
||||
EXTRA_COMMANDS="download verify"
|
||||
EXTRA_HELP=\
|
||||
" download_ookla Download Ookla Speedtest-CLI
|
||||
ookla_verify Verify Ookla Speedtest-CLI integrity"
|
||||
" download Download Ookla Speedtest-CLI
|
||||
verify Verify Ookla Speedtest-CLI integrity"
|
||||
|
||||
#
|
||||
OOKLA_SPEEDTEST='/usr/bin/speedtest'
|
||||
# uci
|
||||
CONFIG='netspeedtest'
|
||||
NAMEDDSECTION='config'
|
||||
log='/tmp/netspeedtest.log'
|
||||
|
||||
get_config() {
|
||||
config_load netspeedtest
|
||||
config_get "proxy_enabled" "config" "proxy_enabled" "0"
|
||||
download() {
|
||||
. /etc/openwrt_release
|
||||
local url arch=$1
|
||||
local proxy=$2
|
||||
[ -z "$arch" ] && arch=$DISTRIB_ARCH
|
||||
[ -z "$proxy" ] && proxy='0'
|
||||
|
||||
[ "$proxy" == "1" ] && export ALL_PROXY="http://192.168.10.8:1080"
|
||||
|
||||
UA='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36'
|
||||
url=$( \
|
||||
curl --connect-timeout 10 --retry 3 -sSL 'https://www.speedtest.net/apps/cli' \
|
||||
--user-agent "$UA" \
|
||||
| grep "Download for Linux" \
|
||||
| sed 's|<|\n<|g' \
|
||||
| sed -n '/Download for Linux/,/<\/div>/p' \
|
||||
| sed -En "s|.*<a href=\"([^\"]+)\">${arch}|\1|p" \
|
||||
)
|
||||
[ -z "$url" ] && { echo "Failed to get download URL" >> "$log"; return 1; }
|
||||
|
||||
# Backup existing file
|
||||
[ -f "$OOKLA_SPEEDTEST" ] && mv "$OOKLA_SPEEDTEST" "${OOKLA_SPEEDTEST}.bak"
|
||||
|
||||
if curl -sSL "$url" --user-agent "$UA" | tar -xvz -C /tmp; then
|
||||
mkdir -p "${OOKLA_SPEEDTEST%/*}" 2>/dev/null
|
||||
cp -f /tmp/speedtest "$OOKLA_SPEEDTEST"
|
||||
rm -rf /tmp/speedtest
|
||||
chmod 755 "$OOKLA_SPEEDTEST"
|
||||
|
||||
if verify; then
|
||||
echo "Download successful: $($OOKLA_SPEEDTEST --version | awk '/Speedtest/{print $1" ver:"$4}')" >> "$log"
|
||||
else
|
||||
echo "Download failed: binary verification failed" >> "$log"
|
||||
[ -f "${OOKLA_SPEEDTEST}.bak" ] && mv "${OOKLA_SPEEDTEST}.bak" "$OOKLA_SPEEDTEST"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
echo "Download failed: could not retrieve package" >> "$log"
|
||||
[ -f "${OOKLA_SPEEDTEST}.bak" ] && mv "${OOKLA_SPEEDTEST}.bak" "$OOKLA_SPEEDTEST"
|
||||
return 1
|
||||
fi
|
||||
|
||||
unset ALL_PROXY
|
||||
}
|
||||
|
||||
|
||||
download_ookla() {
|
||||
local url arch=$1
|
||||
[ -z "$arch" ] && return 1
|
||||
|
||||
[ "$(uci -q get $CONFIG.$NAMEDDSECTION.proxy_enabled)" == "1" ] && \
|
||||
export ALL_PROXY=$(uci -q get $CONFIG.$NAMEDDSECTION.proxy_protocol)://$(uci -q get $CONFIG.$NAMEDDSECTION.proxy_server)
|
||||
|
||||
UA='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36'
|
||||
url=$( \
|
||||
curl --connect-timeout 10 --retry 3 -sSL 'https://www.speedtest.net/apps/cli' \
|
||||
--user-agent "$UA" \
|
||||
| grep "Download for Linux" \
|
||||
| sed 's|<|\n<|g' \
|
||||
| sed -n '/Download for Linux/,/<\/div>/p' \
|
||||
| sed -En "s|.*<a href=\"([^\"]+)\">${arch}|\1|p" \
|
||||
)
|
||||
[ -z "$url" ] && return 1
|
||||
|
||||
[ -n "$url" ] && curl -sSL $url --user-agent "$UA" | tar -xvz -C /tmp
|
||||
mkdir -p ${OOKLA_SPEEDTEST%/*} 2>/dev/null
|
||||
cp -f /tmp/speedtest $OOKLA_SPEEDTEST
|
||||
chmod 755 $OOKLA_SPEEDTEST
|
||||
ookla_verify || rm -f $OOKLA_SPEEDTEST
|
||||
unset ALL_PROXY
|
||||
verify() {
|
||||
[ -x "$OOKLA_SPEEDTEST" ] && "$OOKLA_SPEEDTEST" --version >/dev/null 2>&1
|
||||
}
|
||||
|
||||
ookla_verify() {
|
||||
if [ -x "$OOKLA_SPEEDTEST" ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
start() {
|
||||
if ! verify; then
|
||||
download || {
|
||||
echo "Critical: Failed to install Speedtest CLI" >> "$log"
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
}
|
||||
|
||||
start_service() {
|
||||
ookla_verify
|
||||
|
||||
}
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "netspeedtest"
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
sleep 1
|
||||
start
|
||||
restart() {
|
||||
start
|
||||
}
|
||||
|
|
|
@ -3,35 +3,54 @@ mkdir -p /etc/speedtest
|
|||
export HOME='/etc/speedtest'
|
||||
SPEEDTEST_CLI='/usr/bin/speedtest'
|
||||
SPEEDTEST_RESULT='/tmp/speedtest_result'
|
||||
LOG='/tmp/netspeedtest.log'
|
||||
|
||||
# 记录开始时间
|
||||
echo "=== Speedtest started at $(date) ===" >> "$LOG"
|
||||
|
||||
[ -n "$(pgrep -f "$SPEEDTEST_CLI")" ] && exit 1
|
||||
|
||||
echo "Start Testing" > "$SPEEDTEST_RESULT"
|
||||
LOCAL_IP=$(curl -s -4 --connect-timeout 3 http://ip.3322.net)
|
||||
echo "Local IP: $LOCAL_IP" >> "$LOG"
|
||||
|
||||
BAIDU_SK="LHHGlmhcb4ENvIXpR9QQ2tBYa6ooUowX hYCENCEx1nXO0Nt46ldexfG9oI49xBGh 0kKZnWWhXEPfzIkklmzAa3dZ"
|
||||
if [ -n "$LOCAL_IP" ]; then
|
||||
for SK in $BAIDU_SK
|
||||
do
|
||||
INFO=$(curl -sk --connect-timeout 3 "https://api.map.baidu.com/location/ip?ip="$LOCAL_IP"&coor=bd09ll&ak=$SK")
|
||||
if [ "$(echo $INFO | jsonfilter -e "@['status']")" = 0 ]; then
|
||||
status=0
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "$status" = 0 ]; then
|
||||
lon=$(echo $INFO | jsonfilter -e "@['content']['point']['x']")
|
||||
lat=$(echo $INFO | jsonfilter -e "@['content']['point']['y']")
|
||||
server_id=$(curl -sk --connect-timeout 3 "https://www.speedtest.net/api/ios-config.php?lon=$lon&lat=$lat" | grep "server url" | head -n1 | sed 's/.*id="//;s/".*//')
|
||||
[ -n "$server_id" ] && ARG="-s $server_id"
|
||||
fi
|
||||
for SK in $BAIDU_SK
|
||||
do
|
||||
INFO=$(curl -sk --connect-timeout 3 "https://api.map.baidu.com/location/ip?ip="$LOCAL_IP"&coor=bd09ll&ak=$SK")
|
||||
if [ "$(echo $INFO | jsonfilter -e "@['status']")" = 0 ]; then
|
||||
status=0
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "$status" = 0 ]; then
|
||||
lon=$(echo $INFO | jsonfilter -e "@['content']['point']['x']")
|
||||
lat=$(echo $INFO | jsonfilter -e "@['content']['point']['y']")
|
||||
server_id=$(curl -sk --connect-timeout 3 "https://www.speedtest.net/api/ios-config.php?lon=$lon&lat=$lat" | grep "server url" | head -n1 | sed 's/.*id="//;s/".*//')
|
||||
[ -n "$server_id" ] && ARG="-s $server_id"
|
||||
echo "Selected server ID: $server_id" >> "$LOG"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Testing" > "$SPEEDTEST_RESULT"
|
||||
RUNTEST=$($SPEEDTEST_CLI --accept-gdpr --accept-license --progress=no $ARG 2>&1)
|
||||
if [ $(echo $RUNTEST | grep -c "No servers defined") -ge 1 ] || [ $(echo $RUNTEST | grep -c "error") -ge 1 ]; then
|
||||
RUNTEST=$($SPEEDTEST_CLI --accept-gdpr --accept-license --progress=no 2>&1)
|
||||
echo "Fallback to default server selection" >> "$LOG"
|
||||
RUNTEST=$($SPEEDTEST_CLI --accept-gdpr --accept-license --progress=no 2>&1)
|
||||
fi
|
||||
|
||||
# 将完整测试结果记录到日志
|
||||
echo "$RUNTEST" >> "$LOG"
|
||||
|
||||
RESULT=$(echo "$RUNTEST" | grep "Result URL" | awk '{print $NF}')
|
||||
|
||||
[ -n "$RESULT" ] && echo "$RESULT" > "$SPEEDTEST_RESULT" || echo "Test failed" > "$SPEEDTEST_RESULT"
|
||||
if [ -n "$RESULT" ]; then
|
||||
echo "$RESULT" > "$SPEEDTEST_RESULT"
|
||||
else
|
||||
echo "Test failed" > "$SPEEDTEST_RESULT"
|
||||
echo "Test failed" >> "$LOG"
|
||||
fi
|
||||
|
||||
# 记录结束时间
|
||||
echo "=== Speedtest completed at $(date) ===" >> "$LOG"
|
||||
echo "" >> "$LOG" # 添加空行分隔不同测试记录
|
||||
|
|
|
@ -41,5 +41,13 @@
|
|||
"type": "view",
|
||||
"path": "netspeedtest/openspeedtest"
|
||||
}
|
||||
},
|
||||
"admin/network/netspeedtest/logs": {
|
||||
"title": "Log",
|
||||
"order": 6,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "netspeedtest/logs"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,15 +5,16 @@
|
|||
"file": {
|
||||
"/etc/init.d/netspeedtest": [ "exec" ],
|
||||
"/usr/lib/netspeedtest/speedtest": [ "exec" ],
|
||||
"/tmp/speedtest_result": [ "read" ]
|
||||
"/tmp/speedtest_result": [ "read" ],
|
||||
"/tmp/netspeedtest.log": [ "read" ]
|
||||
},
|
||||
"ubus": {
|
||||
"service": [ "list" ]
|
||||
},
|
||||
"uci": [ "netspeedtest" ]
|
||||
"uci": [ "netspeedtest" ,"netspeedtest"]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "netspeedtest" ]
|
||||
"uci": [ "netspeedtest","netspeedtest" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue