Zip import semi broken.

Need to figure out why temp dir is not being passed correctly
Need to make sure tempdir gets deleted.
This commit is contained in:
Andrew 2022-01-09 22:21:28 -05:00
parent 369ac7ad15
commit b815cf38a8
4 changed files with 181 additions and 68 deletions

View File

@ -18,6 +18,7 @@ from requests import get
from contextlib import suppress
import ctypes
import telnetlib
from app.classes.web.websocket_helper import websocket_helper
from datetime import datetime
from socket import gethostname
@ -731,12 +732,67 @@ class Helpers:
return output
@staticmethod
def unzipServer(zip_path):
tempDir = tempfile.mkdtemp()
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
def generate_zip_tree(folder, output=""):
file_list = os.listdir(folder)
file_list = sorted(file_list, key=str.casefold)
output += \
"""<ul class="tree-nested d-block" id="{}ul">"""\
.format(folder)
for raw_filename in file_list:
filename = html.escape(raw_filename)
rel = os.path.join(folder, raw_filename)
if os.path.isdir(rel):
output += \
"""<li class="tree-item" data-path="{}">
\n<div id="{}" data-path="{}" data-name="{}" class="tree-caret tree-ctx-item tree-folder">
<input type="radio" name="root_path" value="{}">
<span id="{}span" class="files-tree-title" data-path="{}" data-name="{}" onclick="getDirView(event)">
<i class="far fa-folder"></i>
<i class="far fa-folder-open"></i>
{}
</span>
</input></div><li>
\n"""\
.format(os.path.join(folder, filename), os.path.join(folder, filename), os.path.join(folder, filename), os.path.join(folder, filename), filename, os.path.join(folder, filename), os.path.join(folder, filename), filename, filename)
return output
@staticmethod
def generate_zip_dir(folder, output=""):
file_list = os.listdir(folder)
file_list = sorted(file_list, key=str.casefold)
output += \
"""<ul class="tree-nested d-block" id="{}ul">"""\
.format(folder)
for raw_filename in file_list:
filename = html.escape(raw_filename)
rel = os.path.join(folder, raw_filename)
if os.path.isdir(rel):
output += \
"""<li class="tree-item" data-path="{}">
\n<div id="{}" data-path="{}" data-name="{}" class="tree-caret tree-ctx-item tree-folder">
<input type="radio" name="root_path" value="{}">
<span id="{}span" class="files-tree-title" data-path="{}" data-name="{}" onclick="getDirView(event)">
<i class="far fa-folder"></i>
<i class="far fa-folder-open"></i>
{}
</span>
</input></div><li>"""\
.format(os.path.join(folder, filename), os.path.join(folder, filename), os.path.join(folder, filename), os.path.join(folder, filename), filename, os.path.join(folder, filename), os.path.join(folder, filename), filename, filename)
return output
def unzipServer(self, zip_path, user_id):
temp_uuid = str(uuid.uuid4()) + 'temp'
servers_path = str(self.get_servers_root_dir())
tempDir = os.path.join(servers_path, temp_uuid)
os.mkdir(tempDir)
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
#extracts archive to temp directory
zip_ref.extractall(tempDir)
return tempDir
if user_id:
websocket_helper.broadcast_user(user_id, 'send_temp_path',{
'path': tempDir
})
return
@staticmethod
def in_path(parent_path, child_path):

View File

@ -134,6 +134,22 @@ class AjaxHandler(BaseHandler):
helper.generate_tree(path))
self.finish()
elif page == "get_zip_tree":
server_id = self.get_argument('id', None)
path = self.get_argument('path', None)
self.write(helper.get_os_understandable_path(path) + '\n' +
helper.generate_zip_tree(path))
self.finish()
elif page == "get_zip_dir":
server_id = self.get_argument('id', None)
path = self.get_argument('path', None)
self.write(helper.get_os_understandable_path(path) + '\n' +
helper.generate_zip_dir(path))
self.finish()
elif page == "get_dir":
server_id = self.get_argument('id', None)
path = self.get_argument('path', None)
@ -277,12 +293,9 @@ class AjaxHandler(BaseHandler):
self.redirect('/panel/dashboard')
elif page == "unzip_server":
print("in unzip server")
path = self.get_argument('path', None)
logger.info(
"Removing server from panel for server: {}".format(self.controller.servers.get_server_friendly_name(server_id)))
self.controller.remove_server(server_id, False)
return "test"
helper.unzipServer(path, exec_user_id)
return
@tornado.web.authenticated

View File

@ -191,12 +191,14 @@ class ServerHandler(BaseHandler):
self.get_remote_ip())
elif import_type == 'import_zip':
# here import_server_path means the zip path
good_path = self.controller.verify_zip_server(import_server_path)
zip_path = bleach.clean(self.get_argument('root_path'))
print(zip_path)
good_path = helper.check_path_exists(zip_path)
if not good_path:
self.redirect("/panel/error?error=Zip file not found!")
self.redirect("/panel/error?error=Temp path not found!")
return
new_server_id = self.controller.import_zip_server(server_name, import_server_path,import_server_jar, min_mem, max_mem, port)
new_server_id = self.controller.import_zip_server(server_name, import_server_path, import_server_jar, min_mem, max_mem, port)
if new_server_id == "false":
self.redirect("/panel/error?error=Zip file not accessible! You can fix this permissions issue with sudo chown -R crafty:crafty {} And sudo chmod 2775 -R {}".format(import_server_path, import_server_path))
return
@ -204,6 +206,8 @@ class ServerHandler(BaseHandler):
"imported a zip server named \"{}\"".format(server_name), # Example: Admin imported a server named "old creative"
new_server_id,
self.get_remote_ip())
#deletes temp dir
shutil.rmtree(zip_path)
else:
if len(server_parts) != 2:
self.redirect("/panel/error?error=Invalid server data")

View File

@ -302,6 +302,33 @@
<input type="text" class="form-control" id="zip_root_path" name="zip_root_path">
</div>
</div>
<div class="modal fade" id="dir_select" tabindex="-1" role="dialog" aria-labelledby="dir_select" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle">Select Root Dir</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="tree-ctx-item" data-path="" style="overflow: scroll; max-height:75%;">
<input type="radio" id="main-tree-input" name="root_path" value="" checked>
<span id="main-tree" class="files-tree-title tree-caret-down root-dir" data-path="">
<i class="far fa-folder"></i>
<i class="far fa-folder-open"></i>
{{ translate('serverFiles', 'files', data['lang']) }}
</span>
</input>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" id="modal-okay" data-dismiss="modal" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</div>
<button id="zip_submit" type="submit" title="You must select server root dir first" disabled class="btn btn-primary mr-2">{{ translate('serverWizard', 'importServerButton', data['lang']) }}</button>
<button type="reset" class="btn btn-danger mr-2">{{ translate('serverWizard', 'resetForm', data['lang']) }}</button>
@ -313,31 +340,6 @@
</div>
</div>
</div>
<div class="modal fade" id="dir_select" tabindex="-1" role="dialog" aria-labelledby="dir_select" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="tree-ctx-item" data-path="">
<span id="main-tree" class="files-tree-title tree-caret-down root-dir" data-path="">
<i class="far fa-folder"></i>
<i class="far fa-folder-open"></i>
{{ translate('serverFiles', 'files', data['lang']) }}
</span>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" onclick="" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
<style>
.scroll {
max-height: 12em;
@ -367,6 +369,44 @@
z-index: 100;
}
</style>
<style>
/* Remove default bullets */
.tree-view,
.tree-nested {
list-style-type: none;
margin: 0;
padding: 0;
margin-left: 10px;
}
/* Style the items */
.tree-item,
.files-tree-title {
cursor: pointer;
user-select: none; /* Prevent text selection */
}
/* Create the caret/arrow with a unicode, and style it */
.tree-caret .fa-folder {
display: inline-block;
}
.tree-caret .fa-folder-open {
display: none;
}
/* Rotate the caret/arrow icon when clicked on (using JavaScript) */
.tree-caret-down .fa-folder {
display: none;
}
.tree-caret-down .fa-folder-open {
display: inline-block;
}
/* Hide the nested list */
.tree-nested {
display: none;
}
</style>
{% end %}
@ -374,22 +414,30 @@
<script>
document.getElementById("root_files_button").addEventListener("click", function(){
if(document.forms["zip"]["server_path"].value != ""){
path = document.getElementById('server_path')
var token = getCookie("_xsrf")
if(document.getElementById('root_files_button').classList.contains('clicked')){
document.getElementById('main-tree').innerHTML = '<i class="far fa-folder"></i><i class="far fa-folder-open"></i>{{ translate("serverFiles", "files", data["lang"]) }}</span>'
}else{
document.getElementById('root_files_button').classList.add('clicked')
}
path = document.forms["zip"]["server_path"].value;
console.log(document.forms["zip"]["server_path"].value)
var token = getCookie("_xsrf");
var dialog = bootbox.dialog({
message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i> Please wait while we gather your files...</p>',
closeButton: false
});
setTimeout(function(){
dialog.modal('hide');
}, 2000);
$.ajax({
type: "POST",
headers: {'X-XSRFToken': token},
url: '/ajax/unzip_server',
data: {
path: path,
server_id: '-1'
},
url: '/ajax/unzip_server?id=-1&path='+path,
});
}else{
bootbox.alert("You must input a path before selecting this button");
}
});
</script>
<script>
@ -431,7 +479,6 @@ function hide(event) {
function show_file_tree(){
$("#dir_select").modal();
}
function check_sizes(a, b, changed){
max_mem = parseFloat(a.val());
@ -444,24 +491,13 @@ function hide(event) {
}
}
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 getTreeView(event) {
path = '/'
function getTreeView(path) {
document.getElementById('zip_submit').disabled = false;
path = path
$.ajax({
type: "GET",
url: '/ajax/get_tree?id=1&path='+path,
url: '/ajax/get_zip_tree?id=-1&path='+path,
dataType: 'text',
success: function(data){
console.log("got response:");
@ -472,8 +508,8 @@ function hide(event) {
text = dataArr.join('\n');
try{
document.getElementById(path).innerHTML += text;
event.target.parentElement.classList.add("clicked");
document.getElementById('main-tree').innerHTML += text;
document.getElementById('main-tree').parentElement.classList.add("clicked");
}catch{
document.getElementById('files-tree').innerHTML = text;
}
@ -482,7 +518,6 @@ function hide(event) {
document.getElementsByClassName('files-tree-title')[0].setAttribute('data-path', serverDir);
document.getElementsByClassName('files-tree-title')[0].setAttribute('data-name', 'Files');
setTimeout(function () {setTreeViewContext()}, 1000);
},
});
}
@ -493,6 +528,7 @@ function hide(event) {
document.getElementById(path+"span").classList.toggle("tree-caret-down");
document.getElementById(path+"span").classList.toggle("tree-caret");
}
function getDirView(event) {
path = event.target.parentElement.getAttribute('data-path');
@ -509,7 +545,7 @@ function hide(event) {
}else{
$.ajax({
type: "GET",
url: '/ajax/get_dir?id=1&path='+path,
url: '/ajax/get_zip_dir?id=-1&path='+path,
dataType: 'text',
success: function(data){
console.log("got response:");
@ -526,8 +562,6 @@ function hide(event) {
console.log("Bad")
}
setTimeout(function () {setTreeViewContext()}, 1000);
var toggler = document.getElementById(path);
if (toggler.classList.contains('files-tree-title')){
@ -540,7 +574,13 @@ function hide(event) {
});
}
}
if (webSocket) {
webSocket.on('send_temp_path', function (data) {
document.getElementById('main-tree-input').setAttribute('data-path', data.path)
getTreeView(data.path);
show_file_tree();
});
}
</script>
<script type="text/javascript">