From 3c8e7dbef06ed1f0ebb82e99e56a11352fd782a0 Mon Sep 17 00:00:00 2001 From: Daniel Markstedt Date: Tue, 27 Sep 2022 17:38:34 -0700 Subject: [PATCH] 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 --- python/web/src/templates/index.html | 87 +++++++++++++---------------- python/web/src/web.py | 41 ++++++-------- python/web/tests/api/test_files.py | 43 ++++---------- 3 files changed, 64 insertions(+), 107 deletions(-) diff --git a/python/web/src/templates/index.html b/python/web/src/templates/index.html index 24568413..cb874cab 100644 --- a/python/web/src/templates/index.html +++ b/python/web/src/templates/index.html @@ -334,6 +334,7 @@ {% if bridge_configured %}
  • {{ _("The rascsi_bridge network bridge is active and ready to be used by an emulated network adapter!") }}
  • {% endif %} +
  • {{ _("To browse the modern web, install a vintage web proxy like Macproxy.", url="https://github.com/akuker/RASCSI/wiki/Vintage-Web-Proxy#macproxy") }}
  • {{ _("The Printer and Host Services device are currently supported on compatible Atari systems, and require driver software to be installed on the host system.", url="https://www.hddriver.net/en/rascsi_tools.html") }} @@ -385,28 +386,31 @@ {% endfor %} -{% if macproxy_configured %} -

    {{ _("Macproxy is running at %(ip_addr)s (default port 5000)", ip_addr=ip_addr) }}

    -{% else %} -

    {{ _("Install Macproxy 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") }}

    -{% endif %}
    - {{ _("Upload File") }} + {{ _("Upload File from Local Computer") }}
      -
    • {{ _("Files are uploaded to %(directory)s.", directory=base_dir) }}
    • {{ _("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) }}
    • {{ _("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.") }}
    • +
    • {{ _("Install Netatalk to use the AFP File Server.", url="https://github.com/akuker/RASCSI/wiki/AFP-File-Sharing") }}
    -
    +
    +

    + + +

    +
    @@ -443,20 +447,26 @@
    - {{ _("Download File to Images") }} + {{ _("Download File from the Web") }}
      -
    • {{ _("Given a URL, download that file to the %(directory)s directory.", directory=base_dir) }}
    • +
    • {{ _("Choose the desination directory and download a file from the Web to your Raspberry Pi.") }}
    • +
    • {{ _("Install Netatalk to use the AFP File Server.", url="https://github.com/akuker/RASCSI/wiki/AFP-File-Sharing") }}
    @@ -464,43 +474,6 @@
    -
    - - {{ _("Download File to AppleShare") }} - -
      -
    • {{ _("Given a URL, download that file to the %(directory)s directory and share it over AFP.", directory=AFP_DIR) }}
    • -
    • {{ _("Manage the files you download here through AppleShare on your vintage Mac.") }}
    • -
    • {{ _("Requires Netatalk to be installed and configured correctly for your network.", url="https://github.com/akuker/RASCSI/wiki/AFP-File-Sharing") }}
    • -
    -
    - -{% if netatalk_configured %} -
    -
    + + + - +
    - - - -
    -
    - - - -
    -
    - -{% if netatalk_configured == 1 %} -

    {{ _("The AppleShare server is running. No active connections.") }}

    -{% elif 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 %} -{% else %} -

    {{ _("Install Netatalk to use the AppleShare File Server.", url="https://github.com/akuker/RASCSI/wiki/AFP-File-Sharing") }}

    -{% endif %} - -
    -
    {{ _("Download File and Create CD-ROM image") }} @@ -725,4 +698,20 @@ +
    + {% 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 %} +
    +
    +{% if macproxy_configured %} +
    {{ _("Macproxy is running at %(ip_addr)s (default port 5000)", ip_addr=env['ip_addr']) }}
    +{% endif %} +
    + {% endblock content %} diff --git a/python/web/src/web.py b/python/web/src/web.py index d53d93d6..54e36d6c 100644 --- a/python/web/src/web.py +++ b/python/web/src/web.py @@ -824,34 +824,20 @@ def download_to_iso(): ]) -@APP.route("/files/download_to_images", methods=["POST"]) +@APP.route("/files/download_url", methods=["POST"]) @login_required -def download_img(): +def download_file(): """ Downloads a remote file onto the images dir on the Pi """ + destination = request.form.get("destination") url = request.form.get("url") - server_info = ractl_cmd.get_server_info() - process = file_cmd.download_to_dir(url, server_info["image_dir"], Path(url).name) - process = ReturnCodeMapper.add_msg(process) - if process["status"]: - return response(message=process["msg"]) - - return response(error=True, message=[ - (_("Failed to download file from %(url)s", url=url), "error"), - (process["msg"], "error"), - ]) - - -@APP.route("/files/download_to_afp", methods=["POST"]) -@login_required -def download_afp(): - """ - Downloads a remote file onto the AFP shared dir on the Pi - """ - url = request.form.get("url") - file_name = Path(url).name - process = file_cmd.download_to_dir(url, AFP_DIR, file_name) + if destination == "afp": + destination_dir = AFP_DIR + else: + server_info = ractl_cmd.get_server_info() + destination_dir = server_info["image_dir"] + process = file_cmd.download_to_dir(url, destination_dir, Path(url).name) process = ReturnCodeMapper.add_msg(process) if process["status"]: return response(message=process["msg"]) @@ -873,8 +859,13 @@ def upload_file(): if auth["status"] and "username" not in session: return make_response(auth["msg"], 403) - server_info = ractl_cmd.get_server_info() - return upload_with_dropzonejs(server_info["image_dir"]) + destination = request.form.get("destination") + if destination == "afp": + destination_dir = AFP_DIR + else: + server_info = ractl_cmd.get_server_info() + destination_dir = server_info["image_dir"] + return upload_with_dropzonejs(destination_dir) @APP.route("/files/create", methods=["POST"]) diff --git a/python/web/tests/api/test_files.py b/python/web/tests/api/test_files.py index 81f7d381..177aac89 100644 --- a/python/web/tests/api/test_files.py +++ b/python/web/tests/api/test_files.py @@ -122,8 +122,9 @@ def test_extract_file( ) http_client.post( - "/files/download_to_images", + "/files/download_url", data={ + "destination": "images", "url": url, }, ) @@ -200,7 +201,10 @@ def test_upload_file(http_client, delete_file): def test_download_file(http_client, create_test_image): file_name = create_test_image() - response = http_client.post("/files/download", data={"file": f"{IMAGES_DIR}/{file_name}"}) + response = http_client.post( + "/files/download", + data={"file": f"{IMAGES_DIR}/{file_name}"} + ) assert response.status_code == 200 assert response.headers["content-type"] == "application/octet-stream" @@ -208,36 +212,8 @@ def test_download_file(http_client, create_test_image): assert response.headers["content-length"] == str(FILE_SIZE_1_MIB) -# route("/files/download_to_afp", methods=["POST"]) -def test_download_url_to_afp_dir(httpserver, http_client): - file_name = str(uuid.uuid4()) - http_path = f"/images/{file_name}" - url = httpserver.url_for(http_path) - - with open("tests/assets/test_image.hds", mode="rb") as file: - file_data = file.read() - - httpserver.expect_request(http_path).respond_with_data( - file_data, - mimetype="application/octet-stream", - ) - - response = http_client.post( - "/files/download_to_afp", - data={ - "url": url, - }, - ) - - response_data = response.json() - - assert response.status_code == 200 - assert response_data["status"] == STATUS_SUCCESS - assert response_data["messages"][0]["message"] == f"{file_name} downloaded to {AFP_DIR}" - - -# route("/files/download_to_images", methods=["POST"]) -def test_download_url_to_images_dir(httpserver, http_client, list_files, delete_file): +# route("/files/download_url", methods=["POST"]) +def test_download_url_to_dir(httpserver, http_client, list_files, delete_file): file_name = str(uuid.uuid4()) http_path = f"/images/{file_name}" url = httpserver.url_for(http_path) @@ -251,8 +227,9 @@ def test_download_url_to_images_dir(httpserver, http_client, list_files, delete_ ) response = http_client.post( - "/files/download_to_images", + "/files/download_url", data={ + "destination": "images", "url": url, }, )