# backend/routes/cases.py import os from flask import Blueprint, request, jsonify, current_app from werkzeug.utils import secure_filename from datetime import datetime from ..db import get_db_connection, release_db_connection cases_blueprint = Blueprint('cases', __name__) # Helper to serialize case rows def serialize_case(row): return { "id": row[0], "violator_url": row[1], "violator_article": row[2], "my_article": row[3], "comment": row[4], "status": row[5], "created_at": row[6].isoformat() if row[6] else None, "updated_at": row[7].isoformat() if row[7] else None, } # ---------- CASE CRUD ---------- @cases_blueprint.route('/cases', methods=['GET']) def list_cases(): # optional filters: ?article=...&status=... article = request.args.get('article') status = request.args.get('status') conn = get_db_connection() cur = conn.cursor() query = "SELECT * FROM cases" params = [] conditions = [] if article: conditions.append("violator_article = %s") params.append(article) if status: conditions.append("status = %s") params.append(status) if conditions: query += " WHERE " + " AND ".join(conditions) cur.execute(query, params) rows = cur.fetchall() release_db_connection(conn) return jsonify([serialize_case(r) for r in rows]) @cases_blueprint.route('/cases', methods=['POST']) def create_case(): data = request.json required = ["violator_url", "violator_article"] for f in required: if f not in data: return jsonify({"error": f"Missing field {f}"}), 400 conn = get_db_connection() cur = conn.cursor() cur.execute( """INSERT INTO cases (violator_url, violator_article, my_article, comment, status) VALUES (%s, %s, %s, %s, %s) RETURNING id""", ( data.get('violator_url'), data.get('violator_article'), data.get('my_article'), data.get('comment'), data.get('status', 'new') ) ) case_id = cur.fetchone()[0] conn.commit() release_db_connection(conn) return jsonify({"id": case_id}), 201 @cases_blueprint.route('/cases/', methods=['GET']) def get_case(case_id): conn = get_db_connection() cur = conn.cursor() cur.execute("SELECT * FROM cases WHERE id = %s", (case_id,)) row = cur.fetchone() release_db_connection(conn) if not row: return jsonify({"error": "Case not found"}), 404 return jsonify(serialize_case(row)) @cases_blueprint.route('/cases/', methods=['PUT']) def update_case(case_id): data = request.json fields = [] params = [] allowed = ["violator_url", "violator_article", "my_article", "comment", "status"] for f in allowed: if f in data: fields.append(f"{f} = %s") params.append(data[f]) if not fields: return jsonify({"error": "No updatable fields provided"}), 400 params.append(case_id) conn = get_db_connection() cur = conn.cursor() cur.execute(f"UPDATE cases SET {', '.join(fields)}, updated_at = %s WHERE id = %s", (*params[:-1], datetime.utcnow(), case_id)) conn.commit() release_db_connection(conn) return jsonify({"message": "Case updated"}) @cases_blueprint.route('/cases/', methods=['DELETE']) def delete_case(case_id): conn = get_db_connection() cur = conn.cursor() cur.execute("DELETE FROM cases WHERE id = %s", (case_id,)) conn.commit() release_db_connection(conn) return jsonify({"message": "Case deleted"}) # ---------- FILE UPLOAD ---------- @cases_blueprint.route('/cases//files', methods=['POST']) def upload_files(case_id): if 'files' not in request.files: return jsonify({"error": "No files part in request"}), 400 files = request.files.getlist('files') saved_paths = [] upload_folder = current_app.config['UPLOAD_FOLDER'] conn = get_db_connection() cur = conn.cursor() for f in files: if f.filename == '': continue filename = secure_filename(f.filename) timestamp = datetime.utcnow().strftime('%Y%m%d%H%M%S%f') unique_name = f"{timestamp}_{filename}" file_path = os.path.join(upload_folder, unique_name) f.save(file_path) # store relative path in DB rel_path = os.path.relpath(file_path, start=os.path.dirname(os.path.abspath(__file__))) cur.execute( "INSERT INTO files (case_id, file_path) VALUES (%s, %s) RETURNING id", (case_id, rel_path) ) saved_paths.append(rel_path) conn.commit() release_db_connection(conn) return jsonify({"files": saved_paths}), 201 # Get files for a case @cases_blueprint.route('/cases//files', methods=['GET']) def list_files(case_id): conn = get_db_connection() cur = conn.cursor() cur.execute("SELECT id, file_path, uploaded_at FROM files WHERE case_id = %s", (case_id,)) rows = cur.fetchall() release_db_connection(conn) files = [{"id": r[0], "path": r[1], "uploaded_at": r[2].isoformat()} for r in rows] return jsonify(files)