Merge pull request #789 from nucleogenic/webui-add-extra-archive-format-support

Allow images to be extracted from StuffIt, tarball, gzip, and 7z
This commit is contained in:
Daniel Markstedt
2022-08-19 10:56:39 -07:00
committed by GitHub
13 changed files with 438 additions and 127 deletions
+8
View File
@@ -37,6 +37,14 @@ class ReturnCodeMapper:
_("Could not read properties from file: %(file_path)s"),
ReturnCodes.ATTACHIMAGE_COULD_NOT_ATTACH:
_("Cannot insert an image for %(device_type)s into a %(current_device_type)s device"),
ReturnCodes.EXTRACTIMAGE_SUCCESS:
_("Extracted %(count)s file(s)"),
ReturnCodes.EXTRACTIMAGE_NO_FILES_SPECIFIED:
_("Unable to extract archive: No files were specified"),
ReturnCodes.EXTRACTIMAGE_NO_FILES_EXTRACTED:
_("No files were extracted (existing files are skipped)"),
ReturnCodes.EXTRACTIMAGE_COMMAND_ERROR:
_("Unable to extract archive: %(error)s"),
}
@staticmethod
-2
View File
@@ -12,8 +12,6 @@ AFP_DIR = f"{HOME_DIR}/afpshare"
MAX_FILE_SIZE = getenv("MAX_FILE_SIZE", str(1024 * 1024 * 1024 * 4)) # 4gb
ARCHIVE_FILE_SUFFIX = "zip"
# The file name of the default config file that loads when rascsi-web starts
DEFAULT_CONFIG = f"default.{rascsi.common_settings.CONFIG_FILE_SUFFIX}"
# File containing canonical drive properties
+2
View File
@@ -35,12 +35,14 @@ table, tr, td {
color: white;
font-size:20px;
background-color:red;
white-space: pre-line;
}
.message {
color: white;
font-size:20px;
background-color:green;
white-space: pre-line;
}
td.inactive {
+32 -31
View File
@@ -185,41 +185,41 @@
</ul>
</details>
</td>
{% elif file["zip_members"] %}
{% elif file["archive_contents"] %}
<td>
<details>
<summary>
{{ file["name"] }}
</summary>
<ul style="list-style: none;">
{% for member in file["zip_members"] %}
{% if not member.lower().endswith(PROPERTIES_SUFFIX) %}
<li>
{% if member + "." + PROPERTIES_SUFFIX in file["zip_members"] %}
<details><summary>{{ member }}
<form action="/files/unzip" method="post">
<input name="zip_file" type="hidden" value="{{ file['name'] }}">
<input name="zip_member" type="hidden" value="{{ member }}">
<input type="submit" value="{{ _("Unzip") }}" onclick="processNotify('{{ _("Unzipping a single file...") }}')">
</form>
</summary>
<ul style="list-style: none;">
{% for member in file["archive_contents"] %}
{% if not member["is_properties_file"] %}
<li>
{{ member + "." + PROPERTIES_SUFFIX }}
{% if member["related_properties_file"] %}
<details>
<summary>
<label>{{ member["path"] }}</label>
<form action="/files/extract_image" method="post">
<input name="archive_file" type="hidden" value="{{ file['name'] }}">
<input name="archive_members" type="hidden" value="{{ member["path"] }}|{{ member["related_properties_file"] }}">
<input type="submit" value="{{ _("Extract") }}" onclick="processNotify('{{ _("Extracting a single file...") }}')">
</form>
</summary>
<ul style="list-style: none;">
<li>{{ member["related_properties_file"] }}</li>
</ul>
</details>
{% else %}
<label>{{ member["path"] }}</label>
<form action="/files/extract_image" method="post">
<input name="archive_file" type="hidden" value="{{ file["name"] }}">
<input name="archive_members" type="hidden" value="{{ member["path"] }}">
<input type="submit" value="{{ _("Extract") }}" onclick="processNotify('{{ _("Extracting a single file...") }}')">
</form>
{% endif %}
</li>
</ul>
</details>
{% else %}
<label for="zip_member">{{ member }}</label>
<form action="/files/unzip" method="post">
<input name="zip_file" type="hidden" value="{{ file['name'] }}">
<input name="zip_member" type="hidden" value="{{ member }}">
<input type="submit" value="{{ _("Unzip") }}" onclick="processNotify('{{ _("Unzipping a single file...") }}')">
</form>
{% endif %}
</li>
{% endif %}
{% endfor %}
{% endfor %}
</ul>
</details>
</td>
@@ -238,11 +238,12 @@
{{ _("Attached!") }}
</center>
{% else %}
{% if file["name"].lower().endswith(ARCHIVE_FILE_SUFFIX) %}
<form action="/files/unzip" method="post">
<input name="zip_file" type="hidden" value="{{ file['name'] }}">
<input name="zip_members" type="hidden" value="{{ file['zip_members'] }}">
<input type="submit" value="{{ _("Unzip All") }}" onclick="processNotify('{{ _("Unzipping all files...") }}')">
{% if file["archive_contents"] %}
<form action="/files/extract_image" method="post">
<input name="archive_file" type="hidden" value="{{ file['name'] }}">
{% set pipe = joiner("|") %}
<input name="archive_members" type="hidden" value="{% for member in file["archive_contents"] %}{{ pipe() }}{{ member["path"] }}{% endfor %}">
<input type="submit" value="{{ _("Extract All") }}" onclick="processNotify('{{ _("Extracting all files...") }}')">
</form>
{% else %}
<form action="/scsi/attach" method="post">
+30 -27
View File
@@ -8,9 +8,9 @@ import argparse
from pathlib import Path
from functools import wraps
from grp import getgrall
from ast import literal_eval
import bjoern
from rascsi.return_codes import ReturnCodes
from werkzeug.utils import secure_filename
from simplepam import authenticate
from flask_babel import Babel, Locale, refresh, _
@@ -37,6 +37,7 @@ from rascsi.common_settings import (
CFG_DIR,
CONFIG_FILE_SUFFIX,
PROPERTIES_SUFFIX,
ARCHIVE_FILE_SUFFIXES,
RESERVATIONS,
)
@@ -55,7 +56,6 @@ from web_utils import (
from settings import (
AFP_DIR,
MAX_FILE_SIZE,
ARCHIVE_FILE_SUFFIX,
DEFAULT_CONFIG,
DRIVE_PROPERTIES_FILE,
AUTH_GROUP,
@@ -133,14 +133,13 @@ def index():
scsi_ids, recommended_id = get_valid_scsi_ids(devices["device_list"], reserved_scsi_ids)
formatted_devices = sort_and_format_devices(devices["device_list"])
valid_file_suffix = "."+", .".join(
valid_file_suffix = "." + ", .".join(
server_info["sahd"] +
server_info["schd"] +
server_info["scrm"] +
server_info["scmo"] +
server_info["sccd"] +
[ARCHIVE_FILE_SUFFIX]
)
ARCHIVE_FILE_SUFFIXES)
if "username" in session:
username = session["username"]
@@ -182,7 +181,6 @@ def index():
mo_file_suffix=tuple(server_info["scmo"]),
username=username,
auth_active=auth_active(AUTH_GROUP)["status"],
ARCHIVE_FILE_SUFFIX=ARCHIVE_FILE_SUFFIX,
PROPERTIES_SUFFIX=PROPERTIES_SUFFIX,
REMOVABLE_DEVICE_TYPES=ractl_cmd.get_removable_device_types(),
DISK_DEVICE_TYPES=ractl_cmd.get_disk_device_types(),
@@ -945,33 +943,38 @@ def copy():
return redirect(url_for("index"))
@APP.route("/files/unzip", methods=["POST"])
@APP.route("/files/extract_image", methods=["POST"])
@login_required
def unzip():
def extract_image():
"""
Unzips all files in a specified zip archive, or a single file in the zip archive
Extracts all or a subset of files in the specified archive
"""
zip_file = request.form.get("zip_file")
zip_member = request.form.get("zip_member") or False
zip_members = request.form.get("zip_members") or False
archive_file = request.form.get("archive_file")
archive_members_raw = request.form.get("archive_members") or None
archive_members = archive_members_raw.split("|") if archive_members_raw else None
if zip_members:
zip_members = literal_eval(zip_members)
extract_result = file_cmd.extract_image(
archive_file,
archive_members
)
process = file_cmd.unzip_file(zip_file, zip_member, zip_members)
if process["status"]:
if not process["msg"]:
flash(_("Aborted unzip: File(s) with the same name already exists."), "error")
return redirect(url_for("index"))
flash(_("Unzipped the following files:"))
for msg in process["msg"]:
flash(msg)
if process["prop_flag"]:
flash(_("Properties file(s) have been moved to %(directory)s", directory=CFG_DIR))
return redirect(url_for("index"))
if extract_result["return_code"] == ReturnCodes.EXTRACTIMAGE_SUCCESS:
flash(ReturnCodeMapper.add_msg(extract_result).get("msg"))
for properties_file in extract_result["properties_files_moved"]:
if properties_file["status"]:
flash(_("Properties file %(file)s moved to %(directory)s",
file=properties_file['name'],
directory=CFG_DIR
))
else:
flash(_("Failed to move properties file %(file)s to %(directory)s",
file=properties_file['name'],
directory=CFG_DIR
), "error")
else:
flash(ReturnCodeMapper.add_msg(extract_result).get("msg"), "error")
flash(_("Failed to unzip %(zip_file)s", zip_file=zip_file), "error")
flash(process["msg"], "error")
return redirect(url_for("index"))
+5
View File
@@ -25,6 +25,11 @@ if ! command -v unzip &> /dev/null ; then
echo "Run 'sudo apt install unzip' to fix."
ERROR=1
fi
if ! command -v unar &> /dev/null ; then
echo "unar could not be found"
echo "Run 'sudo apt install unar' to fix."
ERROR=1
fi
if [ $ERROR = 1 ] ; then
echo
echo "Fix errors and re-run ./start.sh"