|
1 | 1 | import datetime
|
2 | 2 | import difflib
|
3 | 3 | import logging
|
| 4 | +import io |
4 | 5 | import os
|
5 | 6 | import shutil
|
6 | 7 | import tempfile
|
| 8 | +import time |
| 9 | +import zipfile |
7 | 10 |
|
8 | 11 | from bokeh.embed import components
|
9 | 12 |
|
|
15 | 18 | from flask import render_template
|
16 | 19 | from flask import request
|
17 | 20 | from flask import send_from_directory
|
| 21 | +from flask import send_file |
18 | 22 |
|
19 | 23 | from wtforms import StringField
|
20 | 24 | from wtforms.widgets import TextArea
|
@@ -992,3 +996,42 @@ def toggle_competition(submission_hash):
|
992 | 996 | return redirect(
|
993 | 997 | '/{}/{}'.format(submission_hash, submission.files[0].f_name)
|
994 | 998 | )
|
| 999 | + |
| 1000 | + |
| 1001 | +@mod.route("/download/<submission_hash>") |
| 1002 | +@flask_login.login_required |
| 1003 | +def download_submission(submission_hash): |
| 1004 | + """Download a submission from the server. |
| 1005 | +
|
| 1006 | + Parameters |
| 1007 | + ---------- |
| 1008 | + submission_hash : str |
| 1009 | + The submission hash of the current submission. |
| 1010 | + """ |
| 1011 | + submission = (Submission.query.filter_by(hash_=submission_hash) |
| 1012 | + .one_or_none()) |
| 1013 | + if submission is None: |
| 1014 | + error_str = 'Missing submission: {}'.format(submission_hash) |
| 1015 | + return redirect_to_user(error_str) |
| 1016 | + |
| 1017 | + access_code = is_accessible_code( |
| 1018 | + db.session, submission.event_team.event.name, |
| 1019 | + flask_login.current_user.name, submission.id |
| 1020 | + ) |
| 1021 | + if not access_code: |
| 1022 | + error_str = 'Unauthorized access: {}'.format(submission_hash) |
| 1023 | + return redirect_to_user(error_str) |
| 1024 | + |
| 1025 | + file_in_memory = io.BytesIO() |
| 1026 | + with zipfile.ZipFile(file_in_memory, 'w') as zf: |
| 1027 | + for ff in submission.files: |
| 1028 | + data = zipfile.ZipInfo(ff.f_name) |
| 1029 | + data.date_time = time.localtime(time.time())[:6] |
| 1030 | + data.compress_type = zipfile.ZIP_DEFLATED |
| 1031 | + zf.writestr(data, ff.get_code()) |
| 1032 | + file_in_memory.seek(0) |
| 1033 | + return send_file( |
| 1034 | + file_in_memory, |
| 1035 | + attachment_filename=f"submission_{submission.id}.zip", |
| 1036 | + as_attachment=True, |
| 1037 | + ) |
0 commit comments