aboutsummaryrefslogtreecommitdiffstats
path: root/shareit/shareit.py
diff options
context:
space:
mode:
Diffstat (limited to 'shareit/shareit.py')
-rwxr-xr-xshareit/shareit.py98
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')