import os import re import hashlib import time from pathlib import Path from flask import Flask, render_template, request from flask_dropzone import Dropzone enabled_filetypes = ['txt', 'csv', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'] regex_email = re.compile('^[a-z0-9]+[\._]?[a-z0-9]+[@]\w+[.]\w{2,3}$') basedir = Path(__file__).resolve().parent upload_dir = basedir / 'uploads' if not upload_dir.exists: upload_dir.mkdir() app = Flask(__name__) app.config.update( UPLOADED_PATH = upload_dir, MAX_CONTENT_LENGTH = 1000000000 # 1GB ) dropzone = Dropzone(app) @app.route('/') def index(): return render_template('index.html') @app.route('/upload', methods=['POST']) def handle_upload(): files = request.files if len(files) > 20: return 'Naložite lahko do 20 datotek hkrati.', 400 elif len(files) < 1: return 'Priložena ni bila nobena datoteka.', 400 err = check_suffixes(files) if err: return err, 400 err = check_form(request.form) if err: return err, 400 file_hashes = create_file_hashes(files) store_metadata(request.form, file_hashes) store_datafiles(files, file_hashes) return 'Uspešno ste oddali datotek(e). Št. datotek: {}'.format(len(files)) def check_suffixes(files): for key, f in files.items(): if key.startswith('file'): suffix = f.filename.split('.')[-1] if suffix not in enabled_filetypes: return 'Datoteka "{}" ni pravilnega formata.'.format(f.filename) return None def check_form(form): tip = form.get('tip') ime = form.get('ime') podjetje = form.get('podjetje') email = form.get('email') telefon = form.get('telefon') if tip not in ['enojez', 'prevodi']: return 'Napačen tip besedila.' if len(ime) > 100: return 'Predolgo ime.' if len(podjetje) > 100: return 'Predolgo ime institucije' if len(email) > 100: return 'Predolgi email naslov' elif not re.search(regex_email, email): return 'Email napačnega formata.' if len(telefon) > 100: return 'Predolga telefonska št.' return None def create_file_hashes(files): res = dict() for key, f in files.items(): if key.startswith('file'): h = hashlib.md5(f.filename.encode()) h.update(f.stream.read()) res[key] = h.hexdigest() f.seek(0) return res def store_metadata(form, file_hashes): base = app.config['UPLOADED_PATH'] / 'meta' if not base.exists(): base.mkdir() tip = form.get('tip') ime = form.get('ime') podjetje = form.get('podjetje') email = form.get('email') telefon = form.get('telefon') # This hash serves as an identifier for the whole upload. metahash = hashlib.md5((tip+ime+podjetje+email+telefon).encode()) # Include file hashes to avoid metafile name collisions if they have the same form values, # but different data files. Sort hashes first so upload order doesn't matter. sorted_f_hashes = list(file_hashes.values()) sorted_f_hashes.sort() metahash.update(''.join(sorted_f_hashes).encode()) metahash = metahash.hexdigest() timestamp = int(time.time()) filename = str(timestamp) + '-' + email + '-' + metahash + '.meta' path = base / filename with path.open('w') as f: f.write('tip=' + tip) f.write('\nime=' + ime) f.write('\npodjetje=' + podjetje) f.write('\nemail=' + email) f.write('\ndatoteke=' + str(sorted_f_hashes)) def store_datafiles(files, file_hashes): base = app.config['UPLOADED_PATH'] / 'files' if not base.exists(): base.mkdir() for key, f in files.items(): if key.startswith('file'): path = base / file_hashes[key] if not path.exists(): path.mkdir() f.save(path / f.filename) if __name__ == '__main__': app.run(debug=True)