File size: 7,502 Bytes
9bc9525
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# modules/firebase_manager.py
"""
Firebase انٹیگریشن - ڈیٹا محفوظ کرنے کے لیے
"""

import os
import logging
from datetime import datetime
from typing import Optional, Dict, List

logger = logging.getLogger(__name__)

# Firebase کو conditional import کریں
try:
    import firebase_admin
    from firebase_admin import credentials, firestore
    FIREBASE_AVAILABLE = True
except ImportError:
    FIREBASE_AVAILABLE = False
    logger.warning("Firebase not installed. Running without database.")


class FirebaseManager:
    """Firebase Firestore کے ساتھ کام کرنے کے لیے"""
    
    _instance = None
    
    def __new__(cls):
        """Singleton pattern"""
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance._initialized = False
        return cls._instance
    
    def __init__(self):
        """Initialize Firebase"""
        if self._initialized:
            return
        
        self.enabled = False
        
        if not FIREBASE_AVAILABLE:
            logger.warning("Firebase SDK not available")
            self._initialized = True
            return
        
        try:
            # Hugging Face Spaces secrets سے credentials
            cred_dict = self._get_credentials_from_env()
            
            if cred_dict:
                cred = credentials.Certificate(cred_dict)
                
                if not firebase_admin._apps:
                    firebase_admin.initialize_app(cred)
                
                self.db = firestore.client()
                self.enabled = True
                logger.info("Firebase initialized successfully")
            else:
                logger.warning("Firebase credentials not found in environment")
            
        except Exception as e:
            logger.error(f"Firebase initialization failed: {e}")
            self.enabled = False
        
        self._initialized = True
    
    def _get_credentials_from_env(self) -> Optional[Dict]:
        """Environment variables سے credentials بنائیں"""
        
        required_vars = [
            'FIREBASE_PROJECT_ID',
            'FIREBASE_PRIVATE_KEY',
            'FIREBASE_CLIENT_EMAIL'
        ]
        
        # چیک کریں کہ سب variables موجود ہیں
        if not all(os.getenv(var) for var in required_vars):
            return None
        
        # Private key کو ٹھیک کریں (\\n کو \n میں)
        private_key = os.getenv('FIREBASE_PRIVATE_KEY', '')
        private_key = private_key.replace('\\n', '\n')
        
        cred_dict = {
            "type": "service_account",
            "project_id": os.getenv('FIREBASE_PROJECT_ID'),
            "private_key_id": os.getenv('FIREBASE_PRIVATE_KEY_ID', ''),
            "private_key": private_key,
            "client_email": os.getenv('FIREBASE_CLIENT_EMAIL'),
            "client_id": os.getenv('FIREBASE_CLIENT_ID', ''),
            "auth_uri": "https://accounts.google.com/o/oauth2/auth",
            "token_uri": "https://oauth2.googleapis.com/token",
            "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
            "client_x509_cert_url": os.getenv('FIREBASE_CLIENT_CERT_URL', '')
        }
        
        return cred_dict
    
    def save_essay_result(
        self,
        user_id: str,
        essay_data: Dict,
        grading_result: Dict
    ) -> Optional[str]:
        """
        مضمون کے نتائج محفوظ کریں
        
        Args:
            user_id: صارف کا ID
            essay_data: مضمون کی تفصیلات
            grading_result: جانچ کے نتائج
        
        Returns:
            Document ID یا None
        """
        if not self.enabled:
            logger.debug("Firebase not enabled, skipping save")
            return None
        
        try:
            doc_ref = self.db.collection('essays').document()
            
            data = {
                'user_id': user_id,
                'student_name': essay_data.get('student_name', 'Unknown'),
                'grade_level': essay_data.get('grade_level'),
                'essay_type': essay_data.get('essay_type'),
                'language': essay_data.get('language'),
                'word_count': essay_data.get('word_count', 0),
                'essay_text': essay_data.get('text', '')[:1000],
                'grading': {
                    'total_score': grading_result['total_score'],
                    'scores': grading_result['scores'],
                    'grade': grading_result['grade']
                },
                'created_at': firestore.SERVER_TIMESTAMP,
                'month': datetime.now().strftime('%Y-%m')
            }
            
            doc_ref.set(data)
            logger.info(f"Essay saved to Firebase: {doc_ref.id}")
            return doc_ref.id
            
        except Exception as e:
            logger.error(f"Failed to save to Firebase: {e}")
            return None
    
    def get_user_essays(
        self,
        user_id: str,
        limit: int = 20
    ) -> List[Dict]:
        """
        صارف کے مضامین حاصل کریں
        
        Args:
            user_id: صارف کا ID
            limit: زیادہ سے زیادہ تعداد
        
        Returns:
            مضامین کی فہرست
        """
        if not self.enabled:
            return []
        
        try:
            query = self.db.collection('essays')\
                .where('user_id', '==', user_id)\
                .order_by('created_at', direction=firestore.Query.DESCENDING)\
                .limit(limit)
            
            docs = query.stream()
            
            essays = []
            for doc in docs:
                data = doc.to_dict()
                data['id'] = doc.id
                essays.append(data)
            
            logger.info(f"Retrieved {len(essays)} essays for user {user_id}")
            return essays
            
        except Exception as e:
            logger.error(f"Failed to get essays: {e}")
            return []
    
    def check_monthly_limit(
        self,
        user_id: str,
        subscription: str = 'free'
    ) -> tuple:
        """
        ماہانہ حد چیک کریں
        
        Args:
            user_id: صارف کا ID
            subscription: 'free', 'basic', یا 'premium'
        
        Returns:
            (حد میں ہے؟, استعمال شدہ, باقی)
        """
        if not self.enabled:
            return (True, 0, 999)
        
        limits = {
            'free': 20,
            'basic': 100,
            'premium': 999999
        }
        
        max_essays = limits.get(subscription, 20)
        
        try:
            current_month = datetime.now().strftime('%Y-%m')
            
            query = self.db.collection('essays')\
                .where('user_id', '==', user_id)\
                .where('month', '==', current_month)
            
            count = len(list(query.stream()))
            
            remaining = max(0, max_essays - count)
            within_limit = remaining > 0
            
            logger.info(f"User {user_id}: {count}/{max_essays} essays used")
            
            return (within_limit, count, remaining)
            
        except Exception as e:
            logger.error(f"Failed to check limit: {e}")
            return (True, 0, max_essays)