from datetime import timedelta from django.contrib.auth.decorators import login_required from django.http import HttpResponseBadRequest, JsonResponse from django.shortcuts import render from django.utils import timezone from backup_data.models import RouterBackup from router_manager.models import Router, RouterStatus ALLOWED_DAYS = [3,5,7,10, 15, 30] # Define allowed values import os import shutil from django.conf import settings def human_readable_size(size): """Convert bytes to a human-readable format (KB, MB, GB).""" for unit in ['B', 'KB', 'MB', 'GB']: if size < 1024.0: return f"{size:.2f} {unit}" size /= 1024.0 return f"{size:.2f} TB" # For sizes larger than GB def get_directory_statistics(directory_path): # Get total disk usage total, used, free = shutil.disk_usage(directory_path) # Calculate the size of the directory directory_used = sum(os.path.getsize(os.path.join(root, file)) for root, dirs, files in os.walk(directory_path) for file in files) # Get sizes in a human-readable format total_human = human_readable_size(total) used_human = human_readable_size(directory_used) free_human = human_readable_size(free) # Calculate usage percentage usage_percentage = (directory_used / total) * 100 if total > 0 else 0 # Determine storage warning storage_warning = "" if usage_percentage > 90: storage_warning = "Warning: Storage usage is above 90%!" elif usage_percentage > 75: storage_warning = "Caution: Storage usage is above 75%." return { "total": total_human, "used": used_human, "free": free_human, "usage_percentage": round(usage_percentage, 2) if total > 0 else 0, "storage_warning": storage_warning } @login_required def view_dashboard(request): context = {'page_title': 'Welcome to routerfleet'} return render(request, 'dashboard/welcome.html', context=context) @login_required def view_status(request): settings.MEDIA_ROOT context = { 'page_title': 'Welcome to routerfleet', 'media_root_stats': get_directory_statistics(settings.MEDIA_ROOT), 'queue': RouterBackup.objects.filter(success=False, error=False).count(), 'success_backup_last_24h': RouterBackup.objects.filter(success=True, created__gte=timezone.now() - timedelta(days=1)).count(), 'error_backup_last_24h': RouterBackup.objects.filter(error=True, created__gte=timezone.now() - timedelta(days=1)).count(), 'total_router_count':Router.objects.all().count(), 'router_enabled_count': Router.objects.filter(enabled=True).count(), 'router_disabled_count': Router.objects.filter(enabled=False).count(), 'router_online_count': RouterStatus.objects.filter(status_online=True, router__monitoring=True).count(), 'router_offline_count': RouterStatus.objects.filter(status_online=False, router__monitoring=True).count(), 'router_not_monitored_count': Router.objects.filter(enabled=True, monitoring=False).count(), 'routerfleet_version': settings.ROUTERFLEET_VERSION, } return render(request, 'dashboard/status.html', context=context) @login_required def backup_statistics_data(request): try: days = int(request.GET.get('days', 7)) except ValueError: return HttpResponseBadRequest("Invalid 'days' parameter") if days not in ALLOWED_DAYS: return HttpResponseBadRequest("Invalid 'days' parameter") today = timezone.now() start_date = today - timedelta(days=days) dates = [start_date + timedelta(days=i) for i in range(days + 1)] success_data = [] error_data = [] for i in range(days): day_start = dates[i] day_end = dates[i + 1] success_count = RouterBackup.objects.filter(created__gte=day_start, created__lt=day_end, success=True).count() error_count = RouterBackup.objects.filter(created__gte=day_start, created__lt=day_end, error=True).count() success_data.append(success_count) error_data.append(error_count) data = { 'dates': [date.strftime('%Y-%m-%d') for date in dates[:-1]], 'success_data': success_data, 'error_data': error_data, } return JsonResponse(data) @login_required def router_status_data(request): try: days = int(request.GET.get('days', '7')) except ValueError: return HttpResponseBadRequest(f"Invalid 'days' {days} parameter") if days not in ALLOWED_DAYS: return HttpResponseBadRequest("Invalid 'days' parameter. Must be one of: " + ', '.join(map(str, ALLOWED_DAYS))) today = timezone.now() start_date = today - timedelta(days=days) # Create a list of dates for the period dates = [start_date + timedelta(days=i) for i in range(days + 1)] router_statuses = RouterStatus.objects.filter(router__enabled=True) online_data = [] offline_data = [] for i in range(days): day_start = dates[i] day_end = dates[i + 1] # Get statuses that changed within the current day daily_statuses = router_statuses.filter(last_status_change__gte=day_start, last_status_change__lt=day_end) online_count = daily_statuses.filter(status_online=True).count() offline_count = daily_statuses.filter(status_online=False).count() # Get routers that have not changed status on the current day unchanged_routers = router_statuses.exclude(last_status_change__gte=day_start, last_status_change__lt=day_end) for router_status in unchanged_routers: last_change = router_status.last_status_change # Only perform the comparison if last_change is not None if last_change and last_change < day_start: if router_status.status_online: online_count += 1 else: offline_count += 1 online_data.append(online_count) offline_data.append(offline_count) data = { 'dates': [date.strftime('%Y-%m-%d') for date in dates[:-1]], 'online_data': online_data, 'offline_data': offline_data, } return JsonResponse(data)