Ensure uploaded images are permanently stored in object storage

Integrates Replit Object Storage for persistent file uploads, replacing ephemeral local storage and adding `google-cloud-storage` dependency.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: cd9a7d26-a4e5-4215-975c-c59f4ed1f06d
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 093bebfc-3b06-4716-8c6a-2dea6a89816d
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d0a1d46d-d203-4308-bc6a-312ac7c0243b/cd9a7d26-a4e5-4215-975c-c59f4ed1f06d/D3TcT39
This commit is contained in:
abhiramtx
2025-11-13 05:36:58 +00:00
parent 01623ac850
commit f4d32ff9ee
7 changed files with 740 additions and 22 deletions

64
app.py
View File

@@ -4,6 +4,7 @@ from psycopg2.extras import RealDictCursor
from flask import Flask, render_template, request, redirect, url_for, session, flash, jsonify
from werkzeug.utils import secure_filename
from datetime import datetime
from object_storage import ObjectStorageService
app = Flask(__name__)
app.secret_key = os.environ.get('SECRET_KEY', 'techturb-secret-key-change-in-production')
@@ -12,10 +13,38 @@ app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
ADMIN_PASSWORD = 'techturb123'
# Initialize Object Storage Service
try:
storage_service = ObjectStorageService()
USING_OBJECT_STORAGE = True
except ValueError as e:
print(f"Warning: Object Storage not configured - {e}")
print("Files will be saved locally (ephemeral storage)")
storage_service = None
USING_OBJECT_STORAGE = False
def get_db_connection():
conn = psycopg2.connect(os.environ['DATABASE_URL'])
return conn
def upload_file_to_storage(file, folder='uploads'):
"""
Upload file to object storage if available, otherwise fall back to local storage
Returns the file path/URL
"""
if not file or not file.filename:
return None
if USING_OBJECT_STORAGE and storage_service:
# Upload to persistent object storage
return storage_service.upload_file(file, folder)
else:
# Fallback to local storage (ephemeral)
filename = secure_filename(file.filename)
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(filepath)
return f'images/{filename}'
@app.route('/')
@app.route('/home')
def home():
@@ -155,13 +184,13 @@ def add_member():
role = request.form.get('role')
member_type = request.form.get('type')
# Upload image to object storage
image_path = 'images/default.jpg'
if 'image' in request.files:
file = request.files['image']
if file and file.filename:
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
image_path = f'images/{filename}'
uploaded_path = upload_file_to_storage(file, folder='members')
if uploaded_path:
image_path = uploaded_path
conn = get_db_connection()
cur = conn.cursor()
@@ -189,13 +218,11 @@ def update_member():
conn = get_db_connection()
cur = conn.cursor()
# Upload image to object storage
image_path = None
if 'image' in request.files:
file = request.files['image']
if file and file.filename:
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
image_path = f'images/{filename}'
image_path = upload_file_to_storage(file, folder='members')
if member_type == 'mentor':
if image_path:
@@ -259,13 +286,11 @@ def add_competition():
awards_raw = request.form.get('awards')
awards = '|'.join([line.strip() for line in awards_raw.split('\n') if line.strip()])
# Upload image to object storage
image_path = None
if 'image' in request.files:
file = request.files['image']
if file and file.filename:
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
image_path = f'images/{filename}'
image_path = upload_file_to_storage(file, folder='competitions')
conn = get_db_connection()
cur = conn.cursor()
@@ -297,13 +322,12 @@ def edit_competition():
current_comp = cur.fetchone()
image_path = current_comp['image_path'] if current_comp else None
# Handle new image upload
# Handle new image upload to object storage
if 'image' in request.files:
file = request.files['image']
if file and file.filename:
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
image_path = f'images/{filename}'
uploaded_path = upload_file_to_storage(file, folder='competitions')
if uploaded_path:
image_path = uploaded_path
# Update competition
cur.execute('''UPDATE competitions
@@ -350,13 +374,11 @@ def add_sponsor():
name = request.form.get('name')
website_url = request.form.get('website_url')
# Upload logo to object storage
logo_path = None
if 'logo' in request.files:
file = request.files['logo']
if file and file.filename:
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
logo_path = f'images/{filename}'
logo_path = upload_file_to_storage(file, folder='sponsors')
conn = get_db_connection()
cur = conn.cursor()