From 33a32a331e954c3efe8ac58115c7f40ed7ad89ab Mon Sep 17 00:00:00 2001 From: Xargana Date: Mon, 14 Jul 2025 01:38:51 +0300 Subject: [PATCH] jankv3 --- AGENT.md | 30 ++++++++++++++++++++++++++++++ config.toml | 2 +- src/client.py | 18 ++++++++++++++---- src/database.py | 13 +++++++------ 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/AGENT.md b/AGENT.md index 607c200..feadc20 100644 --- a/AGENT.md +++ b/AGENT.md @@ -25,3 +25,33 @@ - **Naming**: snake_case for variables/functions, PascalCase for classes - **Types**: Type hints required (`typing` module), dataclasses for data structures - **Async**: All I/O operations use async/await, proper cleanup in finally blocks + +## Recent Changes & Fixes + +### Database Integration (2025-07-14) +- **✅ Remote MariaDB Support**: Added full support for remote MariaDB connections via .env credentials +- **✅ MariaDB->JSON Fallback**: Smart database factory that tries MariaDB first, falls back to JSON +- **✅ Dictionary Cursors**: Fixed asyncmy integration to return proper dictionary results instead of tuples +- **✅ Transaction Handling**: Proper async transaction management with START TRANSACTION/COMMIT/ROLLBACK +- **✅ Duplicate Key Handling**: Added INSERT IGNORE to prevent duplicate user-server entries + +### Discord Data Collection Improvements +- **✅ Enhanced Bio Collection**: Multiple fallback methods for user bio extraction (direct, profile fetch, activity-based) +- **✅ Better Status Tracking**: Comprehensive status collection including platform-specific status (desktop/mobile/web) +- **✅ Activity Tracking**: Multi-activity support with proper type detection and formatting +- **✅ Discord API Fixes**: Fixed Guild.fetch_members() coroutine handling for discord.py-self + +### CLI Enhancements +- **✅ Server Management Commands**: Added `servers`, `user-servers`, `server-users` commands for detailed server tracking +- **✅ Enhanced Search**: Search results now include bio, status, activity, and server membership info +- **✅ Better Formatting**: Improved output formatting with truncation and better readability + +### Network & Connectivity +- **✅ Connection Testing**: Added early Discord connectivity testing with clear error messages +- **✅ Graceful Error Handling**: Better error messages for network issues and missing dependencies + +## Production Status +- **Database**: ✅ Working (11 users collected from 1 server) +- **Discord Integration**: ✅ Working (logged in as _pixelparadox#0, 5 servers connected) +- **Data Collection**: ✅ Working (users, status, server membership being tracked) +- **Remote Storage**: ✅ Working (MariaDB at xargana.tr:3306, ~52KB database) diff --git a/config.toml b/config.toml index e9c3209..bec7d0e 100644 --- a/config.toml +++ b/config.toml @@ -17,7 +17,7 @@ server_membership = true # Delay between API requests in seconds request_delay = 1.0 # Maximum requests per minute -max_requests_per_minute = 30 +max_requests_per_minute = 120 [monitoring] # List of specific server IDs to monitor (leave empty to monitor all) diff --git a/src/client.py b/src/client.py index d3213c7..0b3cb08 100644 --- a/src/client.py +++ b/src/client.py @@ -107,8 +107,10 @@ class DiscordDataClient(discord.Client): self.logger.info(f"Scanning server: {guild.name} ({guild.id})") try: - # Get all members - different API for discord.py-self - members = [member async for member in guild.fetch_members()] + # Get all members - discord.py-self API + members = [] + async for member in guild.fetch_members(): + members.append(member) for member in members: if not member.bot: @@ -181,6 +183,7 @@ class DiscordDataClient(discord.Client): # Method 1: Check if user object already has bio if hasattr(user, 'bio') and user.bio: bio = user.bio + self.logger.debug(f"Found bio via user.bio for {user.name}") # Method 2: Try to get full user profile elif hasattr(user, 'id'): @@ -188,16 +191,23 @@ class DiscordDataClient(discord.Client): profile = await self.fetch_user(user.id) if hasattr(profile, 'bio') and profile.bio: bio = profile.bio - except Exception: - pass + self.logger.debug(f"Found bio via profile fetch for {user.name}") + else: + self.logger.debug(f"No bio found in profile for {user.name}") + except Exception as e: + self.logger.debug(f"Profile fetch failed for {user.name}: {e}") # Method 3: Check for activities that might contain bio-like info if not bio and hasattr(user, 'activities'): for activity in user.activities: if hasattr(activity, 'name') and activity.name and len(activity.name) > 20: bio = f"Activity: {activity.name}" + self.logger.debug(f"Using activity as bio for {user.name}: {activity.name}") break + if not bio: + self.logger.debug(f"No bio found for user {user.name}") + return bio[:500] if bio else None # Limit bio length except Exception as e: diff --git a/src/database.py b/src/database.py index 14a3705..bf5aa90 100644 --- a/src/database.py +++ b/src/database.py @@ -413,7 +413,7 @@ class MariaDBDatabase: if user_data.servers: for server_id in user_data.servers: await cursor.execute( - "INSERT INTO user_servers (user_id, server_id) VALUES (%s, %s)", + "INSERT IGNORE INTO user_servers (user_id, server_id) VALUES (%s, %s)", (user_data.user_id, server_id) ) @@ -428,10 +428,11 @@ class MariaDBDatabase: async def add_server_to_user(self, user_id: int, server_id: int): """Add a server to user's server list.""" - await self._execute_query(""" - INSERT IGNORE INTO user_servers (user_id, server_id) - VALUES (%s, %s) - """, (user_id, server_id)) + async with self.pool.cursor() as cursor: + await cursor.execute(""" + INSERT IGNORE INTO user_servers (user_id, server_id) + VALUES (%s, %s) + """, (user_id, server_id)) async def get_all_users(self) -> List[UserData]: """Get all users from the database.""" @@ -512,5 +513,5 @@ class MariaDBDatabase: async def close(self): """Close database connection.""" if self.pool: - await self.pool.close() + self.pool.close() self.logger.info("Database connection closed")