From fa7ec5a87ef9fae703be1fbcf2ed1538dbb9e660 Mon Sep 17 00:00:00 2001 From: Ultradesu Date: Mon, 21 Jul 2025 17:40:03 +0300 Subject: [PATCH] Improve server page --- vpn/admin.py | 17 ++++++++--- vpn/server_plugins/outline.py | 55 +++++++++++++++++++++++++---------- vpn/tasks.py | 4 +-- 3 files changed, 54 insertions(+), 22 deletions(-) diff --git a/vpn/admin.py b/vpn/admin.py index e571569..4932335 100644 --- a/vpn/admin.py +++ b/vpn/admin.py @@ -1347,20 +1347,29 @@ class ACLLinkAdmin(admin.ModelAdmin): if not stats.daily_usage: return mark_safe('No data') - # Create mini chart + # Create wider mini chart for better visibility max_val = max(stats.daily_usage) if stats.daily_usage else 1 - chart_html = '
' + chart_html = '
' - for day_count in stats.daily_usage[-14:]: # Last 14 days for compact view + # Show last 30 days with wider bars for better visibility + for day_count in stats.daily_usage[-30:]: # Last 30 days if max_val > 0: height_percent = (day_count / max_val) * 100 else: height_percent = 0 color = '#4ade80' if day_count > 0 else '#e5e7eb' - chart_html += f'
' + chart_html += f'
' chart_html += '
' + + # Add summary info below chart + total_last_30 = sum(stats.daily_usage[-30:]) if stats.daily_usage else 0 + avg_daily = total_last_30 / 30 if total_last_30 > 0 else 0 + chart_html += f'
' + chart_html += f'Max: {max_val} | Avg: {avg_daily:.1f}' + chart_html += f'
' + return mark_safe(chart_html) except: return mark_safe('-') diff --git a/vpn/server_plugins/outline.py b/vpn/server_plugins/outline.py index 08f95f7..3579dd4 100644 --- a/vpn/server_plugins/outline.py +++ b/vpn/server_plugins/outline.py @@ -165,18 +165,41 @@ class OutlineServer(Server): raise OutlineServerErrorException(f"Error searching for key: {e}") def get_user(self, user, raw=False): - user_info = self._get_key(user) - if raw: - return user_info - else: - outline_key_dict = user_info.__dict__ + try: + user_info = self._get_key(user) + if raw: + return user_info + else: + outline_key_dict = user_info.__dict__ - outline_key_dict = { - key: value - for key, value in user_info.__dict__.items() - if not key.startswith('_') and key not in [] # fields to mask - } - return outline_key_dict + outline_key_dict = { + key: value + for key, value in user_info.__dict__.items() + if not key.startswith('_') and key not in [] # fields to mask + } + return outline_key_dict + except OutlineServerErrorException as e: + # If user key not found, try to create it automatically + if "Key not found" in str(e): + self.logger.warning(f"[{self.name}] Key not found for user {user.username}, attempting to create") + try: + self.add_user(user) + # Try to get the key again after creation + user_info = self._get_key(user) + if raw: + return user_info + else: + outline_key_dict = { + key: value + for key, value in user_info.__dict__.items() + if not key.startswith('_') and key not in [] + } + return outline_key_dict + except Exception as create_error: + self.logger.error(f"[{self.name}] Failed to create missing key for user {user.username}: {create_error}") + raise OutlineServerErrorException(f"Failed to get credentials: {e}") + else: + raise def add_user(self, user): @@ -195,9 +218,9 @@ class OutlineServer(Server): # Check if user needs update - but don't delete immediately needs_update = ( server_user.method != "chacha20-ietf-poly1305" or - server_user.port != int(self.client_port) or server_user.name != user.username or server_user.password != user.hash + # Don't check port as Outline can assign different ports automatically ) if needs_update: @@ -215,8 +238,8 @@ class OutlineServer(Server): name=user.username, method="chacha20-ietf-poly1305", password=user.hash, - data_limit=None, - port=int(self.client_port) + data_limit=None + # Don't specify port - let server assign automatically ) logger.info(f"[{self.name}] User {user.username} updated") except OutlineServerErrorException as e: @@ -233,8 +256,8 @@ class OutlineServer(Server): name=user.username, method="chacha20-ietf-poly1305", password=user.hash, - data_limit=None, - port=int(self.client_port) + data_limit=None + # Don't specify port - let server assign automatically ) logger.info(f"[{self.name}] User {user.username} created") except OutlineServerErrorException as e: diff --git a/vpn/tasks.py b/vpn/tasks.py index 704d2c6..3db5474 100644 --- a/vpn/tasks.py +++ b/vpn/tasks.py @@ -119,8 +119,8 @@ def sync_users(self, server_id): server = Server.objects.get(id=server_id) except Server.DoesNotExist: error_message = f"Server with id {server_id} not found - may have been deleted" - logger.error(error_message) - create_task_log(task_id, "sync_all_users_on_server", "Server not found", 'FAILURE', message=error_message, execution_time=time.time() - start_time) + logger.warning(error_message) + create_task_log(task_id, "sync_all_users_on_server", "Server not found", 'SUCCESS', message=error_message, execution_time=time.time() - start_time) return error_message # Don't raise exception for deleted servers # Test server connectivity before proceeding