diff options
Diffstat (limited to 'shareit/shareit.py')
-rwxr-xr-x | shareit/shareit.py | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/shareit/shareit.py b/shareit/shareit.py new file mode 100755 index 0000000..8f841d3 --- /dev/null +++ b/shareit/shareit.py @@ -0,0 +1,98 @@ +#!/usr/bin/python3 + +import bottle +import hashlib +import json +import io +import os +import jinja2 +import tempfile +from pathlib import Path + +#from bottle import Jinja2Template as Template +#from bottle import SimpleTemplate as Template + +DEV_FILES_DIR = '/tmp/files' +PROD_FILES_DIR = '/files' +FILES_DIR = PROD_FILES_DIR + +# load templates +#templates = {} +#for template in ['propose_upload', 'upload']: +# with open(Path('templates', template + '.html').as_posix(), 'r') as fi: +# templates[template] = Template(fi.read(), lookup='./templates/') +templates = jinja2.Environment( + loader=jinja2.FileSystemLoader('templates')) + +#app = application = bottle.Bottle() +# with line above, routing decorators then needs to be @app.route(...) +# app is optional, but smaller. If you use default_app instead and call +# bottle.route instead of application.route, app is not needed +application = bottle.default_app() # defines application used for wsgi mode + +CHUNK_SIZE = 1024*1024 + +valid_languages = ['en', 'fr'] +def get_language(): + headlang = bottle.request.headers.get('accept-language', 'en')[:2].lower() + if headlang in valid_languages: + return headlang + return valid_languages[0] + +@bottle.route('/') +@bottle.route('/propose_upload/') +def propose_upload(): + lang = get_language() + return templates.get_template('propose_upload.html').render(lang=lang) + +@bottle.route('/upload/', method='POST') +def upload_route(): + lang = get_language() + upload = bottle.request.files.get('upload') + fp = upload.file + md5 = hashlib.md5() + size = 0 + while True: + data = fp.read(CHUNK_SIZE) + if not data: + break + size += len(data) + md5.update(data) + if not size: + bottle.abort(400, 'File should not be empty') + digest = md5.hexdigest() + link = 'http://shareit.devys.org/download/{digest}'.format(digest=digest) + fp.seek(0) + filename = Path(FILES_DIR, digest) + upload.save(filename.as_posix(), overwrite=True) + with open(filename.as_posix() + '.meta', 'w') as fo: + fo.write(json.dumps({'filename': upload.raw_filename})) + return templates.get_template('upload.html').render( + link=link, digest=digest, lang=lang) + +@bottle.route('/download/<filename:re:[a-f0-9]{32}>') +def download(filename): + server_filename = Path(FILES_DIR, filename).as_posix() + meta_filename = server_filename + '.meta' + if os.path.exists(meta_filename): + with open(meta_filename, 'r') as fi: + raw_filename = json.loads(fi.read())['filename'] + return bottle.static_file(filename, root=FILES_DIR, + download=raw_filename, mimetype='binary') + abort(404, 'Requested file might have expired') + +@bottle.route('/favicon.ico') +def favicon(): + return bottle.static_file('favicon.ico', root='./static/') + +@bottle.route('/robot.txt') +def robot(): + return bottle.static_file('robot.txt', root='./static/') + +if __name__ == '__main__': + print('I: Starting shareit application as development server') + FILES_DIR = DEV_FILES_DIR + #bottle.run(host='0.0.0.0', port=8080) + bottle.run(host='0.0.0.0', port=8080, debug=True) +else: + print('I: Starting shareit application as module or wsgi application') |