Forum Archive

Share code: Serving files over HTTP

Webmaster4o

Note: This has been done before, but there were a few improvements I wanted to make to what had been done before.

This script is an editor action, called "Serve Files." It has three improvements over existing implementations:
- Serve every file from the directory of your script at its filename
- Serve a zip of the entire directory in which your script is contained at /. This is useful for copying a lot of files to a computer at once
- Printing your local IP to the console, to make it easier to see where you should go on your computer

It will also clean up the zip it creates after you stop the server.

Here's the script:

import os
import shutil
import socket
import urllib.parse

import dialogs
import editor
import flask


# SETUP


# Resolve local IP by connecting to Google's DNS server
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
localip = s.getsockname()[0]
s.close()


# Initialize Flask
app = flask.Flask(__name__)

# Calculate path details
directory, filename = os.path.split(editor.get_path())
dirpath, dirname = os.path.split(directory.rstrip("/"))
zippath = os.path.abspath("./{}.zip".format(dirname))

# Make an archive
shutil.make_archive(dirname, "zip", dirpath, dirname)


# Configure server routings
@app.route("/")
def index():
    """Serve a zip of it all from the root"""
    return flask.send_file(zippath)


@app.route("/<path:path>")
def serve_file(path):
    """Serve individual files from elsewhere"""
    return flask.send_from_directory(directory, path)

# Run the app
print("Running at {}".format(localip))
app.run(host="0.0.0.0", port=80)

# After it finishes
os.remove(zippath)
mpvano

Hi:

Thanks very much for this - it's cute and looks very useful. As a new Python programmer, I'm amazed at the power of the Flask library and am studying its manual closely at the moment.

No problem installing and running the script on the latest Pythonista - I do have one practical problem using the script however:

The file downloaded on connection to my macbook pro running OSX 10.11.5 Safari takes on the name of the url of the connection - in my case "mpv-ipad.local", since the URL I used to connect used Bonjour.

I had to manually rename it with a .zip extension before it could be recognized and opened. Shouldn't there be an easy way to get the server to provide a header that results in the correct filetype (and hopefully filename as well) being downloaded?

thanks...

M

Webmaster4o

I think Flask tries to get the Content-Type correct, but I'm not sure if there's a header for forcing download. I'll look into it. 👍