🌴 Sync 2026-03-05 23:51:42

This commit is contained in:
github-actions[bot] committed 2026-03-05 23:51:42 +08:00
1 parent 97c049ed0a
commit 0acff03804
14253 files changed
+3893239

No files matched your search

+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 BobbyUnknown
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+23
View File
@@ -0,0 +1,23 @@
# This is open source software, licensed under the MIT License.
#
# Copyright (C) 2024 BobbyUnknown
#
# Description:
# This software provides a RAM release scheduling application for OpenWrt.
# The application allows users to configure and automate the process of
# releasing RAM on their OpenWrt routers at specified intervals, helping
# to optimize system performance and resource management through
# a user-friendly web interface.
include $(TOPDIR)/rules.mk
PKG_MAINTAINER:=BobbyUnknown <bobbyun.known88@gmail.com>
LUCI_TITLE:=LuCI for System Control
LUCI_DEPENDS:=+luci-base
LUCI_PKGARCH:=all
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
+63
View File
@@ -0,0 +1,63 @@
## System Control
**Luci app system control for openwrt**
[![GitHub Downloads](https://img.shields.io/github/downloads/bobbyunknown/luci-app-syscontrol/total?style=for-the-badge&logo=github)](https://github.com/bobbyunknown/luci-app-syscontrol/releases)
[![GitHub Views](https://img.shields.io/badge/VIEWS-973-brightgreen?style=for-the-badge&logo=github)](https://github.com/bobbyunknown/luci-app-syscontrol)
#### Telegram group:
[![SanTech](https://img.shields.io/badge/SanTech-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white)](https://t.me/+TuLCASzJrVJmNzM1)
### Features
- Release RAM (also available in LuCI menu)
- Shutdown (also available in LuCI menu)
- Normal reboot and force reboot
- RAM release schedule
- Add shutdown and release RAM menu in LuCI menu
### Install
- For manual installation, please download from the release
- Auto install
```
bash -c "$(curl -fsSL https://raw.githubusercontent.com/bobbyunknown/luci-app-syscontrol/refs/heads/main/install.sh)"
```
### Screenshot
<details>
<summary>RAM Release Schedule</summary>
![RAM Release Schedule](img/jadwal_release_ram.png)
</details>
<details>
<summary>Log</summary>
![Log](img/log.png)
</details>
<details>
<summary>Menu</summary>
![Menu](img/menu.png)
</details>
<details>
<summary>Overview</summary>
![Overview](img/overview.png)
</details>
<details>
<summary>Reboot</summary>
![Reboot](img/reboot.png)
</details>
<details>
<summary>Shutdown</summary>
![Shutdown](img/shutdown.png)
</details>
+65
View File
@@ -0,0 +1,65 @@
## System control
**Luci app system control untuk openwrt**
[![EN](https://img.shields.io/badge/lang-EN-red.svg?style=for-the-badge)](README-EN.md)
[![GitHub Downloads](https://img.shields.io/github/downloads/bobbyunknown/luci-app-syscontrol/total?style=for-the-badge&logo=github)](https://github.com/bobbyunknown/luci-app-syscontrol/releases)
[![GitHub Views](https://img.shields.io/badge/VIEWS-973-brightgreen?style=for-the-badge&logo=github)](https://github.com/bobbyunknown/luci-app-syscontrol)
#### Telegram group:
[![SanTech](https://img.shields.io/badge/SanTech-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white)](https://t.me/+TuLCASzJrVJmNzM1)
### Fitur
- Release RAM (tersedia juga di menu LuCI)
- Shutdown (tersedia juga di menu LuCI)
- Normal reboot dan force reboot
- Jadwal release RAM
- Menambah menu shutdown dan release RAM di menu LuCI
### Install
- Install manual silakan download di release
- Auto install
```
bash -c "$(curl -fsSL https://raw.githubusercontent.com/bobbyunknown/luci-app-syscontrol/refs/heads/main/install.sh)"
```
### Screenshot
<details>
<summary>Jadwal Release RAM</summary>
![Jadwal Release RAM](img/jadwal_release_ram.png)
</details>
<details>
<summary>Log</summary>
![Log](img/log.png)
</details>
<details>
<summary>Menu</summary>
![Menu](img/menu.png)
</details>
<details>
<summary>Overview</summary>
![Overview](img/overview.png)
</details>
<details>
<summary>Reboot</summary>
![Reboot](img/reboot.png)
</details>
<details>
<summary>Shutdown</summary>
![Shutdown](img/shutdown.png)
</details>
@@ -0,0 +1,105 @@
/*
* This is open source software, licensed under the MIT License.
*
* Copyright (C) 2024 BobbyUnknown
*
* Description:
* This software provides a RAM release scheduling application for OpenWrt.
* The application allows users to configure and automate the process of
* releasing RAM on their OpenWrt router at specified intervals, helping
* to optimize system performance and resource management through a
* user-friendly web interface.
*/
'use strict';
'require form';
'require view';
'require uci';
'require ui';
'require fs';
'require tools.widgets as widgets';
return view.extend({
render: function() {
var m, s, o, footerSection;
m = new form.Map('77_syscontrol', _('RAM Release Schedule'),
_('Configure schedule for automatic RAM release.'));
s = m.section(form.NamedSection, 'schedule', 'ram_release', _('Schedule Settings'));
s.anonymous = true;
s.addremove = false;
o = s.option(form.Flag, 'enabled', _('Enable'),
_('Enable automatic RAM release schedule'));
o.rmempty = false;
o.write = function(section_id, value) {
form.Flag.prototype.write.apply(this, arguments);
return fs.exec('/etc/init.d/ram_release', [value === '1' ? 'enable' : 'disable'])
.then(function() {
return fs.exec('/etc/init.d/ram_release', [value === '1' ? 'start' : 'stop']);
});
};
o = s.option(form.DummyValue, '_status', _('Service Status'));
o.rawhtml = true;
o.load = function(section_id) {
return fs.exec('/etc/init.d/ram_release', ['status']).then(function(res) {
if (res.code === 0) {
return '<span style="color:green;font-weight:bold;">Running</span>';
} else {
return '<span style="color:red;font-weight:bold;">Stopped</span>';
}
}).catch(function(err) {
ui.addNotification(null, E('p', _('Error checking service status: ') + err.message), 'error');
return '<span style="color:gray;font-weight:bold;">Unknown</span>';
});
};
o = s.option(form.Value, 'time', _('Time'),
_('Enter time for RAM release (24-hour format, e.g. 23:30)'));
o.datatype = 'string';
o.validate = function(section_id, value) {
if (!/^([01]\d|2[0-3]):([0-5]\d)$/.test(value)) {
return _('Invalid time format. Please use HH:MM (24-hour format).');
}
return true;
};
o = s.option(form.MultiValue, 'days', _('Days'),
_('Select days for RAM release'));
o.multiple = true;
o.value('mon', _('Monday'));
o.value('tue', _('Tuesday'));
o.value('wed', _('Wednesday'));
o.value('thu', _('Thursday'));
o.value('fri', _('Friday'));
o.value('sat', _('Saturday'));
o.value('sun', _('Sunday'));
footerSection = m.section(form.NamedSection, 'footer', 'footer');
footerSection.render = function() {
return E('div', { 'style': 'text-align: center; padding: 10px; font-style: italic;' }, [
E('span', {}, [
_('© Dibuat oleh '),
E('a', {
'href': 'https://github.com/bobbyunknow',
'target': '_blank',
'style': 'text-decoration: none;'
}, 'BobbyUnknown')
])
]);
};
return m.render().then(function(rendered) {
console.log('Form rendered:', rendered);
console.log('Enabled:', uci.get('77_syscontrol', 'schedule', 'enabled'));
console.log('Time:', uci.get('77_syscontrol', 'schedule', 'time'));
console.log('Days:', uci.get('77_syscontrol', 'schedule', 'days'));
return rendered;
}).catch(function(err) {
console.error('Error rendering form:', err);
ui.addNotification(null, E('p', _('Error loading configuration: ' + err.message)), 'error');
});
}
});
@@ -0,0 +1,98 @@
/*
* This is open source software, licensed under the MIT License.
*
* Copyright (C) 2024 BobbyUnknown
*
* Description:
* This software provides a RAM release scheduling application for OpenWrt.
* The application allows users to configure and automate the process of
* releasing RAM on their OpenWrt router at specified intervals, helping
* to optimize system performance and resource management through a
* user-friendly web interface.
*/
'use strict';
'require view';
'require fs';
'require ui';
'require poll';
return view.extend({
handleSaveApply: null,
handleSave: null,
handleReset: null,
loadLog: function() {
return fs.read('/var/log/ram_release.log')
.then(function(log) {
return log.trim() || _('No log entries found');
})
.catch(function(err) {
console.error('Error reading log:', err);
return _('Error reading log file or file is empty');
});
},
createDefaultLog: function() {
var defaultMessage = 'No log found';
return fs.write('/var/log/ram_release.log', defaultMessage + '\n')
.then(function() {
return defaultMessage;
})
.catch(function(err) {
console.error('Error creating default log:', err);
return 'Error: Unable to initialize log file';
});
},
render: function() {
var logContainer = E('div', { 'class': 'cbi-section' });
var updateLog = function() {
this.loadLog().then(function(log) {
logContainer.innerHTML = '<pre style="white-space: pre-wrap; word-wrap: break-word;">' + log + '</pre>';
});
}.bind(this);
updateLog();
poll.add(updateLog, 5);
return E('div', { 'class': 'cbi-map' }, [
E('h2', _('RAM Release Log')),
logContainer,
E('div', { 'class': 'cbi-section-actions' }, [
E('button', {
'class': 'btn cbi-button cbi-button-remove',
'click': ui.createHandlerFn(this, function(ev) {
var button = ev.target;
button.disabled = true;
button.textContent = _('Clearing...');
return fs.write('/var/log/ram_release.log', 'Log cleared\n')
.then(function() {
updateLog();
})
.catch(function(err) {
console.error('Error clearing log:', err);
})
.finally(function() {
button.disabled = false;
button.textContent = _('Clear Log');
});
})
}, _('Clear Log'))
]),
E('div', { 'style': 'text-align: center; padding: 10px; font-style: italic;' }, [
E('span', {}, [
_('© Dibuat oleh '),
E('a', {
'href': 'https://github.com/bobbyunknow',
'target': '_blank',
'style': 'text-decoration: none;'
}, 'BobbyUnknown')
])
])
]);
}
});
@@ -0,0 +1,122 @@
/*
* This is open source software, licensed under the MIT License.
*
* Copyright (C) 2024 BobbyUnknown
*
* Description:
* This software provides a RAM release scheduling application for OpenWrt.
* The application allows users to configure and automate the process of
* releasing RAM on their OpenWrt router at specified intervals, helping
* to optimize system performance and resource management through a
* user-friendly web interface.
*/
'use strict';
'require view';
'require ui';
'require rpc';
'require poll';
var callSystemInfo = rpc.declare({
object: 'system',
method: 'info'
});
return view.extend({
load: function() {
console.log('Load function called');
return callSystemInfo().then(function(data) {
console.log('RAM information loaded:', JSON.stringify(data.memory));
return {
memory: data.memory
};
}).catch(function(error) {
console.error('Error loading RAM information:', error);
throw error;
});
},
updateMemoryStatus: function(memory) {
console.log('Updating memory status with:', memory);
if (!memory) {
console.error('Memory information is missing');
return;
}
var totalMB = Math.round(memory.total / 1024 / 1024);
var freeMB = Math.round(memory.free / 1024 / 1024);
var cachedMB = Math.round(memory.cached / 1024 / 1024);
var usedMB = totalMB - freeMB - cachedMB;
var usedPercent = Math.round((usedMB / totalMB) * 100);
var memoryStatusElement = document.getElementById('memory-status');
if (memoryStatusElement) {
memoryStatusElement.innerHTML = '';
memoryStatusElement.appendChild(
E('div', { 'class': 'table' }, [
E('div', { 'class': 'tr' }, [
E('div', { 'class': 'td left' }, _('Total RAM:')),
E('div', { 'class': 'td left' }, totalMB + ' MB')
]),
E('div', { 'class': 'tr' }, [
E('div', { 'class': 'td left' }, _('Used RAM:')),
E('div', { 'class': 'td left' }, usedMB + ' MB (' + usedPercent + '%)')
]),
E('div', { 'class': 'tr' }, [
E('div', { 'class': 'td left' }, _('Cached RAM:')),
E('div', { 'class': 'td left' }, cachedMB + ' MB')
]),
E('div', { 'class': 'tr' }, [
E('div', { 'class': 'td left' }, _('Free RAM:')),
E('div', { 'class': 'td left' }, freeMB + ' MB')
])
])
);
} else {
console.error('Memory status element not found');
}
},
render: function(data) {
console.log('Render function called with:', JSON.stringify(data));
var view = E('div', { 'class': 'cbi-map' }, [
E('h2', _('RAM Status')),
E('div', { 'class': 'cbi-section' }, [
E('div', { 'id': 'memory-status' })
]),
E('div', { 'style': 'text-align: center; padding: 10px; font-style: italic;' }, [
E('span', {}, [
_('© Dibuat oleh '),
E('a', {
'href': 'https://github.com/bobbyunknow',
'target': '_blank',
'style': 'text-decoration: none;'
}, 'BobbyUnknown')
])
])
]);
requestAnimationFrame(L.bind(function() {
this.updateMemoryStatus(data.memory);
}, this));
return view;
},
handleSaveApply: null,
handleSave: null,
handleReset: null,
poll: {
interval: 5,
task: function() {
console.log('Polling task running');
return callSystemInfo().then(L.bind(function(data) {
console.log('Polling task received RAM information:', JSON.stringify(data.memory));
this.updateMemoryStatus(data.memory);
}, this)).catch(function(error) {
console.error('Error in polling task:', error);
});
}
}
});
@@ -0,0 +1,130 @@
/*
* This is open source software, licensed under the MIT License.
*
* Copyright (C) 2024 BobbyUnknown
*
* Description:
* This software provides a RAM release scheduling application for OpenWrt.
* The application allows users to configure and automate the process of
* releasing RAM on their OpenWrt router at specified intervals, helping
* to optimize system performance and resource management through a
* user-friendly web interface.
*/
'use strict';
'require view';
'require rpc';
'require ui';
'require uci';
var callReboot = rpc.declare({
object: 'system',
method: 'reboot',
expect: { result: 0 }
});
var callForceReboot = rpc.declare({
object: 'system',
method: 'reboot',
params: [ '-f' ],
expect: { result: 0 }
});
return view.extend({
load: function() {
return uci.changes();
},
render: function(changes) {
var body = E([
E('h2', _('System reboot')),
E('p', {}, _('Reboots the operating system of your device'))
]);
for (var config in (changes || {})) {
body.appendChild(E('p', { 'class': 'alert-message warning' },
_('Warning: There are unsaved changes that will get lost on reboot!')));
break;
}
body.appendChild(E('hr'));
body.appendChild(E('button', {
'class': 'cbi-button cbi-button-action important',
'click': ui.createHandlerFn(this, 'handleReboot', false)
}, _('Normal Reboot')));
body.appendChild(E('button', {
'class': 'cbi-button cbi-button-negative important',
'click': ui.createHandlerFn(this, 'handleReboot', true)
}, _('Force Reboot')));
body.appendChild(E('div', { 'style': 'text-align: center; padding: 10px; font-style: italic;' }, [
E('span', {}, [
_('© Dibuat oleh '),
E('a', {
'href': 'https://github.com/bobbyunknow',
'target': '_blank',
'style': 'text-decoration: none;'
}, 'BobbyUnknown')
])
]));
return body;
},
handleReboot: function(ev, force) {
var rebootCall = force ? callForceReboot : callReboot;
var rebootType = force ? _('Force Reboot') : _('Normal Reboot');
ui.showModal(_('Confirm Reboot'), [
E('h4', { style: 'color: #d9534f; text-align: center;' }, _('Are you absolutely sure you want to reboot the system?')),
E('p', { style: 'text-align: center;' }, _('This will restart your device. All running processes will be stopped.')),
E('div', { class: 'right' }, [
E('button', {
'class': 'btn',
'click': ui.hideModal
}, _('Cancel')),
' ',
E('button', {
'class': 'btn btn-danger',
'click': ui.createHandlerFn(this, function() {
ui.hideModal();
return rebootCall().then(function(res) {
if (res != 0) {
ui.addNotification(null, E('p', _('The reboot command failed with code %d').format(res)));
throw new Error('Reboot failed');
}
ui.showModal(_('Rebooting…'), [
E('p', { 'class': 'spinning' }, _('Waiting for device...'))
]);
var checkInterval = window.setInterval(function() {
fetch(window.location.href, { method: 'HEAD', cache: 'no-cache' })
.then(function() {
window.clearInterval(checkInterval);
window.location.reload();
})
.catch(function() {});
}, 5000);
window.setTimeout(function() {
ui.showModal(_('Rebooting…'), [
E('p', { 'class': 'spinning alert-message warning' },
_('Device unreachable! Still waiting for device...'))
]);
}, 150000);
}).catch(function(e) {
ui.addNotification(null, E('p', e.message));
});
})
}, rebootType)
])
]);
},
handleSaveApply: null,
handleSave: null,
handleReset: null
});
@@ -0,0 +1,35 @@
/*
* This is open source software, licensed under the MIT License.
*
* Copyright (C) 2024 BobbyUnknown
*
* Description:
* This software provides a RAM release scheduling application for OpenWrt.
* The application allows users to configure and automate the process of
* releasing RAM on their OpenWrt router at specified intervals, helping
* to optimize system performance and resource management through a
* user-friendly web interface.
*/
'use strict';
'require fs';
'require view';
return view.extend({
handleSaveApply: null,
handleSave: null,
handleReset: null,
load: function() {
fs.exec('/usr/bin/ram_release.sh', ['release']);
return null;
},
render: function() {
window.location.href = '/cgi-bin/luci/admin/system/syscontrol';
return E('div');
}
});
@@ -0,0 +1,75 @@
/*
* This is open source software, licensed under the MIT License.
*
* Copyright (C) 2024 BobbyUnknown
*
* Description:
* This software provides a RAM release scheduling application for OpenWrt.
* The application allows users to configure and automate the process of
* releasing RAM on their OpenWrt router at specified intervals, helping
* to optimize system performance and resource management through a
* user-friendly web interface.
*/
'use strict';
'require view';
'require ui';
'require fs';
return view.extend({
render: function() {
return E('div', { class: 'cbi-map' }, [
E('h2', _('System shutdown')),
E('div', { class: 'cbi-section' }, [
E('p', _('Shutting down the system will power off your device. Make sure all important processes are completed before proceeding.')),
E('div', { class: 'cbi-section-actions' }, [
E('button', {
class: 'btn cbi-button cbi-button-negative',
click: ui.createHandlerFn(this, 'handleShutdown')
}, _('Shutdown System'))
])
]),
E('div', { 'style': 'text-align: center; padding: 10px; font-style: italic;' }, [
E('span', {}, [
_('© Dibuat oleh '),
E('a', {
'href': 'https://github.com/bobbyunknow',
'target': '_blank',
'style': 'text-decoration: none;'
}, 'BobbyUnknown')
])
])
]);
},
handleShutdown: function() {
return ui.showModal(_('Confirm Shutdown'), [
E('h4', { style: 'color: #d9534f; text-align: center;' }, _('Are you absolutely sure you want to shut down the system?')),
E('p', { style: 'text-align: center;' }, _('This will power off your device. All running processes will be stopped.')),
E('div', { class: 'right' }, [
E('button', {
'class': 'btn',
'click': ui.hideModal
}, _('Cancel')),
' ',
E('button', {
'class': 'btn btn-danger',
'click': ui.createHandlerFn(this, function() {
ui.hideModal();
ui.showModal(_('Shutting down...'), [
E('p', { 'class': 'spinning' }, _('The system is shutting down. GoodBye :)...'))
]);
return fs.exec('/sbin/poweroff').catch(function(e) {
ui.addNotification(null, E('p', e.message));
});
})
}, _('Shutdown'))
])
]);
},
handleSaveApply: null,
handleSave: null,
handleReset: null
});
Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

+164
View File
@@ -0,0 +1,164 @@
#!/bin/sh
# Copyright (c) 2023 bobbyunknown
# https://github.com/bobbyunknown
#
# Hak Cipta Dilindungi Undang-Undang
# https://rem.mit-license.org/
PACKAGE_NAME="luci-app-syscontrol"
get_latest_release_url() {
REPO="bobbyunknown/luci-app-syscontrol"
API_URL="https://api.github.com/repos/$REPO/releases/latest"
DOWNLOAD_URL=$(curl -s "$API_URL" | grep "browser_download_url.*ipk" | cut -d '"' -f 4)
if [ ! -z "$DOWNLOAD_URL" ]; then
FILENAME=$(basename "$DOWNLOAD_URL")
echo "$DOWNLOAD_URL|$FILENAME"
else
echo ""
fi
}
check_system_resources() {
FREE_SPACE=$(df -h /tmp | awk 'NR==2 {print $4}')
echo "Ruang disk tersedia di /tmp: $FREE_SPACE"
}
install_package() {
check_system_resources
echo "Menginstal $PACKAGE_NAME..."
opkg update
RELEASE_INFO=$(get_latest_release_url)
if [ -z "$RELEASE_INFO" ]; then
echo "Gagal mendapatkan informasi rilis. Silakan coba lagi nanti."
read -p "Tekan Enter untuk melanjutkan..."
return 1
fi
DOWNLOAD_URL=$(echo "$RELEASE_INFO" | cut -d'|' -f1)
FILENAME=$(echo "$RELEASE_INFO" | cut -d'|' -f2)
echo "Mengunduh $FILENAME..."
if ! curl -L -o "/tmp/$FILENAME" "$DOWNLOAD_URL"; then
echo "Gagal mengunduh file. Silakan periksa koneksi internet Anda."
read -p "Tekan Enter untuk melanjutkan..."
return 1
fi
if [ ! -f "/tmp/$FILENAME" ]; then
echo "File tidak ditemukan setelah unduhan. Silakan coba lagi."
read -p "Tekan Enter untuk melanjutkan..."
return 1
fi
echo "File yang diunduh: /tmp/$FILENAME"
ls -l "/tmp/$FILENAME"
echo "Menginstal paket..."
if ! opkg install "/tmp/$FILENAME"; then
echo "Gagal menginstal paket. Silakan coba opsi force install."
rm -f "/tmp/$FILENAME"
read -p "Tekan Enter untuk melanjutkan..."
return 1
fi
rm -f "/tmp/$FILENAME"
echo "Instalasi $PACKAGE_NAME selesai."
read -p "Tekan Enter untuk melanjutkan..."
}
force_install_package() {
check_system_resources
echo "Melakukan force install $PACKAGE_NAME..."
opkg update
RELEASE_INFO=$(get_latest_release_url)
if [ -z "$RELEASE_INFO" ]; then
echo "Gagal mendapatkan informasi rilis. Silakan coba lagi nanti."
read -p "Tekan Enter untuk melanjutkan..."
return 1
fi
DOWNLOAD_URL=$(echo "$RELEASE_INFO" | cut -d'|' -f1)
FILENAME=$(echo "$RELEASE_INFO" | cut -d'|' -f2)
echo "Mengunduh $FILENAME..."
if ! curl -L -o "/tmp/$FILENAME" "$DOWNLOAD_URL"; then
echo "Gagal mengunduh file. Silakan periksa koneksi internet Anda."
read -p "Tekan Enter untuk melanjutkan..."
return 1
fi
if [ ! -f "/tmp/$FILENAME" ]; then
echo "File tidak ditemukan setelah unduhan. Silakan coba lagi."
read -p "Tekan Enter untuk melanjutkan..."
return 1
fi
echo "File yang diunduh: /tmp/$FILENAME"
ls -l "/tmp/$FILENAME"
echo "Melakukan force install paket..."
if ! opkg install --force-reinstall "/tmp/$FILENAME"; then
echo "Gagal melakukan force install paket."
rm -f "/tmp/$FILENAME"
read -p "Tekan Enter untuk melanjutkan..."
return 1
fi
rm -f "/tmp/$FILENAME"
echo "Force install $PACKAGE_NAME selesai."
read -p "Tekan Enter untuk melanjutkan..."
}
uninstall_package() {
echo "Menghapus $PACKAGE_NAME..."
opkg remove "$PACKAGE_NAME"
find / -type d -name "*syscontrol*" -exec rm -rf {} + 2>/dev/null
find / -type f -name "*syscontrol*" -delete 2>/dev/null
echo "Paket $PACKAGE_NAME dan file-file terkait berhasil dihapus."
read -p "Tekan Enter untuk melanjutkan..."
}
while true; do
clear
echo "┌─────────────────────────────────────┐"
echo "│ luci-app-syscontrol Installer │"
echo "│ github.com/bobbyunknown │"
echo "├─────────────────────────────────────┤"
echo "│ │"
echo "│ 1. Install syscontrol │"
echo "│ 2. Force Install syscontrol │"
echo "│ 3. Uninstall syscontrol │"
echo "│ 4. Keluar │"
echo "│ │"
echo "└─────────────────────────────────────┘"
echo
read -p "Pilihan Anda [1-4]: " choice
echo
case $choice in
1)
install_package
;;
2)
force_install_package
;;
3)
uninstall_package
;;
4)
echo "Keluar dari program."
exit 0
;;
*)
echo "Pilihan tidak valid. Silakan coba lagi."
;;
esac
echo "Operasi selesai."
echo
done
+1
View File
@@ -0,0 +1 @@
zh_Hans
@@ -0,0 +1,53 @@
msgid ""
msgstr ""
"PO-Revision-Date: 2024-04-10 09:38+0000\n"
"Last-Translator: MkQtS <MkQtS@users.noreply.hosted.weblate.org>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"openwrt/luciapplicationsacl/zh_Hans/>\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"
"X-Generator: Weblate 5.5-dev\n"
msgid "System control"
msgstr "系统控制"
msgid "RAM Status"
msgstr "内存状态"
msgid "Total RAM"
msgstr "总内存"
msgid "Used RAM"
msgstr "已使用内存"
msgid "Cached RAM"
msgstr "已缓存内存"
msgid "Free RAM"
msgstr "空闲内存"
msgid "Release RAM"
msgstr "释放内存"
msgid "Shutdown"
msgstr "关机"
msgid "Shutdown System"
msgstr "关机"
msgid "System shutdown"
msgstr "关机"
msgid "RAM Release Schedule"
msgstr "定期释放内存"
msgid "Schedule Settings"
msgstr "计划设置"
msgid "RAM Release Log"
msgstr "内存释放日志"
msgid "Clear Log"
msgstr "清除日志"
@@ -0,0 +1,4 @@
config ram_release 'schedule'
option enabled '0'
option time '03:00'
option days 'mon tue wed thu fri sat sun'
+25
View File
@@ -0,0 +1,25 @@
#!/bin/sh /etc/rc.common
START=99
STOP=10
USE_PROCD=1
start_service() {
procd_open_instance
procd_set_param command /bin/sh -c "/usr/bin/ram_release.sh start && sleep infinity"
procd_set_param respawn
procd_close_instance
}
stop_service() {
/usr/bin/ram_release.sh stop
}
service_triggers() {
procd_add_reload_trigger "77_syscontrol"
}
reload_service() {
stop
start
}
@@ -0,0 +1,5 @@
#!/bin/sh
chmod +x /etc/init.d/ram_release /usr/bin/ram_release.sh
exit 0
+155
View File
@@ -0,0 +1,155 @@
#!/bin/sh
# This is open source software, licensed under the MIT License.
#
# Copyright (C) 2024 BobbyUnknown
#
# Description:
# This software provides a RAM release scheduling application for OpenWrt.
# The application allows users to configure and automate the process of
# releasing RAM on their OpenWrt routers at specified intervals, helping
# to optimize system performance and resource management through
# a user-friendly web interface.
. /lib/functions.sh
. /usr/share/libubox/jshn.sh
export TZ='Asia/Shanghai'
LOG_FILE="/var/log/ram_release.log"
PID_FILE="/var/run/ram_release.pid"
log_message() {
local timestamp=$(TZ='Asia/Shanghai' date +"%Y-%m-%d %H:%M:%S %Z")
echo "$timestamp: $1" >> "$LOG_FILE"
logger -t "RAM Release" -- "$1"
}
get_config() {
config_load "77_syscontrol"
config_get enabled schedule enabled "0"
config_get time schedule time
config_get days schedule days
}
update_cron() {
get_config
log_message "Update cron started"
log_message "Enabled: $enabled, Time: $time, Days: $days"
sed -i '/ram_release/d' /etc/crontabs/root
if [ "$enabled" = "1" ]; then
cron_days=$(echo $days | sed 's/mon/1/g; s/tue/2/g; s/wed/3/g; s/thu/4/g; s/fri/5/g; s/sat/6/g; s/sun/0/g')
hour=$(echo $time | cut -d: -f1)
minute=$(echo $time | cut -d: -f2)
cron_entry="$minute $hour * * $cron_days TZ='Asia/Shanghai' /usr/bin/ram_release.sh release"
echo "$cron_entry" >> /etc/crontabs/root
log_message "Cron job updated: $cron_entry"
else
log_message "Schedule disabled"
fi
/etc/init.d/cron restart
}
release_ram() {
log_message "RAM release started"
log_memory_state() {
local state=$1
log_message "$state cleaning (in MB):"
free | awk '
/^Mem:/ {
total=$2/1024; used=$3/1024; free=$4/1024; shared=$5/1024;
buff_cache=$6/1024; available=$7/1024;
printf " Total RAM: %.1f MB\n", total;
printf " Used RAM: %.1f MB (%.1f%%)\n", used, (used/total*100);
printf " Free RAM: %.1f MB\n", free;
printf " Shared RAM: %.1f MB\n", shared;
printf " Buff/Cache: %.1f MB\n", buff_cache;
printf " Available RAM: %.1f MB\n", available;
}' | while read line; do log_message "$line"; done
}
before_clean=$(free | awk '/^Mem:/ {printf "%.1f %.1f %.1f %.1f %.1f", $2/1024, $3/1024, $4/1024, $6/1024, $7/1024}')
log_memory_state "Before"
sync
echo 3 > /proc/sys/vm/drop_caches
swapoff -a && swapon -a
echo 1 > /proc/sys/vm/compact_memory
sleep 5
after_clean=$(free | awk '/^Mem:/ {printf "%.1f %.1f %.1f %.1f %.1f", $2/1024, $3/1024, $4/1024, $6/1024, $7/1024}')
log_memory_state "After"
set -- $before_clean
before_total=$1; before_used=$2; before_free=$3; before_buffers_cache=$4; before_available=$5
set -- $after_clean
after_total=$1; after_used=$2; after_free=$3; after_buffers_cache=$4; after_available=$5
log_message "Changes (in MB):"
awk -v bu="$before_used" -v au="$after_used" 'BEGIN {printf " Used RAM change: %.1f MB\n", au - bu}' | while read line; do log_message "$line"; done
awk -v bf="$before_free" -v af="$after_free" 'BEGIN {printf " Free RAM change: %.1f MB\n", af - bf}' | while read line; do log_message "$line"; done
awk -v bbc="$before_buffers_cache" -v abc="$after_buffers_cache" 'BEGIN {printf " Buff/Cache change: %.1f MB\n", abc - bbc}' | while read line; do log_message "$line"; done
awk -v ba="$before_available" -v aa="$after_available" 'BEGIN {printf " Available RAM change: %.1f MB\n", aa - ba}' | while read line; do log_message "$line"; done
log_message "RAM release completed"
}
start_service() {
if [ -f "$PID_FILE" ]; then
log_message "Service already running"
exit 0
fi
get_config
if [ "$enabled" = "1" ]; then
update_cron
echo $$ > "$PID_FILE"
log_message "Service started"
else
log_message "Service not enabled"
fi
}
stop_service() {
if [ -f "$PID_FILE" ]; then
rm "$PID_FILE"
sed -i '/ram_release/d' /etc/crontabs/root
/etc/init.d/cron restart
log_message "Service stopped"
else
log_message "Service not running"
fi
}
case "$1" in
start)
start_service
;;
stop)
stop_service
;;
restart)
stop_service
start_service
;;
update)
update_cron
;;
release)
release_ram
;;
*)
echo "Usage: $0 {start|stop|restart|update|release}"
exit 1
;;
esac
exit 0
reload_service() {
restart
}
@@ -0,0 +1,10 @@
{
"admin/system/shutdown": {
"title": "Shutdown",
"order": 90,
"action": {
"type": "view",
"path": "syscontrol/shutdown"
}
}
}
@@ -0,0 +1,10 @@
{
"admin/system/release_ram": {
"title": "Release RAM",
"order": 89,
"action": {
"type": "view",
"path": "syscontrol/release-ram"
}
}
}
@@ -0,0 +1,61 @@
{
"admin/system/syscontrol": {
"title": "System control",
"order": 60,
"action": {
"type": "firstchild"
},
"depends": {
"acl": [ "luci-app-syscontrol" ],
"uci": { "system": true }
}
},
"admin/system/syscontrol/overview": {
"title": "Overview",
"order": 10,
"action": {
"type": "view",
"path": "syscontrol/overview"
}
},
"admin/system/syscontrol/release-ram": {
"title": "Release RAM",
"order": 20,
"action": {
"type": "view",
"path": "syscontrol/release-ram"
}
},
"admin/system/syscontrol/reboot": {
"title": "Reboot",
"order": 30,
"action": {
"type": "view",
"path": "syscontrol/reboot"
}
},
"admin/system/syscontrol/shutdown": {
"title": "Shutdown",
"order": 40,
"action": {
"type": "view",
"path": "syscontrol/shutdown"
}
},
"admin/system/syscontrol/config": {
"title": "RAM Release Schedule",
"order": 50,
"action": {
"type": "view",
"path": "syscontrol/config"
}
},
"admin/system/syscontrol/log": {
"title": "RAM Release Log",
"order": 60,
"action": {
"type": "view",
"path": "syscontrol/log"
}
}
}
@@ -0,0 +1,32 @@
{
"luci-app-syscontrol": {
"description": "Grant access to system control functions",
"read": {
"ubus": {
"system": [ "info" ],
"file": [ "read" ],
"service": [ "list" ]
},
"uci": [ "system", "77_syscontrol" ],
"file": {
"/sbin/poweroff": [ "exec" ],
"/usr/bin/ram_release.sh": [ "exec" ],
"/var/log/ram_release.log": [ "read" ],
"/etc/init.d/ram_release": [ "exec" ]
}
},
"write": {
"ubus": {
"system": [ "drop_caches", "reboot" ],
"file": [ "exec", "write" ],
"service": [ "start", "stop" ]
},
"uci": [ "77_syscontrol" ],
"file": {
"/usr/bin/ram_release.sh": [ "exec" ],
"/var/log/ram_release.log": [ "write" ],
"/etc/init.d/ram_release": [ "exec" ]
}
}
}
}