mirror of https://github.com/akuker/RASCSI.git
WebUI: Traverse target dir to get subdirs to download/upload to (#1115)
This commit is contained in:
parent
3de66af55c
commit
5fd0dc420b
|
@ -4,7 +4,7 @@ Module for methods reading from and writing to the file system
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
from os import walk
|
from os import walk, path
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
from pathlib import PurePath, Path
|
from pathlib import PurePath, Path
|
||||||
from zipfile import ZipFile, is_zipfile
|
from zipfile import ZipFile, is_zipfile
|
||||||
|
@ -57,7 +57,7 @@ class FileCmds:
|
||||||
# noinspection PyMethodMayBeStatic
|
# noinspection PyMethodMayBeStatic
|
||||||
def list_config_files(self):
|
def list_config_files(self):
|
||||||
"""
|
"""
|
||||||
Finds fils with file ending CONFIG_FILE_SUFFIX in CFG_DIR.
|
Finds files with file ending CONFIG_FILE_SUFFIX in CFG_DIR.
|
||||||
Returns a (list) of (str) files_list
|
Returns a (list) of (str) files_list
|
||||||
"""
|
"""
|
||||||
files_list = []
|
files_list = []
|
||||||
|
@ -67,6 +67,26 @@ class FileCmds:
|
||||||
files_list.append(file)
|
files_list.append(file)
|
||||||
return files_list
|
return files_list
|
||||||
|
|
||||||
|
# noinspection PyMethodMayBeStatic
|
||||||
|
def list_subdirs(self, directory):
|
||||||
|
"""
|
||||||
|
Finds subdirs within the (str) directory dir.
|
||||||
|
Returns a (list) of (str) subdir_list.
|
||||||
|
"""
|
||||||
|
subdir_list = []
|
||||||
|
# Filter out file sharing meta data dirs
|
||||||
|
excluded_dirs = ("Network Trash Folder", "Temporary Items", "TheVolumeSettingsFolder")
|
||||||
|
for root, dirs, _files in walk(directory, topdown=True):
|
||||||
|
# Strip out dirs that begin with .
|
||||||
|
dirs[:] = [d for d in dirs if not d[0] == "."]
|
||||||
|
for dir in dirs:
|
||||||
|
if dir not in excluded_dirs:
|
||||||
|
dirpath = path.join(root, dir)
|
||||||
|
subdir_list.append(dirpath.replace(directory, "", 1))
|
||||||
|
|
||||||
|
subdir_list.sort()
|
||||||
|
return subdir_list
|
||||||
|
|
||||||
def list_images(self):
|
def list_images(self):
|
||||||
"""
|
"""
|
||||||
Sends a IMAGE_FILES_INFO command to the server
|
Sends a IMAGE_FILES_INFO command to the server
|
||||||
|
|
|
@ -393,8 +393,20 @@
|
||||||
<input name="url" id="download_url" required="" type="url">
|
<input name="url" id="download_url" required="" type="url">
|
||||||
<input type="radio" name="destination" id="disk_images" value="disk_images" checked="checked">
|
<input type="radio" name="destination" id="disk_images" value="disk_images" checked="checked">
|
||||||
<label for="disk_images">{{ _("Disk Images") }}</label>
|
<label for="disk_images">{{ _("Disk Images") }}</label>
|
||||||
|
<select name="images_subdir" id="images_subdir">
|
||||||
|
{% for dir in images_subdirs %}
|
||||||
|
<option value="{{dir}}">{{dir}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
<option value="/" selected>/</option>
|
||||||
|
</select>
|
||||||
<input type="radio" name="destination" id="shared_files" value="shared_files">
|
<input type="radio" name="destination" id="shared_files" value="shared_files">
|
||||||
<label for="shared_files">{{ _("Shared Files") }}</label>
|
<label for="shared_files">{{ _("Shared Files") }}</label>
|
||||||
|
<select name="shared_subdir" id="shared_subdir">
|
||||||
|
{% for dir in shared_subdirs %}
|
||||||
|
<option value="{{dir}}">{{dir}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
<option value="/" selected>/</option>
|
||||||
|
</select>
|
||||||
<input type="submit" value="{{ _("Download") }}" onclick="processNotify('{{ _("Downloading File...") }}')">
|
<input type="submit" value="{{ _("Download") }}" onclick="processNotify('{{ _("Downloading File...") }}')">
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -14,13 +14,20 @@
|
||||||
<form name="dropper" action="/files/upload" method="post" class="dropzone dz-clickable" enctype="multipart/form-data" id="dropper">
|
<form name="dropper" action="/files/upload" method="post" class="dropzone dz-clickable" enctype="multipart/form-data" id="dropper">
|
||||||
<input type="radio" name="destination" id="disk_images" value="disk_images" checked="checked">
|
<input type="radio" name="destination" id="disk_images" value="disk_images" checked="checked">
|
||||||
<label for="disk_images">{{ _("Disk Images") }}</label>
|
<label for="disk_images">{{ _("Disk Images") }}</label>
|
||||||
<select name="subdir" id="subdir">
|
<select name="images_subdir" id="images_subdir">
|
||||||
{% for subdir, group in formatted_image_files.items() %}
|
{% for dir in images_subdirs %}
|
||||||
<option value="{{subdir}}"{% if subdir == "images/" %} selected{% endif %}>{{subdir}}</option>
|
<option value="{{dir}}">{{dir}}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
<option value="/" selected>/</option>
|
||||||
</select>
|
</select>
|
||||||
<input type="radio" name="destination" id="shared_files" value="shared_files">
|
<input type="radio" name="destination" id="shared_files" value="shared_files">
|
||||||
<label for="shared_files">{{ _("Shared Files") }}</label>
|
<label for="shared_files">{{ _("Shared Files") }}</label>
|
||||||
|
<select name="shared_subdir" id="shared_subdir">
|
||||||
|
{% for dir in shared_subdirs %}
|
||||||
|
<option value="{{dir}}">{{dir}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
<option value="/" selected>/</option>
|
||||||
|
</select>
|
||||||
<input type="radio" name="destination" id="piscsi_config" value="piscsi_config">
|
<input type="radio" name="destination" id="piscsi_config" value="piscsi_config">
|
||||||
<label for="piscsi_config">{{ _("PiSCSI Config") }}</label>
|
<label for="piscsi_config">{{ _("PiSCSI Config") }}</label>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -275,6 +275,8 @@ def index():
|
||||||
image_suffixes_to_create=image_suffixes_to_create,
|
image_suffixes_to_create=image_suffixes_to_create,
|
||||||
valid_image_suffixes=valid_image_suffixes,
|
valid_image_suffixes=valid_image_suffixes,
|
||||||
drive_properties=format_drive_properties(APP.config["PISCSI_DRIVE_PROPERTIES"]),
|
drive_properties=format_drive_properties(APP.config["PISCSI_DRIVE_PROPERTIES"]),
|
||||||
|
images_subdirs=file_cmd.list_subdirs(server_info["image_dir"]),
|
||||||
|
shared_subdirs=file_cmd.list_subdirs(FILE_SERVER_DIR),
|
||||||
RESERVATIONS=RESERVATIONS,
|
RESERVATIONS=RESERVATIONS,
|
||||||
CFG_DIR=CFG_DIR,
|
CFG_DIR=CFG_DIR,
|
||||||
FILE_SERVER_DIR=FILE_SERVER_DIR,
|
FILE_SERVER_DIR=FILE_SERVER_DIR,
|
||||||
|
@ -314,13 +316,13 @@ def upload_page():
|
||||||
"""
|
"""
|
||||||
Sets up the data structures and kicks off the rendering of the file uploading page
|
Sets up the data structures and kicks off the rendering of the file uploading page
|
||||||
"""
|
"""
|
||||||
image_files = file_cmd.list_images()
|
server_info = piscsi_cmd.get_server_info()
|
||||||
formatted_image_files = format_image_list(image_files["files"])
|
|
||||||
|
|
||||||
return response(
|
return response(
|
||||||
template="upload.html",
|
template="upload.html",
|
||||||
page_title=_("PiSCSI File Upload"),
|
page_title=_("PiSCSI File Upload"),
|
||||||
formatted_image_files=formatted_image_files,
|
images_subdirs=file_cmd.list_subdirs(server_info["image_dir"]),
|
||||||
|
shared_subdirs=file_cmd.list_subdirs(FILE_SERVER_DIR),
|
||||||
max_file_size=int(int(MAX_FILE_SIZE) / 1024 / 1024),
|
max_file_size=int(int(MAX_FILE_SIZE) / 1024 / 1024),
|
||||||
CFG_DIR=CFG_DIR,
|
CFG_DIR=CFG_DIR,
|
||||||
FILE_SERVER_DIR=FILE_SERVER_DIR,
|
FILE_SERVER_DIR=FILE_SERVER_DIR,
|
||||||
|
@ -959,11 +961,22 @@ def download_file():
|
||||||
"""
|
"""
|
||||||
destination = request.form.get("destination")
|
destination = request.form.get("destination")
|
||||||
url = request.form.get("url")
|
url = request.form.get("url")
|
||||||
if destination == "shared_files":
|
images_subdir = request.form.get("images_subdir")
|
||||||
destination_dir = FILE_SERVER_DIR
|
shared_subdir = request.form.get("shared_subdir")
|
||||||
else:
|
if destination == "disk_images":
|
||||||
|
safe_path = is_safe_path(Path("." + images_subdir))
|
||||||
|
if not safe_path["status"]:
|
||||||
|
return make_response(safe_path["msg"], 403)
|
||||||
server_info = piscsi_cmd.get_server_info()
|
server_info = piscsi_cmd.get_server_info()
|
||||||
destination_dir = server_info["image_dir"]
|
destination_dir = server_info["image_dir"] + images_subdir
|
||||||
|
elif destination == "shared_files":
|
||||||
|
safe_path = is_safe_path(Path("." + shared_subdir))
|
||||||
|
if not safe_path["status"]:
|
||||||
|
return make_response(safe_path["msg"], 403)
|
||||||
|
destination_dir = FILE_SERVER_DIR + shared_subdir
|
||||||
|
else:
|
||||||
|
return response(error=True, message=_("Unknown destination"))
|
||||||
|
|
||||||
process = file_cmd.download_to_dir(url, destination_dir, Path(url).name)
|
process = file_cmd.download_to_dir(url, destination_dir, Path(url).name)
|
||||||
process = ReturnCodeMapper.add_msg(process)
|
process = ReturnCodeMapper.add_msg(process)
|
||||||
if process["status"]:
|
if process["status"]:
|
||||||
|
@ -990,19 +1003,23 @@ def upload_file():
|
||||||
return make_response(auth["msg"], 403)
|
return make_response(auth["msg"], 403)
|
||||||
|
|
||||||
destination = request.form.get("destination")
|
destination = request.form.get("destination")
|
||||||
subdir = request.form.get("subdir").replace("images/", "", 1)
|
images_subdir = request.form.get("images_subdir")
|
||||||
|
shared_subdir = request.form.get("shared_subdir")
|
||||||
if destination == "disk_images":
|
if destination == "disk_images":
|
||||||
safe_path = is_safe_path(Path(subdir))
|
safe_path = is_safe_path(Path("." + images_subdir))
|
||||||
if not safe_path["status"]:
|
if not safe_path["status"]:
|
||||||
return make_response(safe_path["msg"], 403)
|
return make_response(safe_path["msg"], 403)
|
||||||
server_info = piscsi_cmd.get_server_info()
|
server_info = piscsi_cmd.get_server_info()
|
||||||
destination_dir = Path(server_info["image_dir"]) / subdir
|
destination_dir = server_info["image_dir"] + images_subdir
|
||||||
elif destination == "shared_files":
|
elif destination == "shared_files":
|
||||||
destination_dir = FILE_SERVER_DIR
|
safe_path = is_safe_path(Path("." + shared_subdir))
|
||||||
|
if not safe_path["status"]:
|
||||||
|
return make_response(safe_path["msg"], 403)
|
||||||
|
destination_dir = FILE_SERVER_DIR + shared_subdir
|
||||||
elif destination == "piscsi_config":
|
elif destination == "piscsi_config":
|
||||||
destination_dir = CFG_DIR
|
destination_dir = CFG_DIR
|
||||||
else:
|
else:
|
||||||
return make_response("Unknown destination", 403)
|
return make_response(_("Unknown destination"), 403)
|
||||||
|
|
||||||
return upload_with_dropzonejs(destination_dir)
|
return upload_with_dropzonejs(destination_dir)
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,8 @@ def test_extract_file(
|
||||||
http_client.post(
|
http_client.post(
|
||||||
"/files/download_url",
|
"/files/download_url",
|
||||||
data={
|
data={
|
||||||
"destination": "images",
|
"destination": "disk_images",
|
||||||
|
"images_subdir": "/",
|
||||||
"url": url,
|
"url": url,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -254,7 +255,7 @@ def test_upload_file(http_client, delete_file):
|
||||||
|
|
||||||
form_data = {
|
form_data = {
|
||||||
"destination": "disk_images",
|
"destination": "disk_images",
|
||||||
"subdir": "",
|
"images_subdir": "/",
|
||||||
"dzuuid": str(uuid.uuid4()),
|
"dzuuid": str(uuid.uuid4()),
|
||||||
"dzchunkindex": chunk_number,
|
"dzchunkindex": chunk_number,
|
||||||
"dzchunksize": chunk_size,
|
"dzchunksize": chunk_size,
|
||||||
|
@ -334,6 +335,7 @@ def test_download_properties(http_client, list_files, delete_file):
|
||||||
def test_download_url_to_dir(env, httpserver, http_client, list_files, delete_file):
|
def test_download_url_to_dir(env, httpserver, http_client, list_files, delete_file):
|
||||||
file_name = str(uuid.uuid4())
|
file_name = str(uuid.uuid4())
|
||||||
http_path = f"/images/{file_name}"
|
http_path = f"/images/{file_name}"
|
||||||
|
subdir = "/"
|
||||||
url = httpserver.url_for(http_path)
|
url = httpserver.url_for(http_path)
|
||||||
|
|
||||||
with open("tests/assets/test_image.hds", mode="rb") as file:
|
with open("tests/assets/test_image.hds", mode="rb") as file:
|
||||||
|
@ -347,7 +349,8 @@ def test_download_url_to_dir(env, httpserver, http_client, list_files, delete_fi
|
||||||
response = http_client.post(
|
response = http_client.post(
|
||||||
"/files/download_url",
|
"/files/download_url",
|
||||||
data={
|
data={
|
||||||
"destination": "images",
|
"destination": "disk_images",
|
||||||
|
"images_subdir": subdir,
|
||||||
"url": url,
|
"url": url,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -358,7 +361,8 @@ def test_download_url_to_dir(env, httpserver, http_client, list_files, delete_fi
|
||||||
assert response_data["status"] == STATUS_SUCCESS
|
assert response_data["status"] == STATUS_SUCCESS
|
||||||
assert file_name in list_files()
|
assert file_name in list_files()
|
||||||
assert (
|
assert (
|
||||||
response_data["messages"][0]["message"] == f"{file_name} downloaded to {env['images_dir']}"
|
response_data["messages"][0]["message"]
|
||||||
|
== f"{file_name} downloaded to {env['images_dir']}{subdir}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
|
|
Loading…
Reference in New Issue