From 060216d381d28c34cd603dbed63d58ea6f63c6ed Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Thu, 12 Mar 2026 19:31:54 +0100 Subject: [PATCH] feat: implement downloading from s3 --- server.py | 30 +++++++++++++++++++++++++++++- templates/datatable.html | 2 +- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/server.py b/server.py index 86b6256..5dc962e 100755 --- a/server.py +++ b/server.py @@ -17,6 +17,9 @@ import sqlalchemy from sqlalchemy import Column, Integer, String, Boolean, or_, and_, asc, desc from flask_sqlalchemy import SQLAlchemy +import os +from flask import send_from_directory, abort + app = flask.Flask("TM Friends Replay Server") app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False @@ -222,7 +225,7 @@ class ParsedReplay(db.Model): def to_dict(self): d = dict() d.update({ "login" : self.login }) - d.update({ "filehash" : self.login }) + d.update({ "filehash" : self.filehash }) d.update({ "race_time" : self.get_human_readable_time() }) d.update({ "filepath" : self.filepath }) d.update({ "upload_dt" : self.upload_dt }) @@ -597,6 +600,31 @@ def check_replay_trigger(replay): if settings and settings.notifications_self: notifications.send_notification(app, settings.user, map_obj.map_uid, second, replay) +@app.route("/downloads/") +def downloads(filename): + + # Ensure directory exists + os.makedirs("uploads", exist_ok=True) + local_path = os.path.join("uploads/", filename) + + if not os.path.isfile(local_path): + print(f"{local_path} missing, attempting to retrieve from S3") + s3 = get_s3_client() + + try: + s3.download_file( + S3_BUCKET, + f"{filename}", + os.path.join("uploads/", filename) + ) + + except Exception: + print(f"{filename} not found on S3") + abort(404) + + print(f"Sending {filename}") + return send_from_directory("uploads/", filename) + def create_app(): db.create_all() diff --git a/templates/datatable.html b/templates/datatable.html index 64584a0..ab8475e 100644 --- a/templates/datatable.html +++ b/templates/datatable.html @@ -37,7 +37,7 @@ { "targets": 3, "render": function ( data, type, full, meta ) { - return 'Download'; + return 'Download'; } }, {