File size: 5,055 Bytes
8de5b21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
from supabase import create_client, Client
from typing import Optional
import logging

from app.config.settings import settings
from app.db.models import NarratorExtractionRecord, NarratorAnalysisRecord


class DatabaseService:
    """Service for database operations with Supabase."""
    
    def __init__(self):
        self.logger = logging.getLogger(__name__)
        self.supabase: Optional[Client] = None
        
        if settings.SUPABASE_URL and settings.SUPABASE_SERVICE_KEY:
            try:
                self.supabase = create_client(
                    settings.SUPABASE_URL, 
                    settings.SUPABASE_SERVICE_KEY
                )
            except Exception as e:
                self.logger.error(f"Failed to initialize Supabase client: {e}")

    async def store_extraction_record(self, record: NarratorExtractionRecord) -> Optional[str]:
        """Store narrator extraction record in database."""
        if not self.supabase:
            self.logger.warning("Supabase client not available, skipping database storage")
            return None
        
        try:
            # Convert record to dict, excluding None id
            record_dict = record.dict(exclude_none=True)
            if "id" in record_dict and record_dict["id"] is None:
                del record_dict["id"]
            
            # Convert datetime objects to ISO strings
            if record.created_at:
                record_dict["created_at"] = record.created_at.isoformat()
            
            response = self.supabase.table("narrator_extractions").insert(record_dict).execute()
            
            if response.data:
                return response.data[0]["id"]
            else:
                self.logger.error("No data returned from extraction record insertion")
                return None
                
        except Exception as e:
            self.logger.error(f"Error storing extraction record: {e}")
            return None

    async def store_analysis_record(self, record: NarratorAnalysisRecord) -> Optional[str]:
        """Store narrator analysis record in database."""
        if not self.supabase:
            self.logger.warning("Supabase client not available, skipping database storage")
            return None
        
        try:
            # Convert record to dict, excluding None id
            record_dict = record.dict(exclude_none=True)
            if "id" in record_dict and record_dict["id"] is None:
                del record_dict["id"]
            
            # Convert datetime objects to ISO strings
            if record.created_at:
                record_dict["created_at"] = record.created_at.isoformat()
            
            response = self.supabase.table("narrator_analyses").insert(record_dict).execute()
            
            if response.data:
                return response.data[0]["id"]
            else:
                self.logger.error("No data returned from analysis record insertion")
                return None
                
        except Exception as e:
            self.logger.error(f"Error storing analysis record: {e}")
            return None

    async def get_user_extractions(self, user_id: str, limit: int = 50) -> list:
        """Get user's extraction history."""
        if not self.supabase:
            return []
        
        try:
            response = self.supabase.table("narrator_extractions").select("*").eq("user_id", user_id).order("created_at", desc=True).limit(limit).execute()
            return response.data or []
        except Exception as e:
            self.logger.error(f"Error fetching user extractions: {e}")
            return []

    async def get_user_analyses(self, user_id: str, limit: int = 50) -> list:
        """Get user's analysis history."""
        if not self.supabase:
            return []
        
        try:
            response = self.supabase.table("narrator_analyses").select("*").eq("user_id", user_id).order("created_at", desc=True).limit(limit).execute()
            return response.data or []
        except Exception as e:
            self.logger.error(f"Error fetching user analyses: {e}")
            return []

    async def get_extraction_stats(self) -> dict:
        """Get extraction statistics."""
        if not self.supabase:
            return {}
        
        try:
            response = self.supabase.rpc("get_extraction_stats").execute()
            return response.data[0] if response.data else {}
        except Exception as e:
            self.logger.error(f"Error fetching extraction stats: {e}")
            return {}

    async def get_popular_narrators(self, limit: int = 10) -> list:
        """Get most analyzed narrators."""
        if not self.supabase:
            return []
        
        try:
            response = self.supabase.rpc("get_popular_narrators", {"limit_count": limit}).execute()
            return response.data or []
        except Exception as e:
            self.logger.error(f"Error fetching popular narrators: {e}")
            return []