mirror of
https://github.com/akuker/RASCSI.git
synced 2026-04-19 20:16:52 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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"))
|
||||
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user