File size: 7,819 Bytes
469692c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9391632
84e6d52
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
"""
User Analytics Management
Tracks user registrations, analytics events, and predictions for admin dashboard
"""

import os
import json
from datetime import datetime
from typing import Dict, List, Optional
from collections import defaultdict

class UserAnalytics:
    """Manage user analytics data storage and retrieval"""
    
    def __init__(self, data_dir: str = '../data'):
        self.data_dir = os.path.abspath(data_dir)
        os.makedirs(self.data_dir, exist_ok=True)
        
        self.users_file = os.path.join(self.data_dir, 'users.json')
        self.analytics_file = os.path.join(self.data_dir, 'analytics.json')
        self.predictions_file = os.path.join(self.data_dir, 'predictions.json')
        
        # Initialize files if they don't exist
        self._init_files()
    
    def _init_files(self):
        """Initialize JSON files with empty structures"""
        if not os.path.exists(self.users_file):
            self._save_file(self.users_file, {
                'users': [],
                'last_updated': None
            })
        
        if not os.path.exists(self.analytics_file):
            self._save_file(self.analytics_file, {
                'events': [],
                'last_updated': None
            })
        
        if not os.path.exists(self.predictions_file):
            self._save_file(self.predictions_file, {
                'predictions': [],
                'last_updated': None
            })
    
    def _load_file(self, filepath: str) -> Dict:
        """Load JSON file"""
        try:
            if os.path.exists(filepath):
                with open(filepath, 'r', encoding='utf-8') as f:
                    return json.load(f)
        except Exception as e:
            print(f"Error loading {filepath}: {e}")
        return {}
    
    def _save_file(self, filepath: str, data: Dict):
        """Save JSON file"""
        try:
            data['last_updated'] = datetime.now().isoformat()
            with open(filepath, 'w', encoding='utf-8') as f:
                json.dump(data, f, indent=2, ensure_ascii=False)
        except Exception as e:
            print(f"Error saving {filepath}: {e}")
    
    def register_user(self, user_data: Dict) -> str:
        """Register a new user"""
        data = self._load_file(self.users_file)
        users = data.get('users', [])
        
        # Add registration timestamp if not present
        if 'registration_date' not in user_data:
            user_data['registration_date'] = datetime.now().isoformat()
        
        # Add to users list
        users.append(user_data)
        data['users'] = users
        self._save_file(self.users_file, data)
        
        return user_data.get('user_id', 'unknown')
    
    def track_event(self, event_name: str, event_data: Dict):
        """Track an analytics event"""
        data = self._load_file(self.analytics_file)
        events = data.get('events', [])
        
        event = {
            'name': event_name,
            'timestamp': datetime.now().isoformat(),
            'data': event_data
        }
        
        events.append(event)
        
        # Keep only last 1000 events to prevent file from growing too large
        if len(events) > 1000:
            events = events[-1000:]
        
        data['events'] = events
        self._save_file(self.analytics_file, data)
    
    def track_prediction(self, prediction_data: Dict):
        """Track a prediction"""
        data = self._load_file(self.predictions_file)
        predictions = data.get('predictions', [])
        
        # Add timestamp if not present
        if 'timestamp' not in prediction_data:
            prediction_data['timestamp'] = datetime.now().isoformat()
        
        predictions.append(prediction_data)
        
        # Keep only last 1000 predictions
        if len(predictions) > 1000:
            predictions = predictions[-1000:]
        
        data['predictions'] = predictions
        self._save_file(self.predictions_file, data)
    
    def get_user_stats(self) -> Dict:
        """Get user statistics"""
        data = self._load_file(self.users_file)
        users = data.get('users', [])
        
        if not users:
            return {
                'total_users': 0,
                'active_users_7d': 0,
                'active_users_30d': 0,
                'new_users_7d': 0,
                'new_users_30d': 0
            }
        
        now = datetime.now()
        active_7d = []
        active_30d = []
        new_7d = []
        new_30d = []
        
        for user in users:
            reg_date_str = user.get('registration_date', '')
            if reg_date_str:
                try:
                    reg_date = datetime.fromisoformat(reg_date_str.replace('Z', '+00:00'))
                    days_ago = (now - reg_date.replace(tzinfo=None)).days
                    
                    if days_ago <= 30:
                        active_30d.append(user.get('user_id'))
                    if days_ago <= 7:
                        active_7d.append(user.get('user_id'))
                        new_7d.append(user.get('user_id'))
                    elif days_ago <= 30:
                        new_30d.append(user.get('user_id'))
                except:
                    pass
        
        return {
            'total_users': len(users),
            'active_users_7d': len(set(active_7d)),
            'active_users_30d': len(set(active_30d)),
            'new_users_7d': len(new_7d),
            'new_users_30d': len(new_30d) + len(new_7d)
        }
    
    def get_platform_distribution(self) -> Dict:
        """Get platform distribution"""
        data = self._load_file(self.users_file)
        users = data.get('users', [])
        
        platforms = defaultdict(int)
        for user in users:
            platform = user.get('platform', 'unknown')
            platforms[platform] += 1
        
        return dict(platforms)
    
    def get_language_distribution(self) -> Dict:
        """Get language distribution"""
        data = self._load_file(self.users_file)
        users = data.get('users', [])
        
        languages = defaultdict(int)
        for user in users:
            language = user.get('language', 'unknown')
            languages[language] += 1
        
        return dict(languages)
    
    def get_user_timeline(self, days: int = 30) -> List[Dict]:
        """Get user registration timeline"""
        data = self._load_file(self.users_file)
        users = data.get('users', [])
        
        now = datetime.now()
        timeline = defaultdict(int)
        
        for user in users:
            reg_date_str = user.get('registration_date', '')
            if reg_date_str:
                try:
                    reg_date = datetime.fromisoformat(reg_date_str.replace('Z', '+00:00'))
                    days_ago = (now - reg_date.replace(tzinfo=None)).days
                    
                    if days_ago <= days:
                        date_str = reg_date.strftime('%Y-%m-%d')
                        timeline[date_str] += 1
                except:
                    pass
        
        # Convert to list of dicts sorted by date
        result = [{'date': date, 'count': count} 
                 for date, count in sorted(timeline.items())]
        return result
    
    def get_recent_users(self, limit: int = 10) -> List[Dict]:
        """Get recent user registrations"""
        data = self._load_file(self.users_file)
        users = data.get('users', [])
        
        # Sort by registration date (most recent first)
        sorted_users = sorted(users, 
                            key=lambda x: x.get('registration_date', ''),
                            reverse=True)
        
        return sorted_users[:limit]