mirror of
https://github.com/akuker/RASCSI.git
synced 2025-01-12 01:29:58 +00:00
Feature image padding (#269)
* Implement pad_image method * Reintroduce list_files method, rename the other to list_images * Add iso file padding UI * HDD image UI * Tweak label * Store padded image in the right dir * Show only images that need padding * Support padding MO images * Cleanup * UI flow to show drive properites (#270) * Adjust MO padding to align with current develop * Add docstrings * Fix image padding code * Tweak labels
This commit is contained in:
parent
7717890b5f
commit
5727f3ba0f
@ -200,6 +200,22 @@ def download_image(url):
|
|||||||
return {"status": False, "msg": "Error loading the URL"}
|
return {"status": False, "msg": "Error loading the URL"}
|
||||||
|
|
||||||
|
|
||||||
|
def pad_image(file_name, file_size):
|
||||||
|
"""
|
||||||
|
Adds a number of bytes to the end of a file up to a size
|
||||||
|
Takes str file_name, int file_size
|
||||||
|
Returns a dict with boolean status and str msg
|
||||||
|
"""
|
||||||
|
from subprocess import run
|
||||||
|
|
||||||
|
dd_proc = run(
|
||||||
|
["dd", "if=/dev/null", f"of={file_name}", "bs=1", "count=1", f"seek={file_size}" ], capture_output=True
|
||||||
|
)
|
||||||
|
if dd_proc.returncode != 0:
|
||||||
|
return {"status": False, "msg": str(dd_proc)}
|
||||||
|
return {"status": True, "msg": "File padding successful" }
|
||||||
|
|
||||||
|
|
||||||
def write_config(file_name):
|
def write_config(file_name):
|
||||||
"""
|
"""
|
||||||
Takes str file_name
|
Takes str file_name
|
||||||
|
@ -320,6 +320,53 @@
|
|||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Pad Image File</summary>
|
||||||
|
<ul>
|
||||||
|
<li>If RaSCSI fails to attach an image with a size error, you can try to pad it here. This will create a "_padded" copy of the file.</li>
|
||||||
|
<li>Drive images are padded to the nearest multiple of 512 bytes, CD-ROM images to multiples of 2048 bytes.</li>
|
||||||
|
<li>The UI only lists image files that may need padding based on their file sizes.</li>
|
||||||
|
<li>For other usecases, pad your file manually using a tool like <tt>dd</tt> on Linux.</li>
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<table style="border: none">
|
||||||
|
<tr style="border: none">
|
||||||
|
<td style="border: none; vertical-align:top;">
|
||||||
|
<form action="/files/pad" method="post">
|
||||||
|
<label for="image">Drive images:</label>
|
||||||
|
<select name="image">
|
||||||
|
{% for f in drive_files %}
|
||||||
|
{% if f[1] % 512 %}
|
||||||
|
<option value="{{f[0]}},{{f[1]}}">{{f[0]}}</option>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<input type="hidden" name="multiple" value="512" />
|
||||||
|
<input type="submit" value="Pad image" />
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border: none">
|
||||||
|
<td style="border: none; vertical-align:top;">
|
||||||
|
<form action="/files/pad" method="post">
|
||||||
|
<label for="image">CD-ROM images:</label>
|
||||||
|
<select name="image">
|
||||||
|
{% for f in cdrom_files %}
|
||||||
|
{% if f[1] % 2048 %}
|
||||||
|
<option value="{{f[0]}},{{f[1]}}">{{f[0]}}</option>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<input type="hidden" name="multiple" value="2048" />
|
||||||
|
<input type="submit" value="Pad image" />
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Logging</summary>
|
<summary>Logging</summary>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -13,6 +13,7 @@ from flask import (
|
|||||||
|
|
||||||
from file_cmds import (
|
from file_cmds import (
|
||||||
list_config_files,
|
list_config_files,
|
||||||
|
list_files,
|
||||||
list_images,
|
list_images,
|
||||||
create_new_image,
|
create_new_image,
|
||||||
download_file_to_iso,
|
download_file_to_iso,
|
||||||
@ -20,6 +21,7 @@ from file_cmds import (
|
|||||||
delete_file,
|
delete_file,
|
||||||
unzip_file,
|
unzip_file,
|
||||||
download_image,
|
download_image,
|
||||||
|
pad_image,
|
||||||
write_config,
|
write_config,
|
||||||
read_config,
|
read_config,
|
||||||
write_drive_properties,
|
write_drive_properties,
|
||||||
@ -60,6 +62,9 @@ def index():
|
|||||||
device_types=get_device_types()
|
device_types=get_device_types()
|
||||||
files = list_images()
|
files = list_images()
|
||||||
config_files = list_config_files()
|
config_files = list_config_files()
|
||||||
|
drive_files = list_files(tuple(server_info["sahd"] + \
|
||||||
|
server_info["schd"] + server_info["scrm"] + server_info["scmo"]))
|
||||||
|
cdrom_files = list_files(tuple(server_info["sccd"]))
|
||||||
|
|
||||||
sorted_image_files = sorted(files["files"], key = lambda x: x["name"].lower())
|
sorted_image_files = sorted(files["files"], key = lambda x: x["name"].lower())
|
||||||
sorted_config_files = sorted(config_files, key = lambda x: x.lower())
|
sorted_config_files = sorted(config_files, key = lambda x: x.lower())
|
||||||
@ -84,6 +89,8 @@ def index():
|
|||||||
devices=formatted_devices,
|
devices=formatted_devices,
|
||||||
files=sorted_image_files,
|
files=sorted_image_files,
|
||||||
config_files=sorted_config_files,
|
config_files=sorted_config_files,
|
||||||
|
drive_files=drive_files,
|
||||||
|
cdrom_files=cdrom_files,
|
||||||
base_dir=base_dir,
|
base_dir=base_dir,
|
||||||
cfg_dir=cfg_dir,
|
cfg_dir=cfg_dir,
|
||||||
scsi_ids=scsi_ids,
|
scsi_ids=scsi_ids,
|
||||||
@ -559,6 +566,39 @@ def create_file():
|
|||||||
return redirect(url_for("index"))
|
return redirect(url_for("index"))
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/files/pad", methods=["POST"])
|
||||||
|
def image_padding():
|
||||||
|
image = request.form.get("image")
|
||||||
|
multiple = request.form.get("multiple")
|
||||||
|
|
||||||
|
if not image:
|
||||||
|
flash(f"No file selected!", "error")
|
||||||
|
return redirect(url_for("index"))
|
||||||
|
|
||||||
|
file, size = image.split(",")
|
||||||
|
|
||||||
|
if not int(size) % int(multiple):
|
||||||
|
flash(f"{file} does not need to be padded!", "error")
|
||||||
|
return redirect(url_for("index"))
|
||||||
|
else:
|
||||||
|
target_size = int(size) - (int(size) % int(multiple)) + int(multiple)
|
||||||
|
|
||||||
|
from pathlib import PurePath
|
||||||
|
padded_image = base_dir + str(PurePath(file).stem) + "_padded" + str(PurePath(file).suffix)
|
||||||
|
from shutil import copyfile
|
||||||
|
copyfile(base_dir + file, padded_image)
|
||||||
|
|
||||||
|
process = pad_image(padded_image, target_size)
|
||||||
|
if process["status"] == True:
|
||||||
|
flash(f"Added " + str(target_size - int(size)) + " bytes to " + padded_image + "!")
|
||||||
|
flash(process["msg"])
|
||||||
|
return redirect(url_for("index"))
|
||||||
|
else:
|
||||||
|
flash(f"Failed to pad image!", "error")
|
||||||
|
flash(process["msg"], "error")
|
||||||
|
return redirect(url_for("index"))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/files/download", methods=["POST"])
|
@app.route("/files/download", methods=["POST"])
|
||||||
def download():
|
def download():
|
||||||
image = request.form.get("image")
|
image = request.form.get("image")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user