File size: 3,797 Bytes
aa27d2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
817ad83
0edd56d
 
 
aa27d2d
 
 
 
 
 
 
0edd56d
 
aa27d2d
817ad83
0edd56d
 
817ad83
0edd56d
3bf6386
aa27d2d
 
 
 
 
0edd56d
 
aa27d2d
0edd56d
 
817ad83
 
 
 
 
0edd56d
 
 
 
 
 
 
 
 
817ad83
 
 
 
 
 
 
0edd56d
817ad83
aa27d2d
 
 
67264dd
 
 
3bf6386
aa27d2d
 
3bf6386
aa27d2d
 
0edd56d
 
 
 
 
817ad83
 
0edd56d
aa27d2d
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import time
import uuid
from sqlalchemy.orm import Session
from app.models.file_model import File
from app.ai.nsfw_detector import detect_ai_image
from app.ai.frequency_detector import frequency_score
from app.ai.cnn_detector import cnn_artifact_score
from app.ai.hybrid_detector import hybrid_decision
from app.ai.meta_classifier import predict_ai
from app.ai.explainer import generate_heatmap
from app.ai.reasoning import generate_reasoning
from app.ai.model_loader import model_loader
from app.ai.feature_extractor import extract_features
from app.ai.attribution import generate_attribution
from app.ai.explanation_engine import generated_structured_explanation
from app.ai.explanation_formatter import format_explanation_with_llm
from app.ai.geometry_detector import analyze_perspective
from app.core.storage import active_storage
import os


def process_file(file_id: int, db: Session):
    file = db.query(File).filter(File.id == file_id).first()
    
    if not file:
        return
    
    local_path = active_storage.download_to_temp(file.filepath)

    safe_heatmap_name = f"{uuid.uuid4().hex}.png"
    safe_geometry_name = f"geom_{uuid.uuid4().hex}.png"
    os.makedirs("uploads/heatmaps", exist_ok=True)
    local_heatmap_path = f"uploads/heatmaps/{safe_heatmap_name}"
    local_geometry_path = f"uploads/heatmaps/{safe_geometry_name}"
    
    file.status = "PROCESSING"
    active_version = model_loader.get_latest_model_version()
    file.model_version_used = active_version
    db.commit()
    
    try:
        nsfw_result = detect_ai_image(local_path)
        features = extract_features(local_path)
        label, prob = predict_ai(features["frequency_score"], features["cnn_score"])
        attribution_data = generate_attribution(local_path, local_heatmap_path)
        
        # Geometry Perspective Analysis
        geom_result = analyze_perspective(local_path, local_geometry_path)
        features["geometry_score"] = geom_result["score"]
        features["geometry_message"] = geom_result["message"]
        
        class MockFile:
            def __init__(self, f):
                self.file = f
                self.content_type = "image/png"
                
        with open(local_heatmap_path, "rb") as hf:
            mock_hf = MockFile(hf)
            r2_heatmap_key = active_storage.save(mock_hf, f"heatmaps/{safe_heatmap_name}")
            
        if os.path.exists(local_geometry_path):
            with open(local_geometry_path, "rb") as gf:
                mock_gf = MockFile(gf)
                r2_geometry_key = active_storage.save(mock_gf, f"heatmaps/{safe_geometry_name}")
            file.geometry_path = r2_geometry_key
        
        file.geometry_score = geom_result["score"]
        file.heatmap_path = r2_heatmap_key
        
        structured_reasoning = generated_structured_explanation(features, prob)
        natural_reasoning = format_explanation_with_llm(structured_reasoning)
            
        file.result = f"{label}\nFREQ:{features['frequency_score']:.2f}\nCNN:{features['cnn_score']:.2f}\nNSFW: {nsfw_result}"
        file.confidence = float(prob * 100)
        file.ai_explanation = natural_reasoning
        file.status = "COMPLETED"
        
    except Exception as e:
        file.status = "FAILED"
        file.result = str(e)
        
    finally:
        if 'local_path' in locals() and os.path.exists(local_path) and getattr(active_storage, '__class__').__name__ == "R2StorageProvider":
            os.remove(local_path)
        if 'local_heatmap_path' in locals() and os.path.exists(local_heatmap_path):
            os.remove(local_heatmap_path)
        if 'local_geometry_path' in locals() and os.path.exists(local_geometry_path):
            os.remove(local_geometry_path)
            
    db.commit()
    db.close()