aboutsummaryrefslogtreecommitdiffstats
path: root/shareit
diff options
context:
space:
mode:
authorVG <vg@devys.org>2015-01-28 18:45:29 +0100
committerVG <vg@devys.org>2015-01-28 18:45:29 +0100
commit12240fb74c0c6f2768e1070f849cd265ea3dd181 (patch)
tree6f5cb93e0e020bd918e015aba164e90db1fd0739 /shareit
downloadshareit-12240fb74c0c6f2768e1070f849cd265ea3dd181.tar.gz
shareit-12240fb74c0c6f2768e1070f849cd265ea3dd181.tar.bz2
shareit-12240fb74c0c6f2768e1070f849cd265ea3dd181.zip
First commit
Diffstat (limited to 'shareit')
-rwxr-xr-xshareit/purge.sh4
-rwxr-xr-xshareit/shareit.py98
-rw-r--r--shareit/static/favicon.icobin0 -> 360414 bytes
-rw-r--r--shareit/static/robots.txt0
-rw-r--r--shareit/templates/base.html12
-rw-r--r--shareit/templates/propose_upload.html21
-rw-r--r--shareit/templates/upload.html33
7 files changed, 168 insertions, 0 deletions
diff --git a/shareit/purge.sh b/shareit/purge.sh
new file mode 100755
index 0000000..961cbb1
--- /dev/null
+++ b/shareit/purge.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+find /files/ -type f -mtime +10 ! -name '*.meta' \
+ -exec rm {} \; -exec rm {}.meta \;
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')
diff --git a/shareit/static/favicon.ico b/shareit/static/favicon.ico
new file mode 100644
index 0000000..93f8a23
--- /dev/null
+++ b/shareit/static/favicon.ico
Binary files differ
diff --git a/shareit/static/robots.txt b/shareit/static/robots.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/shareit/static/robots.txt
diff --git a/shareit/templates/base.html b/shareit/templates/base.html
new file mode 100644
index 0000000..85e840f
--- /dev/null
+++ b/shareit/templates/base.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<html>
+<head>
+ <title>{% block title %}Home{% endblock %} - Shareit</title>
+ <link rel="icon" sizes="256 128 64 32 16" href="/favicon.ico" />
+ <link rel="icon" type="image/x-icon" href="/favicon.ico" />
+ <link rel="icon" href="/favicon.ico" />
+</head>
+<body>
+ {% block content %}{% endblock %}
+</body>
+</html>
diff --git a/shareit/templates/propose_upload.html b/shareit/templates/propose_upload.html
new file mode 100644
index 0000000..c3c8bb9
--- /dev/null
+++ b/shareit/templates/propose_upload.html
@@ -0,0 +1,21 @@
+{% extends "base.html" %}
+{% block title %}
+{% if lang == 'en' %}Upload{% else %}Dépôt{% endif %}
+{% endblock %}
+{% block content %}
+<form action="/upload/" method="post" enctype="multipart/form-data">
+
+<p>
+ {% if lang == 'en' %}
+ <label for="browse_file">Select your file:</label>
+ {% else %}
+ <label for="browse_file">Sélectionnez votre fichier:</label>
+ {% endif %}
+
+ <input type="file" id="browse_file" name="upload" />
+
+ <input type="submit" />
+</p>
+
+</form>
+{% endblock content %}
diff --git a/shareit/templates/upload.html b/shareit/templates/upload.html
new file mode 100644
index 0000000..5d9fb31
--- /dev/null
+++ b/shareit/templates/upload.html
@@ -0,0 +1,33 @@
+{% extends "base.html" %}
+{% block title
+%}{% if lang == 'en'
+ %}Correctly uploaded{%
+else
+ %}Téléchargé correctement{%
+endif %}{% endblock %}
+{% block content %}
+{% if lang == 'en' %}
+<p>
+ Your file was correctly uploaded. <br />
+ It will be available for 10 days. <br />
+ To share it with others, use this link:
+ <a href="{{link}}" >{{link}}</a> <br />
+ You can check the integrity of your download with the md5 hash: {{digest}}
+</p>
+<p>
+ <a href="/">Go back to the upload form</a>
+</p>
+{% else %}
+<p>
+ Votre fichier a correctement été enregistré sur le serveur. <br />
+ Il sera disponible pendant 10 jours. <br />
+ Pour le partager avec d'autres personnes, utilisez ce lien:
+ <a href="{{link}}" >{{link}}</a> <br />
+ Vous pouvez vérifier l'intégrité de votre téléchargement via la somme md5
+ suivante: {{digest}}
+</p>
+<p>
+ <a href="/">Revenir sur le formulaire d'envoi de fichiers</a>
+</p>
+{% endif %}
+{% endblock %}