diff --git a/luci-app-easyconfig-transfer/Makefile b/luci-app-easyconfig-transfer/Makefile
index 719e15563..bcba70eaf 100644
--- a/luci-app-easyconfig-transfer/Makefile
+++ b/luci-app-easyconfig-transfer/Makefile
@@ -9,9 +9,9 @@ include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI JS Support for easyconfig transfer statistics
PKG_MAINTAINER:=Rafał Wabik <4Rafal@gmail.com>
LUCI_DESCRIPTION:=LuCI JS interface for the easyconfig transfer statistics.
-LUCI_DEPENDS:=+luci-base
-PKG_VERSION:=1.0.18
-PKG_RELEASE:=1
+LUCI_DEPENDS:=+luci-base +jq
+PKG_VERSION:=1.0.20
+PKG_RELEASE:=2
LUCI_PKGARCH:=all
diff --git a/luci-app-easyconfig-transfer/htdocs/luci-static/resources/view/transfer/config.js b/luci-app-easyconfig-transfer/htdocs/luci-static/resources/view/transfer/config.js
index 422601c1f..726fb4b52 100644
--- a/luci-app-easyconfig-transfer/htdocs/luci-static/resources/view/transfer/config.js
+++ b/luci-app-easyconfig-transfer/htdocs/luci-static/resources/view/transfer/config.js
@@ -94,6 +94,52 @@ return view.extend({
render: function(devs) {
var m, s, o;
+
+ var updateCron = function() {
+ var transferEnabled = uci.get('easyconfig_transfer', 'global', 'transfer_enabled');
+ var PD = uci.get('easyconfig_transfer', 'global', 'dataread_period');
+ var autoReset = uci.get('easyconfig_transfer', 'global', 'auto_reset');
+ var enableBackup = uci.get('easyconfig_transfer', 'traffic', 'enable_backup');
+ var makeTime = uci.get('easyconfig_transfer', 'traffic', 'make_time');
+ var restoreTime = uci.get('easyconfig_transfer', 'traffic', 'restore_time');
+
+ return L.resolveDefault(fs.read('/etc/crontabs/root'), '').then(function(crontab) {
+ var lines = (crontab || '').replace(/\r\n/g, '\n').split('\n');
+
+ var filtered = lines.filter(function(l) {
+ return l.trim() !== '' &&
+ !l.includes('easyconfig_statistics.sh') &&
+ !l.includes('auto_reset_statistics.sh') &&
+ !l.includes('/usr/lib/easyconfig');
+ });
+
+ if (transferEnabled === '1') {
+ filtered.push('*/' + PD + ' * * * * /usr/bin/easyconfig_statistics.sh');
+
+ if (autoReset === '1') {
+ filtered.push('0 0 1 1 * /usr/bin/auto_reset_statistics.sh');
+ }
+
+ if (enableBackup === '1' && makeTime && restoreTime) {
+ var makeParts = makeTime.split(':');
+ var makeHH = parseInt(makeParts[0], 10);
+ var makeMM = parseInt(makeParts[1], 10);
+
+ var restoreParts = restoreTime.split(':');
+ var restoreHH = parseInt(restoreParts[0], 10);
+ var restoreMM = parseInt(restoreParts[1], 10);
+
+ filtered.push(makeMM + ' ' + makeHH + ' * * * cp /tmp/easyconfig_statistics.json /usr/lib/easyconfig');
+ filtered.push(restoreMM + ' ' + restoreHH + ' * * * cp /usr/lib/easyconfig/easyconfig_statistics.json /tmp');
+ }
+ }
+
+ return fs.write('/etc/crontabs/root', filtered.join('\n') + '\n');
+ }).then(function() {
+ return fs.exec('/etc/init.d/cron', ['restart']);
+ });
+ };
+
m = new form.Map('easyconfig_transfer', _('Configuration - Transfer'), _('Configuration panel of the application calculating transfer statistics.'));
s = m.section(form.TypedSection, 'ectransfer', _('Main Settings'), null);
@@ -105,38 +151,28 @@ return view.extend({
o.rmempty = false;
o.write = function(section_id, value) {
- if(value == '1') {
- uci.set('easyconfig_transfer', 'global', 'transfer_enabled', "1");
- uci.save();
- fs.exec('sleep 2');
- fs.exec_direct('/sbin/transfer2cron.sh');
- }
- if(value == '0') {
- uci.set('easyconfig_transfer', 'global', 'transfer_enabled', "0");
- uci.save();
- fs.exec('sleep 2');
- fs.exec_direct('/sbin/transfer2cron.sh');
- }
- return form.Flag.prototype.write.apply(this, [section_id, value]);
+ return uci.load('easyconfig_transfer').then(function() {
+ uci.set('easyconfig_transfer', 'global', 'transfer_enabled', value);
+ return uci.save();
+ }).then(function() {
+ return updateCron();
+ }).then(function() {
+ return form.Flag.prototype.write.apply(this, [section_id, value]);
+ }.bind(this));
};
o = s.option(form.Flag, 'auto_reset', _('Auto data reset'), _('Check this option if you want reset data with the new year.'));
o.rmempty = false;
o.write = function(section_id, value) {
- if(value == '1') {
- uci.set('easyconfig_transfer', 'global', 'auto_reset', "1");
- uci.save();
- fs.exec('sleep 2');
- fs.exec_direct('/sbin/ar2cron.sh');
- }
- if(value == '0') {
- uci.set('easyconfig_transfer', 'global', 'auto_reset', "0");
- uci.save();
- fs.exec('sleep 2');
- fs.exec_direct('/sbin/ar2cron.sh');
- }
- return form.Flag.prototype.write.apply(this, [section_id, value]);
+ return uci.load('easyconfig_transfer').then(function() {
+ uci.set('easyconfig_transfer', 'global', 'auto_reset', value);
+ return uci.save();
+ }).then(function() {
+ return updateCron();
+ }).then(function() {
+ return form.Flag.prototype.write.apply(this, [section_id, value]);
+ }.bind(this));
};
o = s.option(widgets.NetworkSelect, 'network', _('Interface'), _('Network interface for Internet access.'));
@@ -200,16 +236,6 @@ return view.extend({
o = s.taboption('trTab', form.Flag, 'wan_view', _('Show wan in table'), _('Check this option if you want wan to be visible in the table.'));
o.rmempty = false;
- o = s.taboption('trTab', form.DynamicList, 'host_names', _('Add a hostname'), _('Enter data as MAC adress;Hostname.'));
- o.rmempty = true;
- o.validate = function(section_id, value) {
- if(value === "" || value.match(/^([0-9A-F]{2}:){5}([0-9A-F]{2});.+$/)) {
- return true;
- } else {
- return _('Enter the MAC address;Hostname');
- }
- };
-
o = s.taboption('trTab', form.Flag, 'warning_enabled', _('Enable data usage progress bar'), _('Show a visualization of transfer usage in the form of a progress bar.'));
o.rmempty = true;
@@ -289,14 +315,10 @@ return view.extend({
if(value == '1') {
uci.set('easyconfig_transfer', 'service', 'traffic', 'external_backup', "1");
uci.save();
- //fs.exec('sleep 2');
- //fs.exec_direct('/sbin/backup2cron.sh');
}
if(value == '0') {
uci.set('easyconfig_transfer', 'service', 'traffic', 'external_backup', "0");
uci.save();
- //fs.exec('sleep 2');
- //fs.exec_direct('/sbin/backup2cron.sh');
}
return form.Flag.prototype.write.apply(this, [section_id, value]);
};
@@ -311,21 +333,14 @@ return view.extend({
o = s.taboption('bkTab', form.Flag, 'enable_backup', _('Move .json file'), _('Check this option if you want to save data during a scheduled device restart.'));
o.rmempty = false;
o.write = function(section_id, value) {
- if(value == '1') {
- uci.set('easyconfig_transfer', 'service', 'traffic', 'enable_backup', "1");
- uci.save();
- uci.apply();
- fs.exec('sleep 2');
- fs.exec_direct('/sbin/backup2cron.sh');
- }
- if(value == '0') {
- uci.set('easyconfig_transfer', 'service', 'traffic', 'enable_backup', "0");
- uci.save();
- uci.apply();
- fs.exec('sleep 2');
- fs.exec_direct('/sbin/backup2cron.sh');
- }
- return form.Flag.prototype.write.apply(this, [section_id, value]);
+ return uci.load('easyconfig_transfer').then(function() {
+ uci.set('easyconfig_transfer', 'service', 'traffic', 'enable_backup', value);
+ return uci.save();
+ }).then(function() {
+ return updateCron();
+ }).then(function() {
+ return form.Flag.prototype.write.apply(this, [section_id, value]);
+ }.bind(this));
};
//o.depends('transfer_enabled', '1');
@@ -361,6 +376,75 @@ return view.extend({
};
o.default = '05:10';
+ s.tab('hnTab', _('Hostname Settings'));
+ o = s.taboption('hnTab', form.DynamicList, 'host_names', _('Add a hostname'), _('Enter data as MAC adress;Hostname.'));
+ o.rmempty = false;
+ o.ucioption = 'host_names';
+
+ var PLACEHOLDER = 'AA:BB:CC:DD:EE:FF;' + _('hostname');
+
+ o.ucisection = function() {
+ var sections = uci.sections('easyconfig_transfer', 'hostname');
+ return sections.length > 0 ? sections[0]['.name'] : null;
+ };
+
+ o.load = function(section_id) {
+ var hostnameSection = uci.sections('easyconfig_transfer', 'hostname');
+ var values = [];
+ if (hostnameSection.length > 0) {
+ values = hostnameSection[0].host_names || [];
+ }
+ if (values.length === 0) {
+ values = [PLACEHOLDER];
+ }
+ return values;
+ };
+
+ o.write = function(section_id, value) {
+ var hostnameSection = uci.sections('easyconfig_transfer', 'hostname');
+ var targetSection = hostnameSection.length > 0 ? hostnameSection[0]['.name'] : null;
+
+ if (!targetSection) {
+ targetSection = uci.add('easyconfig_transfer', 'hostname');
+ }
+
+ var filtered = Array.isArray(value)
+ ? value.filter(function(v) { return v !== PLACEHOLDER; })
+ : [];
+
+ if (filtered.length === 0) {
+ var existing = uci.get('easyconfig_transfer', targetSection, 'host_names');
+ if (existing !== undefined && existing !== null) {
+ uci.unset('easyconfig_transfer', targetSection, 'host_names');
+ }
+ } else {
+ uci.set('easyconfig_transfer', targetSection, 'host_names', filtered);
+ }
+
+ return uci.save();
+ };
+
+ o.remove = function(section_id) {
+ var hostnameSection = uci.sections('easyconfig_transfer', 'hostname');
+ if (hostnameSection.length > 0) {
+ var sectionName = hostnameSection[0]['.name'];
+ var existing = uci.get('easyconfig_transfer', sectionName, 'host_names');
+ if (existing !== undefined && existing !== null) {
+ uci.unset('easyconfig_transfer', sectionName, 'host_names');
+ }
+ return uci.save();
+ }
+ return Promise.resolve();
+ };
+
+ o.validate = function(section_id, value) {
+ if (value === PLACEHOLDER) return true;
+ if (value === '' || value.match(/^([0-9A-F]{2}:){5}([0-9A-F]{2});.+$/)) {
+ return true;
+ }
+ return _('Enter the MAC address;Hostname');
+ };
+
return m.render();
}
});
diff --git a/luci-app-easyconfig-transfer/htdocs/luci-static/resources/view/transfer/details.js b/luci-app-easyconfig-transfer/htdocs/luci-static/resources/view/transfer/details.js
index 6b8b7b2a1..e91987c96 100644
--- a/luci-app-easyconfig-transfer/htdocs/luci-static/resources/view/transfer/details.js
+++ b/luci-app-easyconfig-transfer/htdocs/luci-static/resources/view/transfer/details.js
@@ -525,6 +525,70 @@ function sortClientObjectsByHeader(tableKey) {
return out;
}
+function handleAddHostname(macAddr, inputId) {
+ var inputField = document.getElementById(inputId);
+ if (!inputField) return;
+
+ var hostname = inputField.value.trim();
+ if (!hostname) {
+ ui.addNotification(null, E('p', _('Please enter a hostname')), 'error');
+ return;
+ }
+
+ var entry = macAddr + ';' + hostname;
+ var macUpper = macAddr.toUpperCase();
+
+ var sections = uci.sections('easyconfig_transfer', 'hostname');
+ var targetSection = null;
+
+ for (var i = 0; i < sections.length; i++) {
+ if (sections[i]['.name'] === 'hostnames') {
+ targetSection = sections[i];
+ break;
+ }
+ }
+
+ if (!targetSection) {
+ uci.add('easyconfig_transfer', 'hostname', 'hostnames');
+ targetSection = { host_names: [] };
+ }
+
+ var hostNames = Array.isArray(targetSection.host_names) ? targetSection.host_names.slice() : [];
+
+ var existingIndex = -1;
+ for (var i = 0; i < hostNames.length; i++) {
+ if (hostNames[i].split(';')[0].toUpperCase() === macUpper) {
+ existingIndex = i;
+ break;
+ }
+ }
+
+ if (existingIndex >= 0) {
+ hostNames[existingIndex] = entry;
+ } else {
+ hostNames.push(entry);
+ }
+
+ uci.set('easyconfig_transfer', 'hostnames', 'host_names', hostNames);
+ uci.save();
+
+ L.ui.showModal(_('Please wait...'), [
+ E('p', { 'class': 'spinning' }, _('Hostname added successfully. Reloading...'))
+ ]);
+
+ uci.apply().then(function() {
+ setTimeout(function() {
+ location.reload();
+ }, 4000);
+ });
+}
+
+function isHostnameDuplicate(macAddr, hostname) {
+ var cleanMac = macAddr.replace(/:/g, '').toUpperCase();
+ var cleanHostname = hostname.replace(/:/g, '').replace(/\s/g, '').toUpperCase();
+ return cleanHostname.indexOf(cleanMac) !== -1;
+}
+
function renderClientTableManual(table, tableKey) {
while (table.childElementCount > 1) {
table.removeChild(table.lastElementChild);
@@ -563,9 +627,54 @@ function renderClientTableManual(table, tableKey) {
});
} else {
rows.forEach(function(o, i){
+ var shouldShowInput = (o.nameOut === '-') || isHostnameDuplicate(o.macOut, o.nameOut);
+
+ var hostnameCell;
+ if (shouldShowInput) {
+ var inputId = 'hostname-input-' + o.macOut.replace(/:/g, '_');
+ var ipAddress = '';
+ var ipMatch = o.nameOut.match(/\(([0-9.]+)\)/);
+ if (ipMatch && ipMatch[1]) {
+ ipAddress = ' (' + ipMatch[1] + ')';
+ }
+
+ var inputElements = [
+ E('input', {
+ 'type': 'text',
+ 'id': inputId,
+ 'placeholder': _('Enter hostname'),
+ 'style': 'width: 150px; padding: 0.25em 0.5em !important; border: 1px solid #ccc; border-radius: 3px; font-size: inherit; height: auto !important; line-height: normal !important; box-sizing: border-box !important; vertical-align: middle !important;',
+ 'keydown': function(ev) {
+ if (ev.keyCode === 13) {
+ handleAddHostname(o.macOut, inputId);
+ }
+ }
+ }),
+ E('button', {
+ 'class': 'btn cbi-button cbi-button-add',
+ 'style': 'padding: 0.25em 0.6em !important; height: auto !important; line-height: normal !important; font-size: inherit !important; font-weight: bold; box-sizing: border-box !important; vertical-align: middle !important; min-height: 0 !important;',
+ 'click': function() {
+ handleAddHostname(o.macOut, inputId);
+ }
+ }, [ '+' ])
+ ];
+
+ if (ipAddress) {
+ inputElements.push(
+ E('span', { 'style': 'color: #666; margin-left: 0.5em; font-size: inherit; vertical-align: middle;' }, ipAddress)
+ );
+ }
+
+ hostnameCell = E('td', { 'class': 'td', 'data-title': _('Hostname'), 'style': 'padding: 5px;' }, [
+ E('span', { 'class': 'control-group', 'style': 'display: inline-flex; gap: 0.25em; align-items: center; vertical-align: middle;' }, inputElements)
+ ]);
+ } else {
+ hostnameCell = E('td', { 'class': 'td', 'data-title': _('Hostname') }, o.nameOut);
+ }
+
var tr = E('tr', { 'class': 'tr cbi-rowstyle-%d'.format(i % 2 ? 2 : 1) }, [
E('td', { 'class': 'td', 'data-title': _('MAC Address') }, o.macOut),
- E('td', { 'class': 'td', 'data-title': _('Hostname') }, o.nameOut && o.nameOut.length>1 ? o.nameOut : '-'),
+ hostnameCell,
E('td', { 'class': 'td', 'data-title': _('First Seen') }, o.first),
E('td', { 'class': 'td', 'data-title': _('Last Seen') }, o.last),
(function(){
@@ -1772,7 +1881,15 @@ function updatePieChart(key, jsonData, dates) {
var sections = uci.sections('easyconfig_transfer');
var hideZeros = sections[1].zero_view;
var hidden_data_value = sections[1].hidden_data;
- var mac_list = Array.isArray(sections[1].host_names) ? sections[1].host_names : [];
+
+ var hostnamesSection = null;
+ for (var i = 0; i < sections.length; i++) {
+ if (sections[i]['.name'] === 'hostnames') {
+ hostnamesSection = sections[i];
+ break;
+ }
+ }
+ var mac_list = (hostnamesSection && Array.isArray(hostnamesSection.host_names)) ? hostnamesSection.host_names : [];
var macs_list = [];
for (var i = 0; i < mac_list.length; i++) macs_list.push(mac_list[i]);
@@ -2540,7 +2657,15 @@ function populateClientDropdowns(jsonData) {
if (clientDropdown) {
clientDropdown.innerHTML = '';
var sections2 = uci.sections('easyconfig_transfer');
- var mac_list2 = Array.isArray(sections2[1].host_names) ? sections2[1].host_names : [];
+
+ var hostnamesSection2 = null;
+ for (var i = 0; i < sections2.length; i++) {
+ if (sections2[i]['.name'] === 'hostnames') {
+ hostnamesSection2 = sections2[i];
+ break;
+ }
+ }
+ var mac_list2 = (hostnamesSection2 && Array.isArray(hostnamesSection2.host_names)) ? hostnamesSection2.host_names : [];
callLuciDHCPLeases().then(function(leaseData2) {
var leases2 = Array.isArray(leaseData2.dhcp_leases) ? leaseData2.dhcp_leases : [];
var clients = getClientsList(jsonData, leases2, mac_list2);
@@ -2621,7 +2746,15 @@ function updateClientTable(tableKey, jsonData, dates) {
var sections = uci.sections('easyconfig_transfer');
var hideZeros = sections[1].zero_view;
var hidden_data_value = sections[1].hidden_data;
- var mac_list = Array.isArray(sections[1].host_names) ? sections[1].host_names : [];
+
+ var hostnamesSection = null;
+ for (var i = 0; i < sections.length; i++) {
+ if (sections[i]['.name'] === 'hostnames') {
+ hostnamesSection = sections[i];
+ break;
+ }
+ }
+ var mac_list = (hostnamesSection && Array.isArray(hostnamesSection.host_names)) ? hostnamesSection.host_names : [];
var macs_list = [];
for (var i = 0; i < mac_list.length; i++) macs_list.push(mac_list[i]);
diff --git a/luci-app-easyconfig-transfer/po/de/easyconfig-transfer.po b/luci-app-easyconfig-transfer/po/de/easyconfig-transfer.po
index e68d805cb..4dde7d090 100644
--- a/luci-app-easyconfig-transfer/po/de/easyconfig-transfer.po
+++ b/luci-app-easyconfig-transfer/po/de/easyconfig-transfer.po
@@ -1,8 +1,10 @@
msgid ""
msgstr ""
-"Project-Id-Version: luci-app-easyconfig-transfer\n"
"Language-Team: Rafał Wabik (IceG)\n"
"Language: de\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
msgid "Transfer"
msgstr "Transfer"
@@ -491,3 +493,24 @@ msgstr "Datum"
msgid "Statistics restored from external backup"
msgstr "Statistiken aus externem Backup wiederhergestellt"
+
+msgid "Please enter a hostname"
+msgstr "Bitte geben Sie einen Hostnamen ein"
+
+msgid "Configuration error"
+msgstr "Konfigurationsfehler"
+
+msgid "Hostname added successfully. Reloading..."
+msgstr "Hostname erfolgreich hinzugefügt. Neu laden…"
+
+msgid "Enter hostname"
+msgstr "Hostname eingeben"
+
+msgid "Hostname"
+msgstr "Hostname"
+
+msgid "Hostname Settings"
+msgstr "Hostname-Einstellungen"
+
+msgid "hostname"
+msgstr "Hostname"
diff --git a/luci-app-easyconfig-transfer/po/es/easyconfig-transfer.po b/luci-app-easyconfig-transfer/po/es/easyconfig-transfer.po
new file mode 100644
index 000000000..d904b5ca8
--- /dev/null
+++ b/luci-app-easyconfig-transfer/po/es/easyconfig-transfer.po
@@ -0,0 +1,513 @@
+msgid ""
+msgstr ""
+"Language-Team: Rafał Wabik (IceG)\n"
+"Language: es\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+msgid "Transfer"
+msgstr "Transferencia"
+
+msgid "User interface for easyconfig scripts estimating transfer consumption. More information on the %seko.one.pl forum%s."
+msgstr "Interfaz de usuario para scripts easyconfig que estiman el consumo de transferencia. Más información en el foro %seko.one.pl%s."
+
+msgid "Estimated data usage"
+msgstr "Uso de datos estimado"
+
+msgid "First Seen"
+msgstr "Primera sesión"
+
+msgid "Last Seen"
+msgstr "Última sesión"
+
+msgid "Downloaded"
+msgstr "Descargado"
+
+msgid "Uploaded"
+msgstr "Subido"
+
+msgid "Configuration - Transfer"
+msgstr "Configuración - Transferencia"
+
+msgid "Configuration panel of the application calculating transfer statistics."
+msgstr "Panel de configuración de la aplicación que calcula las estadísticas de transferencia."
+
+msgid "Data reading period"
+msgstr "Periodo de lectura de datos"
+
+msgid "Data recording period"
+msgstr "Periodo de registro de datos"
+
+msgid "Beginning of the billing period"
+msgstr "Inicio del periodo de facturación"
+
+msgid "Warning enabled"
+msgstr "Aviso activado"
+
+msgid "Transfer available"
+msgstr "Transferencia disponible"
+
+msgid "Warning level"
+msgstr "Nivel de aviso"
+
+msgid "Warning cycle"
+msgstr "Ciclo de aviso"
+
+msgid "per period"
+msgstr "por periodo"
+
+msgid "per day"
+msgstr "por día"
+
+msgid "Days until the end of the billing period"
+msgstr "Días hasta el final del periodo de facturación"
+
+msgid "Estimated remaining transfer"
+msgstr "Transferencia restante estimada"
+
+msgid "approximately remains"
+msgstr "resta aproximadamente"
+
+msgid "Summary"
+msgstr "Resumen"
+
+msgid "Today"
+msgstr "Hoy"
+
+msgid "Yesterday"
+msgstr "Ayer"
+
+msgid "Last 7 days"
+msgstr "Últimos 7 días"
+
+msgid "Last 30 days"
+msgstr "Últimos 30 días"
+
+msgid "Yearly"
+msgstr "Anual"
+
+msgid "Clients data usage"
+msgstr "Uso de datos por cliente(s)"
+
+msgid "Total"
+msgstr "Total"
+
+msgid "Current billing period"
+msgstr "Periodo de facturación actual"
+
+msgid "Expected data usage for the current period"
+msgstr "Uso de datos previsto para el periodo actual"
+
+msgid "Previous billing period"
+msgstr "Periodo de facturación anterior"
+
+msgid "Transfer usage statistics"
+msgstr "Estadísticas de uso de transferencia"
+
+msgid "Calculations may differ from the operator indications"
+msgstr "Los cálculos pueden diferir de las indicaciones del operador"
+
+msgid "Make a copy of Database"
+msgstr "Crear una copia de la base de datos"
+
+msgid "Restore"
+msgstr "Restaurar"
+
+msgid "Make"
+msgstr "Realizar"
+
+msgid "a backup"
+msgstr "una copia"
+
+msgid "Make a backup"
+msgstr "Realizar una copia de seguridad"
+
+msgid "Reset data"
+msgstr "Restablecer datos"
+
+msgid "Main Settings"
+msgstr "Ajustes principales"
+
+msgid "Traffic Settings"
+msgstr "Ajustes de tráfico"
+
+msgid "Hide MAC addresses"
+msgstr "Ocultar direcciones MAC"
+
+msgid "Hide MAC addresses without transfer information."
+msgstr "Ocultar direcciones MAC sin información de transferencia."
+
+msgid ""
+"Select how often a compressed copy of the data will be made.
Archive path /usr/lib/easyconfig/easyconfig_statistics.json.gz.
Important
Please "
+"remember that frequent write operations shorten the life cycle of memory."
+msgstr ""
+"Seleccione la frecuencia con la que se realizará una copia comprimida de los datos.
Ruta del archivo /usr/lib/easyconfig/easyconfig_statistics.json.gz.
Importante
Recuerde "
+"que las operaciones frecuentes de escritura acortan el ciclo de vida de la memoria."
+
+msgid ""
+"Enable transfer data collection.
Data is saved to file /tmp/easyconfig_statistics.json.
What you should know
With "
+"flow offloading enabled, transfer data will be inconsistent with reality or may be completely unavailable."
+msgstr ""
+"Activa la recopilación de datos de transferencia.
Los datos se guardan en el archivo /tmp/easyconfig_statistics.json.
Lo que debe saber
Con el "
+"flow offloading activado, los datos de transferencia serán inconsistentes con la realidad o podrían no estar disponibles."
+
+msgid "1 minute"
+msgstr "1 minuto"
+
+msgid "3 minutes"
+msgstr "3 minutos"
+
+msgid "5 minutes"
+msgstr "5 minutos"
+
+msgid "10 minutes"
+msgstr "10 minutos"
+
+msgid "15 minutes"
+msgstr "15 minutos"
+
+msgid "30 minutes"
+msgstr "30 minutos"
+
+msgid "1 hour"
+msgstr "1 hora"
+
+msgid "3 hours"
+msgstr "3 horas"
+
+msgid "6 hours"
+msgstr "6 horas"
+
+msgid "12 hours"
+msgstr "12 horas"
+
+msgid "24 hours"
+msgstr "24 horas"
+
+msgid "Enter the starting day of the billing period."
+msgstr "Introduzca el día de inicio del periodo de facturación."
+
+msgid "Hide selected data in the table"
+msgstr "Ocultar datos seleccionados en la tabla"
+
+msgid "Select data that will be hidden."
+msgstr "Seleccione los datos que se ocultarán."
+
+msgid "MAC addresses"
+msgstr "Direcciones MAC"
+
+msgid "MAC addresses & Hostnames"
+msgstr "Direcciones MAC y Nombres de host"
+
+msgid "Show wan in table"
+msgstr "Mostrar WAN en la tabla"
+
+msgid "Check this option if you want wan to be visible in the table."
+msgstr "Marque esta opción si desea que la WAN sea visible en la tabla."
+
+msgid "Enable data usage progress bar"
+msgstr "Activar barra de progreso de uso de datos"
+
+msgid "Show a visualization of transfer usage in the form of a progress bar."
+msgstr "Muestra una visualización del uso de transferencia en forma de barra de progreso."
+
+msgid "Enter the available transfer during the billing period."
+msgstr "Introduzca la transferencia disponible durante el periodo de facturación."
+
+msgid "Unit of data size"
+msgstr "Unidad de tamaño de datos"
+
+msgid "Data Count Cycle"
+msgstr "Ciclo de conteo de datos"
+
+msgid "Specify the data visualization/counting interval."
+msgstr "Especifique el intervalo de visualización/conteo de datos."
+
+msgid "Check this option if you want to save data during a scheduled device restart."
+msgstr "Marque esta opción si desea guardar los datos durante un reinicio programado del dispositivo."
+
+msgid "Backup at"
+msgstr "Copia de seguridad a las"
+
+msgid "Restore backup at"
+msgstr "Restaurar copia de seguridad a las"
+
+msgid "Backup Settings"
+msgstr "Ajustes de copia de seguridad"
+
+msgid "Move .json file"
+msgstr "Mover archivo .json"
+
+msgid "Correct time format HH:MM."
+msgstr "Formato de hora correcto HH:MM."
+
+msgid "Expected time is in HH:MM format"
+msgstr "Se espera la hora en formato HH:MM"
+
+msgid "Enter a numeric value"
+msgstr "Introduzca un valor numérico"
+
+msgid "Add a hostname"
+msgstr "Añadir un nombre de host"
+
+msgid "Enter data as MAC adress;Hostname."
+msgstr "Introduzca los datos como Dirección MAC;Nombre de host."
+
+msgid "Transfer details"
+msgstr "Detalles de transferencia"
+
+msgid "Enter the MAC address;Hostname"
+msgstr "Introduzca la dirección MAC;Nombre de host"
+
+msgid "Do you want to clear transfer statistics data?"
+msgstr "¿Desea borrar los datos de las estadísticas de transferencia?"
+
+msgid "Transfer statistics"
+msgstr "Estadísticas de transferencia"
+
+msgid "There are currently no data to show..."
+msgstr "Actualmente no hay datos que mostrar..."
+
+msgid "Additional settings"
+msgstr "Ajustes adicionales"
+
+msgid "from"
+msgstr "desde"
+
+msgid "out of"
+msgstr "de"
+
+msgid "You have exceeded your available transfer by over"
+msgstr "Ha excedido su transferencia disponible por más de"
+
+msgid "Statistics from the current billing period."
+msgstr "Estadísticas del periodo de facturación actual."
+
+msgid "Must be configured"
+msgstr "Debe ser configurado"
+
+msgid "Press Continue to restore the backup, or Cancel to abort the operation."
+msgstr "Presione Continuar para restaurar la copia de seguridad, o Cancelar para abortar la operación."
+
+msgid "Restore .json file from archive"
+msgstr "Restaurar archivo .json desde el archivo comprimido"
+
+msgid "Option allows user to restore statistics from the archive."
+msgstr "Esta opción permite al usuario restaurar las estadísticas desde el archivo comprimido."
+
+msgid "Restore .json file"
+msgstr "Restaurar archivo .json"
+
+msgid "Option allows user to restore statistics from .json file."
+msgstr "Esta opción permite al usuario restaurar las estadísticas desde un archivo .json."
+
+msgid "Download .gz archive"
+msgstr "Descargar archivo .gz"
+
+msgid "Click to download .gz archive."
+msgstr "Haga clic para descargar el archivo .gz."
+
+msgid "easyconfig_statistics.json.gz file not found."
+msgstr "No se encontró el archivo easyconfig_statistics.json.gz."
+
+msgid "Download error"
+msgstr "Error de descarga"
+
+msgid "Download .json file"
+msgstr "Descargar archivo .json"
+
+msgid "Click to download .json file."
+msgstr "Haga clic para descargar el archivo .json."
+
+msgid "Download of easyconfig_statistics.json failed. Please try again."
+msgstr "Falló la descarga de easyconfig_statistics.json. Por favor, inténtelo de nuevo."
+
+msgid "Error executing easyconfig_statistics.sh"
+msgstr "Error al ejecutar easyconfig_statistics.sh"
+
+msgid "Upload .gz archive"
+msgstr "Subir archivo .gz"
+
+msgid "Upload .json file"
+msgstr "Subir archivo .json"
+
+msgid "Save .gz file"
+msgstr "Guardar archivo .gz"
+
+msgid "Save .json file"
+msgstr "Guardar archivo .json"
+
+msgid "Copy .json file to external storage"
+msgstr "Copiar archivo .json a almacenamiento externo"
+
+msgid "Check this option if you want to create a copy on an external drive."
+msgstr "Marque esta opción si desea crear una copia en una unidad externa."
+
+msgid "Path to .json file"
+msgstr "Ruta del archivo .json"
+
+msgid "Enter the path to the directory where a copy of the .json file will be saved."
+msgstr "Introduzca la ruta del directorio donde se guardará una copia del archivo .json."
+
+msgid "Data in easyconfig_statistics.json file has been reset."
+msgstr "Se han restablecido los datos del archivo easyconfig_statistics.json."
+
+msgid "Successfully copied easyconfig_statistics.json file to"
+msgstr "Archivo easyconfig_statistics.json copiado correctamente en"
+
+msgid "Successfully copied easyconfig_statistics.json file to /usr/lib/easyconfig."
+msgstr "Archivo easyconfig_statistics.json copiado correctamente desde /usr/lib/easyconfig."
+
+msgid "Auto data reset"
+msgstr "Restablecimiento automático"
+
+msgid "Check this option if you want reset data with the new year."
+msgstr "Marque esta opción si desea restablecer los datos con el nuevo año."
+
+msgid "Monthly"
+msgstr "Mensual"
+
+msgid "Last 12 months"
+msgstr "Últimos 12 meses"
+
+msgid "Refreshing data…"
+msgstr "Actualizando datos…"
+
+msgid "Current period"
+msgstr "Periodo actual"
+
+msgid "Presentation of downloaded and uploaded data. Click Refresh to update the charts."
+msgstr "Presentación de datos descargados y subidos. Haga clic en Actualizar para actualizar los gráficos."
+
+msgid "Jan"
+msgstr "Ene"
+
+msgid "Feb"
+msgstr "Feb"
+
+msgid "Mar"
+msgstr "Mar"
+
+msgid "Apr"
+msgstr "Abr"
+
+msgid "May"
+msgstr "May"
+
+msgid "Jun"
+msgstr "Jun"
+
+msgid "Jul"
+msgstr "Jul"
+
+msgid "Aug"
+msgstr "Ago"
+
+msgid "Sep"
+msgstr "Sep"
+
+msgid "Oct"
+msgstr "Oct"
+
+msgid "Nov"
+msgstr "Nov"
+
+msgid "Dec"
+msgstr "Dic"
+
+msgid "No data available"
+msgstr "No hay datos disponibles"
+
+msgid "Percentage"
+msgstr "Porcentaje"
+
+msgid "Legend"
+msgstr "Leyenda"
+
+msgid "Select day"
+msgstr "Seleccionar día"
+
+msgid "Select month"
+msgstr "Seleccionar mes"
+
+msgid "Select year"
+msgstr "Seleccionar año"
+
+msgid "Select period"
+msgstr "Seleccionar periodo"
+
+msgid "Others"
+msgstr "Otros"
+
+msgid "(Hour-by-hour data usage chart for selected day)"
+msgstr "(Gráfico de uso de datos hora por hora para el día seleccionado)"
+
+msgid "(Daily usage chart for a selected month)"
+msgstr "(Gráfico de uso diario para el mes seleccionado)"
+
+msgid "(Data usage chart for individual months)"
+msgstr "(Gráfico de uso de datos por meses individuales)"
+
+msgid "(Data usage chart for each month of the year "
+msgstr "(Gráfico de uso de datos para cada mes del año "
+
+msgid "Refreshing data..."
+msgstr "Actualizando datos..."
+
+msgid "Please wait..."
+msgstr "Por favor, espere..."
+
+msgid "Statistics of data usage by clients."
+msgstr "Estadísticas de uso de datos por cliente(s)."
+
+msgid "Clients"
+msgstr "Clientes"
+
+msgid "Statistics data cleared"
+msgstr "Datos estadísticos borrados"
+
+msgid "No hourly data available for this day"
+msgstr "No hay datos horarios disponibles para este día"
+
+msgid "Would you like to show an estimated hourly distribution based on daily totals? (This is only an approximation)"
+msgstr "¿Le gustaría mostrar una distribución horaria estimada basada en los totales diarios? (Esto es solo una aproximación)."
+
+msgid "Yes, show estimate"
+msgstr "Sí, mostrar estimación"
+
+msgid "Size of .json file"
+msgstr "Tamaño del archivo .json"
+
+msgid "Size of .gz file"
+msgstr "Tamaño del archivo .gz"
+
+msgid "Client"
+msgstr "Cliente"
+
+msgid "Date"
+msgstr "Fecha"
+
+msgid "Statistics restored from external backup"
+msgstr "Estadísticas restauradas desde copia de seguridad externa"
+
+msgid "Please enter a hostname"
+msgstr "Por favor, introduzca un nombre de host"
+
+msgid "Configuration error"
+msgstr "Error de configuración"
+
+msgid "Hostname added successfully. Reloading..."
+msgstr "Nombre de host añadido correctamente. Recargando..."
+
+msgid "Enter hostname"
+msgstr "Introducir nombre de host"
+
+msgid "Hostname"
+msgstr "Nombre de host"
+
+msgid "Hostname Settings"
+msgstr "Ajustes de nombre de host"
+
+msgid "hostname"
+msgstr "nombre de host"
diff --git a/luci-app-easyconfig-transfer/po/fr/easyconfig-transfer.po b/luci-app-easyconfig-transfer/po/fr/easyconfig-transfer.po
index 16085e21e..b192e01fd 100644
--- a/luci-app-easyconfig-transfer/po/fr/easyconfig-transfer.po
+++ b/luci-app-easyconfig-transfer/po/fr/easyconfig-transfer.po
@@ -1,10 +1,10 @@
msgid ""
msgstr ""
-"Project-Id-Version: luci-app-easyconfig-transfer\n"
"Language-Team: Rafał Wabik (IceG)\n"
"Language: fr\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
msgid "Transfer"
msgstr "Transfert"
@@ -493,3 +493,24 @@ msgstr "Date"
msgid "Statistics restored from external backup"
msgstr "Statistiques restaurées depuis une sauvegarde externe"
+
+msgid "Please enter a hostname"
+msgstr "Veuillez saisir un nom d’hôte"
+
+msgid "Configuration error"
+msgstr "Erreur de configuration"
+
+msgid "Hostname added successfully. Reloading..."
+msgstr "Nom d’hôte ajouté avec succès. Rechargement…"
+
+msgid "Enter hostname"
+msgstr "Saisir le nom d’hôte"
+
+msgid "Hostname"
+msgstr "Nom d’hôte"
+
+msgid "Hostname Settings"
+msgstr "Paramètres du nom d’hôte"
+
+msgid "hostname"
+msgstr "nom d’hôte"
diff --git a/luci-app-easyconfig-transfer/po/it/easyconfig-transfer.po b/luci-app-easyconfig-transfer/po/it/easyconfig-transfer.po
index c6d84fabf..5e6216ea4 100644
--- a/luci-app-easyconfig-transfer/po/it/easyconfig-transfer.po
+++ b/luci-app-easyconfig-transfer/po/it/easyconfig-transfer.po
@@ -1,8 +1,11 @@
msgid ""
msgstr ""
-"Project-Id-Version: luci-app-easyconfig-transfer\n"
"Language-Team: Rafał Wabik (IceG)\n"
-"Language: it\n"
+"Language: lt\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"(n%100<10 || n%100>=20) ? 1 : 2);\n"
msgid "Transfer"
msgstr "Trasferimento"
@@ -491,3 +494,24 @@ msgstr "Data"
msgid "Statistics restored from external backup"
msgstr "Statistiche ripristinate dal backup esterno"
+
+msgid "Please enter a hostname"
+msgstr "Inserire un nome host"
+
+msgid "Configuration error"
+msgstr "Errore di configurazione"
+
+msgid "Hostname added successfully. Reloading..."
+msgstr "Nome host aggiunto correttamente. Ricaricamento…"
+
+msgid "Enter hostname"
+msgstr "Inserisci nome host"
+
+msgid "Hostname"
+msgstr "Nome host"
+
+msgid "Hostname Settings"
+msgstr "Impostazioni del nome host"
+
+msgid "hostname"
+msgstr "nome host"
diff --git a/luci-app-easyconfig-transfer/po/ja/easyconfig-transfer.po b/luci-app-easyconfig-transfer/po/ja/easyconfig-transfer.po
new file mode 100644
index 000000000..05dd77dd1
--- /dev/null
+++ b/luci-app-easyconfig-transfer/po/ja/easyconfig-transfer.po
@@ -0,0 +1,517 @@
+msgid ""
+msgstr ""
+"Language: ja\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgid "Transfer"
+msgstr "転送"
+
+msgid "User interface for easyconfig scripts estimating transfer consumption. More information on the %seko.one.pl forum%s."
+msgstr "転送消費量を推定するeasyconfigスクリプト用のユーザーインターフェース。詳細は%seko.one.plフォーラム%sを参照してください。"
+
+msgid "Estimated data usage"
+msgstr "推定データ使用量"
+
+msgid "First Seen"
+msgstr "初回検出"
+
+msgid "Last Seen"
+msgstr "最終検出"
+
+msgid "Downloaded"
+msgstr "ダウンロード"
+
+msgid "Uploaded"
+msgstr "アップロード"
+
+msgid "Configuration - Transfer"
+msgstr "設定 - 転送"
+
+msgid "Configuration panel of the application calculating transfer statistics."
+msgstr "転送統計を計算するアプリケーションの設定パネル。"
+
+msgid "Data reading period"
+msgstr "データ読み込み期間"
+
+msgid "Data recording period"
+msgstr "データ記録期間"
+
+msgid "Beginning of the billing period"
+msgstr "請求期間の開始"
+
+msgid "Warning enabled"
+msgstr "警告を有効にする"
+
+msgid "Transfer available"
+msgstr "利用可能な転送"
+
+msgid "Warning level"
+msgstr "警告レベル"
+
+msgid "Warning cycle"
+msgstr "警告サイクル"
+
+msgid "per period"
+msgstr "期間あたり"
+
+msgid "per day"
+msgstr "1日あたり"
+
+msgid "Days until the end of the billing period"
+msgstr "請求期間終了までの日数"
+
+msgid "Estimated remaining transfer"
+msgstr "推定残存転送"
+
+msgid "approximately remains"
+msgstr "およそ残存"
+
+msgid "Summary"
+msgstr "概要"
+
+msgid "Today"
+msgstr "今日"
+
+msgid "Yesterday"
+msgstr "昨日"
+
+msgid "Last 7 days"
+msgstr "過去7日間"
+
+msgid "Last 30 days"
+msgstr "過去30日間"
+
+msgid "Yearly"
+msgstr "年単位"
+
+msgid "Clients data usage"
+msgstr "クライアントのデータ使用量"
+
+msgid "Total"
+msgstr "合計"
+
+msgid "Current billing period"
+msgstr "現在の請求期間"
+
+msgid "Expected data usage for the current period"
+msgstr "現在の期間の予想データ使用量"
+
+msgid "Previous billing period"
+msgstr "前の請求期間"
+
+msgid "Transfer usage statistics"
+msgstr "転送使用統計"
+
+msgid "Calculations may differ from the operator indications"
+msgstr "計算はオペレーターの表示と異なる場合があります"
+
+msgid "Make a copy of Database"
+msgstr "データベースのコピーを作成"
+
+msgid "Restore"
+msgstr "復元"
+
+msgid "Make"
+msgstr "作成"
+
+msgid "a backup"
+msgstr "バックアップ"
+
+msgid "Make a backup"
+msgstr "バックアップを作成"
+
+msgid "Reset data"
+msgstr "データをリセット"
+
+msgid "Main Settings"
+msgstr "メイン設定"
+
+msgid "Traffic Settings"
+msgstr "トラフィック設定"
+
+msgid "Traffic Settings"
+msgstr "トラフィック設定"
+
+msgid "Hide MAC addresses"
+msgstr "MACアドレスを非表示"
+
+msgid "Hide MAC addresses without transfer information."
+msgstr "転送情報がないMACアドレスを非表示にします。"
+
+msgid ""
+"Select how often a compressed copy of the data will be made.
Archive path /usr/lib/easyconfig/easyconfig_statistics.json.gz.
Important
Please "
+"remember that frequent write operations shorten the life cycle of memory."
+msgstr ""
+"圧縮されたデータコピーを作成する頻度を選択します。
アーカイブパス /usr/lib/easyconfig/easyconfig_statistics.json.gz。
重要
頻繁な書き込み操作はメモリのライフサイクルを短縮することに注意してください。"
+
+msgid ""
+"Enable transfer data collection.
Data is saved to file /tmp/easyconfig_statistics.json.
What you should know
With "
+"flow offloading enabled, transfer data will be inconsistent with reality or may be completely unavailable."
+
+msgstr ""
+"転送データ収集を有効にします。
データはファイル/tmp/easyconfig_statistics.jsonに保存されます。
ご注意
フローオフロードが有効になっている場合、転送データは現実と一致しなくなるか、完全に利用できなくなる可能性があります。"
+
+msgid "1 minute"
+msgstr "1分"
+
+msgid "3 minutes"
+msgstr "3分"
+
+msgid "5 minutes"
+msgstr "5分"
+
+msgid "10 minutes"
+msgstr "10分"
+
+msgid "15 minutes"
+msgstr "15分"
+
+msgid "30 minutes"
+msgstr "30分"
+
+msgid "1 hour"
+msgstr "1時間"
+
+msgid "3 hours"
+msgstr "3時間"
+
+msgid "6 hours"
+msgstr "6時間"
+
+msgid "12 hours"
+msgstr "12時間"
+
+msgid "24 hours"
+msgstr "24時間"
+
+msgid "Enter the starting day of the billing period."
+msgstr "請求期間の開始日を入力します。"
+
+msgid "Hide selected data in the table"
+msgstr "テーブル内の選択したデータを非表示"
+
+msgid "Select data that will be hidden."
+msgstr "非表示にするデータを選択します。"
+
+msgid "MAC addresses"
+msgstr "MACアドレス"
+
+msgid "MAC addresses & Hostnames"
+msgstr "MACアドレス&ホスト名"
+
+msgid "Show wan in table"
+msgstr "テーブルにwanを表示"
+
+msgid "Check this option if you want wan to be visible in the table."
+msgstr "テーブルにwanが表示されるようにする場合はこのオプションをチェックします。"
+
+msgid "Enable data usage progress bar"
+msgstr "データ使用状況進捗バーを有効にする"
+
+msgid "Show a visualization of transfer usage in the form of a progress bar."
+msgstr "転送使用量をプログレスバーの形式で視覚化します。"
+
+msgid "Enter the available transfer during the billing period."
+msgstr "請求期間中に利用可能な転送を入力します。"
+
+msgid "Unit of data size"
+msgstr "データサイズの単位"
+
+msgid "Data Count Cycle"
+msgstr "データカウントサイクル"
+
+msgid "Specify the data visualization/counting interval."
+msgstr "データの可視化/カウント間隔を指定します。"
+
+msgid "Check this option if you want to save data during a scheduled device restart."
+msgstr "スケジュール設定されたデバイス再起動時にデータを保存する場合はこのオプションをチェックします。"
+
+msgid "Backup at"
+msgstr "バックアップを実行時刻"
+
+msgid "Restore backup at"
+msgstr "バックアップを復元時刻"
+
+msgid "Backup Settings"
+msgstr "バックアップ設定"
+
+msgid "Move .json file"
+msgstr ".jsonファイルを移動"
+
+msgid "Correct time format HH:MM."
+msgstr "正しい時刻形式HH:MM。"
+
+msgid "Expected time is in HH:MM format"
+msgstr "予想時刻はHH:MM形式です"
+
+msgid "Enter a numeric value"
+msgstr "数値を入力します"
+
+msgid "Add a hostname"
+msgstr "ホスト名を追加"
+
+msgid "Enter data as MAC adress;Hostname."
+msgstr "データをMACアドレス;ホスト名として入力します。"
+
+msgid "Transfer details"
+msgstr "転送の詳細"
+
+msgid "Enter the MAC address;Hostname"
+msgstr "MACアドレス;ホスト名を入力"
+
+msgid "Do you want to clear transfer statistics data?"
+msgstr "転送統計データをクリアしますか?"
+
+msgid "Transfer statistics"
+msgstr "転送統計"
+
+msgid "There are currently no data to show..."
+msgstr "表示するデータがありません..."
+
+msgid "Additional settings"
+msgstr "追加設定"
+
+msgid "from"
+msgstr "から"
+
+msgid "out of"
+msgstr "の中から"
+
+msgid "You have exceeded your available transfer by over"
+msgstr "利用可能な転送を超えています"
+
+msgid "Statistics from the current billing period."
+msgstr "現在の請求期間の統計。"
+
+msgid "Must be configured"
+msgstr "設定する必要があります"
+
+msgid "Press Continue to restore the backup, or Cancel to abort the operation."
+msgstr "バックアップを復元するには[続行]を押すか、操作を中止するには[キャンセル]を押します。"
+
+msgid "Restore .json file from archive"
+msgstr "アーカイブから.jsonファイルを復元"
+
+msgid "Option allows user to restore statistics from the archive."
+msgstr "オプションを使用するとユーザーはアーカイブから統計を復元できます。"
+
+msgid "Restore .json file"
+msgstr ".jsonファイルを復元"
+
+msgid "Option allows user to restore statistics from .json file."
+msgstr "オプションを使用するとユーザーは.jsonファイルから統計を復元できます。"
+
+msgid "Download .gz archive"
+msgstr ".gzアーカイブをダウンロード"
+
+msgid "Click to download .gz archive."
+msgstr "クリックして.gzアーカイブをダウンロード。"
+
+msgid "easyconfig_statistics.json.gz file not found."
+msgstr "easyconfig_statistics.json.gzファイルが見つかりません。"
+
+msgid "Download error"
+msgstr "ダウンロードエラー"
+
+msgid "Download .json file"
+msgstr ".jsonファイルをダウンロード"
+
+msgid "Click to download .json file."
+msgstr "クリックして.jsonファイルをダウンロード。"
+
+msgid "Download of easyconfig_statistics.json failed. Please try again."
+msgstr "easyconfig_statistics.jsonのダウンロードに失敗しました。もう一度お試しください。"
+
+msgid "Error executing easyconfig_statistics.sh"
+msgstr "easyconfig_statistics.shの実行エラー"
+
+msgid "Upload .gz archive"
+msgstr ".gzアーカイブをアップロード"
+
+msgid "Upload .json file"
+msgstr ".jsonファイルをアップロード"
+
+msgid "Save .gz file"
+msgstr ".gzファイルを保存"
+
+msgid "Save .json file"
+msgstr ".jsonファイルを保存"
+
+msgid "Copy .json file to external storage"
+msgstr ".jsonファイルを外部ストレージにコピー"
+
+msgid "Check this option if you want to create a copy on an external drive."
+msgstr "外部ドライブにコピーを作成する場合はこのオプションをチェックします。"
+
+msgid "Path to .json file"
+msgstr ".jsonファイルへのパス"
+
+msgid "Enter the path to the directory where a copy of the .json file will be saved."
+msgstr ".jsonファイルのコピーが保存されるディレクトリへのパスを入力します。"
+
+msgid "Data in easyconfig_statistics.json file has been reset."
+msgstr "easyconfig_statistics.jsonファイル内のデータがリセットされました。"
+
+msgid "Successfully copied easyconfig_statistics.json file to"
+msgstr "easyconfig_statistics.jsonファイルを正常にコピーしました"
+
+msgid "Successfully copied easyconfig_statistics.json file to /usr/lib/easyconfig."
+msgstr "easyconfig_statistics.jsonファイルを/usr/lib/easyconfigに正常にコピーしました。"
+
+msgid "Auto data reset"
+msgstr "自動データリセット"
+
+msgid "Check this option if you want reset data with the new year."
+msgstr "新年にデータをリセットする場合はこのオプションをチェックします。"
+
+msgid "Monthly"
+msgstr "月単位"
+
+msgid "Last 12 months"
+msgstr "過去12か月"
+
+msgid "Refreshing data…"
+msgstr "データを更新中…"
+
+msgid "Current period"
+msgstr "現在の期間"
+
+msgid "Presentation of downloaded and uploaded data. Click Refresh to update the charts."
+msgstr "ダウンロードおよびアップロードされたデータの表示。[更新]をクリックしてグラフを更新します。"
+
+msgid "Jan"
+msgstr "1月"
+
+msgid "Feb"
+msgstr "2月"
+
+msgid "Mar"
+msgstr "3月"
+
+msgid "Apr"
+msgstr "4月"
+
+msgid "May"
+msgstr "5月"
+
+msgid "Jun"
+msgstr "6月"
+
+msgid "Jul"
+msgstr "7月"
+
+msgid "Aug"
+msgstr "8月"
+
+msgid "Sep"
+msgstr "9月"
+
+msgid "Oct"
+msgstr "10月"
+
+msgid "Nov"
+msgstr "11月"
+
+msgid "Dec"
+msgstr "12月"
+
+msgid "No data available"
+msgstr "データが利用できません"
+
+msgid "Percentage"
+msgstr "パーセンテージ"
+
+msgid "Legend"
+msgstr "凡例"
+
+msgid "Select day"
+msgstr "日を選択"
+
+msgid "Select month"
+msgstr "月を選択"
+
+msgid "Select year"
+msgstr "年を選択"
+
+msgid "Select period"
+msgstr "期間を選択"
+
+msgid "Others"
+msgstr "その他"
+
+msgid "(Hour-by-hour data usage chart for selected day)"
+msgstr "(選択した日の時間ごとのデータ使用量グラフ)"
+
+msgid "(Daily usage chart for a selected month)"
+msgstr "(選択した月の日単位使用量グラフ)"
+
+msgid "(Data usage chart for individual months)"
+msgstr "(個別の月のデータ使用量グラフ)"
+
+msgid "(Data usage chart for each month of the year "
+msgstr "(年の各月のデータ使用量グラフ"
+
+msgid "Refreshing data..."
+msgstr "データを更新しています..."
+
+msgid "Please wait..."
+msgstr "お待ちください..."
+
+msgid "Statistics of data usage by clients."
+msgstr "クライアントによるデータ使用統計。"
+
+msgid "Clients"
+msgstr "クライアント"
+
+msgid "Do you want to clear transfer statistics data?"
+msgstr "転送統計データをクリアしますか?"
+
+msgid "Statistics data cleared"
+msgstr "統計データがクリアされました"
+
+msgid "No hourly data available for this day"
+msgstr "この日の時間ごとのデータはありません"
+
+msgid "Would you like to show an estimated hourly distribution based on daily totals? (This is only an approximation)"
+msgstr "日単位の合計に基づいて推定時間分布を表示しますか?(これは近似値です)"
+
+msgid "Yes, show estimate"
+msgstr "はい、推定値を表示"
+
+msgid "Size of .json file"
+msgstr ".jsonファイルのサイズ"
+
+msgid "Size of .gz file"
+msgstr ".gzファイルのサイズ"
+
+msgid "Client"
+msgstr "クライアント"
+
+msgid "Date"
+msgstr "日付"
+
+msgid "Statistics restored from external backup"
+msgstr "外部バックアップから復元された統計"
+
+msgid "Please enter a hostname"
+msgstr "ホスト名を入力してください"
+
+msgid "Configuration error"
+msgstr "設定エラー"
+
+msgid "Hostname added successfully. Reloading..."
+msgstr "ホスト名が正常に追加されました。リロード中..."
+
+msgid "Enter hostname"
+msgstr "ホスト名を入力"
+
+msgid "Hostname"
+msgstr "ホスト名"
+
+msgid "Hostname Settings"
+msgstr "ホスト名設定"
+
+msgid "hostname"
+msgstr "ホスト名"
diff --git a/luci-app-easyconfig-transfer/po/ko/easyconfig-transfer.po b/luci-app-easyconfig-transfer/po/ko/easyconfig-transfer.po
new file mode 100644
index 000000000..c1eea8488
--- /dev/null
+++ b/luci-app-easyconfig-transfer/po/ko/easyconfig-transfer.po
@@ -0,0 +1,517 @@
+msgid ""
+msgstr ""
+"Language: ko\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgid "Transfer"
+msgstr "전송"
+
+msgid "User interface for easyconfig scripts estimating transfer consumption. More information on the %seko.one.pl forum%s."
+msgstr "전송 소비를 추정하는 easyconfig 스크립트용 사용자 인터페이스. 자세한 정보는 %seko.one.pl 포럼%s을(를) 참조하세요."
+
+msgid "Estimated data usage"
+msgstr "추정 데이터 사용량"
+
+msgid "First Seen"
+msgstr "처음 확인"
+
+msgid "Last Seen"
+msgstr "마지막 확인"
+
+msgid "Downloaded"
+msgstr "다운로드"
+
+msgid "Uploaded"
+msgstr "업로드"
+
+msgid "Configuration - Transfer"
+msgstr "설정 - 전송"
+
+msgid "Configuration panel of the application calculating transfer statistics."
+msgstr "전송 통계를 계산하는 애플리케이션의 설정 패널."
+
+msgid "Data reading period"
+msgstr "데이터 읽기 기간"
+
+msgid "Data recording period"
+msgstr "데이터 기록 기간"
+
+msgid "Beginning of the billing period"
+msgstr "청구 기간 시작"
+
+msgid "Warning enabled"
+msgstr "경고 활성화"
+
+msgid "Transfer available"
+msgstr "사용 가능한 전송"
+
+msgid "Warning level"
+msgstr "경고 수준"
+
+msgid "Warning cycle"
+msgstr "경고 주기"
+
+msgid "per period"
+msgstr "기간당"
+
+msgid "per day"
+msgstr "일당"
+
+msgid "Days until the end of the billing period"
+msgstr "청구 기간 종료까지의 일수"
+
+msgid "Estimated remaining transfer"
+msgstr "추정 남은 전송"
+
+msgid "approximately remains"
+msgstr "대략 남음"
+
+msgid "Summary"
+msgstr "요약"
+
+msgid "Today"
+msgstr "오늘"
+
+msgid "Yesterday"
+msgstr "어제"
+
+msgid "Last 7 days"
+msgstr "지난 7일"
+
+msgid "Last 30 days"
+msgstr "지난 30일"
+
+msgid "Yearly"
+msgstr "연간"
+
+msgid "Clients data usage"
+msgstr "클라이언트 데이터 사용량"
+
+msgid "Total"
+msgstr "합계"
+
+msgid "Current billing period"
+msgstr "현재 청구 기간"
+
+msgid "Expected data usage for the current period"
+msgstr "현재 기간의 예상 데이터 사용량"
+
+msgid "Previous billing period"
+msgstr "이전 청구 기간"
+
+msgid "Transfer usage statistics"
+msgstr "전송 사용 통계"
+
+msgid "Calculations may differ from the operator indications"
+msgstr "계산이 운영자 표시와 다를 수 있습니다"
+
+msgid "Make a copy of Database"
+msgstr "데이터베이스 복사본 만들기"
+
+msgid "Restore"
+msgstr "복원"
+
+msgid "Make"
+msgstr "만들기"
+
+msgid "a backup"
+msgstr "백업"
+
+msgid "Make a backup"
+msgstr "백업 만들기"
+
+msgid "Reset data"
+msgstr "데이터 재설정"
+
+msgid "Main Settings"
+msgstr "주요 설정"
+
+msgid "Traffic Settings"
+msgstr "트래픽 설정"
+
+msgid "Traffic Settings"
+msgstr "트래픽 설정"
+
+msgid "Hide MAC addresses"
+msgstr "MAC 주소 숨기기"
+
+msgid "Hide MAC addresses without transfer information."
+msgstr "전송 정보가 없는 MAC 주소를 숨깁니다."
+
+msgid ""
+"Select how often a compressed copy of the data will be made.
Archive path /usr/lib/easyconfig/easyconfig_statistics.json.gz.
Important
Please "
+"remember that frequent write operations shorten the life cycle of memory."
+msgstr ""
+"압축된 데이터 복사본을 만드는 빈도를 선택합니다.
아카이브 경로 /usr/lib/easyconfig/easyconfig_statistics.json.gz.
중요
빈번한 쓰기 작업은 메모리의 수명을 단축한다는 점을 기억하세요."
+
+msgid ""
+"Enable transfer data collection.
Data is saved to file /tmp/easyconfig_statistics.json.
What you should know
With "
+"flow offloading enabled, transfer data will be inconsistent with reality or may be completely unavailable."
+
+msgstr ""
+"전송 데이터 수집을 활성화합니다.
데이터는 파일 /tmp/easyconfig_statistics.json에 저장됩니다.
알아야 할 사항
플로우 오프로딩이 활성화되면 전송 데이터가 현실과 일치하지 않거나 완전히 사용할 수 없을 수 있습니다."
+
+msgid "1 minute"
+msgstr "1분"
+
+msgid "3 minutes"
+msgstr "3분"
+
+msgid "5 minutes"
+msgstr "5분"
+
+msgid "10 minutes"
+msgstr "10분"
+
+msgid "15 minutes"
+msgstr "15분"
+
+msgid "30 minutes"
+msgstr "30분"
+
+msgid "1 hour"
+msgstr "1시간"
+
+msgid "3 hours"
+msgstr "3시간"
+
+msgid "6 hours"
+msgstr "6시간"
+
+msgid "12 hours"
+msgstr "12시간"
+
+msgid "24 hours"
+msgstr "24시간"
+
+msgid "Enter the starting day of the billing period."
+msgstr "청구 기간의 시작일을 입력합니다."
+
+msgid "Hide selected data in the table"
+msgstr "테이블에서 선택된 데이터 숨기기"
+
+msgid "Select data that will be hidden."
+msgstr "숨길 데이터를 선택합니다."
+
+msgid "MAC addresses"
+msgstr "MAC 주소"
+
+msgid "MAC addresses & Hostnames"
+msgstr "MAC 주소 & 호스트 이름"
+
+msgid "Show wan in table"
+msgstr "테이블에서 wan 표시"
+
+msgid "Check this option if you want wan to be visible in the table."
+msgstr "테이블에서 wan을 표시하려면 이 옵션을 선택합니다."
+
+msgid "Enable data usage progress bar"
+msgstr "데이터 사용량 진행률 표시줄 활성화"
+
+msgid "Show a visualization of transfer usage in the form of a progress bar."
+msgstr "전송 사용량을 진행률 표시줄 형태로 시각화합니다."
+
+msgid "Enter the available transfer during the billing period."
+msgstr "청구 기간 중 사용 가능한 전송을 입력합니다."
+
+msgid "Unit of data size"
+msgstr "데이터 크기 단위"
+
+msgid "Data Count Cycle"
+msgstr "데이터 카운트 주기"
+
+msgid "Specify the data visualization/counting interval."
+msgstr "데이터 시각화/카운팅 간격을 지정합니다."
+
+msgid "Check this option if you want to save data during a scheduled device restart."
+msgstr "예약된 장치 재시작 시 데이터를 저장하려면 이 옵션을 선택합니다."
+
+msgid "Backup at"
+msgstr "백업 시간"
+
+msgid "Restore backup at"
+msgstr "백업 복원 시간"
+
+msgid "Backup Settings"
+msgstr "백업 설정"
+
+msgid "Move .json file"
+msgstr ".json 파일 이동"
+
+msgid "Correct time format HH:MM."
+msgstr "올바른 시간 형식 HH:MM."
+
+msgid "Expected time is in HH:MM format"
+msgstr "예상 시간은 HH:MM 형식입니다"
+
+msgid "Enter a numeric value"
+msgstr "숫자 값을 입력합니다"
+
+msgid "Add a hostname"
+msgstr "호스트 이름 추가"
+
+msgid "Enter data as MAC adress;Hostname."
+msgstr "데이터를 MAC 주소;호스트 이름으로 입력합니다."
+
+msgid "Transfer details"
+msgstr "전송 세부 정보"
+
+msgid "Enter the MAC address;Hostname"
+msgstr "MAC 주소;호스트 이름 입력"
+
+msgid "Do you want to clear transfer statistics data?"
+msgstr "전송 통계 데이터를 지우시겠습니까?"
+
+msgid "Transfer statistics"
+msgstr "전송 통계"
+
+msgid "There are currently no data to show..."
+msgstr "표시할 데이터가 없습니다..."
+
+msgid "Additional settings"
+msgstr "추가 설정"
+
+msgid "from"
+msgstr "에서"
+
+msgid "out of"
+msgstr "중에서"
+
+msgid "You have exceeded your available transfer by over"
+msgstr "사용 가능한 전송을 초과했습니다"
+
+msgid "Statistics from the current billing period."
+msgstr "현재 청구 기간의 통계입니다."
+
+msgid "Must be configured"
+msgstr "구성해야 함"
+
+msgid "Press Continue to restore the backup, or Cancel to abort the operation."
+msgstr "백업을 복원하려면 계속을 누르거나 작업을 중단하려면 취소를 누르세요."
+
+msgid "Restore .json file from archive"
+msgstr "아카이브에서 .json 파일 복원"
+
+msgid "Option allows user to restore statistics from the archive."
+msgstr "옵션을 사용하면 사용자가 아카이브에서 통계를 복원할 수 있습니다."
+
+msgid "Restore .json file"
+msgstr ".json 파일 복원"
+
+msgid "Option allows user to restore statistics from .json file."
+msgstr "옵션을 사용하면 사용자가 .json 파일에서 통계를 복원할 수 있습니다."
+
+msgid "Download .gz archive"
+msgstr ".gz 아카이브 다운로드"
+
+msgid "Click to download .gz archive."
+msgstr ".gz 아카이브를 다운로드하려면 클릭합니다."
+
+msgid "easyconfig_statistics.json.gz file not found."
+msgstr "easyconfig_statistics.json.gz 파일을 찾을 수 없습니다."
+
+msgid "Download error"
+msgstr "다운로드 오류"
+
+msgid "Download .json file"
+msgstr ".json 파일 다운로드"
+
+msgid "Click to download .json file."
+msgstr ".json 파일을 다운로드하려면 클릭합니다."
+
+msgid "Download of easyconfig_statistics.json failed. Please try again."
+msgstr "easyconfig_statistics.json 다운로드 실패. 다시 시도하세요."
+
+msgid "Error executing easyconfig_statistics.sh"
+msgstr "easyconfig_statistics.sh 실행 오류"
+
+msgid "Upload .gz archive"
+msgstr ".gz 아카이브 업로드"
+
+msgid "Upload .json file"
+msgstr ".json 파일 업로드"
+
+msgid "Save .gz file"
+msgstr ".gz 파일 저장"
+
+msgid "Save .json file"
+msgstr ".json 파일 저장"
+
+msgid "Copy .json file to external storage"
+msgstr ".json 파일을 외부 저장소에 복사"
+
+msgid "Check this option if you want to create a copy on an external drive."
+msgstr "외부 드라이브에 복사본을 만들려면 이 옵션을 선택합니다."
+
+msgid "Path to .json file"
+msgstr ".json 파일 경로"
+
+msgid "Enter the path to the directory where a copy of the .json file will be saved."
+msgstr ".json 파일의 복사본이 저장될 디렉토리의 경로를 입력합니다."
+
+msgid "Data in easyconfig_statistics.json file has been reset."
+msgstr "easyconfig_statistics.json 파일의 데이터가 재설정되었습니다."
+
+msgid "Successfully copied easyconfig_statistics.json file to"
+msgstr "easyconfig_statistics.json 파일을 다음으로 성공적으로 복사했습니다"
+
+msgid "Successfully copied easyconfig_statistics.json file to /usr/lib/easyconfig."
+msgstr "easyconfig_statistics.json 파일을 /usr/lib/easyconfig에 성공적으로 복사했습니다."
+
+msgid "Auto data reset"
+msgstr "자동 데이터 재설정"
+
+msgid "Check this option if you want reset data with the new year."
+msgstr "새해에 데이터를 재설정하려면 이 옵션을 선택합니다."
+
+msgid "Monthly"
+msgstr "월간"
+
+msgid "Last 12 months"
+msgstr "지난 12개월"
+
+msgid "Refreshing data…"
+msgstr "데이터 새로 고침 중…"
+
+msgid "Current period"
+msgstr "현재 기간"
+
+msgid "Presentation of downloaded and uploaded data. Click Refresh to update the charts."
+msgstr "다운로드 및 업로드된 데이터의 표시입니다. 차트를 업데이트하려면 새로 고침을 클릭합니다."
+
+msgid "Jan"
+msgstr "1월"
+
+msgid "Feb"
+msgstr "2월"
+
+msgid "Mar"
+msgstr "3월"
+
+msgid "Apr"
+msgstr "4월"
+
+msgid "May"
+msgstr "5월"
+
+msgid "Jun"
+msgstr "6월"
+
+msgid "Jul"
+msgstr "7월"
+
+msgid "Aug"
+msgstr "8월"
+
+msgid "Sep"
+msgstr "9월"
+
+msgid "Oct"
+msgstr "10월"
+
+msgid "Nov"
+msgstr "11월"
+
+msgid "Dec"
+msgstr "12월"
+
+msgid "No data available"
+msgstr "사용 가능한 데이터 없음"
+
+msgid "Percentage"
+msgstr "백분율"
+
+msgid "Legend"
+msgstr "범례"
+
+msgid "Select day"
+msgstr "날짜 선택"
+
+msgid "Select month"
+msgstr "월 선택"
+
+msgid "Select year"
+msgstr "연도 선택"
+
+msgid "Select period"
+msgstr "기간 선택"
+
+msgid "Others"
+msgstr "기타"
+
+msgid "(Hour-by-hour data usage chart for selected day)"
+msgstr "(선택한 날짜의 시간별 데이터 사용량 차트)"
+
+msgid "(Daily usage chart for a selected month)"
+msgstr "(선택한 월의 일일 사용량 차트)"
+
+msgid "(Data usage chart for individual months)"
+msgstr "(개별 월의 데이터 사용량 차트)"
+
+msgid "(Data usage chart for each month of the year "
+msgstr "(연도의 각 월 데이터 사용량 차트"
+
+msgid "Refreshing data..."
+msgstr "데이터를 새로 고치는 중..."
+
+msgid "Please wait..."
+msgstr "잠시 기다려주세요..."
+
+msgid "Statistics of data usage by clients."
+msgstr "클라이언트별 데이터 사용 통계입니다."
+
+msgid "Clients"
+msgstr "클라이언트"
+
+msgid "Do you want to clear transfer statistics data?"
+msgstr "전송 통계 데이터를 지우시겠습니까?"
+
+msgid "Statistics data cleared"
+msgstr "통계 데이터가 지워졌습니다"
+
+msgid "No hourly data available for this day"
+msgstr "이 날짜의 시간별 데이터가 없습니다"
+
+msgid "Would you like to show an estimated hourly distribution based on daily totals? (This is only an approximation)"
+msgstr "일일 합계를 기반으로 예상 시간별 분포를 표시하시겠습니까? (이것은 근사치일 뿐입니다)"
+
+msgid "Yes, show estimate"
+msgstr "예, 예상치 표시"
+
+msgid "Size of .json file"
+msgstr ".json 파일의 크기"
+
+msgid "Size of .gz file"
+msgstr ".gz 파일의 크기"
+
+msgid "Client"
+msgstr "클라이언트"
+
+msgid "Date"
+msgstr "날짜"
+
+msgid "Statistics restored from external backup"
+msgstr "외부 백업에서 복원된 통계"
+
+msgid "Please enter a hostname"
+msgstr "호스트 이름을 입력하세요"
+
+msgid "Configuration error"
+msgstr "구성 오류"
+
+msgid "Hostname added successfully. Reloading..."
+msgstr "호스트 이름이 성공적으로 추가되었습니다. 다시 로드 중..."
+
+msgid "Enter hostname"
+msgstr "호스트 이름 입력"
+
+msgid "Hostname"
+msgstr "호스트 이름"
+
+msgid "Hostname Settings"
+msgstr "호스트 이름 설정"
+
+msgid "hostname"
+msgstr "호스트 이름"
diff --git a/luci-app-easyconfig-transfer/po/pl/easyconfig-transfer.po b/luci-app-easyconfig-transfer/po/pl/easyconfig-transfer.po
index 29f89d2b8..6eea4cb3d 100644
--- a/luci-app-easyconfig-transfer/po/pl/easyconfig-transfer.po
+++ b/luci-app-easyconfig-transfer/po/pl/easyconfig-transfer.po
@@ -492,3 +492,24 @@ msgstr "Data"
msgid "Statistics restored from external backup"
msgstr "Statystyki przywrócone z zewnętrznej kopii zapasowej"
+
+msgid "Please enter a hostname"
+msgstr "Proszę wprowadzić nazwę hosta"
+
+msgid "Configuration error"
+msgstr "Błąd konfiguracji"
+
+msgid "Hostname added successfully. Reloading..."
+msgstr "Nazwa hosta została pomyślnie dodana. Odświeżam widok…"
+
+msgid "Enter hostname"
+msgstr "Podaj nazwę hosta"
+
+msgid "Hostname"
+msgstr "Nazwa hosta"
+
+msgid "Hostname Settings"
+msgstr "Ustawienia nazwy hosta"
+
+msgid "hostname"
+msgstr "nazwa hosta"
diff --git a/luci-app-easyconfig-transfer/po/pt_BR/easyconfig-transfer.po b/luci-app-easyconfig-transfer/po/pt_BR/easyconfig-transfer.po
new file mode 100644
index 000000000..f63f0a3f6
--- /dev/null
+++ b/luci-app-easyconfig-transfer/po/pt_BR/easyconfig-transfer.po
@@ -0,0 +1,517 @@
+msgid ""
+msgstr ""
+"Language: pt_BR\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
+
+msgid "Transfer"
+msgstr "Transferência"
+
+msgid "User interface for easyconfig scripts estimating transfer consumption. More information on the %seko.one.pl forum%s."
+msgstr "Interface do usuário para scripts easyconfig que estimam o consumo de transferência. Mais informações no fórum %seko.one.pl%s."
+
+msgid "Estimated data usage"
+msgstr "Uso estimado de dados"
+
+msgid "First Seen"
+msgstr "Primeira vista"
+
+msgid "Last Seen"
+msgstr "Última vista"
+
+msgid "Downloaded"
+msgstr "Baixado"
+
+msgid "Uploaded"
+msgstr "Enviado"
+
+msgid "Configuration - Transfer"
+msgstr "Configuração - Transferência"
+
+msgid "Configuration panel of the application calculating transfer statistics."
+msgstr "Painel de configuração do aplicativo que calcula estatísticas de transferência."
+
+msgid "Data reading period"
+msgstr "Período de leitura de dados"
+
+msgid "Data recording period"
+msgstr "Período de gravação de dados"
+
+msgid "Beginning of the billing period"
+msgstr "Início do período de cobrança"
+
+msgid "Warning enabled"
+msgstr "Aviso ativado"
+
+msgid "Transfer available"
+msgstr "Transferência disponível"
+
+msgid "Warning level"
+msgstr "Nível de aviso"
+
+msgid "Warning cycle"
+msgstr "Ciclo de aviso"
+
+msgid "per period"
+msgstr "por período"
+
+msgid "per day"
+msgstr "por dia"
+
+msgid "Days until the end of the billing period"
+msgstr "Dias até o final do período de cobrança"
+
+msgid "Estimated remaining transfer"
+msgstr "Transferência restante estimada"
+
+msgid "approximately remains"
+msgstr "aproximadamente permanece"
+
+msgid "Summary"
+msgstr "Resumo"
+
+msgid "Today"
+msgstr "Hoje"
+
+msgid "Yesterday"
+msgstr "Ontem"
+
+msgid "Last 7 days"
+msgstr "Últimos 7 dias"
+
+msgid "Last 30 days"
+msgstr "Últimos 30 dias"
+
+msgid "Yearly"
+msgstr "Anualmente"
+
+msgid "Clients data usage"
+msgstr "Uso de dados dos clientes"
+
+msgid "Total"
+msgstr "Total"
+
+msgid "Current billing period"
+msgstr "Período de cobrança atual"
+
+msgid "Expected data usage for the current period"
+msgstr "Uso de dados esperado para o período atual"
+
+msgid "Previous billing period"
+msgstr "Período de cobrança anterior"
+
+msgid "Transfer usage statistics"
+msgstr "Estatísticas de uso de transferência"
+
+msgid "Calculations may differ from the operator indications"
+msgstr "Os cálculos podem diferir das indicações do operador"
+
+msgid "Make a copy of Database"
+msgstr "Fazer uma cópia do banco de dados"
+
+msgid "Restore"
+msgstr "Restaurar"
+
+msgid "Make"
+msgstr "Fazer"
+
+msgid "a backup"
+msgstr "um backup"
+
+msgid "Make a backup"
+msgstr "Fazer um backup"
+
+msgid "Reset data"
+msgstr "Redefinir dados"
+
+msgid "Main Settings"
+msgstr "Configurações principais"
+
+msgid "Traffic Settings"
+msgstr "Configurações de tráfego"
+
+msgid "Traffic Settings"
+msgstr "Configurações de tráfego"
+
+msgid "Hide MAC addresses"
+msgstr "Ocultar endereços MAC"
+
+msgid "Hide MAC addresses without transfer information."
+msgstr "Oculte endereços MAC sem informações de transferência."
+
+msgid ""
+"Select how often a compressed copy of the data will be made.
Archive path /usr/lib/easyconfig/easyconfig_statistics.json.gz.
Important
Please "
+"remember that frequent write operations shorten the life cycle of memory."
+msgstr ""
+"Selecione com que frequência uma cópia compactada dos dados será feita.
Caminho do arquivo /usr/lib/easyconfig/easyconfig_statistics.json.gz.
Importante
Lembre-se de que operações de escrita frequentes encurtam o ciclo de vida da memória."
+
+msgid ""
+"Enable transfer data collection.
Data is saved to file /tmp/easyconfig_statistics.json.
What you should know
With "
+"flow offloading enabled, transfer data will be inconsistent with reality or may be completely unavailable."
+
+msgstr ""
+"Ativar coleta de dados de transferência.
Os dados são salvos no arquivo /tmp/easyconfig_statistics.json.
O que você deve saber
Com o descarregamento de fluxo ativado, os dados de transferência estarão inconsistentes com a realidade ou podem estar completamente indisponíveis."
+
+msgid "1 minute"
+msgstr "1 minuto"
+
+msgid "3 minutes"
+msgstr "3 minutos"
+
+msgid "5 minutes"
+msgstr "5 minutos"
+
+msgid "10 minutes"
+msgstr "10 minutos"
+
+msgid "15 minutes"
+msgstr "15 minutos"
+
+msgid "30 minutes"
+msgstr "30 minutos"
+
+msgid "1 hour"
+msgstr "1 hora"
+
+msgid "3 hours"
+msgstr "3 horas"
+
+msgid "6 hours"
+msgstr "6 horas"
+
+msgid "12 hours"
+msgstr "12 horas"
+
+msgid "24 hours"
+msgstr "24 horas"
+
+msgid "Enter the starting day of the billing period."
+msgstr "Digite o dia inicial do período de cobrança."
+
+msgid "Hide selected data in the table"
+msgstr "Ocultar dados selecionados na tabela"
+
+msgid "Select data that will be hidden."
+msgstr "Selecione os dados que serão ocultados."
+
+msgid "MAC addresses"
+msgstr "Endereços MAC"
+
+msgid "MAC addresses & Hostnames"
+msgstr "Endereços MAC e nomes de host"
+
+msgid "Show wan in table"
+msgstr "Mostrar wan na tabela"
+
+msgid "Check this option if you want wan to be visible in the table."
+msgstr "Marque esta opção se desejar que wan fique visível na tabela."
+
+msgid "Enable data usage progress bar"
+msgstr "Ativar barra de progresso de uso de dados"
+
+msgid "Show a visualization of transfer usage in the form of a progress bar."
+msgstr "Exiba uma visualização do uso de transferência na forma de uma barra de progresso."
+
+msgid "Enter the available transfer during the billing period."
+msgstr "Digite a transferência disponível durante o período de cobrança."
+
+msgid "Unit of data size"
+msgstr "Unidade de tamanho de dados"
+
+msgid "Data Count Cycle"
+msgstr "Ciclo de contagem de dados"
+
+msgid "Specify the data visualization/counting interval."
+msgstr "Especifique o intervalo de visualização/contagem de dados."
+
+msgid "Check this option if you want to save data during a scheduled device restart."
+msgstr "Marque esta opção se desejar salvar dados durante uma reinicialização agendada do dispositivo."
+
+msgid "Backup at"
+msgstr "Backup em"
+
+msgid "Restore backup at"
+msgstr "Restaurar backup em"
+
+msgid "Backup Settings"
+msgstr "Configurações de backup"
+
+msgid "Move .json file"
+msgstr "Mover arquivo .json"
+
+msgid "Correct time format HH:MM."
+msgstr "Formato de hora correto HH:MM."
+
+msgid "Expected time is in HH:MM format"
+msgstr "A hora esperada está no formato HH:MM"
+
+msgid "Enter a numeric value"
+msgstr "Digite um valor numérico"
+
+msgid "Add a hostname"
+msgstr "Adicionar um nome de host"
+
+msgid "Enter data as MAC adress;Hostname."
+msgstr "Digite os dados como Endereço MAC;Nome do host."
+
+msgid "Transfer details"
+msgstr "Detalhes da transferência"
+
+msgid "Enter the MAC address;Hostname"
+msgstr "Digite o endereço MAC;nome do host"
+
+msgid "Do you want to clear transfer statistics data?"
+msgstr "Deseja limpar os dados de estatísticas de transferência?"
+
+msgid "Transfer statistics"
+msgstr "Estatísticas de transferência"
+
+msgid "There are currently no data to show..."
+msgstr "Atualmente não há dados para mostrar..."
+
+msgid "Additional settings"
+msgstr "Configurações adicionais"
+
+msgid "from"
+msgstr "de"
+
+msgid "out of"
+msgstr "fora de"
+
+msgid "You have exceeded your available transfer by over"
+msgstr "Você excedeu sua transferência disponível por"
+
+msgid "Statistics from the current billing period."
+msgstr "Estatísticas do período de cobrança atual."
+
+msgid "Must be configured"
+msgstr "Deve ser configurado"
+
+msgid "Press Continue to restore the backup, or Cancel to abort the operation."
+msgstr "Pressione Continuar para restaurar o backup ou Cancelar para anular a operação."
+
+msgid "Restore .json file from archive"
+msgstr "Restaurar arquivo .json do arquivo"
+
+msgid "Option allows user to restore statistics from the archive."
+msgstr "A opção permite que o usuário restaure estatísticas do arquivo."
+
+msgid "Restore .json file"
+msgstr "Restaurar arquivo .json"
+
+msgid "Option allows user to restore statistics from .json file."
+msgstr "A opção permite que o usuário restaure estatísticas do arquivo .json."
+
+msgid "Download .gz archive"
+msgstr "Baixar arquivo .gz"
+
+msgid "Click to download .gz archive."
+msgstr "Clique para baixar o arquivo .gz."
+
+msgid "easyconfig_statistics.json.gz file not found."
+msgstr "Arquivo easyconfig_statistics.json.gz não encontrado."
+
+msgid "Download error"
+msgstr "Erro de download"
+
+msgid "Download .json file"
+msgstr "Baixar arquivo .json"
+
+msgid "Click to download .json file."
+msgstr "Clique para baixar o arquivo .json."
+
+msgid "Download of easyconfig_statistics.json failed. Please try again."
+msgstr "O download de easyconfig_statistics.json falhou. Por favor, tente novamente."
+
+msgid "Error executing easyconfig_statistics.sh"
+msgstr "Erro ao executar easyconfig_statistics.sh"
+
+msgid "Upload .gz archive"
+msgstr "Carregar arquivo .gz"
+
+msgid "Upload .json file"
+msgstr "Carregar arquivo .json"
+
+msgid "Save .gz file"
+msgstr "Salvar arquivo .gz"
+
+msgid "Save .json file"
+msgstr "Salvar arquivo .json"
+
+msgid "Copy .json file to external storage"
+msgstr "Copiar arquivo .json para armazenamento externo"
+
+msgid "Check this option if you want to create a copy on an external drive."
+msgstr "Marque esta opção se desejar criar uma cópia em uma unidade externa."
+
+msgid "Path to .json file"
+msgstr "Caminho para o arquivo .json"
+
+msgid "Enter the path to the directory where a copy of the .json file will be saved."
+msgstr "Digite o caminho do diretório onde uma cópia do arquivo .json será salva."
+
+msgid "Data in easyconfig_statistics.json file has been reset."
+msgstr "Os dados no arquivo easyconfig_statistics.json foram redefinidos."
+
+msgid "Successfully copied easyconfig_statistics.json file to"
+msgstr "Arquivo easyconfig_statistics.json copiado com sucesso para"
+
+msgid "Successfully copied easyconfig_statistics.json file to /usr/lib/easyconfig."
+msgstr "Arquivo easyconfig_statistics.json copiado com sucesso para /usr/lib/easyconfig."
+
+msgid "Auto data reset"
+msgstr "Redefinição automática de dados"
+
+msgid "Check this option if you want reset data with the new year."
+msgstr "Marque esta opção se desejar redefinir dados com o novo ano."
+
+msgid "Monthly"
+msgstr "Mensalmente"
+
+msgid "Last 12 months"
+msgstr "Últimos 12 meses"
+
+msgid "Refreshing data…"
+msgstr "Atualizando dados…"
+
+msgid "Current period"
+msgstr "Período atual"
+
+msgid "Presentation of downloaded and uploaded data. Click Refresh to update the charts."
+msgstr "Apresentação de dados baixados e enviados. Clique em Atualizar para atualizar os gráficos."
+
+msgid "Jan"
+msgstr "Jan"
+
+msgid "Feb"
+msgstr "Fev"
+
+msgid "Mar"
+msgstr "Mar"
+
+msgid "Apr"
+msgstr "Abr"
+
+msgid "May"
+msgstr "Mai"
+
+msgid "Jun"
+msgstr "Jun"
+
+msgid "Jul"
+msgstr "Jul"
+
+msgid "Aug"
+msgstr "Ago"
+
+msgid "Sep"
+msgstr "Set"
+
+msgid "Oct"
+msgstr "Out"
+
+msgid "Nov"
+msgstr "Nov"
+
+msgid "Dec"
+msgstr "Dez"
+
+msgid "No data available"
+msgstr "Nenhum dado disponível"
+
+msgid "Percentage"
+msgstr "Porcentagem"
+
+msgid "Legend"
+msgstr "Legenda"
+
+msgid "Select day"
+msgstr "Selecionar dia"
+
+msgid "Select month"
+msgstr "Selecionar mês"
+
+msgid "Select year"
+msgstr "Selecionar ano"
+
+msgid "Select period"
+msgstr "Selecionar período"
+
+msgid "Others"
+msgstr "Outros"
+
+msgid "(Hour-by-hour data usage chart for selected day)"
+msgstr "(Gráfico de uso de dados hora a hora para o dia selecionado)"
+
+msgid "(Daily usage chart for a selected month)"
+msgstr "(Gráfico de uso diário para um mês selecionado)"
+
+msgid "(Data usage chart for individual months)"
+msgstr "(Gráfico de uso de dados para meses individuais)"
+
+msgid "(Data usage chart for each month of the year "
+msgstr "(Gráfico de uso de dados para cada mês do ano "
+
+msgid "Refreshing data..."
+msgstr "Atualizando dados..."
+
+msgid "Please wait..."
+msgstr "Por favor aguarde..."
+
+msgid "Statistics of data usage by clients."
+msgstr "Estatísticas de uso de dados por clientes."
+
+msgid "Clients"
+msgstr "Clientes"
+
+msgid "Do you want to clear transfer statistics data?"
+msgstr "Deseja limpar os dados de estatísticas de transferência?"
+
+msgid "Statistics data cleared"
+msgstr "Dados de estatísticas limpos"
+
+msgid "No hourly data available for this day"
+msgstr "Nenhum dado por hora disponível para este dia"
+
+msgid "Would you like to show an estimated hourly distribution based on daily totals? (This is only an approximation)"
+msgstr "Gostaria de mostrar uma distribuição horária estimada com base nos totais diários? (Esta é apenas uma aproximação)"
+
+msgid "Yes, show estimate"
+msgstr "Sim, mostrar estimativa"
+
+msgid "Size of .json file"
+msgstr "Tamanho do arquivo .json"
+
+msgid "Size of .gz file"
+msgstr "Tamanho do arquivo .gz"
+
+msgid "Client"
+msgstr "Cliente"
+
+msgid "Date"
+msgstr "Data"
+
+msgid "Statistics restored from external backup"
+msgstr "Estatísticas restauradas do backup externo"
+
+msgid "Please enter a hostname"
+msgstr "Por favor, digite um nome de host"
+
+msgid "Configuration error"
+msgstr "Erro de configuração"
+
+msgid "Hostname added successfully. Reloading..."
+msgstr "Nome do host adicionado com sucesso. Recarregando..."
+
+msgid "Enter hostname"
+msgstr "Digitar nome do host"
+
+msgid "Hostname"
+msgstr "Nome do host"
+
+msgid "Hostname Settings"
+msgstr "Configurações de nome de host"
+
+msgid "hostname"
+msgstr "nome do host"
diff --git a/luci-app-easyconfig-transfer/po/ru/easyconfig-transfer.po b/luci-app-easyconfig-transfer/po/ru/easyconfig-transfer.po
index f4de41ba5..ba0c725d2 100644
--- a/luci-app-easyconfig-transfer/po/ru/easyconfig-transfer.po
+++ b/luci-app-easyconfig-transfer/po/ru/easyconfig-transfer.po
@@ -1,10 +1,11 @@
msgid ""
msgstr ""
-"Project-Id-Version: luci-app-easyconfig-transfer\n"
"Language-Team: Rafał Wabik (IceG)\n"
"Language: ru\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
msgid "Transfer"
msgstr "Трафик"
@@ -493,3 +494,24 @@ msgstr "Дата"
msgid "Statistics restored from external backup"
msgstr "Статистика восстановлена из внешней резервной копии"
+
+msgid "Please enter a hostname"
+msgstr "Пожалуйста, введите имя хоста"
+
+msgid "Configuration error"
+msgstr "Ошибка конфигурации"
+
+msgid "Hostname added successfully. Reloading..."
+msgstr "Имя хоста успешно добавлено. Перезагрузка…"
+
+msgid "Enter hostname"
+msgstr "Введите имя хоста"
+
+msgid "Hostname"
+msgstr "Имя хоста"
+
+msgid "Hostname Settings"
+msgstr "Настройки имени хоста"
+
+msgid "hostname"
+msgstr "имя хоста"
diff --git a/luci-app-easyconfig-transfer/po/vi/easyconfig-transfer.po b/luci-app-easyconfig-transfer/po/vi/easyconfig-transfer.po
index a33947c46..5f78572bd 100644
--- a/luci-app-easyconfig-transfer/po/vi/easyconfig-transfer.po
+++ b/luci-app-easyconfig-transfer/po/vi/easyconfig-transfer.po
@@ -1,10 +1,10 @@
msgid ""
msgstr ""
-"Project-Id-Version: luci-app-easyconfig-transfer\n"
"Language-Team: Rafał Wabik (IceG)\n"
"Language: vi\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
msgid "Transfer"
msgstr "Lưu lượng"
@@ -493,3 +493,24 @@ msgstr "Ngày"
msgid "Statistics restored from external backup"
msgstr "Thống kê đã được khôi phục từ bản sao lưu bên ngoài"
+
+msgid "Please enter a hostname"
+msgstr "Vui lòng nhập tên máy chủ"
+
+msgid "Configuration error"
+msgstr "Lỗi cấu hình"
+
+msgid "Hostname added successfully. Reloading..."
+msgstr "Đã thêm tên máy chủ thành công. Đang tải lại…"
+
+msgid "Enter hostname"
+msgstr "Nhập tên máy chủ"
+
+msgid "Hostname"
+msgstr "Tên máy chủ"
+
+msgid "Hostname Settings"
+msgstr "Cài đặt tên máy chủ"
+
+msgid "hostname"
+msgstr "tên máy chủ"
diff --git a/luci-app-easyconfig-transfer/po/zh_Hans/easyconfig-transfer.po b/luci-app-easyconfig-transfer/po/zh_Hans/easyconfig-transfer.po
index 7eb240dca..373be4ded 100644
--- a/luci-app-easyconfig-transfer/po/zh_Hans/easyconfig-transfer.po
+++ b/luci-app-easyconfig-transfer/po/zh_Hans/easyconfig-transfer.po
@@ -1,10 +1,10 @@
msgid ""
msgstr ""
-"Project-Id-Version: luci-app-easyconfig-transfer\n"
"Language-Team: Rafał Wabik (IceG)\n"
-"Language: zh_CN\n"
+"Language: zh_Hans\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
msgid "Transfer"
msgstr "流量"
@@ -493,3 +493,24 @@ msgstr "日期"
msgid "Statistics restored from external backup"
msgstr "统计数据已从外部备份恢复"
+
+msgid "Please enter a hostname"
+msgstr "请输入主机名"
+
+msgid "Configuration error"
+msgstr "配置错误"
+
+msgid "Hostname added successfully. Reloading..."
+msgstr "主机名添加成功。正在重新加载…"
+
+msgid "Enter hostname"
+msgstr "输入主机名"
+
+msgid "Hostname"
+msgstr "主机名"
+
+msgid "Hostname Settings"
+msgstr "主机名设置"
+
+msgid "hostname"
+msgstr "主机名"
diff --git a/luci-app-easyconfig-transfer/po/zh_Hant/easyconfig-transfer.po b/luci-app-easyconfig-transfer/po/zh_Hant/easyconfig-transfer.po
index 9c6e0f477..b4a415243 100644
--- a/luci-app-easyconfig-transfer/po/zh_Hant/easyconfig-transfer.po
+++ b/luci-app-easyconfig-transfer/po/zh_Hant/easyconfig-transfer.po
@@ -1,10 +1,10 @@
msgid ""
msgstr ""
-"Project-Id-Version: luci-app-easyconfig-transfer\n"
"Language-Team: Rafał Wabik (IceG)\n"
-"Language: zh_TW\n"
+"Language: zh_Hant\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
msgid "Transfer"
msgstr "流量"
@@ -493,3 +493,24 @@ msgstr "日期"
msgid "Statistics restored from external backup"
msgstr "統計資料已從外部備份還原"
+
+msgid "Please enter a hostname"
+msgstr "請輸入主機名稱"
+
+msgid "Configuration error"
+msgstr "設定錯誤"
+
+msgid "Hostname added successfully. Reloading..."
+msgstr "主機名稱已成功新增。正在重新載入…"
+
+msgid "Enter hostname"
+msgstr "輸入主機名稱"
+
+msgid "Hostname"
+msgstr "主機名稱"
+
+msgid "Hostname Settings"
+msgstr "主機名稱設定"
+
+msgid "hostname"
+msgstr "主機名稱"
diff --git a/luci-app-easyconfig-transfer/root/etc/uci-defaults/setup_easyconfig_transfer.sh b/luci-app-easyconfig-transfer/root/etc/uci-defaults/setup_easyconfig_transfer.sh
index 92a8acd8b..6a74b8d0f 100644
--- a/luci-app-easyconfig-transfer/root/etc/uci-defaults/setup_easyconfig_transfer.sh
+++ b/luci-app-easyconfig-transfer/root/etc/uci-defaults/setup_easyconfig_transfer.sh
@@ -1,15 +1,18 @@
#!/bin/sh
-# Copyright 2024 Rafał Wabik (IceG) - From eko.one.pl forum
+# Copyright 2024-2026 Rafał Wabik (IceG) - From eko.one.pl forum
# Licensed to the GNU General Public License v3.0.
-chmod +x /etc/uci-defaults/setup_easyconfig_transfer.sh 2>&1 &
-chmod +x /sbin/transfer2cron.sh 2>&1 &
-chmod +x /sbin/backup2cron.sh 2>&1 &
-chmod +x /usr/bin/easyconfig_statistics.sh 2>&1 &
-chmod +x /usr/bin/easyconfig_statistics.uc 2>&1 &
+chmod +x /etc/uci-defaults/setup_easyconfig_transfer.sh >/dev/null 2>&1 &
-echo "{}" > /tmp/easyconfig_statistics.json
+chmod +x /usr/bin/auto_reset_statistics.sh >/dev/null 2>&1 &
-rm -rf /tmp/luci-indexcache 2>&1 &
-rm -rf /tmp/luci-modulecache/ 2>&1 &
+chmod +x /usr/bin/easyconfig_statistics.sh >/dev/null 2>&1 &
+chmod +x /usr/bin/easyconfig_statistics.uc >/dev/null 2>&1 &
+
+echo "{}" > /tmp/easyconfig_statistics.json >/dev/null 2>&1 &
+
+mkdir -p /usr/lib/easyconfig >/dev/null 2>&1 &
+
+rm -rf /tmp/luci-indexcache >/dev/null 2>&1 &
+rm -rf /tmp/luci-modulecache/ >/dev/null 2>&1 &
exit 0
diff --git a/luci-app-easyconfig-transfer/root/usr/bin/easyconfig_statistics.sh b/luci-app-easyconfig-transfer/root/usr/bin/easyconfig_statistics.sh
index 335634dd7..a17718e9c 100755
--- a/luci-app-easyconfig-transfer/root/usr/bin/easyconfig_statistics.sh
+++ b/luci-app-easyconfig-transfer/root/usr/bin/easyconfig_statistics.sh
@@ -24,38 +24,112 @@ MBACKUP=$(uci -q get easyconfig_transfer.traffic.external_backup)
MBACKUPATH=$(uci -q get easyconfig_transfer.traffic.external_path)
EXTERNAL_JSON="$MBACKUPATH/easyconfig_statistics.json"
+json_valid() {
+ local file="$1"
+ [ -e "$file" ] || return 1
+ [ -s "$file" ] || return 1
+ jq -e 'type == "object"' "$file" >/dev/null 2>&1
+}
+
+safe_copy() {
+ local src="$1"
+ local dst="$2"
+ if json_valid "$src"; then
+ cp "$src" "$dst"
+ return 0
+ else
+ logger -t easyconfig_statistics "OSTRZEŻENIE: plik $src zawiera nieprawidłowy JSON, pomijam kopiowanie"
+ return 1
+ fi
+}
+
if [ ! -e "$DB" ]; then
if [ "$MBACKUP" = "1" ] && [ -n "$MBACKUPATH" ] && [ -e "$EXTERNAL_JSON" ] && [ -e "$SDB" ]; then
TMP_GZ=/tmp/easyconfig_statistics_gz_tmp.json
zcat "$SDB" > "$TMP_GZ" 2>/dev/null
if [ -e "$TMP_GZ" ]; then
- EXT_SIZE=$(wc -c < "$EXTERNAL_JSON")
- GZ_SIZE=$(wc -c < "$TMP_GZ")
- if [ "$EXT_SIZE" -gt "$GZ_SIZE" ]; then
+
+ EXT_VALID=0
+ GZ_VALID=0
+ json_valid "$EXTERNAL_JSON" && EXT_VALID=1
+ json_valid "$TMP_GZ" && GZ_VALID=1
+
+ if [ "$EXT_VALID" = "1" ] && [ "$GZ_VALID" = "1" ]; then
+ EXT_SIZE=$(wc -c < "$EXTERNAL_JSON")
+ GZ_SIZE=$(wc -c < "$TMP_GZ")
+ if [ "$EXT_SIZE" -gt "$GZ_SIZE" ]; then
+ cp "$EXTERNAL_JSON" "$DB"
+ else
+ cp "$TMP_GZ" "$DB"
+ easyconfig_statistics.uc "init" "init" 0 0 0 "" 0
+ fi
+ elif [ "$EXT_VALID" = "1" ]; then
+ logger -t easyconfig_statistics "OSTRZEŻENIE: plik gz zawiera nieprawidłowy JSON, używam zewnętrznej kopii"
cp "$EXTERNAL_JSON" "$DB"
- else
+ elif [ "$GZ_VALID" = "1" ]; then
+ logger -t easyconfig_statistics "OSTRZEŻENIE: zewnętrzna kopia zawiera nieprawidłowy JSON, używam pliku gz"
cp "$TMP_GZ" "$DB"
easyconfig_statistics.uc "init" "init" 0 0 0 "" 0
+ else
+ logger -t easyconfig_statistics "OSTRZEŻENIE: oba źródła zawierają nieprawidłowy JSON, inicjalizuję nową bazę"
+ mkdir -p $(dirname "$SDB")
+ echo "{}" > "$DB"
fi
rm -f "$TMP_GZ"
else
- cp "$EXTERNAL_JSON" "$DB"
+ safe_copy "$EXTERNAL_JSON" "$DB" || echo "{}" > "$DB"
fi
elif [ "$MBACKUP" = "1" ] && [ -n "$MBACKUPATH" ] && [ -e "$EXTERNAL_JSON" ]; then
- cp "$EXTERNAL_JSON" "$DB"
+ safe_copy "$EXTERNAL_JSON" "$DB" || echo "{}" > "$DB"
elif [ -e "$SDB" ]; then
- zcat "$SDB" > "$DB"
- easyconfig_statistics.uc "init" "init" 0 0 0 "" 0
+ TMP_GZ=/tmp/easyconfig_statistics_gz_tmp.json
+ zcat "$SDB" > "$TMP_GZ" 2>/dev/null
+ if json_valid "$TMP_GZ"; then
+ mv "$TMP_GZ" "$DB"
+ easyconfig_statistics.uc "init" "init" 0 0 0 "" 0
+ else
+ logger -t easyconfig_statistics "OSTRZEŻENIE: plik gz zawiera nieprawidłowy JSON, inicjalizuję nową bazę"
+ rm -f "$TMP_GZ"
+ mkdir -p $(dirname "$SDB")
+ echo "{}" > "$DB"
+ fi
else
mkdir -p $(dirname "$SDB")
echo "{}" > "$DB"
fi
else
- if [ "$MBACKUP" = "1" ] && [ -n "$MBACKUPATH" ] && [ -e "$EXTERNAL_JSON" ]; then
- EXT_SIZE=$(wc -c < "$EXTERNAL_JSON")
- DB_SIZE=$(wc -c < "$DB")
- if [ "$EXT_SIZE" -gt "$DB_SIZE" ]; then
+ if ! json_valid "$DB"; then
+ logger -t easyconfig_statistics "OSTRZEŻENIE: bieżący plik $DB jest uszkodzony, próba odtworzenia"
+
+ if [ "$MBACKUP" = "1" ] && [ -n "$MBACKUPATH" ] && json_valid "$EXTERNAL_JSON"; then
+ logger -t easyconfig_statistics "Odtwarzanie z zewnętrznej kopii: $EXTERNAL_JSON"
cp "$EXTERNAL_JSON" "$DB"
+ elif [ -e "$SDB" ]; then
+ TMP_GZ=/tmp/easyconfig_statistics_gz_tmp.json
+ zcat "$SDB" > "$TMP_GZ" 2>/dev/null
+ if json_valid "$TMP_GZ"; then
+ logger -t easyconfig_statistics "Odtwarzanie z pliku gz: $SDB"
+ mv "$TMP_GZ" "$DB"
+ else
+ logger -t easyconfig_statistics "BŁĄD: brak poprawnego źródła do odtworzenia, inicjalizuję nową bazę"
+ rm -f "$TMP_GZ"
+ echo "{}" > "$DB"
+ fi
+ else
+ logger -t easyconfig_statistics "BŁĄD: brak źródła do odtworzenia, inicjalizuję nową bazę"
+ echo "{}" > "$DB"
+ fi
+ else
+ if [ "$MBACKUP" = "1" ] && [ -n "$MBACKUPATH" ] && [ -e "$EXTERNAL_JSON" ]; then
+ if json_valid "$EXTERNAL_JSON"; then
+ EXT_SIZE=$(wc -c < "$EXTERNAL_JSON")
+ DB_SIZE=$(wc -c < "$DB")
+ if [ "$EXT_SIZE" -gt "$DB_SIZE" ]; then
+ cp "$EXTERNAL_JSON" "$DB"
+ fi
+ else
+ logger -t easyconfig_statistics "OSTRZEŻENIE: zewnętrzna kopia $EXTERNAL_JSON jest uszkodzona, pomijam nadpisanie"
+ fi
fi
fi
fi
@@ -103,13 +177,21 @@ else
WRITETS=$((NOW - 1))
fi
if [ $WRITETS -le $NOW ]; then
- gzip -k "$DB"
- mv "$DB.gz" "$SDB"
- sync
+ if json_valid "$DB"; then
+ gzip -k "$DB"
+ mv "$DB.gz" "$SDB"
+ sync
+ else
+ logger -t easyconfig_statistics "OSTRZEŻENIE: $DB jest uszkodzony, pomijam zapis do archiwum gz"
+ fi
fi
if [ "$MBACKUP" = "1" ]; then
sleep 10
- cp "$DB" "$MBACKUPATH/easyconfig_statistics.json"
+ if json_valid "$DB"; then
+ cp "$DB" "$MBACKUPATH/easyconfig_statistics.json"
+ else
+ logger -t easyconfig_statistics "OSTRZEŻENIE: $DB jest uszkodzony, pomijam kopię zewnętrzną"
+ fi
fi
lock -u $LOCK
diff --git a/luci-app-easyconfig-transfer/root/usr/bin/easyconfig_statistics.uc b/luci-app-easyconfig-transfer/root/usr/bin/easyconfig_statistics.uc
index edb49a4d9..50006f106 100755
--- a/luci-app-easyconfig-transfer/root/usr/bin/easyconfig_statistics.uc
+++ b/luci-app-easyconfig-transfer/root/usr/bin/easyconfig_statistics.uc
@@ -9,9 +9,10 @@
// From eko.one.pl forum
//
-import { readfile, writefile } from "fs";
+import { readfile, writefile, rename, unlink, error } from "fs";
let filename = `/tmp/easyconfig_statistics.json`;
+let filename_tmp = `/tmp/easyconfig_statistics.json.tmp`;
let MAC = shift(ARGV);
let IFNAME = shift(ARGV);
@@ -43,11 +44,49 @@ let day = sprintf("%04d%02d%02d", ts.year, ts.mon, ts.mday);
let hour = sprintf("%02d", ts.hour);
let ts_now = sprintf("%04d%02d%02d%02d%02d", ts.year, ts.mon, ts.mday, ts.hour, ts.min);
+function safe_write(data) {
+ let serialized = sprintf("%J", data);
+ if (!serialized || length(serialized) < 2) {
+ warn("easyconfig_statistics.uc: błąd serializacji danych, zapis pominięty\n");
+ return false;
+ }
+
+ let verify = null;
+ try { verify = json(serialized); }
+ catch { verify = null; }
+ if (verify === null) {
+ warn("easyconfig_statistics.uc: walidacja JSON nie powiodła się, zapis pominięty\n");
+ return false;
+ }
+
+ let ret = writefile(filename_tmp, serialized);
+ if (!ret) {
+ warn("easyconfig_statistics.uc: nie można zapisać pliku tymczasowego\n");
+ unlink(filename_tmp);
+ return false;
+ }
+
+ if (!rename(filename_tmp, filename)) {
+ warn("easyconfig_statistics.uc: nie można zastąpić pliku docelowego (rename)\n");
+ unlink(filename_tmp);
+ return false;
+ }
+ return true;
+}
+
let db = {};
let content = readfile(filename);
if (content) {
try { db = json(content); }
- catch { db = {}; }
+ catch {
+ warn("easyconfig_statistics.uc: uszkodzony JSON w pliku bazy, resetowanie do {}\n");
+ db = {};
+ }
+
+ if (type(db) != "object" || db === null) {
+ warn("easyconfig_statistics.uc: nieprawidłowy typ danych w bazie, resetowanie do {}\n");
+ db = {};
+ }
}
let tmp = null;
@@ -63,7 +102,7 @@ if (IFNAME == "init") {
}
}
}
- writefile(filename, db);
+ safe_write(db);
exit(0)
}
@@ -71,7 +110,7 @@ if (IFNAME == "delete") {
tmp = db[MAC];
if (tmp) {
delete db[MAC];
- writefile(filename, db);
+ safe_write(db);
}
exit(0)
}
@@ -126,7 +165,6 @@ if (CONNECTED <= 60) {
db[MAC][IFNAME][day].total_tx = total_tx + dtx;
db[MAC][IFNAME][day].total_rx = total_rx + drx;
-// Dodaj statystyki godzinowe tylko jeśli był jakiś ruch danych
if (dtx > 0 || drx > 0) {
if (!db[MAC][IFNAME][day].hours[hour]) {
db[MAC][IFNAME][day].hours[hour] = {
@@ -147,5 +185,5 @@ db[MAC][IFNAME].last_rx = RX;
db[MAC][IFNAME].last_seen = ts_now;
db[MAC].last_seen = ts_now;
-writefile(filename, db);
+safe_write(db);
exit(0);
diff --git a/luci-app-easyconfig-transfer/root/usr/share/rpcd/acl.d/luci-app-easyconfig-transfer.json b/luci-app-easyconfig-transfer/root/usr/share/rpcd/acl.d/luci-app-easyconfig-transfer.json
index 472bc47b0..d5c39c283 100644
--- a/luci-app-easyconfig-transfer/root/usr/share/rpcd/acl.d/luci-app-easyconfig-transfer.json
+++ b/luci-app-easyconfig-transfer/root/usr/share/rpcd/acl.d/luci-app-easyconfig-transfer.json
@@ -18,9 +18,7 @@
"/usr/bin/easyconfig_statistics.uc": [ "exec" ],
"/usr/bin/easyconfig_statistics.sh": [ "exec" ],
"/usr/bin/auto_reset_statistics.sh": [ "exec" ],
- "/sbin/transfer2cron.sh": [ "exec" ],
- "/sbin/backup2cron.sh": [ "exec" ],
- "/sbin/ar2cron.sh": [ "exec" ],
+ "/etc/init.d/cron restart": [ "exec" ],
"/tmp/easyconfig_statistics.json": [ "read" ],
"/tmp/easyconfig_statistics_gz_tmp.json": [ "read" ],
"/tmp/dhcp.leases": [ "read" ],
@@ -28,6 +26,7 @@
"/usr/lib/easyconfig/easyconfig_statistics.json": [ "read" ],
"/var/lock/easyconfig_statistics.lock": [ "read" ],
"/etc/config/easyconfig_transfer": [ "read" ],
+ "/etc/crontabs/root": [ "read" ],
"/mnt/easyconfig_statistics.json": [ "read" ]
},
"uci": [ "easyconfig_transfer" ]
@@ -41,9 +40,7 @@
"/usr/bin/easyconfig_statistics.uc": [ "exec" ],
"/usr/bin/easyconfig_statistics.sh": [ "exec" ],
"/usr/bin/auto_reset_statistics.sh": [ "exec" ],
- "/sbin/transfer2cron.sh": [ "exec" ],
- "/sbin/backup2cron.sh": [ "exec" ],
- "/sbin/ar2cron.sh": [ "exec" ],
+ "/etc/init.d/cron restart": [ "exec" ],
"/tmp/easyconfig_statistics.json": [ "write" ],
"/tmp/easyconfig_statistics.json.gz": [ "write" ],
"/tmp/easyconfig_statistics_gz_tmp.json": [ "write" ],
@@ -51,6 +48,7 @@
"/usr/lib/easyconfig/easyconfig_statistics.json": [ "write" ],
"/var/lock/easyconfig_statistics.lock": [ "write" ],
"/etc/config/easyconfig_transfer": [ "write" ],
+ "/etc/crontabs/root": [ "write" ],
"/mnt/easyconfig_statistics.json": [ "write" ]
},
"ubus": {