aboutsummaryrefslogtreecommitdiffstats
path: root/shareit/shareit.py
blob: d8d05251e9b61b954a917380f7615c0da0c627e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/usr/bin/python3

import bottle
import hashlib
import io
import jinja2
import json
import os
from pathlib import Path


DEV_FILES_DIR = '/tmp/files'
PROD_FILES_DIR = '/files'
FILES_DIR = PROD_FILES_DIR


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 = 'https://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
    os.makedirs(FILES_DIR, mode=0755)
    bottle.run(host='0.0.0.0', port=8080, debug=True)
else:
    print('I: Starting shareit application as module or wsgi application')