Skip to content

Commit 746578f

Browse files
authored
up luci-app-netspeedtest v5.0.2
1 parent d5b3957 commit 746578f

File tree

11 files changed

+253
-188
lines changed

11 files changed

+253
-188
lines changed

luci-app-netspeedtest/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ include $(TOPDIR)/rules.mk
99

1010
PKG_NAME:=luci-app-netspeedtest
1111

12-
PKG_VERSION:=5.0.1
13-
PKG_RELEASE:=20250512
12+
PKG_VERSION:=5.0.2
13+
PKG_RELEASE:=20250513
1414

1515
LUCI_TITLE:=LuCI Support for netspeedtest
1616
LUCI_DEPENDS:=+speedtest-cli +homebox +iperf3-ssl

luci-app-netspeedtest/htdocs/luci-static/resources/view/netspeedtest/homebox.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ return view.extend({
3030

3131
var iframe = E('iframe', {
3232
src: window.location.origin + ':' + state.port,
33-
style: 'width: 100%; min-height: 80vh; border: none; border-radius: 3px;'
33+
style: 'border:none;width: 100%; min-height: 80vh; border: none; border-radius: 3px;overflow:hidden !important;'
3434
});
3535

3636
function checkProcess() {
@@ -42,7 +42,7 @@ return view.extend({
4242

4343
function controlService(action) {
4444
var command = action === 'start'
45-
? 'nohup /usr/bin/homebox > /tmp/homebox.log 2>&1 &'
45+
? 'nohup /usr/bin/homebox > /tmp/netspeedtest.log 2>&1 &'
4646
: '/usr/bin/killall homebox';
4747
return fs.exec('/bin/sh', ['-c', command]);
4848
}

luci-app-netspeedtest/htdocs/luci-static/resources/view/netspeedtest/iperf3.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ var state = {
1212
port: null
1313
};
1414

15-
const logPath = '/var/log/iperf3.log';
15+
const logPath = '/tmp/netspeedtest.log';
1616

1717
function checkProcess() {
1818
return fs.exec('/bin/pidof', ['iperf3']).then(res => ({
@@ -172,7 +172,7 @@ const statusSection = E('div', { 'class': 'cbi-section' }, [
172172
return E('div', [
173173
statusSection,
174174
E('div', { 'class': 'cbi-section' }, [
175-
E('h3', {}, _('Iperf3 Run Log')),
175+
E('h3', {}, _('Run Log')),
176176
logTextarea,
177177
E('div', { 'style': 'text-align: right; font-size: small; margin-top: 5px;' },
178178
_('Refresh every 5 seconds.')
Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* Copyright (C) 2021-2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-netspeedtest */
12
'use strict';
23
'require dom';
34
'require fs';
@@ -11,76 +12,87 @@ var logTextarea;
1112
var log_path;
1213

1314
uci.load('netspeedtest').then(function() {
14-
log_path = '/var/log/netspeedtest.log';
15+
log_path = '/tmp/netspeedtest.log';
1516
});
1617

1718
function pollLog() {
18-
return Promise.all([
19-
fs.read_direct(log_path, 'text').then(function (res) {
20-
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, '');
21-
}),
22-
]).then(function (data) {
23-
logTextarea.value = data[0] || _('No log data.');
19+
return Promise.all([
20+
fs.read_direct(log_path, 'text').then(function(res) {
21+
return res.trim()
22+
.split(/\n/).join('\n')
23+
.replace(/\u001b\[33mWARN\u001b\[0m/g, '')
24+
.replace(/\u001b\[36mINFO\u001b\[0m/g, '')
25+
.replace(/\u001b\[31mERRO\u001b\[0m/g, '');
26+
}),
27+
]).then(function(data) {
28+
logTextarea.value = data[0] || _('No log data.');
2429

25-
if (!userScrolled) {
26-
logTextarea.scrollTop = logTextarea.scrollHeight;
27-
} else {
28-
logTextarea.scrollTop = scrollPosition;
29-
}
30-
});
31-
};
30+
if (!userScrolled) {
31+
logTextarea.scrollTop = logTextarea.scrollHeight;
32+
} else {
33+
logTextarea.scrollTop = scrollPosition;
34+
}
35+
});
36+
}
3237

3338
return view.extend({
34-
handleCleanLogs: function () {
35-
return fs.write(log_path, '')
36-
.catch(function (e) { ui.addNotification(null, E('p', e.message)) });
37-
},
39+
handleCleanLogs: function() {
40+
return fs.write(log_path, '')
41+
.catch(function(e) {
42+
ui.addNotification(null, E('p', e.message))
43+
});
44+
},
3845

39-
render: function () {
40-
logTextarea = E('textarea', {
41-
'class': 'cbi-input-textarea',
42-
'wrap': 'off',
43-
'readonly': 'readonly',
44-
'style': 'width: calc(100% - 20px);height: 535px;margin: 10px;overflow-y: scroll;',
45-
});
46+
render: function() {
47+
logTextarea = E('textarea', {
48+
'class': 'cbi-input-textarea',
49+
'wrap': 'off',
50+
'readonly': 'readonly',
51+
'style': 'width: calc(100% - 20px); height: 535px; margin: 10px; overflow-y: scroll;'
52+
});
4653

47-
logTextarea.addEventListener('scroll', function () {
48-
userScrolled = true;
49-
scrollPosition = logTextarea.scrollTop;
50-
});
54+
logTextarea.addEventListener('scroll', function() {
55+
userScrolled = true;
56+
scrollPosition = logTextarea.scrollTop;
57+
});
5158

52-
var log_textarea_wrapper = E('div', { 'id': 'log_textarea' }, logTextarea);
59+
var log_textarea_wrapper = E('div', { 'id': 'log_textarea' }, logTextarea);
5360

54-
setTimeout(function () {
55-
poll.add(pollLog);
56-
}, 100);
61+
setTimeout(function() {
62+
poll.add(pollLog);
63+
}, 100);
5764

58-
var clear_logs_button = E('input', { 'class': 'btn cbi-button-action', 'type': 'button', 'style': 'margin-left: 10px; margin-top: 10px;', 'value': _('Clear logs') });
59-
clear_logs_button.addEventListener('click', this.handleCleanLogs.bind(this));
65+
var clear_logs_button = E('input', {
66+
'class': 'btn cbi-button-action',
67+
'type': 'button',
68+
'style': 'margin-left: 20px; margin-top: 10px;',
69+
'value': _('Clear logs')
70+
});
71+
clear_logs_button.addEventListener('click', this.handleCleanLogs.bind(this));
6072

61-
return E([
62-
E('div', { 'class': 'cbi-map' }, [
63-
E('div', { 'class': 'cbi-section' }, [
64-
clear_logs_button,
65-
log_textarea_wrapper,
66-
E('div', { 'style': 'text-align:right' },
67-
E('small', {}, _('Refresh every %s seconds.').format(L.env.pollinterval)),
68-
E('div', { 'class': 'cbi-section-actions cbi-section-actions-right' })
69-
]),
70-
E('div', { 'style': 'text-align: right; font-style: italic;' }, [
73+
return E('div', { 'class': 'cbi-map' }, [
74+
E('div', { 'class': 'cbi-section' }, [
75+
clear_logs_button,
76+
log_textarea_wrapper,
77+
E('div', { 'style': 'text-align: right' }, [
78+
E('small', {}, _('Refresh every %s seconds.').format(L.env.pollinterval))
79+
]),
80+
E('div', { 'class': 'cbi-section-actions cbi-section-actions-right' })
81+
]),
82+
E('div', { 'style': 'text-align: right; font-style: italic; margin-top: 10px;' }, [
7183
E('span', {}, [
7284
_('© github '),
73-
E('a', {
74-
'href': 'https://github.com/sirpdboy',
85+
E('a', {
86+
'href': 'https://github.com/sirpdboy',
7587
'target': '_blank',
7688
'style': 'text-decoration: none;'
7789
}, 'by sirpdboy')
78-
])
79-
])
80-
]);
81-
}
90+
])
91+
])
92+
]);
93+
}
8294

8395
// handleSaveApply: null,
84-
// handleSave: null,
96+
// handleSave: null,
8597
// handleReset: null
86-
});
98+
});

luci-app-netspeedtest/htdocs/luci-static/resources/view/netspeedtest/openspeedtest.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* Copyright (C) 2021-2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-netspeedtest */
12
'use strict';
23
'require view';
34
'require uci';
@@ -22,7 +23,7 @@ return view.extend({
2223
s.render = function (section_id) {
2324
return E('iframe', {
2425
src: '//openspeedtest.com/speedtest',
25-
style: 'border:none;width:100%;height:100%;min-height:360px;border:none;overflow:hidden !important;'
26+
style: 'width:100%;height:100%;min-height:360px;border:none;overflow:hidden !important;'
2627
});
2728
};
2829

luci-app-netspeedtest/htdocs/luci-static/resources/view/netspeedtest/speedtest.js

Lines changed: 72 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* Copyright (C) 2021-2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-netspeedtest */
12
'use strict';
23
'require view';
34
'require poll';
@@ -17,7 +18,7 @@ return view.extend({
1718
// handleSaveApply: null,
1819
// handleSave: null,
1920
// handleReset: null,
20-
load: function () {
21+
load() {
2122
return Promise.all([
2223
L.resolveDefault(fs.stat(SpeedtestCli), {}),
2324
L.resolveDefault(fs.read(ResultFile), null),
@@ -26,76 +27,94 @@ return view.extend({
2627
]);
2728
},
2829

29-
poll_status: function (nodes, res) {
30-
var has_ookla = res[0].path,
30+
poll_status(nodes, res) {
31+
var has_ookla = res[0].path,
3132
result_content = res[1] ? res[1].trim().split("\n") : [];
32-
var ookla_stat = nodes.querySelector('#ookla_status'),
33+
var ookla_stat = nodes.querySelector('#ookla_status'),
3334
result_stat = nodes.querySelector('#speedtest_result');
3435

35-
// Update status indicators
36-
ookla_stat.style.color = has_ookla ? 'green' : 'red';
37-
dom.content(ookla_stat, [_(has_ookla ? 'Installed' : 'Not Installed')]);
38-
39-
// Update result display
40-
if (result_content.length) {
41-
if (result_content[0] == 'Testing') {
42-
result_stat.innerHTML = "<span style='color:green;font-weight:bold'>" +
43-
"<img src='/luci-static/resources/icons/loading.gif' height='17' style='vertical-align:middle'/> " +
44-
_('Testing in progress...') +
45-
"</span>";
46-
} else if (result_content[0].match(/https?:\S+/)) {
47-
result_stat.innerHTML = "<div style='max-width:500px'><a href='" +
48-
result_content[0] + "' target='_blank'><img src='" +
49-
result_content[0] + '.png' + "' style='max-width:100%'></a></div>";
50-
} else if (result_content[0] == 'Test failed') {
51-
result_stat.innerHTML = "<span style='color:red;font-weight:bold'>" +
52-
_('Test failed.') + "</span>";
53-
}
54-
} else {
55-
result_stat.innerHTML = "<span style='color:gray'>" +
56-
_('No test results yet.') + "</span>";
36+
// 获取版本号(新增部分)
37+
var version_info = '';
38+
if (has_ookla) {
39+
fs.exec_direct('/usr/bin/speedtest', ['--version'])
40+
.then(function(res) {
41+
if (res.stdout) {
42+
var version_match = res.stdout.match(/Speedtest (\d+\.\d+\.\d+)/);
43+
if (version_match) {
44+
version_info = ' ver:' + version_match[1];
45+
}
46+
}
47+
// 更新状态显示(包含版本号)
48+
ookla_stat.style.color = 'green';
49+
dom.content(ookla_stat, [_(has_ookla ? 'Installed' + version_info : 'Not Installed')]);
50+
})
51+
.catch(function() {
52+
// 如果获取版本失败,仍显示基本状态
53+
ookla_stat.style.color = has_ookla ? 'green' : 'red';
54+
dom.content(ookla_stat, [_(has_ookla ? 'Installed' : 'Not Installed')]);
55+
});
56+
} else {
57+
// 未安装时的显示保持不变
58+
ookla_stat.style.color = 'red';
59+
dom.content(ookla_stat, [_('Not Installed')]);
60+
}
61+
if (result_content.length) {
62+
if (result_content[0] == 'Testing') {
63+
result_stat.innerHTML = "<span style='color:green;font-weight:bold'>" +
64+
"<img src='/luci-static/resources/icons/loading.gif' height='17' style='vertical-align:middle ;margin-left:20px'/> " +
65+
_('SpeedTesting in progress...') +
66+
"</span>";
67+
} else if (result_content[0].match(/https?:\S+/)) {
68+
result_stat.innerHTML = "<div style='max-width:500px'><a href='" +
69+
result_content[0] + "' target='_blank'><img src='" +
70+
result_content[0] + '.png' + "' style='max-width:100%;margin-left:20px'></a></div>";
71+
} else if (result_content[0] == 'Test failed') {
72+
result_stat.innerHTML = "<span style='color:red;font-weight:bold;margin-left:20px'>" +
73+
_('Test failed.') + "</span>";
5774
}
58-
},
75+
} else {
76+
result_stat.innerHTML = "<span style='color:gray;margin-left:20px'>" +
77+
_('No test results yet.') + "</span>";
78+
}
79+
},
5980

60-
render: function (res) {
81+
render(res) {
6182
var has_ookla = res[0].path,
6283
result_content = res[1] ? res[1].trim().split("\n") : [],
6384
result_mtime = res[2] ? res[2].mtime * 1000 : 0,
6485
date = new Date();
6586

6687
var m, s, o;
67-
m = new form.Map('netspeedtest', _('WAN Ookla SpeedTest'));
88+
m = new form.Map('netspeedtest', _('Wan Ookla SpeedTest'));
6889

6990
// Result display section
7091
s = m.section(form.TypedSection, '_result');
7192
s.anonymous = true;
72-
s.render = function () {
73-
var content;
74-
if (result_content.length) {
75-
if (result_content[0] == 'Testing') {
76-
content = E('span', { style: 'color:green;font-weight:bold' }, [
77-
E('img', { src: '/luci-static/resources/icons/loading.gif', height: '20' }),
78-
' ', _('Testing in progress...')
79-
]);
80-
} else if (result_content[0].match(/https?:\S+/)) {
81-
content = E('div', { style: 'max-width:500px' }, [
82-
E('a', { href: result_content[0], target: '_blank' }, [
83-
E('img', { src: result_content[0] + '.png', style: 'max-width:100%' })
84-
])
85-
]);
86-
} else {
87-
content = E('span', { style: 'color:red;font-weight:bold' },
88-
_('Test failed.'));
89-
}
90-
} else {
91-
content = E('span', { style: 'color:gray' },
92-
_('No test results yet.'));
93-
}
94-
return E('div', { id: 'speedtest_result' }, content);
95-
};
93+
s.render = function (section_id) {
94+
if (result_content.length) {
95+
if (result_content[0] == 'Testing') {
96+
return E('div', { 'id': 'speedtest_result' }, [ E('span', { 'style': 'color:yellow;font-weight:bold' }, [
97+
E('img', { 'src': L.resource(['icons/loading.gif']), 'height': '20', 'style': 'vertical-align:middle' }, []),
98+
_('Testing in progress...')
99+
]) ])
100+
};
101+
if (result_content[0].match(/https?:\S+/)) {
102+
return E('div', { 'id': 'speedtest_result' }, [ E('div', { 'style': 'max-width:500px' }, [
103+
E('a', { 'href': result_content[0], 'target': '_blank' }, [
104+
E('img', { 'src': result_content[0] + '.png', 'style': 'max-width:100%;max-height:100%;vertical-align:middle' }, [])
105+
]) ]) ])
106+
};
107+
if (result_content[0] == 'Test failed') {
108+
return E('div', { 'id': 'speedtest_result' }, [ E('span', { 'style': 'color:red;font-weight:bold' }, [ _('Test failed.') ]) ])
109+
}
110+
} else {
111+
return E('div', { 'id': 'speedtest_result' }, [ E('span', { 'style': 'color:red;font-weight:bold;display:none' }, [ _('No result.') ]) ])
112+
}
113+
};
96114

97115
// Configuration section
98116
s = m.section(form.NamedSection, 'config', 'netspeedtest');
117+
s.anonymous = true;
99118

100119
// Start test button
101120
o = s.option(form.Button, '_start', _('Start Ookla SpeedTest'));

0 commit comments

Comments
 (0)