Proyecto LCX Dispatcharr multicuenta
Base Image Build / prepare (push) Has been cancelled
Build and Push Multi-Arch Docker Image / build-and-push (push) Has been cancelled
Frontend Tests / test (push) Has been cancelled
Base Image Build / docker (amd64, ubuntu-24.04) (push) Has been cancelled
Base Image Build / docker (arm64, ubuntu-24.04-arm) (push) Has been cancelled
Base Image Build / create-manifest (push) Has been cancelled
Base Image Build / prepare (push) Has been cancelled
Build and Push Multi-Arch Docker Image / build-and-push (push) Has been cancelled
Frontend Tests / test (push) Has been cancelled
Base Image Build / docker (amd64, ubuntu-24.04) (push) Has been cancelled
Base Image Build / docker (arm64, ubuntu-24.04-arm) (push) Has been cancelled
Base Image Build / create-manifest (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
from django.contrib import admin
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
from django.urls import path
|
||||
from .views import dashboard_view, settings_view, live_dashboard_data
|
||||
|
||||
app_name = 'dashboard'
|
||||
|
||||
urlpatterns = [
|
||||
path('dashboard-data/', live_dashboard_data, name='dashboard_data'),
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class CoreConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'apps.dashboard'
|
||||
@@ -0,0 +1,46 @@
|
||||
# Generated by Django 5.1.6 on 2025-03-05 22:07
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Settings',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('server_name', models.CharField(default='Dispatcharr', max_length=255)),
|
||||
('time_zone', models.CharField(default='UTC', max_length=50)),
|
||||
('default_logo_url', models.URLField(blank=True, null=True)),
|
||||
('max_concurrent_streams', models.PositiveIntegerField(default=10)),
|
||||
('auto_backup_frequency', models.CharField(choices=[('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly')], default='weekly', max_length=50)),
|
||||
('enable_debug_logs', models.BooleanField(default=False)),
|
||||
('schedules_direct_username', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('schedules_direct_password', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('schedules_direct_update_frequency', models.CharField(choices=[('12h', 'Every 12 Hours'), ('daily', 'Daily')], default='daily', max_length=50)),
|
||||
('schedules_direct_api_key', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('transcoding_bitrate', models.PositiveIntegerField(default=2000)),
|
||||
('transcoding_audio_codec', models.CharField(choices=[('aac', 'AAC'), ('mp3', 'MP3')], default='aac', max_length=50)),
|
||||
('transcoding_resolution', models.CharField(choices=[('720p', '720p'), ('1080p', '1080p')], default='1080p', max_length=50)),
|
||||
('failover_behavior', models.CharField(choices=[('sequential', 'Sequential'), ('random', 'Random')], default='sequential', max_length=50)),
|
||||
('stream_health_check_frequency', models.PositiveIntegerField(default=5)),
|
||||
('email_notifications', models.BooleanField(default=False)),
|
||||
('webhook_url', models.URLField(blank=True, null=True)),
|
||||
('cpu_alert_threshold', models.PositiveIntegerField(default=90)),
|
||||
('memory_alert_threshold', models.PositiveIntegerField(default=90)),
|
||||
('hdhr_integration', models.BooleanField(default=True)),
|
||||
('custom_api_endpoints', models.JSONField(blank=True, null=True)),
|
||||
('backup_path', models.CharField(default='backups/', max_length=255)),
|
||||
('backup_frequency', models.CharField(choices=[('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly')], default='weekly', max_length=50)),
|
||||
('ffmpeg_path', models.CharField(default='/usr/bin/ffmpeg', max_length=255)),
|
||||
('custom_transcoding_flags', models.TextField(blank=True, null=True)),
|
||||
('celery_worker_concurrency', models.PositiveIntegerField(default=4)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,66 @@
|
||||
from django.db import models
|
||||
|
||||
class Settings(models.Model):
|
||||
# General Settings
|
||||
server_name = models.CharField(max_length=255, default="Dispatcharr")
|
||||
time_zone = models.CharField(max_length=50, default="UTC")
|
||||
default_logo_url = models.URLField(blank=True, null=True)
|
||||
max_concurrent_streams = models.PositiveIntegerField(default=10)
|
||||
auto_backup_frequency = models.CharField(
|
||||
max_length=50,
|
||||
choices=[("daily", "Daily"), ("weekly", "Weekly"), ("monthly", "Monthly")],
|
||||
default="weekly"
|
||||
)
|
||||
enable_debug_logs = models.BooleanField(default=False)
|
||||
|
||||
# Schedules Direct Settings
|
||||
schedules_direct_username = models.CharField(max_length=255, blank=True, null=True)
|
||||
schedules_direct_password = models.CharField(max_length=255, blank=True, null=True)
|
||||
schedules_direct_update_frequency = models.CharField(
|
||||
max_length=50,
|
||||
choices=[("12h", "Every 12 Hours"), ("daily", "Daily")],
|
||||
default="daily"
|
||||
)
|
||||
schedules_direct_api_key = models.CharField(max_length=255, blank=True, null=True)
|
||||
|
||||
# Stream and Channel Settings
|
||||
transcoding_bitrate = models.PositiveIntegerField(default=2000) # in kbps
|
||||
transcoding_audio_codec = models.CharField(
|
||||
max_length=50,
|
||||
choices=[("aac", "AAC"), ("mp3", "MP3")],
|
||||
default="aac"
|
||||
)
|
||||
transcoding_resolution = models.CharField(
|
||||
max_length=50,
|
||||
choices=[("720p", "720p"), ("1080p", "1080p")],
|
||||
default="1080p"
|
||||
)
|
||||
failover_behavior = models.CharField(
|
||||
max_length=50,
|
||||
choices=[("sequential", "Sequential"), ("random", "Random")],
|
||||
default="sequential"
|
||||
)
|
||||
stream_health_check_frequency = models.PositiveIntegerField(default=5) # in minutes
|
||||
|
||||
# Notifications
|
||||
email_notifications = models.BooleanField(default=False)
|
||||
webhook_url = models.URLField(blank=True, null=True)
|
||||
cpu_alert_threshold = models.PositiveIntegerField(default=90) # Percentage
|
||||
memory_alert_threshold = models.PositiveIntegerField(default=90) # Percentage
|
||||
|
||||
# API Settings
|
||||
hdhr_integration = models.BooleanField(default=True)
|
||||
custom_api_endpoints = models.JSONField(blank=True, null=True)
|
||||
|
||||
# Backup and Restore
|
||||
backup_path = models.CharField(max_length=255, default="backups/")
|
||||
backup_frequency = models.CharField(
|
||||
max_length=50,
|
||||
choices=[("daily", "Daily"), ("weekly", "Weekly"), ("monthly", "Monthly")],
|
||||
default="weekly"
|
||||
)
|
||||
|
||||
# Advanced
|
||||
ffmpeg_path = models.CharField(max_length=255, default="/usr/bin/ffmpeg")
|
||||
custom_transcoding_flags = models.TextField(blank=True, null=True)
|
||||
celery_worker_concurrency = models.PositiveIntegerField(default=4)
|
||||
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
@@ -0,0 +1,10 @@
|
||||
from django.urls import path
|
||||
from .views import dashboard_view, settings_view, live_dashboard_data
|
||||
|
||||
app_name = 'dashboard'
|
||||
|
||||
urlpatterns = [
|
||||
path('', dashboard_view, name='dashboard'),
|
||||
path('settings/', settings_view, name='settings'),
|
||||
path('api/dashboard-data/', live_dashboard_data, name='dashboard_data'),
|
||||
]
|
||||
@@ -0,0 +1,79 @@
|
||||
from django.shortcuts import render
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from psutil import cpu_percent, virtual_memory, net_io_counters
|
||||
from apps.channels.models import Stream
|
||||
from django.http import JsonResponse # ADD THIS LINE
|
||||
|
||||
|
||||
@login_required
|
||||
def dashboard_view(request):
|
||||
# Fetch system metrics
|
||||
try:
|
||||
cpu_usage = cpu_percent(interval=1)
|
||||
ram = virtual_memory()
|
||||
ram_usage = f"{ram.used / (1024 ** 3):.1f} GB / {ram.total / (1024 ** 3):.1f} GB"
|
||||
network = net_io_counters()
|
||||
network_traffic = f"{network.bytes_sent / (1024 ** 2):.1f} MB"
|
||||
except Exception as e:
|
||||
cpu_usage = "N/A"
|
||||
ram_usage = "N/A"
|
||||
network_traffic = "N/A"
|
||||
print(f"Error fetching system metrics: {e}")
|
||||
|
||||
# Fetch active streams and related channels
|
||||
active_streams = Stream.objects.filter(current_viewers__gt=0).prefetch_related('channels')
|
||||
active_streams_list = [
|
||||
f"Stream {i + 1}: {stream.url or 'Unknown'} ({stream.current_viewers} viewers)"
|
||||
for i, stream in enumerate(active_streams)
|
||||
]
|
||||
|
||||
# Pass data to the template
|
||||
context = {
|
||||
"cpu_usage": f"{cpu_usage}%",
|
||||
"ram_usage": ram_usage,
|
||||
"current_streams": active_streams.count(),
|
||||
"network_traffic": network_traffic,
|
||||
"active_streams": active_streams_list,
|
||||
}
|
||||
return render(request, "dashboard/dashboard.html", context)
|
||||
|
||||
@login_required
|
||||
def settings_view(request):
|
||||
# Placeholder for settings functionality
|
||||
return render(request, 'settings.html')
|
||||
|
||||
@login_required
|
||||
def live_dashboard_data(request):
|
||||
try:
|
||||
cpu_usage = cpu_percent(interval=1)
|
||||
ram = virtual_memory()
|
||||
network = net_io_counters()
|
||||
ram_usage = f"{ram.used / (1024 ** 3):.1f} GB / {ram.total / (1024 ** 3):.1f} GB"
|
||||
network_traffic = f"{network.bytes_sent / (1024 ** 2):.1f} MB"
|
||||
|
||||
# Mocked example data for the charts
|
||||
cpu_data = [45, 50, 60, 55, 70, 65]
|
||||
ram_data = [6.5, 7.0, 7.5, 8.0, 8.5, 9.0]
|
||||
network_data = [120, 125, 130, 128, 126, 124]
|
||||
|
||||
active_streams = Stream.objects.filter(current_viewers__gt=0)
|
||||
active_streams_list = [
|
||||
f"Stream {i + 1}: {stream.url or 'Unknown'} ({stream.current_viewers} viewers)"
|
||||
for i, stream in enumerate(active_streams)
|
||||
]
|
||||
|
||||
data = {
|
||||
"cpu_usage": f"{cpu_usage}%",
|
||||
"ram_usage": ram_usage,
|
||||
"current_streams": active_streams.count(),
|
||||
"network_traffic": network_traffic,
|
||||
"active_streams": active_streams_list,
|
||||
"cpu_data": cpu_data,
|
||||
"ram_data": ram_data,
|
||||
"network_data": network_data,
|
||||
}
|
||||
except Exception as e:
|
||||
data = {
|
||||
"error": str(e)
|
||||
}
|
||||
return JsonResponse(data)
|
||||
Reference in New Issue
Block a user