Refactor python code to address Sonarcloud issues (#900)

- copy/move/delete file class methods now take Path objects as arguments
- The file download endpoint in the Web UI uses the safer download from dir method
- Simplified logging
- Merged nested if statements
- Removed naked handling of unknown error states
- Added fallback empty list for drive_properties, to avoid errors when json file is missing or broken
- Move drive_properties to env[]
- Constants for common error messages
- Dummy variable for list comprehension
This commit is contained in:
Daniel Markstedt
2022-10-09 13:50:20 -07:00
committed by GitHub
parent ca23d9b7a3
commit 1b10b123d2
11 changed files with 105 additions and 154 deletions
+3 -3
View File
@@ -13,7 +13,7 @@
<th scope="col">{{ _("Description") }}</th>
<th scope="col">{{ _("Action") }}</th>
</tr>
{% for hd in drive_properties['hd_conf']|sort(attribute='name') %}
{% for hd in env['drive_properties']['hd_conf']|sort(attribute='name') %}
<tr>
<td align="center">
{% if hd.url != "" %}
@@ -48,7 +48,7 @@
<th scope="col">{{ _("Description") }}</th>
<th scope="col">{{ _("Action") }}</th>
</tr>
{% for cd in drive_properties['cd_conf']|sort(attribute='name') %}
{% for cd in env['drive_properties']['cd_conf']|sort(attribute='name') %}
<tr>
<td align="center">
{% if cd.url != "" %}
@@ -88,7 +88,7 @@
<th scope="col">{{ _("Description") }}</th>
<th scope="col">{{ _("Action") }}</th>
</tr>
{% for rm in drive_properties['rm_conf']|sort(attribute='name') %}
{% for rm in env['drive_properties']['rm_conf']|sort(attribute='name') %}
<tr>
<td align="center">
{% if rm.url != "" %}
+5 -5
View File
@@ -256,7 +256,7 @@
{% endif %}
<td align="center">
<form action="/files/download" method="post">
<input name="file" type="hidden" value="{{ env["image_dir"] }}/{{ file['name'] }}">
<input name="file" type="hidden" value="{{ file['name'] }}">
<input type="submit" value="{{ file['size_mb'] }} {{ _("MiB") }} &#8595;">
</form>
</td>
@@ -392,21 +392,21 @@
{{ _("None") }}
</option>
{% if type == "SCCD" %}
{% for drive in drive_properties["cd_conf"] | sort(attribute='name') %}
{% for drive in env["drive_properties"]["cd_conf"] | sort(attribute='name') %}
<option value="{{ drive.name }}">
{{ drive.name }}
</option>
{% endfor %}
{% endif %}
{% if type == "SCRM" %}
{% for drive in drive_properties["rm_conf"] | sort(attribute='name') %}
{% for drive in env["drive_properties"]["rm_conf"] | sort(attribute='name') %}
<option value="{{ drive.name }}">
{{ drive.name }}
</option>
{% endfor %}
{% endif %}
{% if type == "SCMO" %}
{% for drive in drive_properties["mo_conf"] | sort(attribute='name') %}
{% for drive in env["drive_properties"]["mo_conf"] | sort(attribute='name') %}
<option value="{{ drive.name }}">
{{ drive.name }}
</option>
@@ -581,7 +581,7 @@
<option value="">
{{ _("None") }}
</option>
{% for drive in drive_properties["hd_conf"] | sort(attribute='name') %}
{% for drive in env["drive_properties"]["hd_conf"] | sort(attribute='name') %}
<option value="{{ drive.name }}">
{{ drive.name }}
</option>
+19 -37
View File
@@ -22,7 +22,6 @@ from flask import (
flash,
url_for,
redirect,
send_file,
send_from_directory,
make_response,
session,
@@ -98,6 +97,7 @@ def get_env_info():
"cd_suffixes": tuple(server_info["sccd"]),
"rm_suffixes": tuple(server_info["scrm"]),
"mo_suffixes": tuple(server_info["scmo"]),
"drive_properties": format_drive_properties(APP.config["RASCSI_DRIVE_PROPERTIES"]),
}
@@ -229,16 +229,6 @@ def index():
server_info["sccd"]
)
try:
drive_properties = format_drive_properties(APP.config["RASCSI_DRIVE_PROPERTIES"])
except:
drive_properties = {
"hd_conf": [],
"cd_conf": [],
"rm_conf": [],
"mo_conf": [],
}
return response(
template="index.html",
locales=get_supported_locales(),
@@ -257,7 +247,6 @@ def index():
reserved_scsi_ids=reserved_scsi_ids,
image_suffixes_to_create=image_suffixes_to_create,
valid_image_suffixes=valid_image_suffixes,
drive_properties=drive_properties,
max_file_size=int(int(MAX_FILE_SIZE) / 1024 / 1024),
RESERVATIONS=RESERVATIONS,
CFG_DIR=CFG_DIR,
@@ -284,20 +273,10 @@ def drive_list():
"""
Sets up the data structures and kicks off the rendering of the drive list page
"""
try:
drive_properties = format_drive_properties(APP.config["RASCSI_DRIVE_PROPERTIES"])
except:
drive_properties = {
"hd_conf": [],
"cd_conf": [],
"rm_conf": [],
"mo_conf": [],
}
return response(
template="drives.html",
files=file_cmd.list_images()["files"],
drive_properties=drive_properties,
)
@@ -310,10 +289,9 @@ def login():
password = request.form["password"]
groups = [g.gr_name for g in getgrall() if username in g.gr_mem]
if AUTH_GROUP in groups:
if authenticate(str(username), str(password)):
session["username"] = request.form["username"]
return response(env=get_env_info())
if AUTH_GROUP in groups and authenticate(str(username), str(password)):
session["username"] = request.form["username"]
return response(env=get_env_info())
return response(error=True, status_code=401, message=_(
"You must log in with valid credentials for a user in the '%(group)s' group",
@@ -442,7 +420,8 @@ def config_load():
return response(error=True, message=process["msg"])
if "delete" in request.form:
process = file_cmd.delete_file(f"{CFG_DIR}/{file_name}")
file_path = Path(CFG_DIR) / file_name
process = file_cmd.delete_file(file_path)
process = ReturnCodeMapper.add_msg(process)
if process["status"]:
return response(message=process["msg"])
@@ -954,8 +933,9 @@ def download():
"""
Downloads a file from the Pi to the local computer
"""
image = request.form.get("file")
return send_file(image, as_attachment=True)
file_name = request.form.get("file")
server_info = ractl_cmd.get_server_info()
return send_from_directory(server_info["image_dir"], file_name, as_attachment=True)
@APP.route("/files/delete", methods=["POST"])
@@ -974,8 +954,8 @@ def delete():
(_("Image file deleted: %(file_name)s", file_name=file_name), "success")]
# Delete the drive properties file, if it exists
prop_file_path = f"{CFG_DIR}/{file_name}.{PROPERTIES_SUFFIX}"
if Path(prop_file_path).is_file():
prop_file_path = Path(CFG_DIR) / f"{file_name}.{PROPERTIES_SUFFIX}"
if prop_file_path.is_file():
process = file_cmd.delete_file(prop_file_path)
process = ReturnCodeMapper.add_msg(process)
if process["status"]:
@@ -1003,9 +983,9 @@ def rename():
(_("Image file renamed to: %(file_name)s", file_name=new_file_name), "success")]
# Rename the drive properties file, if it exists
prop_file_path = f"{CFG_DIR}/{file_name}.{PROPERTIES_SUFFIX}"
new_prop_file_path = f"{CFG_DIR}/{new_file_name}.{PROPERTIES_SUFFIX}"
if Path(prop_file_path).is_file():
prop_file_path = Path(CFG_DIR) / f"{file_name}.{PROPERTIES_SUFFIX}"
new_prop_file_path = Path(CFG_DIR) / f"{new_file_name}.{PROPERTIES_SUFFIX}"
if prop_file_path.is_file():
process = file_cmd.rename_file(prop_file_path, new_prop_file_path)
process = ReturnCodeMapper.add_msg(process)
if process["status"]:
@@ -1033,9 +1013,9 @@ def copy():
(_("Copy of image file saved as: %(file_name)s", file_name=new_file_name), "success")]
# Create a copy of the drive properties file, if it exists
prop_file_path = f"{CFG_DIR}/{file_name}.{PROPERTIES_SUFFIX}"
new_prop_file_path = f"{CFG_DIR}/{new_file_name}.{PROPERTIES_SUFFIX}"
if Path(prop_file_path).is_file():
prop_file_path = Path(CFG_DIR) / f"{file_name}.{PROPERTIES_SUFFIX}"
new_prop_file_path = Path(CFG_DIR) / f"{new_file_name}.{PROPERTIES_SUFFIX}"
if prop_file_path.is_file():
process = file_cmd.copy_file(prop_file_path, new_prop_file_path)
process = ReturnCodeMapper.add_msg(process)
if process["status"]:
@@ -1171,8 +1151,10 @@ if __name__ == "__main__":
if process["status"]:
APP.config["RASCSI_DRIVE_PROPERTIES"] = process["conf"]
else:
APP.config["RASCSI_DRIVE_PROPERTIES"] = []
logging.error(process["msg"])
else:
APP.config["RASCSI_DRIVE_PROPERTIES"] = []
logging.warning("Could not read drive properties from %s", DRIVE_PROPERTIES_FILE)
logging.basicConfig(stream=sys.stdout,
+1 -12
View File
@@ -294,18 +294,7 @@ def upload_with_dropzonejs(image_dir):
if current_chunk + 1 == total_chunks:
# Validate the resulting file size after writing the last chunk
if path.getsize(save_path) != int(request.form["dztotalfilesize"]):
log.error(
"Finished transferring %s, "
"but it has a size mismatch with the original file. "
"Got %s but we expected %s.",
file_object.filename,
path.getsize(save_path),
request.form['dztotalfilesize'],
)
log.error("File size mismatch between the original file and transferred file.")
return make_response(_("Transferred file corrupted!"), 500)
log.info("File %s has been uploaded successfully", file_object.filename)
log.debug("Chunk %s of %s for file %s completed.",
current_chunk + 1, total_chunks, file_object.filename)
return make_response(_("File upload successful!"), 200)