mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-28 21:52:28 +02:00
Compare commits
No commits in common. "cda5ce739ff63d0958b4c4ff4ef27964451689a0" and "42ee06470c3941d276e49aab8daf59925eca7feb" have entirely different histories.
cda5ce739f
...
42ee06470c
@ -49,7 +49,7 @@ class GroupsMenuItem(MenuItemHook):
|
|||||||
MenuItemHook.__init__(
|
MenuItemHook.__init__(
|
||||||
self,
|
self,
|
||||||
text=_("Groups"),
|
text=_("Groups"),
|
||||||
classes="fa-solid fa-users",
|
classes="fa-solid fa-user",
|
||||||
url_name="groupmanagement:groups",
|
url_name="groupmanagement:groups",
|
||||||
order=25,
|
order=25,
|
||||||
navactive=[
|
navactive=[
|
||||||
|
@ -68,7 +68,7 @@ msgstr "Englisch"
|
|||||||
|
|
||||||
#: allianceauth/authentication/models.py:72
|
#: allianceauth/authentication/models.py:72
|
||||||
msgid "Czech"
|
msgid "Czech"
|
||||||
msgstr "Tschechisch"
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/authentication/models.py:73
|
#: allianceauth/authentication/models.py:73
|
||||||
#: allianceauth/project_template/project_name/settings/base.py:101
|
#: allianceauth/project_template/project_name/settings/base.py:101
|
||||||
@ -108,7 +108,7 @@ msgstr "Russisch"
|
|||||||
#: allianceauth/authentication/models.py:80
|
#: allianceauth/authentication/models.py:80
|
||||||
#: allianceauth/project_template/project_name/settings/base.py:107
|
#: allianceauth/project_template/project_name/settings/base.py:107
|
||||||
msgid "Dutch"
|
msgid "Dutch"
|
||||||
msgstr "Niederländisch"
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/authentication/models.py:81
|
#: allianceauth/authentication/models.py:81
|
||||||
#: allianceauth/project_template/project_name/settings/base.py:108
|
#: allianceauth/project_template/project_name/settings/base.py:108
|
||||||
@ -123,7 +123,7 @@ msgstr "Ukrainisch"
|
|||||||
#: allianceauth/authentication/models.py:83
|
#: allianceauth/authentication/models.py:83
|
||||||
#: allianceauth/project_template/project_name/settings/base.py:111
|
#: allianceauth/project_template/project_name/settings/base.py:111
|
||||||
msgid "Simplified Chinese"
|
msgid "Simplified Chinese"
|
||||||
msgstr "Vereinfachtes Chinesisch"
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/authentication/models.py:99
|
#: allianceauth/authentication/models.py:99
|
||||||
#: allianceauth/menu/templates/menu/menu-user.html:42
|
#: allianceauth/menu/templates/menu/menu-user.html:42
|
||||||
@ -1664,7 +1664,7 @@ msgstr "Anstehende Flotten"
|
|||||||
#: allianceauth/optimer/templates/optimer/management.html:44
|
#: allianceauth/optimer/templates/optimer/management.html:44
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:62
|
#: allianceauth/timerboard/templates/timerboard/view.html:62
|
||||||
msgid "No upcoming timers."
|
msgid "No upcoming timers."
|
||||||
msgstr "Keine anstehenden Timer."
|
msgstr "Keine bevorstehenden Timer."
|
||||||
|
|
||||||
#: allianceauth/optimer/templates/optimer/management.html:52
|
#: allianceauth/optimer/templates/optimer/management.html:52
|
||||||
msgid "Past Fleet Operations"
|
msgid "Past Fleet Operations"
|
||||||
@ -2804,12 +2804,12 @@ msgstr "Entankernd"
|
|||||||
|
|
||||||
#: allianceauth/timerboard/models.py:58
|
#: allianceauth/timerboard/models.py:58
|
||||||
msgid "Abandoned"
|
msgid "Abandoned"
|
||||||
msgstr "Aufgegeben"
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:7
|
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:7
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:53
|
#: allianceauth/timerboard/templates/timerboard/view.html:53
|
||||||
msgid "Upcoming Timers"
|
msgid "Upcoming Timers"
|
||||||
msgstr "Anstehende Timer"
|
msgstr "Bevorstehende Timefr"
|
||||||
|
|
||||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:15
|
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:15
|
||||||
msgid "Timer"
|
msgid "Timer"
|
||||||
|
@ -1,21 +1 @@
|
|||||||
"""
|
|
||||||
Example
|
|
||||||
=======
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from allianceauth.notifications.models import Notification
|
|
||||||
|
|
||||||
|
|
||||||
def notify_user_view(request):
|
|
||||||
'''Simple view sending a notification to the user'''
|
|
||||||
|
|
||||||
Notification.objects.notify_user(
|
|
||||||
user=request.user,
|
|
||||||
title="Some title",
|
|
||||||
message="Some message",
|
|
||||||
level=Notification.Level.INFO,
|
|
||||||
)
|
|
||||||
|
|
||||||
"""
|
|
||||||
from .core import notify # noqa: F401
|
from .core import notify # noqa: F401
|
||||||
|
@ -90,7 +90,7 @@ class MumbleUser(AbstractServiceModel):
|
|||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
editable=False,
|
editable=False,
|
||||||
help_text="Client release. For official releases, this equals the version. For snapshots and git compiles, this will be something else."
|
help_text="The Mumble Release the user last authenticated with"
|
||||||
)
|
)
|
||||||
version = models.IntegerField(
|
version = models.IntegerField(
|
||||||
verbose_name="Mumble Version",
|
verbose_name="Mumble Version",
|
||||||
@ -159,5 +159,4 @@ class MumbleUser(AbstractServiceModel):
|
|||||||
class Meta:
|
class Meta:
|
||||||
permissions = (
|
permissions = (
|
||||||
("access_mumble", "Can access the Mumble service"),
|
("access_mumble", "Can access the Mumble service"),
|
||||||
("view_connection_history", "Can access the connection history of the Mumble service"),
|
|
||||||
)
|
)
|
||||||
|
@ -1,205 +0,0 @@
|
|||||||
{% extends "allianceauth/base-bs5.html" %}
|
|
||||||
|
|
||||||
{% load i18n %}
|
|
||||||
|
|
||||||
{% 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 col-lg-12 mb-3">
|
|
||||||
<div class="card-header">
|
|
||||||
<span class="card-title">{% translate "Server Connection History" %}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table w-100" id="table-mumble-connection-history">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="text-start">{% translate "User" %}</th>
|
|
||||||
<th class="text-start">{% translate "Displayed Name" %}</th>
|
|
||||||
<th class="text-start">{% translate "Release" %}</th>
|
|
||||||
<th class="text-start">{% translate "Version" %}</th>
|
|
||||||
<th class="text-end">{% translate "Last Connect" %}</th>
|
|
||||||
<th class="text-end">{% translate "Last Disconnect" %}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-6">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<span class="card-title">{% translate "Server Connection Breakdown" %}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-body">
|
|
||||||
<canvas id="pieChart"></canvas> <!-- Canvas element for the pie chart -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-lg-6">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<span class="card-title">{% translate "Server Connection Breakdown" %}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table w-100" id="table-mumble-connection-stats">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="text-start">{% translate "Version" %}</th>
|
|
||||||
<th class="text-end">{% 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 %}
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(document).ready(function () {
|
|
||||||
const MUMBLESTATS_DATETIME_FORMAT = 'YYYY-MM-DD, HH:mm';
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
$("#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',
|
|
||||||
render: (data) => {
|
|
||||||
return moment(data).utc().format(MUMBLESTATS_DATETIME_FORMAT);
|
|
||||||
},
|
|
||||||
className: 'text-end',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: 'last_disconnect',
|
|
||||||
render: (data) => {
|
|
||||||
return moment(data).utc().format(MUMBLESTATS_DATETIME_FORMAT);
|
|
||||||
},
|
|
||||||
className: 'text-end',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
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', className: 'text-end' },
|
|
||||||
],
|
|
||||||
order: [[1, 'desc']],
|
|
||||||
processing: true,
|
|
||||||
stateSave: true,
|
|
||||||
stateDuration: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Initialize empty Pie chart
|
|
||||||
const ctx = document.getElementById('pieChart').getContext('2d');
|
|
||||||
const 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: (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: (xhr, status, error) => {
|
|
||||||
console.error('Error fetching pie chart data:', status, error);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock extra_javascript %}
|
|
||||||
|
|
||||||
{% block extra_css %}
|
|
||||||
{% include "bundles/datatables-css-bs5.html" %}
|
|
||||||
{% endblock extra_css %}
|
|
@ -48,9 +48,4 @@
|
|||||||
</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,10 +10,6 @@ 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,11 +3,6 @@ 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
|
||||||
|
|
||||||
@ -40,51 +35,3 @@ 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)),
|
|
||||||
})
|
|
||||||
|
@ -10,6 +10,11 @@
|
|||||||
<i class="fa-solid fa-gauge-high fa-fw"></i> {% translate "Dashboard" %}
|
<i class="fa-solid fa-gauge-high fa-fw"></i> {% translate "Dashboard" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="{% navactive request 'groupmanagement:groups' %}" href="{% url 'groupmanagement:groups' %}">
|
||||||
|
<i class="fa-solid fa-users fa-fw"></i> {% translate "Groups" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
{% menu_items %}
|
{% menu_items %}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
<!-- Start Chart.js js from cdnjs -->
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.min.js" integrity="sha512-CQBWl4fJHWbryGE+Pc7UAxWMUMNMWzWxF4SQo9CgkJIN1kx6djDQZjh3Y8SZ1d+6I+1zze6Z7kHXO7q3UyZAWw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
||||||
<!-- End Chart.js js from cdnjs -->
|
|
@ -45,7 +45,7 @@ class BootstrapDarkThemeHook(ThemeHook):
|
|||||||
self,
|
self,
|
||||||
"Bootstrap Dark",
|
"Bootstrap Dark",
|
||||||
"Powerful, extensible, and feature-packed frontend toolkit.",
|
"Powerful, extensible, and feature-packed frontend toolkit.",
|
||||||
html_tags={"data-theme": "bootstrap-dark", "data-bs-theme":"dark"},
|
html_tags={"data-theme": "bootstrap-dark"},
|
||||||
css=CSS_STATICS,
|
css=CSS_STATICS,
|
||||||
js=JS_STATICS,
|
js=JS_STATICS,
|
||||||
header_padding="3.5em"
|
header_padding="3.5em"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user