Skip to content

Commit cf79901

Browse files
committed
add support config file manager
1 parent 6455623 commit cf79901

File tree

11 files changed

+3037
-36
lines changed

11 files changed

+3037
-36
lines changed

luci-app-neko/htdocs/nekoclash/assets/css/font-awesome.min.css

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
132 KB
Binary file not shown.
Binary file not shown.

luci-app-neko/htdocs/nekoclash/assets/fonts/fontawesome-webfont.svg

Lines changed: 2671 additions & 0 deletions
Loading
Binary file not shown.
Binary file not shown.
Binary file not shown.

luci-app-neko/htdocs/nekoclash/configs.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@
7979
<li class="nav-item">
8080
<a class="col btn btn-lg" data-bs-toggle="tab" href="#converter">Converter</a>
8181
</li>
82+
<li class="nav-item">
83+
<a class="col btn btn-lg" data-bs-toggle="tab" href="#manager">Manager</a>
84+
</li>
8285
</ul>
8386
<div class="tab-content">
8487
<div id="info" class="tab-pane fade show active">
@@ -158,6 +161,12 @@
158161
<iframe class="rounded-4 w-100" scrolling="no" height="700" src="./yamlconv.php" title="yacd" allowfullscreen></iframe>
159162
</div>
160163
</div>
164+
<div id="manager" class="tab-pane fade">
165+
<h2 class="text-center p-2 mb-5">Config File Manager</h2>
166+
<div class="container h-100">
167+
<iframe class="rounded-4 w-100 mb-5" height="700" src="./manager.php" title="yacd" allowfullscreen></iframe>
168+
</div>
169+
</div>
161170
</div>
162171
</div>
163172
</div>
Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
<?php
2+
3+
ob_start();
4+
include './cfg.php';
5+
$cfg_path = "/etc/neko/config";
6+
$proxy_path = "/etc/neko/proxy_provider";
7+
$rule_path = "/etc/neko/rule_provider";
8+
$arrPath = array($cfg_path, $proxy_path, $rule_path, "BACKUP CONFIG", "RESTORE CONFIG");
9+
function create_table($path){
10+
$arr_table = glob("$path/*.yaml");
11+
foreach ($arr_table as $file) {
12+
$file_info = explode("/", $file);
13+
$file_dir = $file_info[3];
14+
$file_name = explode(".", $file_info[4]);
15+
$out_table = "";
16+
$out_table .= " <tr class=\"text-center\">\n";
17+
$out_table .= " <td class=\"col-4\">".$file_info[4]." </br>[ ".formatSize(filesize($file))." - ".date('Y-m-d H:i:s', ((7*3600)+filemtime($file)))." ]"."</td>\n";
18+
$out_table .= " <td class=\"col-2\">\n";
19+
$out_table .= " <form action=\"manager.php\" method=\"post\">\n";
20+
$out_table .= " <div class=\"btn-group col\" role=\"group\" aria-label=\"ctrl\">\n";
21+
$out_table .= " <button type=\"submit\" name=\"file_action\" value=\"down@".$file."\" class=\"btn btn-info d-grid\"><i class=\"fa fa-download\"></i>Download</button>\n";
22+
# $out_table .= " <button type=\"submit\" name=\"file_action\" value=\"ren@".$file."\" class=\"btn btn-warning d-grid\">RENAME</button>\n";
23+
# $out_table .= " <button type=\"submit\" name=\"file_action\" value=\"del@".$file."\" class=\"btn btn-danger d-grid\"><i class=\"fa fa-trash\"></i>DELETE</button>\n";
24+
$out_table .= " <button type=\"button\" onclick=\"topFunction()\" class=\"btn btn-primary d-grid\" data-bs-toggle=\"modal\" data-bs-target=\"#".$file_dir."_".$file_name[0]."\"><i class=\"fa fa-gear\"></i>Option</button>\n";
25+
$out_table .= " </div>\n";
26+
$out_table .= " </form>\n";
27+
$out_table .= " </td>\n";
28+
$out_table .= " </tr>\n";
29+
echo $out_table;
30+
}
31+
32+
}
33+
function create_modal($path) {
34+
$arr_modal = glob("$path/*.yaml");
35+
foreach ($arr_modal as $file) {
36+
$file_info = explode("/", $file);
37+
$file_dir = $file_info[3];
38+
$file_name = explode(".", $file_info[4]);
39+
$out_modal = "";
40+
$out_modal .= "<div class=\"modal fade\" data-bs-keyboard=\"false\" id=\"".$file_dir."_".$file_name[0]."\" tabindex=\"1\" aria-labelledby=\"modal_".$file_dir."_".$file_name[0]."\" aria-hidden=\"true\">\n";
41+
$out_modal .= " <div class=\"modal-dialog modal-xl\">\n";
42+
$out_modal .= " <div class=\"modal-content\">\n";
43+
$out_modal .= " <div class=\"modal-header\">\n";
44+
$out_modal .= " <h5 class=\"modal-title\" id=\"modal_".$file_dir."_".$file_name[0]."\">File Information</h5>\n";
45+
$out_modal .= " <button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button>\n";
46+
$out_modal .= " </div>\n";
47+
$out_modal .= " <div class=\"modal-body\">\n";
48+
$out_modal .= " <a>Name : ".$file_info[4]."</a></br>\n";
49+
$out_modal .= " <a>File Size : ".formatSize(filesize($file))."</a></br>\n";
50+
$out_modal .= " <a>Last Modified : ".date('Y-m-d H:i:s', ((7*3600)+filemtime($file)))."</a></br>\n";
51+
$out_modal .= " <div class=\"col input-group mb-3 justify-content-md-center\">\n";
52+
$out_modal .= " <textarea class=\"form-control\" name=\"datax\" rows=\"15\">".shell_exec("cat $file")."</textarea>\n";
53+
$out_modal .= " </div>\n";
54+
$out_modal .= " </div>\n";
55+
$out_modal .= " <div class=\"modal-footer\">\n";
56+
$out_modal .= " <form action=\"manager.php\" method=\"post\">\n";
57+
$out_modal .= " <button type=\"submit\" name=\"file_action\" value=\"del@".$file."\" class=\"btn btn-danger d-grid\"><i class=\"fa fa-trash\"></i>Delete</button>\n";
58+
$out_modal .= " </form>\n";
59+
$out_modal .= " <form action=\"manager.php\" method=\"post\">\n";
60+
$out_modal .= " <button type=\"submit\" name=\"file_save\" value=\"del@".$file."\" class=\"btn btn-success d-grid\"><i class=\"fa fa-floppy-o\"></i>Save</button>\n";
61+
$out_modal .= " </form>\n";
62+
$out_modal .= " <button type=\"button\" class=\"btn btn-secondary d-grid\" data-bs-dismiss=\"modal\"><i class=\"fa fa-times\"></i>Close</button>\n";
63+
$out_modal .= " </div>\n";
64+
$out_modal .= " </div>\n";
65+
$out_modal .= " </div>\n";
66+
$out_modal .= " </div>\n";
67+
echo $out_modal;
68+
}
69+
}
70+
function up_controller($dir){
71+
$target_file = $dir . "/" . basename($_FILES["file_upload"]["name"]);
72+
$upload_stat = 1;
73+
$fileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
74+
$str_prnt = "";
75+
if (file_exists($target_file)) {
76+
$str_prnt = "File already exists.\n";
77+
$upload_stat = 0;
78+
}
79+
if (!in_array($fileType, ['yaml', 'yml'])) {
80+
$str_prnt = "Only <b>.yaml</b> or <b>.yml</b> files are allowed.";
81+
$upload_stat = 0;
82+
}
83+
if ($_FILES["file_upload"]["size"] > 10485760) {
84+
$str_prnt = "Max file size is 10MB.";
85+
$upload_stat = 0;
86+
}
87+
if (strpos($target_file, ' ') !== false) {
88+
$str_prnt = "File names with spaces are not allowed.";
89+
$upload_stat = 0;
90+
}
91+
if ($upload_stat == 0) {
92+
echo $str_prnt."</br>File not uploaded.";
93+
}
94+
else {
95+
if (move_uploaded_file($_FILES["file_upload"]["tmp_name"], $target_file)) {
96+
$dir_info = explode("/", $dir);
97+
echo "File <b>" . htmlspecialchars(basename($_FILES["file_upload"]["name"])) . "</b> has been uploaded to directory <b>" . $dir_info[3] . "</b>";
98+
} else {
99+
echo "ERROR uploading your files.";
100+
}
101+
}
102+
}
103+
104+
function action_controller($action_str) {
105+
$action = explode("@", $action_str);
106+
$file_path = $action[1];
107+
$file_info = explode("/", $file_path);
108+
switch ($action[0]) {
109+
case "del":
110+
echo "File <b>".$file_info[4]."</b> from directory <b>".$file_info[3]."</b> has ben deleted";
111+
shell_exec("rm -r $file_path");
112+
break;
113+
case "ren":
114+
echo $action[0]." - ".$file_path;
115+
break;
116+
case "down":
117+
echo $action[0]." - ".$file_path;
118+
if (file_exists($file_path)) {
119+
echo $action[0]." - ".$file_path;
120+
121+
ob_clean();
122+
header('Content-Description: File Transfer');
123+
header('Content-Type: application/octet-stream');
124+
header('Content-Disposition: attachment; filename='.basename($file_info[4]));
125+
header('Expires: 0');
126+
header('Content-Length: ' . filesize($file_path));
127+
readfile($file_path);
128+
}
129+
flush();
130+
exit();
131+
break;
132+
default:
133+
echo "undefined";
134+
}
135+
}
136+
137+
function formatSize($bytes) {
138+
if ($bytes >= 1073741824) {
139+
return number_format($bytes / 1073741824, 2) . ' GB';
140+
} elseif ($bytes >= 1048576) {
141+
return number_format($bytes / 1048576, 2) . ' MB';
142+
} elseif ($bytes >= 1024) {
143+
return number_format($bytes / 1024, 2) . ' KB';
144+
} else {
145+
return number_format($bytes, 2) . ' B';
146+
}
147+
}
148+
function restore_controller(){
149+
$target_file = "/etc/neko/" . basename($_FILES["file_upload"]["name"]);
150+
$upload_stat = 1;
151+
$fileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
152+
$str_prnt = "";
153+
if ($fileType !== 'gz') {
154+
$str_prnt = "</br>Only <b>.tar.gz</b> files are allowed.";
155+
$upload_stat = 0;
156+
}
157+
if (strpos($target_file, ' ') !== false) {
158+
$str_prnt = "</br>File names with spaces are not allowed.";
159+
$upload_stat = 0;
160+
}
161+
if ($upload_stat == 0) {
162+
echo $str_prnt."</br>File not uploaded.";
163+
return $target_file."tmp.gz";
164+
}
165+
else {
166+
if (move_uploaded_file($_FILES["file_upload"]["tmp_name"], $target_file)) {
167+
echo "</br>File <b>" . htmlspecialchars(basename($_FILES["file_upload"]["name"])) . "</b> has been uploaded.</br>";
168+
return $target_file;
169+
}
170+
else {
171+
echo "ERROR uploading your files.";
172+
}
173+
}
174+
}
175+
176+
function backupConfig(){
177+
shell_exec("/etc/neko/core/neko -b");
178+
$dir_path = "/tmp";
179+
$file_name = shell_exec("ls /tmp/ | grep neko");
180+
$file_path = trim("$dir_path/$file_name");
181+
echo $file_path;
182+
if (file_exists($file_path)) {
183+
echo "Backuping configuration, please wait...";
184+
ob_clean();
185+
header('Content-Description: File Transfer');
186+
header('Content-Type: application/octet-stream');
187+
header('Content-Disposition: attachment; filename='.basename($file_name));
188+
header('Content-Transfer-Encoding: binary');
189+
header('Expires: 0');
190+
header('Cache-Control: must-revalidate');
191+
header('Pragma: public');
192+
header('Content-Length: ' . filesize($file_path));
193+
}
194+
ob_clean();
195+
flush();
196+
readfile($file_path);
197+
shell_exec("rm -r $file_path");
198+
exit;
199+
}
200+
201+
function restoreConfig(){
202+
echo "Restoring your configuration...";
203+
$str = restore_controller();
204+
if (file_exists($str)){
205+
shell_exec("/etc/neko/core/neko -x");
206+
echo "Your configuration has ben restored.";
207+
}
208+
else{
209+
echo "</br>Can't restore your configuration";
210+
}
211+
}
212+
213+
?>
214+
<!doctype html>
215+
<html lang="en" data-bs-theme="<?php echo substr($neko_theme,0,-4) ?>">
216+
<head>
217+
<meta charset="utf-8">
218+
<meta name="viewport" content="width=device-width, initial-scale=1">
219+
<title>Proxy - Neko</title>
220+
<link rel="icon" href="./assets/img/favicon.png">
221+
<link href="./assets/css/bootstrap.min.css" rel="stylesheet">
222+
<link href="./assets/css/custom.css" rel="stylesheet">
223+
<link href="./assets/css/font-awesome.min.css" rel="stylesheet">
224+
<link href="./assets/theme/<?php echo $neko_theme ?>" rel="stylesheet">
225+
<script type="text/javascript" src="./assets/js/feather.min.js"></script>
226+
<script type="text/javascript" src="./assets/js/jquery-2.1.3.min.js"></script>
227+
<script type="text/javascript" src="./assets/js/bootstrap.min.js"></script>
228+
</head>
229+
<body class="container-bg">
230+
<div>
231+
<?php
232+
create_modal($cfg_path);
233+
create_modal($proxy_path);
234+
create_modal($rule_path);
235+
?>
236+
</div>
237+
<div class="container-bg text-center">
238+
<form action="manager.php" method="post" enctype="multipart/form-data">
239+
<div class="container container-bg border border-3 rounded-4 col-12 mb-4">
240+
<h3>Upload & Backup file</h3>
241+
<a><?php
242+
if(isset($_POST["path_selector"])) {
243+
if ($_POST['path_selector'] == 'Option') echo "Please, select the correct Options!!!";
244+
elseif ($_POST['path_selector'] == 'BACKUP CONFIG') backupConfig();
245+
elseif ($_POST['path_selector'] == 'RESTORE CONFIG') restoreConfig();
246+
else up_controller($_POST['path_selector']);
247+
}
248+
if(isset($_POST["file_action"])) {
249+
action_controller($_POST["file_action"]);
250+
}?>
251+
</a>
252+
<table class="table table-borderless">
253+
<tbody>
254+
<tr class="text-center">
255+
<td class="col-3">
256+
<div class="mb-3">
257+
<input class="form-control" type="file" name="file_upload" accept=".yaml,.yml,.tar.gz">
258+
</div>
259+
</td>
260+
<td class="col-2">
261+
<select class="form-select" name="path_selector" aria-label="themex">
262+
<option selected>Option</option>
263+
<?php foreach ($arrPath as $file) echo " <option value=\"".$file.'">'.$file."</option>\n" ?>
264+
</select>
265+
</td>
266+
<td class="col-2">
267+
<input class="btn btn-info d-grid col-8" type="submit" value="Apply">
268+
</td>
269+
</tr>
270+
</tbody>
271+
</table>
272+
<a><b>NOTE</b></a></br>
273+
<a>Restore your configuration is destroying our old <b>configuration</b> at neko directory!!!</a></br>
274+
<a>Backup is include of directory <b>configs, proxy_provider,</b> and<b> rule_provider.</b></a></br></br>
275+
</div>
276+
</form></br>
277+
<div class="container container-bg border border-3 rounded-4 col-12 mb-4">
278+
<h3>Config files</h3>
279+
<table class="table table-borderless">
280+
<tbody>
281+
<tr class="text-center">
282+
<tr class="text-center">
283+
<td class="col-4">Files</td>
284+
<td class="col-2">Action</td>
285+
</tr>
286+
<?php create_table($cfg_path) ?>
287+
</tr>
288+
</tbody>
289+
</table>
290+
</div>
291+
<div class="container container-bg border border-3 rounded-4 col-12 mb-4">
292+
<h3>Proxy Provider files</h3>
293+
<table class="table table-borderless">
294+
<tbody>
295+
<tr class="text-center">
296+
<tr class="text-center">
297+
<td class="col-4">Files</td>
298+
<td class="col-2">Action</td>
299+
</tr>
300+
<?php create_table($proxy_path) ?>
301+
</tr>
302+
</tbody>
303+
</table>
304+
</div>
305+
<div class="container container-bg border border-3 rounded-4 col-12 mb-4">
306+
<h3>Rules Provider files</h3>
307+
<table class="table table-borderless">
308+
<tbody>
309+
<tr class="text-center">
310+
<tr class="text-center">
311+
<td class="col-4">Files</td>
312+
<td class="col-2">Action</td>
313+
</tr>
314+
<?php create_table($rule_path) ?>
315+
</tr>
316+
</tbody>
317+
</table>
318+
</div></br></br></br></br></br>
319+
</div>
320+
</body>
321+
<script>
322+
function topFunction() {
323+
document.body.scrollTop = 0;
324+
document.documentElement.scrollTop = 0;
325+
}
326+
</script>
327+
</html>

luci-app-neko/root/etc/neko/core/neko

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,14 +258,29 @@ php_stop(){
258258
fi
259259
}
260260

261+
neko_backup(){
262+
cd $neko_dir
263+
filename="neko_backup_`date +%F_%H%M%S`.tar.gz"
264+
tar -czvf $filename config proxy_provider rule_provider
265+
mv $filename /tmp/$filename
266+
}
267+
neko_restore(){
268+
cd $neko_dir
269+
rm -r $neko_dir/config/*
270+
rm -r $neko_dir/proxy_provider/*
271+
rm -r $neko_dir/rule_provider/*
272+
tar -xzf *.tar.gz
273+
rm -r *.tar.gz
274+
}
275+
261276
cleanup(){
262277
logs "Cleanup Temporary..." 2
263278
neko_stop
264279
php_stop
265280
logs "Cleanup Done..."
266281
}
267282

268-
while getopts ":skrpcvh" signal ; do
283+
while getopts ":skrpcvhbx" signal ; do
269284
case $signal in
270285
s)
271286
neko_start
@@ -282,6 +297,12 @@ while getopts ":skrpcvh" signal ; do
282297
c)
283298
cleanup
284299
;;
300+
b)
301+
neko_backup
302+
;;
303+
x)
304+
neko_restore
305+
;;
285306
v)
286307
neko_ver
287308
neko_checknewver

0 commit comments

Comments
 (0)