Adds download options for files in file tree. This does not add ability to download directories.

This commit is contained in:
Andrew 2021-08-24 21:33:29 -04:00
parent aea023b893
commit b77aab954d
6 changed files with 117 additions and 5 deletions

View File

@ -0,0 +1,49 @@
import sys
import json
import logging
import tornado.web
import tornado.escape
import requests
from app.classes.shared.helpers import helper
from app.classes.web.base_handler import BaseHandler
from app.classes.shared.console import console
from app.classes.shared.models import Users, fn, db_helper
logger = logging.getLogger(__name__)
try:
import bleach
except ModuleNotFoundError as e:
logger.critical("Import Error: Unable to load {} module".format(e.name), exc_info=True)
console.critical("Import Error: Unable to load {} module".format(e.name))
sys.exit(1)
class HTTPHandlerPage(BaseHandler):
def get(self, page):
url = self.request.full_url
port = 443
print(url)
if url[len(url)-1] == '/':
url = url.strip(url[len(url)-1])
url_list = url.split('/')
print(url_list)
if url_list[0] != "":
primary_url = url_list[0] + ":"+str(port)+"/"
backup_url = url_list[0] + ":" +str(helper.get_setting["https_port"]) +"/"
for i in range(len(url_list)-1):
primary_url += url_list[i+1]
backup_url += url_list[i+1]
else:
primary_url = url + str(port)
backup_url = url + str(helper.get_setting['https_port'])
try:
resp = requests.get(primary_url)
resp.raise_for_status()
url = primary_url
except Exception as err:
url = backup_url
self.redirect('https://'+url+':'+ str(port))

View File

@ -494,6 +494,58 @@ class PanelHandler(BaseHandler):
template = "panel/activity_logs.html"
elif page == 'download_file':
server_id = self.get_argument('id', None)
file = self.get_argument('path', "")
name = self.get_argument('name', "")
if server_id is None:
self.redirect("/panel/error?error=Invalid Server ID")
return
else:
# does this server id exist?
if not db_helper.server_id_exists(server_id):
self.redirect("/panel/error?error=Invalid Server ID")
return
if exec_user['superuser'] != 1:
#if not db_helper.server_id_authorized(server_id, exec_user_id):
if not db_helper.server_id_authorized(int(server_id), exec_user_id):
self.redirect("/panel/error?error=Invalid Server ID")
return
server_info = db_helper.get_server_data_by_id(server_id)
if not helper.in_path(server_info["path"], file) \
or not os.path.isfile(file):
self.redirect("/panel/error?error=Invalid path detected")
return
self.set_header('Content-Type', 'application/octet-stream')
self.set_header('Content-Disposition', 'attachment; filename=' + name)
chunk_size = 1024 * 1024 * 4 # 4 MiB
with open(file, 'rb') as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
try:
self.write(chunk) # write the chunk to response
self.flush() # send the chunk to client
except iostream.StreamClosedError:
# this means the client has closed the connection
# so break the loop
break
finally:
# deleting the chunk is very important because
# if many clients are downloading files at the
# same time, the chunks in memory will keep
# increasing and will eat up the RAM
del chunk
self.redirect("/panel/server_detail?id={}&subpage=files".format(server_id))
self.render(
template,
data=page_data,

View File

@ -48,10 +48,11 @@
<a onclick="createFileE(event)" href="javascript:void(0)" id="createFile" href="#">{{ translate('serverFiles', 'createFile') }}</a>
<a onclick="createDirE(event)" href="javascript:void(0)" id="createDir" href="#">{{ translate('serverFiles', 'createDir') }}</a>
<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="#">{{ translate('serverFiles', 'upload') }}</a>
<a onclick="unzipFilesE(event)" href="javascript:void(0)" id="unzip" href="#">{{ translate('serverFiles', 'unzip') }}</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="downloadFileE(event)" href="javascript:void(0)" id="downloadFile" href="#">{{ translate('serverFiles', 'download') }}</a>
<a href="javascript:void(0)" class="closebtn" style="color: red;" onclick="document.getElementById('files-tree-nav').style.display = 'none';">{{ translate('serverFiles', 'close') }}</a>
</div>
@ -704,6 +705,7 @@
var isFile = event.target.classList.contains('tree-file');
$('#deleteFile').toggle(isFile);
$('#downloadFile').toggle(isFile);
console.log({ 'event.target': event.target, isDir, isFile });
if(event.target.classList.contains('files-tree-title')) {
@ -712,6 +714,7 @@
$('#renameItem').hide();
$('#deleteDir').hide();
$('#deleteFile').hide();
$('#downloadFile').hide();
$('#upload').show();
}
if(event.target.textContent.endsWith('.zip')){
@ -790,6 +793,11 @@
});
})
}
function downloadFileE(event) {
path = event.target.parentElement.getAttribute('data-path');
name = event.target.parentElement.getAttribute('data-name');
window.location.href = '/panel/download_file?id={{ data['server_stats']['server_id']['server_id'] }}&path='+path+'&name='+name;
}
function renameItemE(event) {
bootbox.prompt("{% raw translate('serverFiles', 'renameItemQuestion') %}", function(result) {

View File

@ -180,7 +180,8 @@
"uploadTitle": "Upload Files to: ",
"waitUpload": "Please wait while we upload your files... This may take a while.",
"stayHere": "DO NOT LEAVE THIS PAGE!",
"close": "Close"
"close": "Close",
"download": "Download"
},
"serverConfig": {
"serverName": "Server Name",

View File

@ -179,7 +179,8 @@
"uploadTitle": "Lähetä tiedostot: ",
"waitUpload": "Odota, kunnes lataamme tiedostosi ... Tämä voi kestää hetken.",
"stayHere": "ÄLÄ JÄTÄ SIVUTA!",
"close": "Kiinni"
"close": "Kiinni",
"download": "Ladata"
},
"serverConfig": {
"serverName": "Palvelimen nimi",

View File

@ -180,7 +180,8 @@
"uploadTitle": "Téléverser les fichiers vers : ",
"waitUpload": "Merci de patienter pendant que nous téléversons tes fichiers... Cela peut prendre un certain temps.",
"stayHere": "NE FERME PAS CETTE PAGE!",
"close": "Presque"
"close": "Presque",
"download": "Télécharger"
},
"serverConfig": {
"serverName": "Nom du Serveur",