File size: 6,660 Bytes
081a454
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# user_manager.py - User Profile Management System
import json
import os
from dataclasses import dataclass, asdict
from typing import List, Optional, Dict, Any
from datetime import datetime
from pathlib import Path

@dataclass
class UserProfile:
    """User profile data structure"""
    user_id: str
    username: str
    display_name: str
    expertise_level: str = "Beginner"
    preferred_languages: List[str] = None
    learning_goals: str = ""
    created_at: str = None
    last_active: str = None
    total_chats: int = 0
    favorite_responses: List[str] = None
    theme_preference: str = "light"
    response_format: str = "detailed"  # detailed, concise, bullet_points
    
    def __post_init__(self):
        if self.preferred_languages is None:
            self.preferred_languages = []
        if self.favorite_responses is None:
            self.favorite_responses = []
        if self.created_at is None:
            self.created_at = datetime.now().isoformat()
        if self.last_active is None:
            self.last_active = datetime.now().isoformat()

class UserManager:
    """Manages user profiles and preferences"""
    
    def __init__(self, data_dir: str):
        self.data_dir = Path(data_dir)
        self.data_dir.mkdir(exist_ok=True)
        self.users_file = self.data_dir / "users.json"
        self.ensure_users_file()
    
    def ensure_users_file(self):
        """Ensure users file exists"""
        if not self.users_file.exists():
            with open(self.users_file, 'w') as f:
                json.dump({}, f)
    
    def create_user(self, profile: UserProfile) -> bool:
        """Create a new user profile"""
        try:
            users = self.load_all_users()
            
            # Check if username already exists
            for user_data in users.values():
                if user_data.get('username') == profile.username:
                    raise ValueError(f"Username '{profile.username}' already exists")
            
            # Save user profile
            users[profile.user_id] = asdict(profile)
            
            with open(self.users_file, 'w') as f:
                json.dump(users, f, indent=2)
            
            return True
            
        except Exception as e:
            raise Exception(f"Failed to create user: {str(e)}")
    
    def load_all_users(self) -> Dict[str, Dict]:
        """Load all users from storage"""
        try:
            with open(self.users_file, 'r') as f:
                return json.load(f)
        except (FileNotFoundError, json.JSONDecodeError):
            return {}
    
    def get_user(self, user_id: str) -> Optional[UserProfile]:
        """Get user profile by ID"""
        users = self.load_all_users()
        user_data = users.get(user_id)
        
        if user_data:
            return UserProfile(**user_data)
        return None
    
    def get_user_by_username(self, username: str) -> Optional[UserProfile]:
        """Get user profile by username"""
        users = self.load_all_users()
        
        for user_data in users.values():
            if user_data.get('username') == username:
                return UserProfile(**user_data)
        return None
    
    def update_user(self, user_id: str, updates: Dict[str, Any]) -> bool:
        """Update user profile"""
        try:
            users = self.load_all_users()
            
            if user_id not in users:
                return False
            
            # Update fields
            users[user_id].update(updates)
            users[user_id]['last_active'] = datetime.now().isoformat()
            
            with open(self.users_file, 'w') as f:
                json.dump(users, f, indent=2)
            
            return True
            
        except Exception:
            return False
    
    def increment_chat_count(self, user_id: str):
        """Increment user's total chat count"""
        self.update_user(user_id, {'total_chats': self.get_chat_count(user_id) + 1})
    
    def get_chat_count(self, user_id: str) -> int:
        """Get user's total chat count"""
        user = self.get_user(user_id)
        return user.total_chats if user else 0
    
    def add_favorite_response(self, user_id: str, response_id: str) -> bool:
        """Add response to user's favorites"""
        user = self.get_user(user_id)
        if user and response_id not in user.favorite_responses:
            user.favorite_responses.append(response_id)
            return self.update_user(user_id, {'favorite_responses': user.favorite_responses})
        return False
    
    def remove_favorite_response(self, user_id: str, response_id: str) -> bool:
        """Remove response from user's favorites"""
        user = self.get_user(user_id)
        if user and response_id in user.favorite_responses:
            user.favorite_responses.remove(response_id)
            return self.update_user(user_id, {'favorite_responses': user.favorite_responses})
        return False
    
    def is_favorite_response(self, user_id: str, response_id: str) -> bool:
        """Check if response is in user's favorites"""
        user = self.get_user(user_id)
        return user and response_id in user.favorite_responses
    
    def get_all_usernames(self) -> List[str]:
        """Get list of all usernames"""
        users = self.load_all_users()
        return [user_data.get('username', '') for user_data in users.values() if user_data.get('username')]
    
    def delete_user(self, user_id: str) -> bool:
        """Delete user profile"""
        try:
            users = self.load_all_users()
            
            if user_id in users:
                del users[user_id]
                
                with open(self.users_file, 'w') as f:
                    json.dump(users, f, indent=2)
                
                return True
            return False
            
        except Exception:
            return False
    
    def get_user_stats(self, user_id: str) -> Dict[str, Any]:
        """Get user statistics"""
        user = self.get_user(user_id)
        if not user:
            return {}
        
        return {
            'total_chats': user.total_chats,
            'favorite_count': len(user.favorite_responses),
            'member_since': user.created_at,
            'last_active': user.last_active,
            'expertise_level': user.expertise_level,
            'preferred_languages': user.preferred_languages
        }