|
3 | 3 | Flask application to serve Lua files for the Steam Lua Patcher desktop app. |
4 | 4 | """ |
5 | 5 |
|
6 | | -from flask import Flask, send_from_directory, jsonify, abort, request, Response |
| 6 | +from flask import Flask, send_from_directory, jsonify, abort, request, Response, send_file |
7 | 7 | import os |
8 | 8 | import json |
| 9 | +import io |
| 10 | +import zipfile |
9 | 11 | from datetime import datetime |
10 | 12 | from functools import wraps |
11 | 13 | from dotenv import load_dotenv |
@@ -229,6 +231,43 @@ def serve_index(): |
229 | 231 | abort(404, description="games_index.json not found. Run generate_index.py first.") |
230 | 232 |
|
231 | 233 |
|
| 234 | +@app.route('/api/free-download') |
| 235 | +def free_download(): |
| 236 | + """Download a game Lua file packaged as a ZIP archive""" |
| 237 | + app_id = request.args.get('appid') |
| 238 | + if not app_id: |
| 239 | + return jsonify({'error': 'Missing appid parameter'}), 400 |
| 240 | + |
| 241 | + # Clean app_id to prevent path traversal |
| 242 | + import re |
| 243 | + app_id = re.sub(r'[^0-9]', '', str(app_id)) |
| 244 | + |
| 245 | + filename = f"{app_id}.lua" |
| 246 | + file_path = os.path.join(GAMES_DIR, filename) |
| 247 | + |
| 248 | + if not os.path.exists(file_path): |
| 249 | + return jsonify({'error': f'Game patch {app_id} not found'}), 404 |
| 250 | + |
| 251 | + try: |
| 252 | + # Create ZIP in memory |
| 253 | + memory_file = io.BytesIO() |
| 254 | + with zipfile.ZipFile(memory_file, 'w', zipfile.ZIP_DEFLATED) as zf: |
| 255 | + zf.write(file_path, arcname=filename) |
| 256 | + |
| 257 | + memory_file.seek(0) |
| 258 | + |
| 259 | + return send_file( |
| 260 | + memory_file, |
| 261 | + mimetype='application/zip', |
| 262 | + as_attachment=True, |
| 263 | + download_name=f"{app_id}_patch.zip" |
| 264 | + ) |
| 265 | + except Exception as e: |
| 266 | + return jsonify({'error': 'Generation failed', 'message': str(e)}), 500 |
| 267 | + |
| 268 | + |
| 269 | + |
| 270 | + |
232 | 271 | @app.route('/api/check/<app_id>') |
233 | 272 | @require_token |
234 | 273 | def check_availability(app_id): |
|
0 commit comments