Skip to content

Instantly share code, notes, and snippets.

@dragoncoder047
Last active October 7, 2023 21:12
Show Gist options
  • Select an option

  • Save dragoncoder047/d8a983552c25d6d1aca7cef8a070db58 to your computer and use it in GitHub Desktop.

Select an option

Save dragoncoder047/d8a983552c25d6d1aca7cef8a070db58 to your computer and use it in GitHub Desktop.
Airdrop for non-Apple users
#! /usr/bin/env python3
from flask import Flask, request, send_file, abort
from os import walk, sep, makedirs, getpid
from os.path import exists, basename
from werkzeug.utils import secure_filename
from subprocess import Popen
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def index():
new_files = []
message = ''
errors = ''
if request.method == 'POST':
count = 0
dirscreated = 0
errcount = 0
for file in request.files.getlist('files') + request.files.getlist('folders'):
name = file.filename.replace('/..', '_')
try:
try:
file.save(name)
new_files.append(name)
except FileNotFoundError:
if sep not in name:
raise
path, _ = name.rsplit(sep, 1)
makedirs(path)
file.save(name)
new_files.append(name.rsplit(sep, 1)[1])
dirscreated += name.count(sep)
except Exception as e:
errors += f'<li>{file.filename} &rarr; <tt>{type(e).__name__}: {e!s}</tt></li>\n'
errcount += 1
else:
count += 1
if count > 0:
message += f'{count} files uploaded. '
if dirscreated > 0:
message += f'{dirscreated} folders created. '
if errors:
errors = f'<details class="err"><summary>{errcount} errors</summary><ul>{errors}</ul></details>'
files_list = ''
tab = '<span class="bar">|</span> '
for root, dirs, files in walk('.'):
tabs = root.count(sep)
folder = basename(root)
if not folder:
folder = root[:-1]
else:
tabs += 1
folder = folder.replace('/./', '/')
files_list += f'{tab*(tabs-1)}{folder}/\n'
tabs += 1
for file in files:
files_list += f'{tab*(tabs-1)}<a href="/{folder}/{file}" download="{file}"'
if file in new_files:
files_list += ' class="hl"'
files_list += f'>{file}</a>\n'
return f'''
<!DOCTYPE html><html><head><title>Airdrop</title>
<style>.hl{{background-color:yellow}}.err{{color:red}}details{{border:1px solid red}}.bar{{opacity:50%}}</style></head>
<body>
<form action="/" enctype="multipart/form-data" method="POST">
Folders: <input type="file" name="files" multiple directory webkitdirectory></input><br>
Files: <input type="file" name="folders" multiple></input><br>
<input type="submit" value="Upload"></input>
</form>
<p><a href="/__EXIT__">Stop server</a></p>
{errors}
<p class="hl">{message}</p>
<pre>{files_list}</pre>
</body></html>'''
@app.route('/favicon.ico')
def icon():
abort(404)
@app.route('/<path:path>')
def send(path):
return send_file(path.lstrip('/'))
@app.route('/__EXIT__')
def stop():
Popen(["sh", "-c", f"sleep 0.75; kill {getpid()}"])
return """<!DOCTYPE html><html>
<head><meta http-equiv="refresh" content="1; url=/" /></head>
<body><h1>Server stopped.</h1></body></html>"""
if __name__ == '__main__':
app.run('192.168.1.158', 4443)

Setup

  1. Make sure you have Flask installed.
  2. Save airdrop.py inside its own folder.
  3. That's literally it!

Don't put it in a folder with a lot of stuff, it will bog down.

Sending files to another device

  1. Put the files you want to send in the same folder or a subfolder as airdrop.py.
  2. Run airdrop.py in its directory (i.e. cd into the directory, then python3 airdrop.py. Or you can open it in IDLE and press F5.)
  3. Go to http://192.168.1.158:4443/ on the other device. It will show you all the files you put in the folder.
  4. Click on each file you want to download.

Recieving files from another device

  1. Run airdrop.py in the same way as above.
  2. Go to http://192.168.1.158:4443/ on the other device.
  3. Click 'Choose...' on the files or folders button to pick files.
  4. Click 'upload' to send them to the other computer. It will tell you if any problems occurred.
  5. The files will now be in the folder alongside airdrop.py.

VERY IMPORTANT

Always stop airdrop.py running when you are finished sending files. If you leave it running it will allow anyone on the same network to mess with those files!

The files list page generated has a link for "Stop server", you can click on it to remotely kill the process (as opposed to having to press Ctrl+C on the remote computer.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment