Skip to content

Commit 3c8e7db

Browse files
authored
Allow the selecting of target dir when uploading or downloading files (#867)
Uses a single endpoint for downloading files Adds a select field to pick target dir for both download and upload forms Moves the Macproxy/Netatalk helptext into the helptext blocks, and the related status messages down into the page footer
1 parent 3ac3abb commit 3c8e7db

3 files changed

Lines changed: 64 additions & 107 deletions

File tree

python/web/src/templates/index.html

Lines changed: 38 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@
334334
{% if bridge_configured %}
335335
<li>{{ _("The <tt>rascsi_bridge</tt> network bridge is active and ready to be used by an emulated network adapter!") }}</li>
336336
{% endif %}
337+
<li>{{ _("To browse the modern web, install a vintage web proxy like <a href=\"%(url)s\">Macproxy</a>.", url="https://github.com/akuker/RASCSI/wiki/Vintage-Web-Proxy#macproxy") }}</li>
337338
</li>
338339
</ul>
339340
<li>{{ _("The Printer and Host Services device are currently supported on compatible Atari systems, and require <a href=\"%(url)s\">driver software</a> to be installed on the host system.", url="https://www.hddriver.net/en/rascsi_tools.html") }}
@@ -385,28 +386,31 @@
385386
</tr>
386387
{% endfor %}
387388
</table>
388-
{% if macproxy_configured %}
389-
<p><small>{{ _("Macproxy is running at %(ip_addr)s (default port 5000)", ip_addr=ip_addr) }}</small></p>
390-
{% else %}
391-
<p><small>{{ _("Install <a href=\"%(url)s\">Macproxy</a> to browse the Web with any vintage browser. It's not just for Macs!", url="https://github.com/akuker/RASCSI/wiki/Vintage-Web-Proxy#macproxy") }}</small></p>
392-
{% endif %}
393389

394390
<hr/>
395391
<details>
396392
<summary class="heading">
397-
{{ _("Upload File") }}
393+
{{ _("Upload File from Local Computer") }}
398394
</summary>
399395
<ul>
400-
<li>{{ _("Files are uploaded to <tt>%(directory)s</tt>.", directory=base_dir) }}</li>
401396
<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>
402397
<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>
398+
<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>
403399
</ul>
404400
</details>
405401

406402
<table style="border: none;">
407403
<tr style="border: none;">
408404
<td style="border: none; vertical-align:top;">
409-
<form name="dropper" action="/files/upload" method="post" class="dropzone dz-clickable" enctype="multipart/form-data" id="dropper"></form>
405+
<form name="dropper" action="/files/upload" method="post" class="dropzone dz-clickable" enctype="multipart/form-data" id="dropper">
406+
<p>
407+
<label for="destination">{{ _("Target directory:") }}</label>
408+
<select name="destination">
409+
<option value="images">{{ base_dir }}</option>
410+
<option value="afp">{{ AFP_DIR }}</option>
411+
</select>
412+
</p>
413+
</form>
410414
</td>
411415
</tr>
412416
</table>
@@ -443,62 +447,31 @@
443447

444448
<details>
445449
<summary class="heading">
446-
{{ _("Download File to Images") }}
450+
{{ _("Download File from the Web") }}
447451
</summary>
448452
<ul>
449-
<li>{{ _("Given a URL, download that file to the <tt>%(directory)s</tt> directory.", directory=base_dir) }}</li>
453+
<li>{{ _("Choose the desination directory and download a file from the Web to your Raspberry Pi.") }}</li>
454+
<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>
450455
</ul>
451456
</details>
452457

453458
<table style="border: none">
454459
<tr style="border: none">
455460
<td style="border: none; vertical-align:top;">
456-
<form action="/files/download_to_images" method="post">
457-
<label for="url">{{ _("URL:") }}</label>
458-
<input name="url" placeholder="{{ _("URL") }}" required="" type="url">
459-
<input type="submit" value="{{ _("Download") }}" onclick="processNotify('{{ _("Downloading File to Images...") }}')">
460-
</form>
461-
</td>
462-
</tr>
463-
</table>
464-
465-
<hr/>
466-
467-
<details>
468-
<summary class="heading">
469-
{{ _("Download File to AppleShare") }}
470-
</summary>
471-
<ul>
472-
<li>{{ _("Given a URL, download that file to the <tt>%(directory)s</tt> directory and share it over AFP.", directory=AFP_DIR) }}</li>
473-
<li>{{ _("Manage the files you download here through AppleShare on your vintage Mac.") }}</li>
474-
<li>{{ _("Requires <a href=\"%(url)s\">Netatalk</a> to be installed and configured correctly for your network.", url="https://github.com/akuker/RASCSI/wiki/AFP-File-Sharing") }}</li>
475-
</ul>
476-
</details>
477-
478-
{% if netatalk_configured %}
479-
<table style="border: none">
480-
<tr style="border: none">
481-
<td style="border: none; vertical-align:top;">
482-
<form action="/files/download_to_afp" method="post">
461+
<form action="/files/download_url" method="post">
462+
<label for="destination">{{ _("Target directory:") }}</label>
463+
<select name="destination">
464+
<option value="images">{{ base_dir }}</option>
465+
<option value="afp">{{ AFP_DIR }}</option>
466+
</select>
483467
<label for="url">{{ _("URL:") }}</label>
484468
<input name="url" placeholder="{{ _("URL") }}" required="" type="url">
485-
<input type="submit" value="{{ _("Download") }}" onclick="processNotify('{{ _("Downloading File to AppleShare...") }}')">
469+
<input type="submit" value="{{ _("Download") }}" onclick="processNotify('{{ _("Downloading File...") }}')">
486470
</form>
487471
</td>
488472
</tr>
489473
</table>
490474

491-
{% if netatalk_configured == 1 %}
492-
<p><small>{{ _("The AppleShare server is running. No active connections.") }}</small></p>
493-
{% elif netatalk_configured == 2 %}
494-
<p><small>{{ _("%(value)d active AFP connection", value=(netatalk_configured - 1)) }}</small></p>
495-
{% elif netatalk_configured > 2 %}
496-
<p><small>{{ _("%(value)d active AFP connections", value=(netatalk_configured - 1)) }}</small></p>
497-
{% endif %}
498-
{% else %}
499-
<p>{{ _("Install <a href=\"%(url)s\">Netatalk</a> to use the AppleShare File Server.", url="https://github.com/akuker/RASCSI/wiki/AFP-File-Sharing") }}</p>
500-
{% endif %}
501-
502475
<hr/>
503476

504477
<details>
@@ -725,4 +698,20 @@
725698
</tr>
726699
</table>
727700

701+
<center><tt>
702+
{% if netatalk_configured == 1 %}
703+
{{ _("The AppleShare server is running. No active connections.") }}
704+
{% endif %}
705+
{% if netatalk_configured == 2 %}
706+
{{ _("%(value)d active AFP connection", value=(netatalk_configured - 1)) }}
707+
{% elif netatalk_configured > 2 %}
708+
{{ _("%(value)d active AFP connections", value=(netatalk_configured - 1)) }}
709+
{% endif %}
710+
</center></tt>
711+
<center><tt>
712+
{% if macproxy_configured %}
713+
<center><tt>{{ _("Macproxy is running at %(ip_addr)s (default port 5000)", ip_addr=env['ip_addr']) }}</tt></center>
714+
{% endif %}
715+
</center></tt>
716+
728717
{% endblock content %}

python/web/src/web.py

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -824,34 +824,20 @@ def download_to_iso():
824824
])
825825

826826

827-
@APP.route("/files/download_to_images", methods=["POST"])
827+
@APP.route("/files/download_url", methods=["POST"])
828828
@login_required
829-
def download_img():
829+
def download_file():
830830
"""
831831
Downloads a remote file onto the images dir on the Pi
832832
"""
833+
destination = request.form.get("destination")
833834
url = request.form.get("url")
834-
server_info = ractl_cmd.get_server_info()
835-
process = file_cmd.download_to_dir(url, server_info["image_dir"], Path(url).name)
836-
process = ReturnCodeMapper.add_msg(process)
837-
if process["status"]:
838-
return response(message=process["msg"])
839-
840-
return response(error=True, message=[
841-
(_("Failed to download file from %(url)s", url=url), "error"),
842-
(process["msg"], "error"),
843-
])
844-
845-
846-
@APP.route("/files/download_to_afp", methods=["POST"])
847-
@login_required
848-
def download_afp():
849-
"""
850-
Downloads a remote file onto the AFP shared dir on the Pi
851-
"""
852-
url = request.form.get("url")
853-
file_name = Path(url).name
854-
process = file_cmd.download_to_dir(url, AFP_DIR, file_name)
835+
if destination == "afp":
836+
destination_dir = AFP_DIR
837+
else:
838+
server_info = ractl_cmd.get_server_info()
839+
destination_dir = server_info["image_dir"]
840+
process = file_cmd.download_to_dir(url, destination_dir, Path(url).name)
855841
process = ReturnCodeMapper.add_msg(process)
856842
if process["status"]:
857843
return response(message=process["msg"])
@@ -873,8 +859,13 @@ def upload_file():
873859
if auth["status"] and "username" not in session:
874860
return make_response(auth["msg"], 403)
875861

876-
server_info = ractl_cmd.get_server_info()
877-
return upload_with_dropzonejs(server_info["image_dir"])
862+
destination = request.form.get("destination")
863+
if destination == "afp":
864+
destination_dir = AFP_DIR
865+
else:
866+
server_info = ractl_cmd.get_server_info()
867+
destination_dir = server_info["image_dir"]
868+
return upload_with_dropzonejs(destination_dir)
878869

879870

880871
@APP.route("/files/create", methods=["POST"])

python/web/tests/api/test_files.py

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,9 @@ def test_extract_file(
122122
)
123123

124124
http_client.post(
125-
"/files/download_to_images",
125+
"/files/download_url",
126126
data={
127+
"destination": "images",
127128
"url": url,
128129
},
129130
)
@@ -200,44 +201,19 @@ def test_upload_file(http_client, delete_file):
200201
def test_download_file(http_client, create_test_image):
201202
file_name = create_test_image()
202203

203-
response = http_client.post("/files/download", data={"file": f"{IMAGES_DIR}/{file_name}"})
204+
response = http_client.post(
205+
"/files/download",
206+
data={"file": f"{IMAGES_DIR}/{file_name}"}
207+
)
204208

205209
assert response.status_code == 200
206210
assert response.headers["content-type"] == "application/octet-stream"
207211
assert response.headers["content-disposition"] == f"attachment; filename={file_name}"
208212
assert response.headers["content-length"] == str(FILE_SIZE_1_MIB)
209213

210214

211-
# route("/files/download_to_afp", methods=["POST"])
212-
def test_download_url_to_afp_dir(httpserver, http_client):
213-
file_name = str(uuid.uuid4())
214-
http_path = f"/images/{file_name}"
215-
url = httpserver.url_for(http_path)
216-
217-
with open("tests/assets/test_image.hds", mode="rb") as file:
218-
file_data = file.read()
219-
220-
httpserver.expect_request(http_path).respond_with_data(
221-
file_data,
222-
mimetype="application/octet-stream",
223-
)
224-
225-
response = http_client.post(
226-
"/files/download_to_afp",
227-
data={
228-
"url": url,
229-
},
230-
)
231-
232-
response_data = response.json()
233-
234-
assert response.status_code == 200
235-
assert response_data["status"] == STATUS_SUCCESS
236-
assert response_data["messages"][0]["message"] == f"{file_name} downloaded to {AFP_DIR}"
237-
238-
239-
# route("/files/download_to_images", methods=["POST"])
240-
def test_download_url_to_images_dir(httpserver, http_client, list_files, delete_file):
215+
# route("/files/download_url", methods=["POST"])
216+
def test_download_url_to_dir(httpserver, http_client, list_files, delete_file):
241217
file_name = str(uuid.uuid4())
242218
http_path = f"/images/{file_name}"
243219
url = httpserver.url_for(http_path)
@@ -251,8 +227,9 @@ def test_download_url_to_images_dir(httpserver, http_client, list_files, delete_
251227
)
252228

253229
response = http_client.post(
254-
"/files/download_to_images",
230+
"/files/download_url",
255231
data={
232+
"destination": "images",
256233
"url": url,
257234
},
258235
)

0 commit comments

Comments
 (0)