mirror of
https://github.com/akuker/RASCSI.git
synced 2025-02-21 07:29:28 +00:00
Allow generating ISO image from local file (#1046)
- Break out generate_iso() into its own class method in file_cmds - Add form and handling of using local file to generate iso image - Reorder index page sections to group actions that create new image files
This commit is contained in:
parent
bf2b210c4c
commit
cde4866844
@ -635,30 +635,48 @@ class FileCmds:
|
||||
)
|
||||
tmp_full_path.unlink(True)
|
||||
|
||||
try:
|
||||
run(
|
||||
[
|
||||
"genisoimage",
|
||||
*iso_args,
|
||||
"-o",
|
||||
str(iso_filename),
|
||||
tmp_dir,
|
||||
],
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
except CalledProcessError as error:
|
||||
logging.warning(SHELL_ERROR, " ".join(error.cmd), error.stderr.decode("utf-8"))
|
||||
return {"status": False, "msg": error.stderr.decode("utf-8")}
|
||||
process = self.generate_iso(iso_filename, Path(tmp_dir), *iso_args)
|
||||
|
||||
if not process["status"]:
|
||||
return {"status": False, "msg": process["msg"]}
|
||||
|
||||
parameters = {"value": " ".join(iso_args)}
|
||||
return {
|
||||
"status": True,
|
||||
"return_code": ReturnCodes.DOWNLOADFILETOISO_SUCCESS,
|
||||
"parameters": parameters,
|
||||
"file_name": iso_filename.name,
|
||||
"return_code": process["return_code"],
|
||||
"parameters": process["parameters"],
|
||||
"file_name": process["file_name"],
|
||||
}
|
||||
|
||||
def generate_iso(self, iso_file, target_path, *iso_args):
|
||||
"""
|
||||
Takes
|
||||
- (Path) iso_file - the path to the file to create
|
||||
- (Path) target_path - the path to the file or dir to generate the iso from
|
||||
- (*str) iso_args - the tuple of arguments to pass to genisoimage
|
||||
"""
|
||||
try:
|
||||
run(
|
||||
[
|
||||
"genisoimage",
|
||||
*iso_args,
|
||||
"-o",
|
||||
str(iso_file),
|
||||
str(target_path),
|
||||
],
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
except CalledProcessError as error:
|
||||
logging.warning(SHELL_ERROR, " ".join(error.cmd), error.stderr.decode("utf-8"))
|
||||
return {"status": False, "msg": error.stderr.decode("utf-8")}
|
||||
|
||||
return {
|
||||
"status": True,
|
||||
"return_code": ReturnCodes.DOWNLOADFILETOISO_SUCCESS,
|
||||
"parameters": {"value": " ".join(iso_args)},
|
||||
"file_name": iso_file.name,
|
||||
}
|
||||
|
||||
# noinspection PyMethodMayBeStatic
|
||||
def download_to_dir(self, url, save_dir, file_name):
|
||||
"""
|
||||
|
@ -741,7 +741,8 @@ section#files p {
|
||||
}
|
||||
|
||||
section#files table#images form.file-attach input[type="submit"],
|
||||
section#attach-devices form.device-attach input[type="submit"] {
|
||||
section#attach-devices form.device-attach input[type="submit"],
|
||||
section#create-iso form.iso-attach input[type="submit"] {
|
||||
background: #efefef url("icons/file-device-attach.svg") no-repeat 0.5rem center;
|
||||
background-size: 1rem;
|
||||
padding-left: 2rem;
|
||||
|
@ -382,6 +382,161 @@
|
||||
|
||||
<hr/>
|
||||
|
||||
<section id="create-iso">
|
||||
<details>
|
||||
<summary class="heading">
|
||||
{{ _("Create CD-ROM Image With File") }}
|
||||
</summary>
|
||||
<ul>
|
||||
<li>{{ _("HFS is for Mac OS, Joliet for Windows, and Rock Ridge for POSIX.") }}</li>
|
||||
<li>{{ _("If the downloaded file is a zip archive, we will attempt to unzip it and store the resulting files.") }}</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
<div>
|
||||
<form action="/files/create_iso" method="post" class="iso-attach">
|
||||
<label for="iso_url">{{ _("Create ISO from URL:") }}</label>
|
||||
<input name="url" id="iso_url" required="" type="url">
|
||||
<label for="iso_url_type">{{ _("Type:") }}</label>
|
||||
<select name="type" id="iso_url_type">
|
||||
<option value="HFS">
|
||||
HFS
|
||||
</option>
|
||||
<option value="ISO-9660 Level 1">
|
||||
ISO-9660 Level 1
|
||||
</option>
|
||||
<option value="ISO-9660 Level 2">
|
||||
ISO-9660 Level 2
|
||||
</option>
|
||||
<option value="ISO-9660 Level 3">
|
||||
ISO-9660 Level 3
|
||||
</option>
|
||||
<option value="Joliet">
|
||||
Joliet
|
||||
</option>
|
||||
<option value="Rock Ridge">
|
||||
Rock Ridge
|
||||
</option>
|
||||
</select>
|
||||
<label for="iso_url_scsi_id">{{ _("ID") }}</label>
|
||||
<select name="scsi_id" id="iso_url_scsi_id">
|
||||
{% for id in scsi_ids["valid_ids"] %}
|
||||
<option value="{{ id }}"{% if id == scsi_ids["recommended_id"] %} selected{% endif %}>
|
||||
{{ id }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input type="submit" value="{{ _("Create and Attach") }}" onclick="processNotify('{{ _("Downloading file and generating CD-ROM image...") }}')">
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<form action="/files/create_iso" method="post" class="iso-attach">
|
||||
<label for="iso_file">{{ _("Create ISO from local file:") }}</label>
|
||||
<select name="file" id="iso_file">
|
||||
{% for f in files|sort(attribute='name') %}
|
||||
<option value="{{ f["name"] }}">{{ f["name"].replace(env["image_dir"], '') }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label for="iso_file_type">{{ _("Type:") }}</label>
|
||||
<select name="type" id="iso_file_type">
|
||||
<option value="HFS">
|
||||
HFS
|
||||
</option>
|
||||
<option value="ISO-9660 Level 1">
|
||||
ISO-9660 Level 1
|
||||
</option>
|
||||
<option value="ISO-9660 Level 2">
|
||||
ISO-9660 Level 2
|
||||
</option>
|
||||
<option value="ISO-9660 Level 3">
|
||||
ISO-9660 Level 3
|
||||
</option>
|
||||
<option value="Joliet">
|
||||
Joliet
|
||||
</option>
|
||||
<option value="Rock Ridge">
|
||||
Rock Ridge
|
||||
</option>
|
||||
</select>
|
||||
<label for="iso_file_scsi_id">{{ _("ID") }}</label>
|
||||
<select name="scsi_id" id="iso_file_scsi_id">
|
||||
{% for id in scsi_ids["valid_ids"] %}
|
||||
<option value="{{ id }}"{% if id == scsi_ids["recommended_id"] %} selected{% endif %}>
|
||||
{{ id }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input type="submit" value="{{ _("Create and Attach") }}" onclick="processNotify('{{ _("Generating CD-ROM image...") }}')">
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr/>
|
||||
|
||||
<section id="create-image">
|
||||
<details>
|
||||
<summary class="heading">
|
||||
{{ _("Create Empty Disk Image File") }}
|
||||
</summary>
|
||||
<ul>
|
||||
<li>{{ _("Please refer to <a href=\"%(url)s\" target=\"_blank\">wiki documentation</a> to learn more about the supported image file types.", url="https://github.com/PiSCSI/piscsi/wiki/Supported-Device-Types#image-types") }}</li>
|
||||
<li>{{ _("It is not recommended to use the Lido hard disk driver with the Macintosh Plus.") }}</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
<form action="/files/create" method="post">
|
||||
<label for="image_create_file_name">{{ _("File Name:") }}</label>
|
||||
<input name="file_name" id="image_create_file_name" required="" type="text">
|
||||
<label for="image_create_type">{{ _("Type:") }}</label>
|
||||
<select name="type" id="image_create_type">
|
||||
{% for key, value in image_suffixes_to_create.items() %}
|
||||
<option value="{{ key }}">
|
||||
{{ value }} [.{{ key }}]
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label for="image_create_size">{{ _("Size:") }}</label>
|
||||
<input name="size" id="image_create_size" type="number" placeholder="{{ _("MiB") }}" min="1" max="262144" required>
|
||||
<label for="image_create_drive_name">{{ _("Masquerade as:") }}</label>
|
||||
<select name="drive_name" id="image_create_drive_name">
|
||||
<option value="">
|
||||
{{ _("None") }}
|
||||
</option>
|
||||
{% for drive in drive_properties["hd_conf"] | sort(attribute='name') %}
|
||||
<option value="{{ drive.name }}">
|
||||
{{ drive.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label for="drive_format">{{ _("Format as:") }}</label>
|
||||
<select name="drive_format" id="drive_format">
|
||||
<option value="">
|
||||
{{ _("None") }}
|
||||
</option>
|
||||
<option value="Lido 7.56">
|
||||
HFS + Lido
|
||||
</option>
|
||||
<option value="SpeedTools 3.6">
|
||||
HFS + SpeedTools
|
||||
</option>
|
||||
<option value="FAT16">
|
||||
FAT16
|
||||
</option>
|
||||
<option value="FAT32">
|
||||
FAT32
|
||||
</option>
|
||||
</select>
|
||||
<input type="submit" value="{{ _("Create") }}">
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section id="create-drive">
|
||||
<a href="/drive/list"><p>{{ _("Create Disk Image With Properties") }}</p></a>
|
||||
</section>
|
||||
|
||||
<hr/>
|
||||
|
||||
<section id="logging">
|
||||
<section id="attach-devices">
|
||||
<details>
|
||||
<summary class="heading">
|
||||
@ -482,120 +637,6 @@
|
||||
|
||||
<hr/>
|
||||
|
||||
<section id="download-to-iso">
|
||||
<details>
|
||||
<summary class="heading">
|
||||
{{ _("Download File and Create CD-ROM Image") }}
|
||||
</summary>
|
||||
<ul>
|
||||
<li>{{ _("Create an ISO file system CD-ROM image with the downloaded file, and mount it on the given SCSI ID.") }}</li>
|
||||
<li>{{ _("HFS is for Mac OS, Joliet for Windows, and Rock Ridge for POSIX.") }}</li>
|
||||
<li>{{ _("If the downloaded file is a zip archive, we will attempt to unzip it and store the resulting files.") }}</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
<form action="/files/download_to_iso" method="post">
|
||||
<label for="iso_url">{{ _("Download file from URL:") }}</label>
|
||||
<input name="url" id="iso_url" required="" type="url">
|
||||
<label for="iso_type">{{ _("Type:") }}</label>
|
||||
<select name="type" id="iso_type">
|
||||
<option value="HFS">
|
||||
HFS
|
||||
</option>
|
||||
<option value="ISO-9660 Level 1">
|
||||
ISO-9660 Level 1
|
||||
</option>
|
||||
<option value="ISO-9660 Level 2">
|
||||
ISO-9660 Level 2
|
||||
</option>
|
||||
<option value="ISO-9660 Level 3">
|
||||
ISO-9660 Level 3
|
||||
</option>
|
||||
<option value="Joliet">
|
||||
Joliet
|
||||
</option>
|
||||
<option value="Rock Ridge">
|
||||
Rock Ridge
|
||||
</option>
|
||||
</select>
|
||||
<label for="iso_scsi_id">{{ _("ID") }}</label>
|
||||
<select name="scsi_id" id="iso_scsi_id">
|
||||
{% for id in scsi_ids["valid_ids"] %}
|
||||
<option value="{{ id }}"{% if id == scsi_ids["recommended_id"] %} selected{% endif %}>
|
||||
{{ id }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input type="submit" value="{{ _("Download and Mount CD-ROM image") }}" onclick="processNotify('{{ _("Downloading File and generating CD-ROM image...") }}')">
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<hr/>
|
||||
|
||||
<section id="create-image">
|
||||
<details>
|
||||
<summary class="heading">
|
||||
{{ _("Create Empty Disk Image File") }}
|
||||
</summary>
|
||||
<ul>
|
||||
<li>{{ _("Please refer to <a href=\"%(url)s\" target=\"_blank\">wiki documentation</a> to learn more about the supported image file types.", url="https://github.com/PiSCSI/piscsi/wiki/Supported-Device-Types#image-types") }}</li>
|
||||
<li>{{ _("It is not recommended to use the Lido hard disk driver with the Macintosh Plus.") }}</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
<form action="/files/create" method="post">
|
||||
<label for="image_create_file_name">{{ _("File Name:") }}</label>
|
||||
<input name="file_name" id="image_create_file_name" required="" type="text">
|
||||
<label for="image_create_type">{{ _("Type:") }}</label>
|
||||
<select name="type" id="image_create_type">
|
||||
{% for key, value in image_suffixes_to_create.items() %}
|
||||
<option value="{{ key }}">
|
||||
{{ value }} [.{{ key }}]
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label for="image_create_size">{{ _("Size:") }}</label>
|
||||
<input name="size" id="image_create_size" type="number" placeholder="{{ _("MiB") }}" min="1" max="262144" required>
|
||||
<label for="image_create_drive_name">{{ _("Masquerade as:") }}</label>
|
||||
<select name="drive_name" id="image_create_drive_name">
|
||||
<option value="">
|
||||
{{ _("None") }}
|
||||
</option>
|
||||
{% for drive in drive_properties["hd_conf"] | sort(attribute='name') %}
|
||||
<option value="{{ drive.name }}">
|
||||
{{ drive.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label for="drive_format">{{ _("Format as:") }}</label>
|
||||
<select name="drive_format" id="drive_format">
|
||||
<option value="">
|
||||
{{ _("None") }}
|
||||
</option>
|
||||
<option value="Lido 7.56">
|
||||
HFS + Lido
|
||||
</option>
|
||||
<option value="SpeedTools 3.6">
|
||||
HFS + SpeedTools
|
||||
</option>
|
||||
<option value="FAT16">
|
||||
FAT16
|
||||
</option>
|
||||
<option value="FAT32">
|
||||
FAT32
|
||||
</option>
|
||||
</select>
|
||||
<input type="submit" value="{{ _("Create") }}">
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section id="create-drive">
|
||||
<a href="/drive/list"><p>{{ _("Create Disk Image With Properties") }}</p></a>
|
||||
</section>
|
||||
|
||||
<hr/>
|
||||
|
||||
<section id="logging">
|
||||
<details>
|
||||
<summary class="heading">
|
||||
{{ _("Logging") }}
|
||||
|
@ -879,7 +879,7 @@ def shutdown():
|
||||
return response(error=True, message=message)
|
||||
|
||||
|
||||
@APP.route("/files/download_to_iso", methods=["POST"])
|
||||
@APP.route("/files/create_iso", methods=["POST"])
|
||||
@login_required
|
||||
def download_to_iso():
|
||||
"""
|
||||
@ -888,6 +888,7 @@ def download_to_iso():
|
||||
scsi_id = request.form.get("scsi_id")
|
||||
url = request.form.get("url")
|
||||
iso_type = request.form.get("type")
|
||||
local_file = request.form.get("file")
|
||||
|
||||
if iso_type == "HFS":
|
||||
iso_args = ["-hfs"]
|
||||
@ -907,7 +908,14 @@ def download_to_iso():
|
||||
message=_("%(iso_type)s is not a valid CD-ROM format.", iso_type=iso_type),
|
||||
)
|
||||
|
||||
process = file_cmd.download_file_to_iso(url, *iso_args)
|
||||
if url:
|
||||
process = file_cmd.download_file_to_iso(url, *iso_args)
|
||||
elif local_file:
|
||||
server_info = piscsi_cmd.get_server_info()
|
||||
file_path = Path(server_info["image_dir"]) / local_file
|
||||
iso_path = Path(str(file_path) + ".iso")
|
||||
process = file_cmd.generate_iso(iso_path, file_path, *iso_args)
|
||||
|
||||
process = ReturnCodeMapper.add_msg(process)
|
||||
if not process["status"]:
|
||||
return response(
|
||||
|
@ -328,9 +328,8 @@ def test_download_url_to_dir(env, httpserver, http_client, list_files, delete_fi
|
||||
delete_file(file_name)
|
||||
|
||||
|
||||
# route("/files/download_to_iso", methods=["POST"])
|
||||
def test_download_url_to_iso(
|
||||
env,
|
||||
# route("/files/create_iso", methods=["POST"])
|
||||
def test_create_iso_from_url(
|
||||
httpserver,
|
||||
http_client,
|
||||
list_files,
|
||||
@ -354,7 +353,7 @@ def test_download_url_to_iso(
|
||||
)
|
||||
|
||||
response = http_client.post(
|
||||
"/files/download_to_iso",
|
||||
"/files/create_iso",
|
||||
data={
|
||||
"scsi_id": SCSI_ID,
|
||||
"type": ISO_TYPE,
|
||||
@ -380,6 +379,47 @@ def test_download_url_to_iso(
|
||||
delete_file(iso_file_name)
|
||||
|
||||
|
||||
# route("/files/create_iso", methods=["POST"])
|
||||
def test_create_iso_from_local_file(
|
||||
http_client,
|
||||
create_test_image,
|
||||
list_files,
|
||||
list_attached_images,
|
||||
detach_devices,
|
||||
delete_file,
|
||||
):
|
||||
test_file_name = create_test_image()
|
||||
iso_file_name = f"{test_file_name}.iso"
|
||||
|
||||
ISO_TYPE = "HFS"
|
||||
|
||||
response = http_client.post(
|
||||
"/files/create_iso",
|
||||
data={
|
||||
"scsi_id": SCSI_ID,
|
||||
"type": ISO_TYPE,
|
||||
"file": test_file_name,
|
||||
},
|
||||
)
|
||||
|
||||
response_data = response.json()
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response_data["status"] == STATUS_SUCCESS
|
||||
assert iso_file_name in list_files()
|
||||
assert iso_file_name in list_attached_images()
|
||||
|
||||
assert (
|
||||
response_data["messages"][0]["message"]
|
||||
== f"CD-ROM image {iso_file_name} with type {ISO_TYPE} was created "
|
||||
f"and attached to SCSI ID {SCSI_ID}"
|
||||
)
|
||||
|
||||
# Cleanup
|
||||
detach_devices()
|
||||
delete_file(iso_file_name)
|
||||
|
||||
|
||||
# route("/files/diskinfo", methods=["POST"])
|
||||
def test_show_diskinfo(http_client, create_test_image):
|
||||
test_image = create_test_image()
|
||||
|
Loading…
x
Reference in New Issue
Block a user