mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2025-01-19 01:35:28 +01:00
Merge branch 'dev' into dev-Silversthorn
This commit is contained in:
commit
31436bdc62
@ -306,7 +306,10 @@ class Controller:
|
||||
tempDir = tempfile.mkdtemp()
|
||||
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
||||
zip_ref.extractall(tempDir)
|
||||
test = zip_ref.filelist[1].filename
|
||||
for i in range(len(zip_ref.filelist)):
|
||||
if len(zip_ref.filelist) > 1 or not zip_ref.filelist[i].filename.endswith('/'):
|
||||
test = zip_ref.filelist[i].filename
|
||||
break
|
||||
path_list = test.split('/')
|
||||
root_path = path_list[0]
|
||||
if len(path_list) > 1:
|
||||
|
@ -2,6 +2,7 @@ import os
|
||||
import re
|
||||
import sys
|
||||
import json
|
||||
import tempfile
|
||||
import time
|
||||
import uuid
|
||||
import string
|
||||
@ -258,6 +259,44 @@ class Helpers:
|
||||
logger.critical("Unable to write to {} - Error: {}".format(path, e))
|
||||
return False
|
||||
|
||||
def unzipFile(self, zip_path):
|
||||
new_dir_list = zip_path.split('/')
|
||||
new_dir = ''
|
||||
for i in range(len(new_dir_list)-1):
|
||||
if i == 0:
|
||||
new_dir += new_dir_list[i]
|
||||
else:
|
||||
new_dir += '/'+new_dir_list[i]
|
||||
|
||||
if helper.check_file_perms(zip_path) and os.path.isfile(zip_path):
|
||||
helper.ensure_dir_exists(new_dir)
|
||||
tempDir = tempfile.mkdtemp()
|
||||
try:
|
||||
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
||||
zip_ref.extractall(tempDir)
|
||||
for i in range(len(zip_ref.filelist)):
|
||||
if len(zip_ref.filelist) > 1 or not zip_ref.filelist[i].filename.endswith('/'):
|
||||
test = zip_ref.filelist[i].filename
|
||||
break
|
||||
path_list = test.split('/')
|
||||
root_path = path_list[0]
|
||||
if len(path_list) > 1:
|
||||
for i in range(len(path_list) - 2):
|
||||
root_path = os.path.join(root_path, path_list[i + 1])
|
||||
|
||||
full_root_path = os.path.join(tempDir, root_path)
|
||||
|
||||
for item in os.listdir(full_root_path):
|
||||
try:
|
||||
shutil.move(os.path.join(full_root_path, item), os.path.join(new_dir, item))
|
||||
except Exception as ex:
|
||||
logger.error('ERROR IN ZIP IMPORT: {}'.format(ex))
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
else:
|
||||
return "false"
|
||||
return
|
||||
|
||||
def ensure_logging_setup(self):
|
||||
log_file = os.path.join(os.path.curdir, 'logs', 'commander.log')
|
||||
session_log_file = os.path.join(os.path.curdir, 'logs', 'session.log')
|
||||
@ -559,14 +598,6 @@ class Helpers:
|
||||
return json.loads(content)
|
||||
|
||||
@staticmethod
|
||||
def zip_directory(file, path, compression=zipfile.ZIP_LZMA):
|
||||
with zipfile.ZipFile(file, 'w', compression) as zf:
|
||||
for root, dirs, files in os.walk(path):
|
||||
for file in files:
|
||||
zf.write(os.path.join(root, file),
|
||||
os.path.relpath(os.path.join(root, file),
|
||||
os.path.join(path, '..')))
|
||||
@staticmethod
|
||||
def copy_files(source, dest):
|
||||
if os.path.isfile(source):
|
||||
shutil.copyfile(source, dest)
|
||||
|
@ -321,7 +321,6 @@ class db_shortcuts:
|
||||
def get_all_authorized_servers(user_id):
|
||||
user_servers = User_Servers.select().where(User_Servers.user_id == user_id)
|
||||
user_roles = User_Roles.select().where(User_Roles.user_id == user_id)
|
||||
server_data = []
|
||||
roles_list = []
|
||||
role_server = []
|
||||
server_data = []
|
||||
@ -596,6 +595,11 @@ class db_shortcuts:
|
||||
def add_user_server(server_id, user_id, us_permissions):
|
||||
servers = User_Servers.insert({User_Servers.server_id: server_id, User_Servers.user_id: user_id, User_Servers.permissions: us_permissions}).execute()
|
||||
return servers
|
||||
|
||||
@staticmethod
|
||||
def add_role_server(server_id, role_id):
|
||||
servers = Role_Servers.insert({Role_Servers.server_id: server_id, Role_Servers.role_id: role_id}).execute()
|
||||
return servers
|
||||
|
||||
|
||||
@staticmethod
|
||||
|
@ -11,6 +11,8 @@ import schedule
|
||||
import logging.config
|
||||
import zipfile
|
||||
from threading import Thread
|
||||
import shutil
|
||||
import zlib
|
||||
import html
|
||||
|
||||
|
||||
@ -416,17 +418,15 @@ class Server:
|
||||
self.is_backingup = True
|
||||
conf = db_helper.get_backup_config(self.server_id)
|
||||
try:
|
||||
backup_filename = "{}/{}.zip".format(self.settings['backup_path'], datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
|
||||
backup_filename = "{}/{}".format(self.settings['backup_path'], datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
|
||||
logger.info("Creating backup of server '{}' (ID#{}) at '{}'".format(self.settings['server_name'], self.server_id, backup_filename))
|
||||
helper.zip_directory(backup_filename, self.server_path)
|
||||
while len(self.list_backups()) > conf["max_backups"]:
|
||||
shutil.make_archive(backup_filename, 'zip', self.server_path)
|
||||
while len(self.list_backups()) > conf["max_backups"] and conf["max_backups"] > 0:
|
||||
backup_list = self.list_backups()
|
||||
oldfile = backup_list[0]
|
||||
backup_path = self.settings['backup_path']
|
||||
old_file_name = oldfile['path']
|
||||
back_old_file = os.path.join(backup_path, old_file_name)
|
||||
logger.info("Removing old backup '{}'".format(oldfile))
|
||||
os.remove(back_old_file)
|
||||
oldfile_path = "{}/{}".format(conf['backup_path'], oldfile['path'])
|
||||
logger.info("Removing old backup '{}'".format(oldfile['path']))
|
||||
os.remove(oldfile_path)
|
||||
self.is_backingup = False
|
||||
logger.info("Backup of server: {} completed".format(self.name))
|
||||
return
|
||||
@ -503,6 +503,7 @@ class Server:
|
||||
|
||||
while db_helper.get_server_stats_by_id(self.server_id)['updating']:
|
||||
if downloaded and not self.is_backingup:
|
||||
print("Backup Status: " + str(self.is_backingup))
|
||||
logger.info("Executable updated successfully. Starting Server")
|
||||
|
||||
db_helper.set_update(self.server_id, False)
|
||||
|
@ -113,16 +113,6 @@ class TasksManager:
|
||||
|
||||
elif command == "update_executable":
|
||||
svr.jar_update()
|
||||
elif command == "delete_server":
|
||||
logger.info(
|
||||
"Removing server from panel for server: {}".format(c['server_id']['server_name']))
|
||||
self.controller.remove_server(c['server_id']['server_id'], False)
|
||||
|
||||
elif command == "delete_server_files":
|
||||
logger.info(
|
||||
"Removing server and all associated files for server: {}".format(c['server_id']['server_name']))
|
||||
self.controller.remove_server(c['server_id']['server_id'], True)
|
||||
|
||||
db_helper.mark_command_complete(c.get('command_id', None))
|
||||
|
||||
time.sleep(1)
|
||||
|
@ -1,5 +1,9 @@
|
||||
import json
|
||||
import logging
|
||||
import tempfile
|
||||
import threading
|
||||
import zipfile
|
||||
|
||||
import tornado.web
|
||||
import tornado.escape
|
||||
import bleach
|
||||
@ -183,10 +187,58 @@ class AjaxHandler(BaseHandler):
|
||||
logger.warning("Invalid path in create_dir ajax call ({})".format(dir_path))
|
||||
console.warning("Invalid path in create_dir ajax call ({})".format(dir_path))
|
||||
return
|
||||
|
||||
# Create the directory
|
||||
os.mkdir(dir_path)
|
||||
|
||||
elif page == "unzip_file":
|
||||
server_id = self.get_argument('id', None)
|
||||
path = self.get_argument('path', None)
|
||||
helper.unzipFile(path)
|
||||
self.redirect("/panel/server_detail?id={}&subpage=files".format(server_id))
|
||||
return
|
||||
|
||||
elif page == "upload_files":
|
||||
server_id = self.get_argument('id', None)
|
||||
path = self.get_argument('path', None)
|
||||
files = self.request.files['files']
|
||||
upload_thread = threading.Thread(target=self.do_upload, daemon=True, name=files[0]['filename'],
|
||||
args=(server_id, path, files))
|
||||
upload_thread.start()
|
||||
self.redirect("/panel/server_detail?id={}&subpage=files".format(server_id))
|
||||
|
||||
def do_upload(self, server_id, path, files):
|
||||
if helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], path):
|
||||
try:
|
||||
for file in files:
|
||||
if file['filename'].split('.') is not None:
|
||||
self._upload_file(file['body'], path, file['filename'])
|
||||
else:
|
||||
logger.error("Directory Detected. Skipping")
|
||||
except Exception as e:
|
||||
logger.error("Error while uploading files: {}".format(e))
|
||||
else:
|
||||
logger.error("Invalid directory requested. Canceling upload")
|
||||
return
|
||||
|
||||
def _upload_file(self, file_data, file_path, file_name):
|
||||
error = ""
|
||||
|
||||
file_full_path = os.path.join(file_path, file_name)
|
||||
if os.path.exists(file_full_path):
|
||||
error = "A file with this name already exists."
|
||||
|
||||
if not helper.check_writeable(file_path):
|
||||
error = "Unwritable Path"
|
||||
|
||||
if error != "":
|
||||
logger.error("Unable to save uploaded file due to: {}".format(error))
|
||||
return False
|
||||
|
||||
output_file = open(file_full_path, 'wb')
|
||||
output_file.write(file_data)
|
||||
logger.info('Saving File: {}'.format(file_full_path))
|
||||
return True
|
||||
|
||||
@tornado.web.authenticated
|
||||
def delete(self, page):
|
||||
if page == "del_file":
|
||||
@ -229,6 +281,18 @@ class AjaxHandler(BaseHandler):
|
||||
# os.rmdir(dir_path) # Would only remove empty directories
|
||||
shutil.rmtree(dir_path) # Removes also when there are contents
|
||||
|
||||
elif page == "delete_server":
|
||||
server_id = self.get_argument('id', None)
|
||||
logger.info(
|
||||
"Removing server from panel for server: {}".format(db_helper.get_server_friendly_name(server_id)))
|
||||
self.controller.remove_server(server_id, False)
|
||||
|
||||
elif page == "delete_server_files":
|
||||
server_id = self.get_argument('id', None)
|
||||
logger.info(
|
||||
"Removing server and all associated files for server: {}".format(db_helper.get_server_friendly_name(server_id)))
|
||||
self.controller.remove_server(server_id, True)
|
||||
|
||||
@tornado.web.authenticated
|
||||
def put(self, page):
|
||||
if page == "save_file":
|
||||
|
@ -338,17 +338,9 @@ class PanelHandler(BaseHandler):
|
||||
|
||||
elif page == "edit_user":
|
||||
user_id = self.get_argument('id', None)
|
||||
user_servers = db_helper.get_authorized_servers(user_id)
|
||||
role_servers = db_helper.get_authorized_servers_from_roles(user_id)
|
||||
page_role_servers = []
|
||||
servers = set()
|
||||
for server in user_servers:
|
||||
flag = False
|
||||
for rserver in role_servers:
|
||||
if rserver['server_id'] == server['server_id']:
|
||||
flag = True
|
||||
if not flag:
|
||||
servers.add(server['server_id'])
|
||||
for server in role_servers:
|
||||
page_role_servers.append(server['server_id'])
|
||||
page_data['new_user'] = False
|
||||
@ -657,7 +649,6 @@ class PanelHandler(BaseHandler):
|
||||
"enabled": enabled,
|
||||
"regen_api": regen_api,
|
||||
"roles": roles,
|
||||
"servers": servers,
|
||||
}
|
||||
db_helper.update_user(user_id, user_data=user_data)
|
||||
|
||||
@ -713,7 +704,6 @@ class PanelHandler(BaseHandler):
|
||||
user_id = db_helper.add_user(username, password=password0, enabled=enabled)
|
||||
user_data = {
|
||||
"roles": roles,
|
||||
"servers": servers,
|
||||
}
|
||||
db_helper.update_user(user_id, user_data)
|
||||
|
||||
|
@ -195,8 +195,11 @@ class ServerHandler(BaseHandler):
|
||||
return
|
||||
server_type, server_version = server_parts
|
||||
# todo: add server type check here and call the correct server add functions if not a jar
|
||||
role_ids = db_helper.get_user_roles_id(exec_user_id)
|
||||
new_server_id = self.controller.create_jar_server(server_type, server_version, server_name, min_mem, max_mem, port)
|
||||
db_helper.add_user_server(new_server_id, exec_user_id, "11111111")
|
||||
for role in role_ids:
|
||||
db_helper.add_role_server(new_server_id, role)
|
||||
db_helper.add_to_audit_log(exec_user_data['user_id'],
|
||||
"created a {} {} server named \"{}\"".format(server_version, str(server_type).capitalize(), server_name), # Example: Admin created a 1.16.5 Bukkit server named "survival"
|
||||
new_server_id,
|
||||
|
@ -79,4 +79,4 @@ body { background-color: var(--dark) !important; /* Firefox */ }
|
||||
|
||||
.actions_serverlist > a > i {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
@ -16188,41 +16188,35 @@ body.avgrund-active {
|
||||
border-radius: 2px; }
|
||||
|
||||
/* Context Menu */
|
||||
.context-menu-icon:before {
|
||||
color: #000;
|
||||
font: normal normal normal 15px/1 "Material Design Icons"; }
|
||||
.context-menu {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
background: lightgray;
|
||||
border: 1px solid black;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.context-menu-icon.context-menu-icon-cut:before {
|
||||
content: '\F190'; }
|
||||
.context-menu ul {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
min-width: 150px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.context-menu-icon.context-menu-icon-edit:before {
|
||||
content: '\F3EF'; }
|
||||
.context-menu ul li {
|
||||
padding-bottom: 7px;
|
||||
padding-top: 7px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.context-menu-icon.context-menu-icon-copy:before {
|
||||
content: '\F18F'; }
|
||||
|
||||
.context-menu-icon.context-menu-icon-paste:before {
|
||||
content: '\F613'; }
|
||||
|
||||
.context-menu-icon.context-menu-icon-delete:before {
|
||||
content: '\F6CB'; }
|
||||
|
||||
.context-menu-icon.context-menu-icon-quit:before {
|
||||
content: '\F156'; }
|
||||
|
||||
.context-menu-list {
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
border: 1px solid #dee2e6; }
|
||||
.context-menu-list .context-menu-item span {
|
||||
color: #000;
|
||||
font-size: 0.75rem;
|
||||
font-family: "roboto", sans-serif; }
|
||||
.context-menu-list .context-menu-item.context-menu-hover {
|
||||
background: #000; }
|
||||
.context-menu-list .context-menu-item.context-menu-hover span {
|
||||
color: #fff; }
|
||||
.context-menu ul li a {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.context-menu ul li:hover {
|
||||
background: darkgray;
|
||||
}
|
||||
/* Clockpicker */
|
||||
.clockpicker-popover {
|
||||
background-color: #dee2e6; }
|
||||
|
@ -121,12 +121,10 @@
|
||||
<tr>
|
||||
<td>{{ server['server_name'] }}</td>
|
||||
<td>
|
||||
{% if server['server_id'] in data['servers'] %}
|
||||
<input type="checkbox" class="form-check-input" id="server_{{ server['server_id'] }}_access" name="server_{{ server['server_id'] }}_access" checked="" value="1">
|
||||
{% elif server['server_id'] in data['role-servers'] %}
|
||||
{% if server['server_id'] in data['role-servers'] %}
|
||||
<input type="checkbox" class="form-check-input" id="server_{{ server['server_id'] }}_access" name="server_{{ server['server_id'] }}_access" checked="" value="" disabled>
|
||||
{% else %}
|
||||
<input type="checkbox" class="form-check-input" id="server_{{ server['server_id'] }}_access" name="server_{{ server['server_id'] }}_access" value="1">
|
||||
<input type="checkbox" class="form-check-input" id="server_{{ server['server_id'] }}_access" name="server_{{ server['server_id'] }}_access" value="1" disabled>
|
||||
{% end %}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -173,6 +173,35 @@
|
||||
|
||||
});
|
||||
|
||||
function deleteServerE(callback) {
|
||||
var token = getCookie("_xsrf")
|
||||
$.ajax({
|
||||
type: "DELETE",
|
||||
headers: {'X-XSRFToken': token},
|
||||
url: '/ajax/delete_server?id={{ data['server_stats']['server_id']['server_id'] }}',
|
||||
data: {
|
||||
},
|
||||
success: function(data){
|
||||
console.log("got response:");
|
||||
console.log(data);
|
||||
},
|
||||
});
|
||||
}
|
||||
function deleteServerFilesE(path, callback) {
|
||||
var token = getCookie("_xsrf")
|
||||
$.ajax({
|
||||
type: "DELETE",
|
||||
headers: {'X-XSRFToken': token},
|
||||
url: '/ajax/delete_server_files?id={{ data['server_stats']['server_id']['server_id'] }}',
|
||||
data: {
|
||||
},
|
||||
success: function(data){
|
||||
console.log("got response:");
|
||||
console.log(data);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
let server_id = '{{ data['server_stats']['server_id']['server_id'] }}';
|
||||
|
||||
function send_command (server_id, command){
|
||||
@ -219,7 +248,7 @@ let server_id = '{{ data['server_stats']['server_id']['server_id'] }}';
|
||||
},
|
||||
callback: function(result) {
|
||||
if (!result){
|
||||
send_command(server_id, 'delete_server');
|
||||
deleteServerE()
|
||||
setTimeout(function(){ window.location = '/panel/dashboard'; }, 5000);
|
||||
bootbox.dialog({
|
||||
backdrop: true,
|
||||
@ -230,7 +259,7 @@ let server_id = '{{ data['server_stats']['server_id']['server_id'] }}';
|
||||
|
||||
return;}
|
||||
else{
|
||||
send_command(server_id, 'delete_server_files');
|
||||
deleteServerFilesE();
|
||||
setTimeout(function(){ window.location = '/panel/dashboard'; }, 5000);
|
||||
bootbox.dialog({
|
||||
backdrop: true,
|
||||
|
@ -42,7 +42,6 @@
|
||||
<div id="files-tree-nav" class="overlay">
|
||||
|
||||
<!-- Button to close the overlay navigation -->
|
||||
<a href="javascript:void(0)" class="closebtn" onclick="document.getElementById('files-tree-nav').style.height = '0%';">×</a>
|
||||
|
||||
<!-- Overlay content -->
|
||||
<div id="files-tree-nav-content" class="overlay-content">
|
||||
@ -51,55 +50,75 @@
|
||||
<a onclick="renameItemE(event)" href="javascript:void(0)" id="renameItem" href="#">{{ translate('serverFiles', 'rename') }}</a>
|
||||
<a onclick="deleteFileE(event)" href="javascript:void(0)" id="deleteFile" href="#">{{ translate('serverFiles', 'delete') }}</a>
|
||||
<a onclick="deleteDirE(event)" href="javascript:void(0)" id="deleteDir" href="#">{{ translate('serverFiles', 'delete') }}</a>
|
||||
<a onclick="uploadFilesE(event)" href="javascript:void(0)" id="upload" href="#">Upload Files</a>
|
||||
<a onclick="unzipFilesE(event)" href="javascript:void(0)" id="unzip" href="#">Unzip</a>
|
||||
<a href="javascript:void(0)" class="closebtn" style="color: red;" onclick="document.getElementById('files-tree-nav').style.display = 'none';">Close</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<style>
|
||||
/* The Overlay (background) */
|
||||
.overlay {
|
||||
/* Height & width depends on how you want to reveal the overlay (see JS below) */
|
||||
height: 0;
|
||||
width: 100vw;
|
||||
position: fixed; /* Stay in place */
|
||||
z-index: 1031; /* Sit on top */
|
||||
left: 0;
|
||||
top: 0;
|
||||
background-color: rgb(0,0,0); /* Black fallback color */
|
||||
background-color: rgba(0,0,0, 0.9); /* Black w/opacity */
|
||||
overflow-x: hidden; /* Disable horizontal scroll */
|
||||
transition: 0.5s; /* 0.5 second transition effect to slide in or slide down the overlay (height or width, depending on reveal) */
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
background-color: #fff;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 10px 20px rgb(64 64 64 / 5%);
|
||||
padding: 10px 0;
|
||||
z-index: 10000;
|
||||
overflow: scroll;
|
||||
|
||||
}
|
||||
.overlay::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hide scrollbar for IE, Edge and Firefox */
|
||||
.overlay {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
|
||||
/* Position the content inside the overlay */
|
||||
.overlay-content {
|
||||
position: relative;
|
||||
top: 25%; /* 25% from the top */
|
||||
width: 100%; /* 100% width */
|
||||
text-align: center; /* Centered text/links */
|
||||
margin-top: 30px; /* 30px top margin to avoid conflict with the close button on smaller screens */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fff;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 10px 20px rgb(64 64 64 / 5%);
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
/* The navigation links inside the overlay */
|
||||
.overlay a {
|
||||
padding: 8px;
|
||||
text-decoration: none;
|
||||
font-size: 36px;
|
||||
color: #818181;
|
||||
display: block; /* Display block instead of inline */
|
||||
transition: 0.3s; /* Transition effects on hover (color) */
|
||||
font: inherit;
|
||||
border: 0;
|
||||
padding: 10px 30px 10px 15px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
text-decoration: unset;
|
||||
color: #000;
|
||||
font-weight: 500;
|
||||
transition: 0.5s linear;
|
||||
-webkit-transition: 0.5s linear;
|
||||
-moz-transition: 0.5s linear;
|
||||
-ms-transition: 0.5s linear;
|
||||
-o-transition: 0.5s linear;
|
||||
}
|
||||
|
||||
/* When you mouse over the navigation links, change their color */
|
||||
.overlay a:hover, .overlay a:focus {
|
||||
color: #f1f1f1;
|
||||
background:#f1f3f7;
|
||||
color: #4b00ff;
|
||||
}
|
||||
|
||||
/* Position the close button (top right corner) */
|
||||
.overlay .closebtn {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 45px;
|
||||
font-size: 60px;
|
||||
.overlay .closebtn .closebtn:hover {
|
||||
background-color: red;
|
||||
color: red;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
/* When the height of the screen is less than 450 pixels, change the font-size of the links and position the close button again, so they don't overlap */
|
||||
@ -489,6 +508,71 @@
|
||||
});
|
||||
}
|
||||
|
||||
function unZip(path, callback) {
|
||||
var token = getCookie("_xsrf")
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
headers: {'X-XSRFToken': token},
|
||||
url: '/ajax/unzip_file?id={{ data['server_stats']['server_id']['server_id'] }}',
|
||||
data: {
|
||||
path: path
|
||||
},
|
||||
});
|
||||
window.location.href = "/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=files"
|
||||
}
|
||||
function uploadFilesE(event){
|
||||
path = event.target.parentElement.getAttribute('data-path');
|
||||
console.log("PATH: " + path);
|
||||
$(function () {
|
||||
server_id = {{ data['server_stats']['server_id']['server_id'] }};
|
||||
var uploadHtml = "<div>" +
|
||||
'<form id="upload_file" enctype="multipart/form-data" action="/ajax/upload_files?id=' + server_id +'&path='+ path +'"method="post">{% raw xsrf_form_html() %}'+"<label class='upload-area' style='width:100%;text-align:center;' for='files'>" +
|
||||
"<input id='files' name='files' type='file' style='display:none;' multiple='true'>" +
|
||||
"<i class='fa fa-cloud-upload fa-3x'></i>" +
|
||||
"<br />" +
|
||||
"Click Here To Upload" +
|
||||
"</label></form>" +
|
||||
"<br />" +
|
||||
"<ul style='margin-left:5px !important;' id='fileList'></ul>" +
|
||||
"</div><div class='clearfix'></div>";
|
||||
|
||||
bootbox.dialog({
|
||||
message: uploadHtml,
|
||||
title: "File Upload",
|
||||
buttons: {
|
||||
success: {
|
||||
label: "Upload",
|
||||
className: "btn-default",
|
||||
callback: function () {
|
||||
$('#upload_file').submit(); //.trigger('submit');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var fileList = document.getElementById("files");
|
||||
fileList.addEventListener("change", function (e) {
|
||||
var list = "";
|
||||
for (var i = 0; i < this.files.length; i++) {
|
||||
list += "<li class='col-xs-12 file-list'>" + this.files[i].name + "</li>"
|
||||
}
|
||||
|
||||
document.getElementById("fileList").innerHTML = list;
|
||||
}, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function uploadFiles(e){
|
||||
path = event.target.parentElement.getAttribute('data-path');
|
||||
server_id = {{ data['server_stats']['server_id']['server_id'] }};
|
||||
var uploadHtml = '<form enctype="multipart/form-data" action="/ajax/upload_files?id=' + server_id +'&path='+ path +'"method="post">{% raw xsrf_form_html() %}<div class="form-group">'+"<label class='upload-area' style='width:100%;text-align:center;' for='fupload'>" +'<input id="files" type="file" name="files" multiple>' +"<i class='fa fa-cloud-upload fa-3x'></i>" +"<br />" +"Upload Files Here" +"</label>" +"<br />" +"<span style='margin-left:5px !important;' id='fileList'></span>"+'</div><br><br><input id="upload_file" type="submit"value="Upload File" class="btn btn-success hidden"/></form>';
|
||||
bootbox.dialog({
|
||||
message: uploadHtml,
|
||||
title: "Upload Files To "+path,
|
||||
});
|
||||
}
|
||||
|
||||
function getTreeView() {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
@ -542,6 +626,7 @@
|
||||
$('#createFile').toggle(isDir);
|
||||
$('#createDir').toggle(isDir);
|
||||
$('#deleteDir').toggle(isDir);
|
||||
$('#upload').toggle(isDir);
|
||||
|
||||
var isFile = event.target.classList.contains('tree-file');
|
||||
$('#deleteFile').toggle(isFile);
|
||||
@ -553,20 +638,46 @@
|
||||
$('#renameItem').hide();
|
||||
$('#deleteDir').hide();
|
||||
$('#deleteFile').hide();
|
||||
$('#upload').show();
|
||||
}
|
||||
if(event.target.textContent.endsWith('.zip')){
|
||||
$('#unzip').show();
|
||||
console.log(event.target.textContent)
|
||||
}else{
|
||||
$('#unzip').hide();}
|
||||
|
||||
var clientX = event.clientX;
|
||||
var clientY = event.clientY;
|
||||
|
||||
|
||||
|
||||
document.getElementById('files-tree-nav-content')
|
||||
.setAttribute('data-path', ctxmenuPath);
|
||||
|
||||
document.getElementById('files-tree-nav-content')
|
||||
.setAttribute('data-name', ctxmenuName);
|
||||
|
||||
document.getElementById("files-tree-nav").style.height = "100%";
|
||||
document.getElementById("files-tree-nav").style.display = "flex";
|
||||
document.getElementById("files-tree-nav").style.position = "fixed";
|
||||
domRect = document.getElementById("files-tree-nav").getBoundingClientRect();
|
||||
sum = (clientY+domRect['height']) - window.innerHeight
|
||||
if(domRect['height']+clientY > window.innerHeight){
|
||||
clientY = clientY - sum
|
||||
}
|
||||
document.getElementById("files-tree-nav").style.top = clientY + 'px';
|
||||
document.getElementById("files-tree-nav").style.left = clientX + 'px';
|
||||
console.log(domRect)
|
||||
console.log(window.innerHeight)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('click', function(e){
|
||||
let inside = (e.target.closest('#files-tree-nav'));
|
||||
if(!inside){
|
||||
let contextMenu = document.getElementById('files-tree-nav');
|
||||
contextMenu.setAttribute('style', 'display:none');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function createFileE(event) {
|
||||
bootbox.prompt("{% raw translate('serverFiles', 'createFileQuestion') %}", function(result) {
|
||||
@ -576,7 +687,7 @@
|
||||
|
||||
createFile(path, result, function () {
|
||||
getTreeView()
|
||||
document.getElementById('files-tree-nav').style.height = '0%';
|
||||
document.getElementById('files-tree-nav').style.display = 'none';
|
||||
});
|
||||
})
|
||||
}
|
||||
@ -589,7 +700,7 @@
|
||||
|
||||
createDir(path, result, function () {
|
||||
getTreeView()
|
||||
document.getElementById('files-tree-nav').style.height = '0%';
|
||||
document.getElementById('files-tree-nav').style.display = 'none';
|
||||
});
|
||||
})
|
||||
}
|
||||
@ -602,10 +713,14 @@
|
||||
|
||||
renameItem(path, result, function () {
|
||||
getTreeView()
|
||||
document.getElementById('files-tree-nav').style.height = '0%';
|
||||
document.getElementById('files-tree-nav').style.display = 'none';
|
||||
});
|
||||
})
|
||||
}
|
||||
function unzipFilesE(event) {
|
||||
path = event.target.parentElement.getAttribute('data-path');
|
||||
unZip(path)
|
||||
}
|
||||
|
||||
function deleteFileE(event) {
|
||||
path = event.target.parentElement.getAttribute('data-path');
|
||||
@ -629,7 +744,7 @@
|
||||
if (!result) return;
|
||||
deleteFile(path, function () {
|
||||
getTreeView()
|
||||
document.getElementById('files-tree-nav').style.height = '0%';
|
||||
document.getElementById('files-tree-nav').style.display = 'none';
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -657,7 +772,7 @@
|
||||
if (!result) return;
|
||||
deleteDir(path, function () {
|
||||
getTreeView()
|
||||
document.getElementById('files-tree-nav').style.height = '0%';
|
||||
document.getElementById('files-tree-nav').style.display = 'none';
|
||||
});
|
||||
}
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user