mirror of
https://github.com/akuker/RASCSI.git
synced 2024-06-10 02:29:33 +00:00
d969fbdcce
* Read the drive properties file once and store it in the Flask app config. Spin out the drive properties formatting to a helper method. * Add empty removable disk drives to the attach peripherals UI * Refinement of UI labels and help text, moving some context to the wiki
751 lines
34 KiB
HTML
751 lines
34 KiB
HTML
{% extends "base.html" %}
|
|
{% block content %}
|
|
|
|
<details>
|
|
<summary class="heading">
|
|
{{ _("Current RaSCSI Configuration") }}
|
|
</summary>
|
|
<ul>
|
|
<li>{{ _("Displays the currently attached devices for each available SCSI ID.") }}</li>
|
|
<li>{{ _("Save and load device configurations, stored as json files in <tt>%(config_dir)s</tt>", config_dir=CFG_DIR) }}</tt></li>
|
|
<li>{{ _("To have a particular device configuration load when RaSCSI starts, save it as <em>default</em>.") }}</li>
|
|
</ul>
|
|
</details>
|
|
|
|
<p><form action="/config/load" method="post">
|
|
<select name="name" required="" width="14">
|
|
{% if config_files %}
|
|
{% for config in config_files|sort %}
|
|
<option value="{{ config }}">
|
|
{{ config.replace(".json", '') }}
|
|
</option>
|
|
{% endfor %}
|
|
{% else %}
|
|
<option disabled>
|
|
{{ _("No saved configurations") }}
|
|
</option>
|
|
{% endif %}
|
|
</select>
|
|
<input name="load" type="submit" value="{{ _("Load") }}" onclick="return confirm('{{ _("Detach all current device and Load configuration?") }}')">
|
|
<input name="delete" type="submit" value="{{ _("Delete") }}" onclick="return confirm('{{ _("Delete configuration file?") }}')">
|
|
</form></p>
|
|
|
|
<p><form action="/config/save" method="post">
|
|
<input name="name" placeholder="default" size="20">
|
|
<input type="submit" value="{{ _("Save") }}">
|
|
</form></p>
|
|
|
|
<table border="black" cellpadding="3">
|
|
<tbody>
|
|
<tr>
|
|
<td><b>{{ _("ID") }}</b></td>
|
|
{% if units %}
|
|
<td><b>{{ _("LUN") }}</b></td>
|
|
{% endif %}
|
|
<td><b>{{ _("Type") }}</b></td>
|
|
<td><b>{{ _("Status") }}</b></td>
|
|
<td><b>{{ _("File") }}</b></td>
|
|
<td><b>{{ _("Product") }}</b></td>
|
|
<td><b>{{ _("Actions") }}</b></td>
|
|
</tr>
|
|
{% for device in devices %}
|
|
<tr>
|
|
{% if device["id"] not in reserved_scsi_ids %}
|
|
<td style="text-align:center">{{ device.id }}</td>
|
|
{% if units %}
|
|
<td style="text-align:center">{{ device.unit }}</td>
|
|
{% endif %}
|
|
<td style="text-align:center">{{ device.device_type }}</td>
|
|
<td style="text-align:center">{{ device.status }}</td>
|
|
<td style="text-align:left">
|
|
{% if "No Media" in device.status %}
|
|
<form action="/scsi/attach" method="post">
|
|
<input name="scsi_id" type="hidden" value="{{ device.id }}">
|
|
<input name="unit" type="hidden" value="{{ device.unit }}">
|
|
<input name="type" type="hidden" value="{{ device.device_type }}">
|
|
<input name="file_size" type="hidden" value="{{ device.size }}">
|
|
<select type="select" name="file_name">
|
|
{% for f in files|sort(attribute='name') %}
|
|
{% if device.device_type == "SCCD" %}
|
|
{% if f["name"].lower().endswith(cdrom_file_suffix) %}
|
|
<option value="{{ f["name"] }}">{{ f["name"].replace(base_dir, '') }}</option>
|
|
{% endif %}
|
|
{% elif device.device_type == "SCRM" %}
|
|
{% if f["name"].lower().endswith(removable_file_suffix) %}
|
|
<option value="{{ f["name"] }}">{{ f["name"].replace(base_dir, '') }}</option>
|
|
{% endif %}
|
|
{% elif device.device_type == "SCMO" %}
|
|
{% if f["name"].lower().endswith(mo_file_suffix) %}
|
|
<option value="{{ f["name"] }}">{{ f["name"].replace(base_dir, '') }}</option>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
</select>
|
|
<input type="submit" value="{{ _("Attach") }}">
|
|
</form>
|
|
{% else %}
|
|
{{ device.file }}
|
|
{% endif %}
|
|
</td>
|
|
{% if device.vendor == "RaSCSI" %}
|
|
<td style="text-align:center">{{ device.product }}</td>
|
|
{% else %}
|
|
<td style="text-align:center">{{ device.vendor }} {{ device.product }}</td>
|
|
{% endif %}
|
|
<td style="text-align:center">
|
|
{% if device.device_type != "-" %}
|
|
{% if device.device_type in REMOVABLE_DEVICE_TYPES and "No Media" not in device.status %}
|
|
<form action="/scsi/eject" method="post" onsubmit="return confirm('{{ _("Eject Disk? WARNING: On Mac OS, eject the Disk in the Finder instead!") }}')">
|
|
<input name="scsi_id" type="hidden" value="{{ device.id }}">
|
|
<input name="unit" type="hidden" value="{{ device.unit }}">
|
|
<input type="submit" value="{{ _("Eject") }}">
|
|
</form>
|
|
{% endif %}
|
|
<form action="/scsi/detach" method="post" onsubmit="return confirm('{{ _("Detach Device?") }}')">
|
|
<input name="scsi_id" type="hidden" value="{{ device.id }}">
|
|
<input name="unit" type="hidden" value="{{ device.unit }}">
|
|
<input type="submit" value="{{ _("Detach") }}">
|
|
</form>
|
|
{% else %}
|
|
<form action="/scsi/reserve" method="post" onsubmit="var memo = prompt('{{ _("Enter a memo for this reservation") }}'); if (memo === null) event.preventDefault(); document.getElementById('memo_{{ device.id }}').value = memo;">
|
|
<input name="scsi_id" type="hidden" value="{{ device.id }}">
|
|
<input name="memo" id="memo_{{ device.id }}" type="hidden" value="">
|
|
<input type="submit" value="{{ _("Reserve") }}">
|
|
</form>
|
|
{% endif %}
|
|
</td>
|
|
{% else %}
|
|
<td class="inactive">{{ device.id }}</td>
|
|
{% if units %}
|
|
<td class="inactive"></td>
|
|
{% endif %}
|
|
<td class="inactive"></td>
|
|
<td class="inactive">{{ _("Reserved ID") }}</td>
|
|
<td class="inactive">{{ RESERVATIONS[device.id] }}</td>
|
|
<td class="inactive"></td>
|
|
<td class="inactive">
|
|
<form action="/scsi/release" method="post">
|
|
<input name="scsi_id" type="hidden" value="{{ device.id }}">
|
|
<input type="submit" value="{{ _("Release") }}">
|
|
</form>
|
|
</td>
|
|
{% endif %}
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
|
|
<table style="border: none;" cellpadding="3">
|
|
<tr style="border: none;">
|
|
<td style="border: none;">
|
|
<form action="/scsi/detach_all" method="post" onsubmit="return confirm('{{ _("Detach all SCSI Devices?") }}')">
|
|
<input type="submit" value="{{ _("Detach All Devices") }}">
|
|
</form>
|
|
</td>
|
|
<td style="border: none;">
|
|
<form action="/scsi/info" method="post">
|
|
<input type="submit" value="{{ _("Show Device Info") }}">
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<hr/>
|
|
|
|
<details>
|
|
<summary class="heading">
|
|
{{ _("Image File Management") }}
|
|
</summary>
|
|
<ul>
|
|
<li>{{ _("Manage image files in the active RaSCSI image directory: <tt>%(directory)s</tt> with a scan depth of %(scan_depth)s.", directory=base_dir, scan_depth=scan_depth) }}</li>
|
|
<li>{{ _("Select a valid SCSI ID and <a href=\"%(url)s\">LUN</a> to attach to. Unless you know what you're doing, always use LUN 0.", url="https://en.wikipedia.org/wiki/Logical_unit_number") }}
|
|
</li>
|
|
<li>{{ _("If RaSCSI was unable to detect the media type associated with the image, you get to choose the type from the dropdown.") }}</li>
|
|
<li>
|
|
{{ _("Recognized image file types:") }}
|
|
{% set comma = joiner(", ") %}
|
|
{% for extension in valid_image_suffixes %}{{ comma() }}.{{ extension}}{% endfor %}
|
|
</li>
|
|
<li>
|
|
{{ _("Recognized archive file types:") }}
|
|
{% set comma = joiner(", ") %}
|
|
{% for extension in ARCHIVE_FILE_SUFFIXES %}{{ comma() }}.{{ extension}}{% endfor %}
|
|
</li>
|
|
</ul>
|
|
</details>
|
|
|
|
<table border="black" cellpadding="3">
|
|
<tbody>
|
|
<tr style="font-weight: bold;">
|
|
<td>{{ _("File") }}</td>
|
|
<td>{{ _("Size") }}</td>
|
|
<td>{{ _("Parameters and Actions") }}</td>
|
|
</tr>
|
|
{% for file in files|sort(attribute='name') %}
|
|
<tr>
|
|
{% if file["prop"] %}
|
|
<td>
|
|
<details>
|
|
<summary>
|
|
{{ file["name"] }}
|
|
</summary>
|
|
<ul style="list-style: none;">
|
|
{% for key in file["prop"] %}
|
|
<li>{{ key }}: {{ file['prop'][key] }}</li>
|
|
{% endfor %}
|
|
<form action="/files/download" method="post">
|
|
<input name="file" type="hidden" value="{{ CFG_DIR }}/{{ file['name'].replace(base_dir, '') }}.{{ PROPERTIES_SUFFIX }}">
|
|
<input type="submit" value="{{ _("Properties File") }} ↓">
|
|
</form>
|
|
</ul>
|
|
</details>
|
|
</td>
|
|
{% elif file["archive_contents"] %}
|
|
<td>
|
|
<details>
|
|
<summary>
|
|
{{ file["name"] }}
|
|
</summary>
|
|
<ul style="list-style: none;">
|
|
{% for member in file["archive_contents"] %}
|
|
{% if not member["is_properties_file"] %}
|
|
<li>
|
|
{% 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>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</ul>
|
|
</details>
|
|
</td>
|
|
{% else %}
|
|
<td>{{ file["name"] }}</td>
|
|
{% endif %}
|
|
<td style="text-align:center">
|
|
<form action="/files/download" method="post">
|
|
<input name="file" type="hidden" value="{{ base_dir }}/{{ file['name'] }}">
|
|
<input type="submit" value="{{ file['size_mb'] }} {{ _("MiB") }} ↓">
|
|
</form>
|
|
</td>
|
|
<td>
|
|
{% if file["name"] in attached_images %}
|
|
{{ _("In use") }}
|
|
{% else %}
|
|
{% 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">
|
|
<input name="file_name" type="hidden" value="{{ file['name'] }}">
|
|
<input name="file_size" type="hidden" value="{{ file['size'] }}">
|
|
<label for="id">{{ _("ID") }}</label>
|
|
<select name="scsi_id">
|
|
{% for id in scsi_ids %}
|
|
<option name="id" value="{{id}}"{% if id == recommended_id %} selected{% endif %}>
|
|
{{ id }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
<label for="unit">{{ _("LUN") }}</label>
|
|
<input name="unit" type="number" value="0" min="0" max="31" step="1">
|
|
{% if file["detected_type"] != "UNDEFINED" %}
|
|
<input name="type" type="hidden" value="{{ file['detected_type'] }}">
|
|
{{ file['detected_type_name'] }}
|
|
{% else %}
|
|
<select name="type">
|
|
<option selected disabled value="">
|
|
{{ _("Select media type") }}
|
|
</option>
|
|
{% for key, value in device_types.items() %}
|
|
{% if key in DISK_DEVICE_TYPES %}
|
|
<option value="{{ key }}">
|
|
{{ value["name"] }}
|
|
</option>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</select>
|
|
{% endif %}
|
|
<input type="submit" value="{{ _("Attach") }}">
|
|
{% endif %}
|
|
</form>
|
|
<form action="/files/rename" method="post" onsubmit="var new_file_name = prompt('{{ _("Enter new file name for: %(file_name)s", file_name=file["name"]) }}', '{{ file['name'] }}'); if (new_file_name === null) event.preventDefault(); document.getElementById('new_file_name_{{ loop.index }}').value = new_file_name;">
|
|
<input name="file_name" type="hidden" value="{{ file['name'] }}">
|
|
<input name="new_file_name" id="new_file_name_{{ loop.index }}" type="hidden" value="">
|
|
<input type="submit" value="{{ _("Rename") }}">
|
|
</form>
|
|
<form action="/files/copy" method="post" onsubmit="var copy_file_name = prompt('{{ _("Save copy of %(file_name)s as:", file_name=file["name"]) }}', '{{ file['name'] }}'); if (copy_file_name === null) event.preventDefault(); document.getElementById('copy_file_name_{{ loop.index }}').value = copy_file_name;">
|
|
<input name="file_name" type="hidden" value="{{ file['name'] }}">
|
|
<input name="copy_file_name" id="copy_file_name_{{ loop.index }}" type="hidden" value="">
|
|
<input type="submit" value="{{ _("Copy") }}">
|
|
</form>
|
|
<form action="/files/delete" method="post" onsubmit="return confirm('{{ _("Delete file: %(file_name)s?", file_name=file["name"]) }}')">
|
|
<input name="file_name" type="hidden" value="{{ file['name'] }}">
|
|
<input type="submit" value="{{ _("Delete") }}">
|
|
</form>
|
|
{% endif %}
|
|
{% if not file["archive_contents"] %}
|
|
<form action="/files/diskinfo" method="post">
|
|
<input name="file_name" type="hidden" value="{{ file['name'] }}">
|
|
<input type="submit" value="{{ _("?") }}">
|
|
</form>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
<p><small>{{ _("%(disk_space)s MiB disk space remaining on the Pi", disk_space=env["free_disk_space"]) }}</small></p>
|
|
|
|
<hr/>
|
|
<details>
|
|
<summary class="heading">
|
|
{{ _("Attach Peripheral Device") }}
|
|
</summary>
|
|
<ul>
|
|
<li>{{ _("Before using a networking device, it is recommended to run easyinstall.sh from the command line to configure your Raspberry Pi.") }}
|
|
</li>
|
|
<ul>
|
|
{% if bridge_configured %}
|
|
<li>{{ _("The <tt>rascsi_bridge</tt> network bridge is active and ready to be used by an emulated network adapter!") }}</li>
|
|
{% else %}
|
|
<li>{{ _("Please configure the <tt>rascsi_bridge</tt> network bridge before attaching an emulated network adapter!") }}</li>
|
|
{% endif %}
|
|
<li>{{ _("If you have a DHCP setup, choose only the interface you have configured the bridge with. You can ignore the inet field when attaching.") }}</li>
|
|
<li>{{ _("To browse the modern web, install a vintage web proxy such as <a href=\"%(url)s\">Macproxy</a>.", url="https://github.com/akuker/RASCSI/wiki/Vintage-Web-Proxy#macproxy") }}</li>
|
|
</li>
|
|
</ul>
|
|
<li>{{ _("Read more about <a href=\"%(url)s\">supported device types</a> on the wiki.", url="https://github.com/akuker/RASCSI/wiki/Supported-Device-Types") }}
|
|
</li>
|
|
</ul>
|
|
</details>
|
|
<table border="black" cellpadding="3">
|
|
<tr style="font-weight: bold;">
|
|
<td>{{ _("Device") }}</td>
|
|
<td>{{ _("Code") }}</td>
|
|
<td>{{ _("Parameters and Actions") }}</td>
|
|
</tr>
|
|
{% for type in REMOVABLE_DEVICE_TYPES + PERIPHERAL_DEVICE_TYPES %}
|
|
<tr>
|
|
<td>
|
|
<div>{{ device_types[type]["name"] }}</div>
|
|
</td>
|
|
<td>
|
|
<div>{{ type }}</div>
|
|
</td>
|
|
<td>
|
|
<form action="/scsi/attach_device" method="post">
|
|
<input name="type" type="hidden" value="{{ type }}">
|
|
{% for key, value in device_types[type]["params"] | dictsort %}
|
|
<label for="{{ key }}">{{ key }}:</label>
|
|
{% if value.isnumeric() %}
|
|
<input name="{{ key }}" type="number" value="{{ value }}">
|
|
{% elif key == "interface" %}
|
|
<select name="interface">
|
|
{% for if in netinfo["ifs"] %}
|
|
<option value="{{ if }}">
|
|
{{ if }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
{% else %}
|
|
<input name="{{ key }}" type="text" size="{{ value|length }}" placeholder="{{ value }}">
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% if type in REMOVABLE_DEVICE_TYPES %}
|
|
<label for="drive_name">{{ _("Masquerade as:") }}</label>
|
|
<select name="drive_name">
|
|
<option value="">
|
|
{{ _("None") }}
|
|
</option>
|
|
{% if type == "SCCD" %}
|
|
{% for drive in 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') %}
|
|
<option value="{{ drive.name }}">
|
|
{{ drive.name }}
|
|
</option>
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% if type == "SCMO" %}
|
|
{% for drive in drive_properties["mo_conf"] | sort(attribute='name') %}
|
|
<option value="{{ drive.name }}">
|
|
{{ drive.name }}
|
|
</option>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</select>
|
|
{% endif %}
|
|
<label for="scsi_id">{{ _("SCSI ID:") }}</label>
|
|
<select name="scsi_id">
|
|
{% for id in scsi_ids %}
|
|
<option value="{{ id }}"{% if id == recommended_id %} selected{% endif %}>
|
|
{{ id }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
<label for="unit">{{ _("LUN") }}</label>
|
|
<input name="unit" type="number" value="0" min="0" max="31" step="1">
|
|
<input type="submit" value="{{ _("Attach") }}">
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</table>
|
|
|
|
<hr/>
|
|
<details>
|
|
<summary class="heading">
|
|
{{ _("Upload File from Local Computer") }}
|
|
</summary>
|
|
<ul>
|
|
<li>{{ _("The largest file size accepted in this form is %(max_file_size)s MiB. Use other file transfer means for larger files.", max_file_size=max_file_size) }}</li>
|
|
<li>{{ _("File uploads will progress only if you stay on this page. If you navigate away before the transfer is completed, you will end up with an incomplete file.") }}</li>
|
|
<li>{{ _("Install <a href=\"%(url)s\">Netatalk</a> to use the AFP File Server.", url="https://github.com/akuker/RASCSI/wiki/AFP-File-Sharing") }}</li>
|
|
</ul>
|
|
</details>
|
|
|
|
<table style="border: none;">
|
|
<tr style="border: none;">
|
|
<td style="border: none; vertical-align:top;">
|
|
<form name="dropper" action="/files/upload" method="post" class="dropzone dz-clickable" enctype="multipart/form-data" id="dropper">
|
|
<p>
|
|
<label for="destination">{{ _("Target directory:") }}</label>
|
|
<select name="destination">
|
|
<option value="images">{{ base_dir }}</option>
|
|
<option value="afp">{{ AFP_DIR }}</option>
|
|
</select>
|
|
</p>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<script type="application/javascript">
|
|
Dropzone.options.dropper = {
|
|
paramName: 'file',
|
|
chunking: true,
|
|
forceChunking: true,
|
|
url: '/files/upload',
|
|
maxFilesize: {{ max_file_size }}, // MiB
|
|
chunkSize: 1000000, // bytes
|
|
dictDefaultMessage: "{{ _("Drop files here to upload") }}",
|
|
dictFallbackMessage: "{{ _("Your browser does not support drag'n'drop file uploads.") }}",
|
|
dictFallbackText: "{{ _("Please use the fallback form below to upload your files like in the olden days.") }}",
|
|
dictFileTooBig: "{{ _("File is too big: {{filesize}}MiB. Max filesize: {{maxFilesize}}MiB.") }}",
|
|
dictInvalidFileType: "{{ _("You can't upload files of this type.") }}",
|
|
dictResponseError: "{{ _("Server responded with code: {{statusCode}}") }}",
|
|
dictCancelUpload:" {{ _("Cancel upload") }}",
|
|
dictUploadCanceled: "{{ _("Upload canceled.") }}",
|
|
dictCancelUploadConfirmation: "{{ _("Are you sure you want to cancel this upload?") }}",
|
|
dictRemoveFile: "{{ _("Remove file") }}",
|
|
dictMaxFilesExceeded: "{{ _("You can not upload any more files.") }}",
|
|
dictFileSizeUnits: {
|
|
tb: "{{ _("TiB") }}",
|
|
gb: "{{ _("GiB") }}",
|
|
mb: "{{ _("MiB") }}",
|
|
kb: "{{ _("KiB") }}",
|
|
b: "{{ _("B") }}"
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<hr/>
|
|
|
|
<details>
|
|
<summary class="heading">
|
|
{{ _("Download File from the Web") }}
|
|
</summary>
|
|
<ul>
|
|
<li>{{ _("Choose the desination directory and download a file from the Web to your Raspberry Pi.") }}</li>
|
|
<li>{{ _("Install <a href=\"%(url)s\">Netatalk</a> to use the AFP File Server.", url="https://github.com/akuker/RASCSI/wiki/AFP-File-Sharing") }}</li>
|
|
</ul>
|
|
</details>
|
|
|
|
<table style="border: none">
|
|
<tr style="border: none">
|
|
<td style="border: none; vertical-align:top;">
|
|
<form action="/files/download_url" method="post">
|
|
<label for="destination">{{ _("Target directory:") }}</label>
|
|
<select name="destination">
|
|
<option value="images">{{ base_dir }}</option>
|
|
<option value="afp">{{ AFP_DIR }}</option>
|
|
</select>
|
|
<label for="url">{{ _("URL:") }}</label>
|
|
<input name="url" placeholder="{{ _("URL") }}" required="" type="url">
|
|
<input type="submit" value="{{ _("Download") }}" onclick="processNotify('{{ _("Downloading File...") }}')">
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<hr/>
|
|
|
|
<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>
|
|
<table style="border: none">
|
|
<tr style="border: none">
|
|
<td style="border: none; vertical-align:top;">
|
|
<label for="scsi_id">{{ _("SCSI ID:") }}</label>
|
|
<form action="/files/download_to_iso" method="post">
|
|
<select name="scsi_id">
|
|
{% for id in scsi_ids %}
|
|
<option value="{{ id }}"{% if id == recommended_id %} selected{% endif %}>
|
|
{{ id }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
<label for="url">{{ _("URL:") }}</label>
|
|
<input name="url" placeholder="{{ _("URL") }}" required="" type="url">
|
|
<label for="type">{{ _("Type:") }}</label>
|
|
<select name="type">
|
|
<option value="-hfs">
|
|
HFS
|
|
</option>
|
|
<option value="-iso-level 1">
|
|
ISO-9660 Level 1
|
|
</option>
|
|
<option value="-iso-level 2">
|
|
ISO-9660 Level 2
|
|
</option>
|
|
<option value="-iso-level 3">
|
|
ISO-9660 Level 3
|
|
</option>
|
|
<option value="-J">
|
|
Joliet
|
|
</option>
|
|
<option value="-r">
|
|
Rock Ridge
|
|
</option>
|
|
</select>
|
|
<input type="submit" value="{{ _("Download and Mount CD-ROM image") }}" onclick="processNotify('{{ _("Downloading File and generating CD-ROM image...") }}')">
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<hr/>
|
|
|
|
<details>
|
|
<summary class="heading">
|
|
{{ _("Create Empty Disk Image File") }}
|
|
</summary>
|
|
<ul>
|
|
<li>{{ _("The Generic Hard Disk image type is recommended for most computer platforms.") }}</li>
|
|
<li>{{ _("The Apple image type improves compatibility with Apple Macintosh computers.") }}</li>
|
|
<li>{{ _("The NEC image type improves compatibility with NEC PC-98 computers.") }}</li>
|
|
<li>{{ _("The SCSI-1 image type makes RaSCSI behave like a legacy SCSI-1 device, which may improve compatibility with very old SCSI controllers.") }}</li>
|
|
<li>{{ _("The Removable Disk image type can be used with SCSI floppy drives, SyQuest drives, Zip drives, etc.") }}</li>
|
|
</ul>
|
|
</details>
|
|
<table style="border: none">
|
|
<tr style="border: none">
|
|
<td style="border: none; vertical-align:top;">
|
|
<form action="/files/create" method="post">
|
|
<label for="file_name">{{ _("File Name:") }}</label>
|
|
<input name="file_name" placeholder="{{ _("File Name") }}" required="" type="text">
|
|
<label for="type">{{ _("Type:") }}</label>
|
|
<select name="type">
|
|
{% for key, value in image_suffixes_to_create.items() %}
|
|
<option value="{{ key }}">
|
|
{{ value }} [.{{ key }}]
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
<label for="size">{{ _("Size:") }}</label>
|
|
<input name="size" type="number" placeholder="{{ _("MiB") }}" min="1" max="262144" required>
|
|
<input type="submit" value="{{ _("Create") }}">
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<hr/>
|
|
|
|
<details>
|
|
<summary class="heading">
|
|
{{ _("Create Named Drive") }}
|
|
</summary>
|
|
<ul>
|
|
<li>{{ _("Create pairs of images and properties files from a list of real-life drives.") }}</li>
|
|
<li>{{ _("This will make RaSCSI use certain vendor strings and block sizes that may improve compatibility with certain systems.") }}</li>
|
|
</ul>
|
|
</details>
|
|
<p><a href="/drive/list">{{ _("Create a named disk image that mimics real-life drives") }}</a></p>
|
|
|
|
<hr/>
|
|
|
|
<details>
|
|
<summary class="heading">
|
|
{{ _("Logging") }}
|
|
</summary>
|
|
<ul>
|
|
<li>{{ _("Fetch a certain number of lines of system logs with the given scope.") }}</li>
|
|
</ul>
|
|
</details>
|
|
<table style="border: none">
|
|
<tr style="border: none">
|
|
<td style="border: none; vertical-align:top;">
|
|
<form action="/logs/show" method="post">
|
|
<label for="lines">{{ _("Log Lines:") }}</label>
|
|
<input name="lines" type="number" value="200" min="0" max="99999" step="100">
|
|
<label for="scope">{{ _("Scope:") }}</label>
|
|
<select name="scope">
|
|
<option value="">
|
|
{{ _("All logs") }}
|
|
</option>
|
|
<option value="rascsi">
|
|
rascsi
|
|
</option>
|
|
<option value="rascsi-web">
|
|
rascsi-web
|
|
</option>
|
|
<option value="rascsi-oled">
|
|
rascsi-oled
|
|
</option>
|
|
<option value="rascsi-ctrlboard">
|
|
rascsi-ctrlboard
|
|
</option>
|
|
</select>
|
|
<input type="submit" value="{{ _("Show Logs") }}">
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<hr/>
|
|
|
|
<details>
|
|
<summary class="heading">
|
|
{{ _("Server Log Level") }}
|
|
</summary>
|
|
<ul>
|
|
<li>{{ _("Change the log level of the RaSCSI backend process.") }}</li>
|
|
<li>{{ _("The current dropdown selection indicates the active log level.") }}</li>
|
|
</ul>
|
|
</details>
|
|
<table style="border: none">
|
|
<tr style="border: none">
|
|
<td style="border: none; vertical-align:top;">
|
|
<form action="/logs/level" method="post">
|
|
<label for="level">{{ _("Log Level:") }}</label>
|
|
<select name="level">
|
|
{% for level in log_levels %}
|
|
<option value="{{ level }}"{% if level == current_log_level %} selected{% endif %}>
|
|
{{ level }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
<input type="submit" value="{{ _("Set Log Level") }}">
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<hr/>
|
|
|
|
<details>
|
|
<summary class="heading">
|
|
{{ _("Language") }}
|
|
</summary>
|
|
<ul>
|
|
<li>{{ _("Change the Web Interface language.") }}</li>
|
|
</ul>
|
|
</details>
|
|
<table style="border: none">
|
|
<tr style="border: none">
|
|
<td style="border: none; vertical-align:top;">
|
|
<form action="/language" method="post">
|
|
<label for="language">{{ _("Language:") }}</label>
|
|
<select name="locale">
|
|
{% for locale in locales %}
|
|
<option value="{{ locale.language }}">
|
|
{{ locale.language }} - {{ locale.display_name }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
<input type="submit" value="{{ _("Change Language") }}">
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<hr/>
|
|
|
|
<details>
|
|
<summary class="heading">
|
|
{{ _("Raspberry Pi Operations") }}
|
|
</summary>
|
|
<ul>
|
|
<li>{{ _("Reboot or shut down the Raspberry Pi that RaSCSI is running on.") }}</li>
|
|
<li>{{ _("IMPORTANT: Always shut down the Pi before turning off the power. Failing to do so may lead to data loss.") }}</li>
|
|
</ul>
|
|
</details>
|
|
<table style="border: none">
|
|
<tr style="border: none">
|
|
<td style="border: none; vertical-align:top;">
|
|
<form action="/pi/reboot" method="post" onclick="if (confirm('{{ _("Reboot the Raspberry Pi?") }}')) shutdownNotify('{{ _("Rebooting the Raspberry Pi...") }}'); else event.preventDefault();">
|
|
<input type="submit" value="{{ _("Reboot Raspberry Pi") }}">
|
|
</form>
|
|
</td>
|
|
<td style="border: none; vertical-align:top;">
|
|
<form action="/pi/shutdown" method="post" onclick="if (confirm('{{ _("Shut down the Raspberry Pi?") }}')) shutdownNotify('{{ _("Shutting down the Raspberry Pi...") }}'); else event.preventDefault();">
|
|
<input type="submit" value="{{ _("Shut Down Raspberry Pi") }}">
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<center><tt>
|
|
{% if netatalk_configured == 1 %}
|
|
{{ _("The AppleShare server is running. No active connections.") }}
|
|
{% endif %}
|
|
{% if netatalk_configured == 2 %}
|
|
{{ _("%(value)d active AFP connection", value=(netatalk_configured - 1)) }}
|
|
{% elif netatalk_configured > 2 %}
|
|
{{ _("%(value)d active AFP connections", value=(netatalk_configured - 1)) }}
|
|
{% endif %}
|
|
</center></tt>
|
|
<center><tt>
|
|
{% if macproxy_configured %}
|
|
<center><tt>{{ _("Macproxy is running at %(ip_addr)s (default port 5000)", ip_addr=env['ip_addr']) }}</tt></center>
|
|
{% endif %}
|
|
</center></tt>
|
|
|
|
{% endblock content %}
|