Skip to content

Commit cbb5e1a

Browse files
committed
Bump version to 0.11, enhance fleth.js for pending status handling, and add IPv6 SLAAC/PD setup functionality
1 parent 120e17e commit cbb5e1a

File tree

6 files changed

+425
-68
lines changed

6 files changed

+425
-68
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ include $(TOPDIR)/rules.mk
33
PKG_NAME:=luci-app-fleth
44
LUCI_TITLE:=LuCI Support for Flet'h
55
LUCI_DESCRIPTION:=luci-app-fleth is a helper that can configure IPv4 over IPv6 tunnel automatically in Japan.
6-
PKG_VERSION:=0.10
6+
PKG_VERSION:=0.11
77
PKG_RELEASE:=1
88

99
LUCI_PKGARCH:=all

htdocs/luci-static/resources/view/fleth.js

Lines changed: 172 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"require fs";
44
"require uci";
55
"require form";
6+
"require ui";
67
"require tools.widgets as widgets";
78

89
// fix css paading (kusa
@@ -19,9 +20,40 @@ return view.extend({
1920
const area = (results[0].stdout || "").trim();
2021
const mape_status = (results[1].stdout || "").split("\n");
2122

22-
const areaValue = area || "UNKNOWN";
23+
let areaValue = area || "UNKNOWN";
2324
const mapeIsUnknown = mape_status.length <= 1 || mape_status[0] === "UNKNOWN";
2425

26+
// Special handling for NURO
27+
if (mape_status[0] === "NURO") {
28+
areaValue = "UNKNOWN(NURO)";
29+
}
30+
31+
// Check for pending status if everything is UNKNOWN
32+
if (areaValue === "UNKNOWN" && mapeIsUnknown) {
33+
return L.resolveDefault(fs.exec("/usr/sbin/fleth", ["get_pending_status"]), { stdout: "" })
34+
.then(function (pendingResult) {
35+
const pendingStatus = (pendingResult.stdout || "").trim();
36+
37+
if (pendingStatus.endsWith("_pending")) {
38+
const detectedArea = pendingStatus.split('_')[0];
39+
return {
40+
area: detectedArea,
41+
dslite_provider: "UNKNOWN",
42+
mape_status: mape_status,
43+
isPending: true,
44+
};
45+
}
46+
47+
// No pending status, return all UNKNOWN
48+
return {
49+
area: areaValue,
50+
dslite_provider: "UNKNOWN",
51+
mape_status: mape_status,
52+
isPending: false,
53+
};
54+
});
55+
}
56+
2557
// Only get DS-Lite if area is not UNKNOWN and MAP-E is UNKNOWN
2658
if (areaValue !== "UNKNOWN" && mapeIsUnknown) {
2759
return L.resolveDefault(fs.exec("/usr/sbin/fleth", ["get_dslite_provider"]), { stdout: "" })
@@ -31,20 +63,30 @@ return view.extend({
3163
area: areaValue,
3264
dslite_provider: dslite_provider || "UNKNOWN",
3365
mape_status: mape_status,
66+
isPending: false,
3467
};
3568
});
3669
} else {
3770
return {
3871
area: areaValue,
3972
dslite_provider: "UNKNOWN",
4073
mape_status: mape_status,
74+
isPending: false,
4175
};
4276
}
4377
});
4478
},
4579

4680
render: async function (data) {
4781
let m, s, o;
82+
83+
// Show pending construction popup if detected
84+
if (data.isPending) {
85+
ui.addNotification(_('Service Status'), E('div', [
86+
E('p', _('Optical line construction completed, provider configuration in progress. Please wait patiently.')),
87+
E('p', { style: 'color: #666; font-size: 0.9em;' }, _('Service typically becomes available in the evening after construction is completed.'))
88+
]), 'info');
89+
}
4890

4991
m = new form.Map(
5092
"fleth",
@@ -73,44 +115,38 @@ return view.extend({
73115
return data.dslite_provider;
74116
};
75117

76-
// Create all MAP-E fields
77-
const mapeFields = [
78-
["mape_provider", "MAP-E Provider"],
79-
["mape_ipaddr", "IP Address"],
80-
["mape_peeraddr", "Peer Address"],
81-
["mape_ip4prefix", "IPv4 prefix"],
82-
["mape_ip4prefixlen", "IPv4 Prefix Length"],
83-
["mape_ip6prefix", "IPv6 Prefix"],
84-
["mape_ip6prefixlen", "IPv6 Prefix Length"],
85-
["mape_ealen", "EA Length"],
86-
["mape_psidlen", "PSID Length"],
87-
["mape_offset", "Offset"],
88-
["mape_map_ports", "Available ports"],
89-
];
118+
// Check if MAP-E data is available
119+
const hasMapeData = data.mape_status[0] !== "UNKNOWN" && data.mape_status.length > 1;
90120

91-
// Check if we should hide MAP-E details initially
92-
const shouldHideMapeDetails = data.mape_status[0] === "UNKNOWN" ||
93-
data.mape_status.length <= 1;
121+
// Always show MAP-E Provider
122+
o = s.taboption("info", form.DummyValue, "mape_provider", _("MAP-E Provider"));
123+
o.cfgvalue = function () {
124+
return data.mape_status[0] || _("UNKNOWN");
125+
};
94126

95-
// Create all MAP-E fields
96-
mapeFields.forEach((field, i) => {
97-
const [fieldName, fieldLabel] = field;
98-
o = s.taboption("info", form.DummyValue, fieldName, _(fieldLabel));
99-
o.cfgvalue = function () {
100-
if (i === 0) { // MAP-E Provider field
101-
return data.mape_status[0] || _("UNKNOWN");
102-
}
103-
return data.mape_status[i] || "";
104-
};
105-
// Add a class to identify MAP-E detail fields for hiding
106-
if (i > 0 && shouldHideMapeDetails) {
107-
o.rmempty = false;
108-
o.editable = false;
109-
// We'll hide these with CSS after render
110-
o.modalonly = false;
111-
o.optional = true;
112-
}
113-
});
127+
// Only show detailed MAP-E fields if we have valid data
128+
if (hasMapeData) {
129+
const mapeDetailFields = [
130+
["mape_ipaddr", "IP Address"],
131+
["mape_peeraddr", "Peer Address"],
132+
["mape_ip4prefix", "IPv4 prefix"],
133+
["mape_ip4prefixlen", "IPv4 Prefix Length"],
134+
["mape_ip6prefix", "IPv6 Prefix"],
135+
["mape_ip6prefixlen", "IPv6 Prefix Length"],
136+
["mape_ealen", "EA Length"],
137+
["mape_psidlen", "PSID Length"],
138+
["mape_offset", "Offset"],
139+
["mape_map_ports", "Available ports"],
140+
];
141+
142+
mapeDetailFields.forEach((field, i) => {
143+
const [fieldName, fieldLabel] = field;
144+
o = s.taboption("info", form.DummyValue, fieldName, _(fieldLabel));
145+
o.cfgvalue = function () {
146+
return data.mape_status[i + 1] || "";
147+
};
148+
});
149+
}
114150

115151
// o = s.taboption('general', form.Button, '_hook_luci-firewall-port-forward');
116152
// o.title = '&#160;';
@@ -197,24 +233,106 @@ return view.extend({
197233
o.nocreate = true;
198234
o.default = "wan";
199235

200-
// Hide MAP-E detail fields initially if no valid data
201-
setTimeout(() => {
202-
if (data.mape_status[0] === "UNKNOWN" ||
203-
data.mape_status.length <= 1) {
204-
const mapeDetailFields = [
205-
"mape_ipaddr", "mape_peeraddr", "mape_ip4prefix", "mape_ip4prefixlen",
206-
"mape_ip6prefix", "mape_ip6prefixlen", "mape_ealen", "mape_psidlen",
207-
"mape_offset", "mape_map_ports"
208-
];
209-
mapeDetailFields.forEach(field => {
210-
const fieldContainer = document.querySelector(`[data-name="${field}"]`);
211-
if (fieldContainer) {
212-
fieldContainer.style.display = 'none';
213-
}
214-
});
215-
}
216-
}, 100);
236+
// Actions section in General Settings
237+
o = s.taboption("general", form.DummyValue, "_actions_description");
238+
o.title = _("Actions");
239+
o.description = _("Actions will automatically save current configuration before execution.");
240+
o.cfgvalue = function () {
241+
return "";
242+
};
243+
244+
o = s.taboption("general", form.Button, "_setup_ipv6_slaac");
245+
o.title = "&#160;";
246+
o.inputtitle = _("Setup IPv6 SLAAC for NEXT(1Gbps) and without Hikari Denwa");
247+
o.inputstyle = "apply";
248+
o.onclick = L.bind(function(m) {
249+
return this.setupIPv6SLAAC(m);
250+
}, this, m);
251+
252+
o = s.taboption("general", form.Button, "_setup_ipv6_pd");
253+
o.title = "&#160;";
254+
o.inputtitle = _("Setup IPv6 PD for Cross(10Gbps) or with Hikari Denwa");
255+
o.inputstyle = "apply";
256+
o.onclick = L.bind(function(m) {
257+
return this.setupIPv6PD(m);
258+
}, this, m);
217259

218260
return m.render();
219261
},
262+
263+
setupIPv6SLAAC: function(mapObj) {
264+
return new Promise(function(resolve, reject) {
265+
// First save current configuration
266+
mapObj.save()
267+
.then(function() {
268+
// Show loading message
269+
ui.showModal(_('Setting up IPv6 SLAAC'), [
270+
E('p', { 'class': 'spinning' }, _('Applying IPv6 SLAAC configuration for NEXT(1Gbps) without Hikari Denwa...'))
271+
]);
272+
273+
// Execute the IPv6 SLAAC setup
274+
return fs.exec('/usr/sbin/fleth', ['setup_ipv6_slaac']);
275+
})
276+
.then(function(result) {
277+
ui.hideModal();
278+
279+
if (result.code === 0 && result.stdout.trim() === 'SUCCESS') {
280+
ui.addNotification(null, E('p', _('IPv6 SLAAC configuration applied successfully!')), 'info');
281+
} else {
282+
ui.addNotification(null, E('div', [
283+
E('p', _('Failed to apply IPv6 SLAAC configuration:')),
284+
E('pre', result.stdout || result.stderr || 'Unknown error')
285+
]), 'error');
286+
}
287+
288+
resolve();
289+
})
290+
.catch(function(error) {
291+
ui.hideModal();
292+
ui.addNotification(null, E('div', [
293+
E('p', _('Error executing IPv6 SLAAC setup:')),
294+
E('pre', error.message || error)
295+
]), 'error');
296+
reject(error);
297+
});
298+
});
299+
},
300+
301+
setupIPv6PD: function(mapObj) {
302+
return new Promise(function(resolve, reject) {
303+
// First save current configuration
304+
mapObj.save()
305+
.then(function() {
306+
// Show loading message
307+
ui.showModal(_('Setting up IPv6 PD'), [
308+
E('p', { 'class': 'spinning' }, _('Applying IPv6 PD configuration for Cross(10Gbps) or with Hikari Denwa...'))
309+
]);
310+
311+
// Execute the IPv6 PD setup
312+
return fs.exec('/usr/sbin/fleth', ['setup_ipv6_pd']);
313+
})
314+
.then(function(result) {
315+
ui.hideModal();
316+
317+
if (result.code === 0 && result.stdout.trim() === 'SUCCESS') {
318+
ui.addNotification(null, E('p', _('IPv6 PD configuration applied successfully!')), 'info');
319+
} else {
320+
ui.addNotification(null, E('div', [
321+
E('p', _('Failed to apply IPv6 PD configuration:')),
322+
E('pre', result.stdout || result.stderr || 'Unknown error')
323+
]), 'error');
324+
}
325+
326+
resolve();
327+
})
328+
.catch(function(error) {
329+
ui.hideModal();
330+
ui.addNotification(null, E('div', [
331+
E('p', _('Error executing IPv6 PD setup:')),
332+
E('pre', error.message || error)
333+
]), 'error');
334+
reject(error);
335+
});
336+
});
337+
},
220338
});

po/ja/fleth.po

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,54 @@ msgstr "このポートにはMAP-Eインターフェースからアクセスで
102102

103103
msgid "(Service Pending)"
104104
msgstr "(回線プロバイダー開通待ち)"
105+
106+
msgid "Actions"
107+
msgstr "アクション"
108+
109+
msgid "Actions will automatically save current configuration before execution."
110+
msgstr "アクションは実行前に現在の設定を自動保存します。"
111+
112+
msgid "Setup IPv6 SLAAC for NEXT(1Gbps) and without Hikari Denwa"
113+
msgstr "NEXT(1Gbps)ひかり電話なし(SLAAC のみ)の IPv6 設定"
114+
115+
msgid "Setting up IPv6 SLAAC"
116+
msgstr "IPv6 SLAAC の設定中"
117+
118+
msgid "Applying IPv6 SLAAC configuration for NEXT(1Gbps) without Hikari Denwa..."
119+
msgstr "NEXT(1Gbps)ひかり電話なし(SLAAC のみ)の IPv6 設定を適用中..."
120+
121+
msgid "IPv6 SLAAC configuration applied successfully!"
122+
msgstr "IPv6 SLAAC 設定が正常に適用されました!"
123+
124+
msgid "Failed to apply IPv6 SLAAC configuration: %s"
125+
msgstr "IPv6 SLAAC 設定の適用に失敗しました:%s"
126+
127+
msgid "Error executing IPv6 SLAAC setup: %s"
128+
msgstr "IPv6 SLAAC 設定の実行中にエラーが発生しました:%s"
129+
130+
msgid "Setup IPv6 PD for Cross(10Gbps) or with Hikari Denwa"
131+
msgstr "クロス(10Gbps)ひかり電話あり(PD)の IPv6 設定"
132+
133+
msgid "Setting up IPv6 PD"
134+
msgstr "IPv6 PD の設定中"
135+
136+
msgid "Applying IPv6 PD configuration for Cross(10Gbps) or with Hikari Denwa..."
137+
msgstr "クロス(10Gbps)ひかり電話あり(PD)の IPv6 設定を適用中..."
138+
139+
msgid "IPv6 PD configuration applied successfully!"
140+
msgstr "IPv6 PD 設定が正常に適用されました!"
141+
142+
msgid "Failed to apply IPv6 PD configuration:"
143+
msgstr "IPv6 PD 設定の適用に失敗しました:"
144+
145+
msgid "Error executing IPv6 PD setup:"
146+
msgstr "IPv6 PD 設定の実行中にエラーが発生しました:"
147+
148+
msgid "Service Status"
149+
msgstr "サービス状況"
150+
151+
msgid "Optical line construction completed, provider configuration in progress. Please wait patiently."
152+
msgstr "現在光回線プロバイダー工事中です。しばらくお待ちください。"
153+
154+
msgid "Service typically becomes available in the evening after construction is completed."
155+
msgstr "工事完了後は通常夕方頃にサービスが開通いたします。"

po/zh_Hans/fleth.po

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,54 @@ msgstr "您无法从 MAP-E 接口访问该端口"
102102

103103
msgid "(Service Pending)"
104104
msgstr "(服务待开通)"
105+
106+
msgid "Actions"
107+
msgstr "操作"
108+
109+
msgid "Actions will automatically save current configuration before execution."
110+
msgstr "操作将在执行前自动保存当前配置。"
111+
112+
msgid "Setup IPv6 SLAAC for NEXT(1Gbps) and without Hikari Denwa"
113+
msgstr "设置 NEXT(1Gbps)无光电话(仅 SLAAC)的 IPv6"
114+
115+
msgid "Setting up IPv6 SLAAC"
116+
msgstr "设置 IPv6 SLAAC"
117+
118+
msgid "Applying IPv6 SLAAC configuration for NEXT(1Gbps) without Hikari Denwa..."
119+
msgstr "正在应用 NEXT(1Gbps)无光电话(仅 SLAAC)的 IPv6 配置..."
120+
121+
msgid "IPv6 SLAAC configuration applied successfully!"
122+
msgstr "IPv6 SLAAC 配置应用成功!"
123+
124+
msgid "Failed to apply IPv6 SLAAC configuration: %s"
125+
msgstr "应用 IPv6 SLAAC 配置失败:%s"
126+
127+
msgid "Error executing IPv6 SLAAC setup: %s"
128+
msgstr "执行 IPv6 SLAAC 设置时出错:%s"
129+
130+
msgid "Setup IPv6 PD for Cross(10Gbps) or with Hikari Denwa"
131+
msgstr "设置 Cross(10Gbps)有光电话(PD)的 IPv6"
132+
133+
msgid "Setting up IPv6 PD"
134+
msgstr "设置 IPv6 PD"
135+
136+
msgid "Applying IPv6 PD configuration for Cross(10Gbps) or with Hikari Denwa..."
137+
msgstr "正在应用 Cross(10Gbps)有光电话(PD)的 IPv6 配置..."
138+
139+
msgid "IPv6 PD configuration applied successfully!"
140+
msgstr "IPv6 PD 配置应用成功!"
141+
142+
msgid "Failed to apply IPv6 PD configuration:"
143+
msgstr "应用 IPv6 PD 配置失败:"
144+
145+
msgid "Error executing IPv6 PD setup:"
146+
msgstr "执行 IPv6 PD 设置时出错:"
147+
148+
msgid "Service Status"
149+
msgstr "服务状态"
150+
151+
msgid "Optical line construction completed, provider configuration in progress. Please wait patiently."
152+
msgstr "光线路施工已完成,正在进行运营商配置。请耐心等待。"
153+
154+
msgid "Service typically becomes available in the evening after construction is completed."
155+
msgstr "施工完成后,服务通常会在傍晚开通。"

0 commit comments

Comments
 (0)