mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-09 12:30:15 +02:00
add Connection History
This commit is contained in:
parent
3f54d49d8b
commit
1dea92ed76
@ -0,0 +1,185 @@
|
|||||||
|
{% extends "allianceauth/base-bs5.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load humanize %}
|
||||||
|
|
||||||
|
{% block page_title %}
|
||||||
|
{% translate "Mumble" %}
|
||||||
|
{% endblock page_title %}
|
||||||
|
|
||||||
|
{% block header_nav_brand %}
|
||||||
|
<a class="navbar-brand">{% trans "Mumble History" %} - {{ mumble_url }}</a>
|
||||||
|
{% endblock header_nav_brand %}
|
||||||
|
{% block header_nav_collapse_left %}
|
||||||
|
{% endblock header_nav_collapse_left %}
|
||||||
|
|
||||||
|
{% block header_nav_collapse_right %}
|
||||||
|
{% endblock header_nav_collapse_right %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="card card-success col-lg-12 container-fluid">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="card-title">{% translate "Server Connection History" %}</span>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-body">
|
||||||
|
<table class="table table-responsive" id="table-mumble-connection-history" style="width: 100%;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-left">{% translate "User" %}</th>
|
||||||
|
<th class="text-left">{% translate "Display_Name" %}</th>
|
||||||
|
<th class="text-left">{% translate "Release" %}</th>
|
||||||
|
<th class="text-left">{% translate "Version" %}</th>
|
||||||
|
<th class="text-left">{% translate "Last Connection" %}</th>
|
||||||
|
<th class="text-left">{% translate "Last Disconnection" %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="card card-success col-lg-6 container-fluid">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="card-title">{% translate "Server Connection Breakdown" %}</span>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-body">
|
||||||
|
<canvas id="pieChart"></canvas> <!-- Canvas element for the pie chart -->
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card card-success col-lg-6 container-fluid">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="card-title">{% translate "Server Connection Breakdown" %}</span>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-body">
|
||||||
|
<table class="table table-responsive" id="table-mumble-connection-stats" style="width: 100%;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-left">{% translate "Version" %}</th>
|
||||||
|
<th class="text-left">{% translate "Number" %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
||||||
|
{% block extra_javascript %}
|
||||||
|
{% include "bundles/datatables-js-bs5.html" %}
|
||||||
|
{% include "bundles/filterdropdown-js.html" %}
|
||||||
|
{% include "bundles/chart-js.html" %}
|
||||||
|
{% include "bundles/moment-js.html" with locale=True %}
|
||||||
|
|
||||||
|
{% endblock extra_javascript %}
|
||||||
|
|
||||||
|
{% block extra_css %}
|
||||||
|
{% include "bundles/datatables-css-bs5.html" %}
|
||||||
|
{% endblock extra_css %}
|
||||||
|
{% block extra_script %}
|
||||||
|
$(document).ready(function () {
|
||||||
|
$("#table-mumble-connection-history").DataTable({
|
||||||
|
ajax: {
|
||||||
|
url: "{% url 'mumble:connection_history_data' %}",
|
||||||
|
dataSrc: "connection_history_data",
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{ data: "user" },
|
||||||
|
{ data: "display_name" },
|
||||||
|
{ data: "release" },
|
||||||
|
{ data: "version" },
|
||||||
|
{ data: "last_connect" },
|
||||||
|
{ data: "last_connect" },
|
||||||
|
],
|
||||||
|
order: [[4, "desc"]],
|
||||||
|
processing: true,
|
||||||
|
stateSave: true,
|
||||||
|
stateDuration: 0,
|
||||||
|
filterDropDown: {
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
idx: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
idx: 3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
bootstrap: true,
|
||||||
|
bootstrap_version: 5,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#table-mumble-connection-stats").DataTable({
|
||||||
|
ajax: {
|
||||||
|
url: "{% url 'mumble:release_counts_data' %}",
|
||||||
|
dataSrc: "release_counts_data",
|
||||||
|
},
|
||||||
|
columns: [{ data: "release" }, { data: "user_count" }],
|
||||||
|
order: [[1, "desc"]],
|
||||||
|
processing: true,
|
||||||
|
stateSave: true,
|
||||||
|
stateDuration: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize empty Pie chart
|
||||||
|
var ctx = document.getElementById("pieChart").getContext("2d");
|
||||||
|
var pieChart = new Chart(ctx, {
|
||||||
|
type: "pie",
|
||||||
|
data: {
|
||||||
|
labels: [], // Initially empty
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Server Connection Breakdown",
|
||||||
|
data: [], // Initially empty
|
||||||
|
backgroundColor: [
|
||||||
|
"rgba(255, 99, 132, 0.2)",
|
||||||
|
"rgba(54, 162, 235, 0.2)",
|
||||||
|
"rgba(255, 206, 86, 0.2)",
|
||||||
|
],
|
||||||
|
borderColor: [
|
||||||
|
"rgba(255, 99, 132, 1)",
|
||||||
|
"rgba(54, 162, 235, 1)",
|
||||||
|
"rgba(255, 206, 86, 1)",
|
||||||
|
],
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
position: "top",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// AJAX call to dynamically update the chart
|
||||||
|
$.ajax({
|
||||||
|
url: "{% url 'mumble:release_pie_chart_data' %}", // Your Django view URL that returns chart data
|
||||||
|
method: "GET",
|
||||||
|
success: function (data) {
|
||||||
|
// Replace chart data with the data from the AJAX response
|
||||||
|
pieChart.data.labels = data.labels; // Set the new labels
|
||||||
|
pieChart.data.datasets[0].data = data.values; // Set the new values
|
||||||
|
|
||||||
|
// Update the chart to reflect the new data
|
||||||
|
pieChart.update();
|
||||||
|
},
|
||||||
|
error: function (xhr, status, error) {
|
||||||
|
console.error("Error fetching pie chart data:", status, error);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
{% endblock extra_script %}
|
@ -48,4 +48,9 @@
|
|||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if request.user.is_superuser %}
|
||||||
|
<a class="btn btn-primary" type="button" id="btnMumbleConnectionHistory" href="{% url 'mumble:connection_history' %}" title="{% translate 'Mumble Connection History' %}">
|
||||||
|
<i class="fa-solid fa-clock-rotate-left"></i> History
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -10,6 +10,10 @@ module_urls = [
|
|||||||
path('deactivate/', views.DeleteMumbleView.as_view(), name='deactivate'),
|
path('deactivate/', views.DeleteMumbleView.as_view(), name='deactivate'),
|
||||||
path('reset_password/', views.ResetPasswordMumbleView.as_view(), name='reset_password'),
|
path('reset_password/', views.ResetPasswordMumbleView.as_view(), name='reset_password'),
|
||||||
path('set_password/', views.SetPasswordMumbleView.as_view(), name='set_password'),
|
path('set_password/', views.SetPasswordMumbleView.as_view(), name='set_password'),
|
||||||
|
path('connection_history/', views.connection_history, name="connection_history"),
|
||||||
|
path('ajax/connection_history_data', views.connection_history_data, name="connection_history_data"),
|
||||||
|
path('ajax/release_counts_data', views.release_counts_data, name="release_counts_data"),
|
||||||
|
path('ajax/release_pie_chart_data', views.release_pie_chart_data, name="release_pie_chart_data"),
|
||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
@ -3,6 +3,11 @@ import logging
|
|||||||
from allianceauth.services.forms import ServicePasswordModelForm
|
from allianceauth.services.forms import ServicePasswordModelForm
|
||||||
from allianceauth.services.abstract import BaseCreatePasswordServiceAccountView, BaseDeactivateServiceAccountView, \
|
from allianceauth.services.abstract import BaseCreatePasswordServiceAccountView, BaseDeactivateServiceAccountView, \
|
||||||
BaseResetPasswordServiceAccountView, BaseSetPasswordServiceAccountView
|
BaseResetPasswordServiceAccountView, BaseSetPasswordServiceAccountView
|
||||||
|
from django.conf import settings
|
||||||
|
from django.contrib.auth.decorators import login_required, permission_required
|
||||||
|
from django.db.models import Count
|
||||||
|
from django.http import HttpResponse, JsonResponse
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
from .models import MumbleUser
|
from .models import MumbleUser
|
||||||
|
|
||||||
@ -35,3 +40,51 @@ class ResetPasswordMumbleView(MumbleViewMixin, BaseResetPasswordServiceAccountVi
|
|||||||
|
|
||||||
class SetPasswordMumbleView(MumbleViewMixin, BaseSetPasswordServiceAccountView):
|
class SetPasswordMumbleView(MumbleViewMixin, BaseSetPasswordServiceAccountView):
|
||||||
form_class = MumblePasswordForm
|
form_class = MumblePasswordForm
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required('mumble.view_connection_history')
|
||||||
|
def connection_history(request) -> HttpResponse:
|
||||||
|
|
||||||
|
context = {
|
||||||
|
"mumble_url": settings.MUMBLE_URL,
|
||||||
|
}
|
||||||
|
|
||||||
|
return render(request, 'services/mumble/mumble_connection_history.html', context)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required("mumble.view_connection_history")
|
||||||
|
def connection_history_data(request) -> JsonResponse:
|
||||||
|
connection_history_data = MumbleUser.objects.all(
|
||||||
|
).values(
|
||||||
|
'user',
|
||||||
|
'display_name',
|
||||||
|
'release',
|
||||||
|
'version',
|
||||||
|
'last_connect',
|
||||||
|
'last_disconnect',
|
||||||
|
)
|
||||||
|
|
||||||
|
return JsonResponse({"connection_history_data": list(connection_history_data)})
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required("mumble.view_connection_history")
|
||||||
|
def release_counts_data(request) -> JsonResponse:
|
||||||
|
release_counts_data = MumbleUser.objects.values('release').annotate(user_count=Count('user_id')).order_by('release')
|
||||||
|
|
||||||
|
return JsonResponse({
|
||||||
|
"release_counts_data": list(release_counts_data),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required("mumble.view_connection_history")
|
||||||
|
def release_pie_chart_data(request) -> JsonResponse:
|
||||||
|
release_counts = MumbleUser.objects.values('release').annotate(user_count=Count('user_id')).order_by('release')
|
||||||
|
|
||||||
|
return JsonResponse({
|
||||||
|
"labels": list(release_counts.values_list("release", flat=True)),
|
||||||
|
"values": list(release_counts.values_list("user_count", flat=True)),
|
||||||
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user