mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-25 20:22:28 +02:00
Compare commits
32 Commits
acff3695bc
...
bd17b95cac
Author | SHA1 | Date | |
---|---|---|---|
|
bd17b95cac | ||
|
4ed1c5b7c4 | ||
|
271fd8e8c4 | ||
|
9b4321281a | ||
|
052c35c8e5 | ||
|
0fcb517b0b | ||
|
dcfddf0add | ||
|
4a4258d0e6 | ||
|
dd15a221aa | ||
|
737e02293a | ||
|
c34efebacf | ||
|
4602097399 | ||
|
7051e06564 | ||
|
9767ce79d8 | ||
|
0c090f1486 | ||
|
618ee81f9b | ||
|
98efb9f887 | ||
|
cbe6c821cc | ||
|
de9d2b39a6 | ||
|
0d5f22288b | ||
|
e0d76dc268 | ||
|
ecc9e68330 | ||
|
710149ec21 | ||
|
3c2c137dad | ||
|
a8271c4189 | ||
|
3315ae7778 | ||
|
d2f048f8fe | ||
|
0fe2855faa | ||
|
79a1fa3d7c | ||
|
96fe88d5c7 | ||
|
59391ad3c5 | ||
|
94e9c08422 |
@ -5,7 +5,7 @@ manage online service access.
|
||||
# This will make sure the app is always imported when
|
||||
# Django starts so that shared_task will use this app.
|
||||
|
||||
__version__ = '4.2.2'
|
||||
__version__ = '4.3.0'
|
||||
__title__ = 'Alliance Auth'
|
||||
__url__ = 'https://gitlab.com/allianceauth/allianceauth'
|
||||
NAME = f'{__title__} v{__version__}'
|
||||
|
3
allianceauth/custom_css/__init__.py
Normal file
3
allianceauth/custom_css/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
"""
|
||||
Initializes the custom_css module.
|
||||
"""
|
25
allianceauth/custom_css/admin.py
Normal file
25
allianceauth/custom_css/admin.py
Normal file
@ -0,0 +1,25 @@
|
||||
"""
|
||||
Admin classes for custom_css app
|
||||
"""
|
||||
|
||||
# Django
|
||||
from django.contrib import admin
|
||||
|
||||
# Django Solos
|
||||
from solo.admin import SingletonModelAdmin
|
||||
|
||||
# Alliance Auth Custom CSS
|
||||
from allianceauth.custom_css.models import CustomCSS
|
||||
from allianceauth.custom_css.forms import CustomCSSAdminForm
|
||||
|
||||
|
||||
@admin.register(CustomCSS)
|
||||
class CustomCSSAdmin(SingletonModelAdmin):
|
||||
"""
|
||||
Custom CSS Admin
|
||||
"""
|
||||
|
||||
form = CustomCSSAdminForm
|
||||
|
||||
# Leave this here for when we decide to add syntax highlighting to the CSS editor
|
||||
# change_form_template = 'custom_css/admin/change_form.html'
|
13
allianceauth/custom_css/apps.py
Normal file
13
allianceauth/custom_css/apps.py
Normal file
@ -0,0 +1,13 @@
|
||||
"""
|
||||
Django app configuration for custom_css
|
||||
"""
|
||||
|
||||
# Django
|
||||
from django.apps import AppConfig
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class CustomCSSConfig(AppConfig):
|
||||
name = "allianceauth.custom_css"
|
||||
label = "custom_css"
|
||||
verbose_name = _("Custom CSS")
|
29
allianceauth/custom_css/forms.py
Normal file
29
allianceauth/custom_css/forms.py
Normal file
@ -0,0 +1,29 @@
|
||||
"""
|
||||
Forms for custom_css app
|
||||
"""
|
||||
|
||||
# Alliance Auth Custom CSS
|
||||
from allianceauth.custom_css.models import CustomCSS
|
||||
from allianceauth.custom_css.widgets import CssEditorWidget
|
||||
|
||||
# Django
|
||||
from django import forms
|
||||
|
||||
|
||||
class CustomCSSAdminForm(forms.ModelForm):
|
||||
"""
|
||||
Form for editing custom CSS
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = CustomCSS
|
||||
fields = ("css",)
|
||||
widgets = {
|
||||
"css": CssEditorWidget(
|
||||
attrs={
|
||||
"style": "width: 90%; height: 100%;",
|
||||
"data-editor": "code-highlight",
|
||||
"data-language": "css",
|
||||
}
|
||||
)
|
||||
}
|
42
allianceauth/custom_css/migrations/0001_initial.py
Normal file
42
allianceauth/custom_css/migrations/0001_initial.py
Normal file
@ -0,0 +1,42 @@
|
||||
# Generated by Django 4.2.15 on 2024-08-14 11:25
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="CustomCSS",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"css",
|
||||
models.TextField(
|
||||
blank=True,
|
||||
help_text="This CSS will be added to the site after the default CSS.",
|
||||
null=True,
|
||||
verbose_name="Your custom CSS",
|
||||
),
|
||||
),
|
||||
("timestamp", models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Custom CSS",
|
||||
"verbose_name_plural": "Custom CSS",
|
||||
"default_permissions": (),
|
||||
},
|
||||
),
|
||||
]
|
0
allianceauth/custom_css/migrations/__init__.py
Normal file
0
allianceauth/custom_css/migrations/__init__.py
Normal file
143
allianceauth/custom_css/models.py
Normal file
143
allianceauth/custom_css/models.py
Normal file
@ -0,0 +1,143 @@
|
||||
"""
|
||||
Models for the custom_css app
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
# Django Solo
|
||||
from solo.models import SingletonModel
|
||||
|
||||
# Django
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class CustomCSS(SingletonModel):
|
||||
"""
|
||||
Model for storing custom CSS for the site
|
||||
"""
|
||||
|
||||
css = models.TextField(
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name=_("Your custom CSS"),
|
||||
help_text=_("This CSS will be added to the site after the default CSS."),
|
||||
)
|
||||
timestamp = models.DateTimeField(auto_now=True)
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
Meta for CustomCSS
|
||||
"""
|
||||
|
||||
default_permissions = ()
|
||||
verbose_name = _("Custom CSS")
|
||||
verbose_name_plural = _("Custom CSS")
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""
|
||||
String representation of CustomCSS
|
||||
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
|
||||
return str(_("Custom CSS"))
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
"""
|
||||
Save method for CustomCSS
|
||||
|
||||
:param args:
|
||||
:type args:
|
||||
:param kwargs:
|
||||
:type kwargs:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
|
||||
self.pk = 1
|
||||
|
||||
if self.css and len(self.css.replace(" ", "")) > 0:
|
||||
# Write the custom CSS to a file
|
||||
custom_css_file = open(
|
||||
f"{settings.STATIC_ROOT}allianceauth/custom-styles.css", "w+"
|
||||
)
|
||||
custom_css_file.write(self.compress_css())
|
||||
custom_css_file.close()
|
||||
else:
|
||||
# Remove the custom CSS file
|
||||
try:
|
||||
os.remove(f"{settings.STATIC_ROOT}allianceauth/custom-styles.css")
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def compress_css(self) -> str:
|
||||
"""
|
||||
Compress CSS
|
||||
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
|
||||
css = self.css
|
||||
new_css = ""
|
||||
|
||||
# Remove comments
|
||||
css = re.sub(pattern=r"\s*/\*\s*\*/", repl="$$HACK1$$", string=css)
|
||||
css = re.sub(pattern=r"/\*[\s\S]*?\*/", repl="", string=css)
|
||||
css = css.replace("$$HACK1$$", "/**/")
|
||||
|
||||
# url() doesn't need quotes
|
||||
css = re.sub(pattern=r'url\((["\'])([^)]*)\1\)', repl=r"url(\2)", string=css)
|
||||
|
||||
# Spaces may be safely collapsed as generated content will collapse them anyway.
|
||||
css = re.sub(pattern=r"\s+", repl=" ", string=css)
|
||||
|
||||
# Shorten collapsable colors: #aabbcc to #abc
|
||||
css = re.sub(
|
||||
pattern=r"#([0-9a-f])\1([0-9a-f])\2([0-9a-f])\3(\s|;)",
|
||||
repl=r"#\1\2\3\4",
|
||||
string=css,
|
||||
)
|
||||
|
||||
# Fragment values can loose zeros
|
||||
css = re.sub(
|
||||
pattern=r":\s*0(\.\d+([cm]m|e[mx]|in|p[ctx]))\s*;", repl=r":\1;", string=css
|
||||
)
|
||||
|
||||
for rule in re.findall(pattern=r"([^{]+){([^}]*)}", string=css):
|
||||
# We don't need spaces around operators
|
||||
selectors = [
|
||||
re.sub(
|
||||
pattern=r"(?<=[\[\(>+=])\s+|\s+(?=[=~^$*|>+\]\)])",
|
||||
repl=r"",
|
||||
string=selector.strip(),
|
||||
)
|
||||
for selector in rule[0].split(",")
|
||||
]
|
||||
|
||||
# Order is important, but we still want to discard repetitions
|
||||
properties = {}
|
||||
porder = []
|
||||
|
||||
for prop in re.findall(pattern="(.*?):(.*?)(;|$)", string=rule[1]):
|
||||
key = prop[0].strip().lower()
|
||||
|
||||
if key not in porder:
|
||||
porder.append(key)
|
||||
|
||||
properties[key] = prop[1].strip()
|
||||
|
||||
# output rule if it contains any declarations
|
||||
if properties:
|
||||
new_css += "{}{{{}}}".format(
|
||||
",".join(selectors),
|
||||
"".join([f"{key}:{properties[key]};" for key in porder])[:-1],
|
||||
)
|
||||
|
||||
return new_css
|
@ -0,0 +1,48 @@
|
||||
{% extends "admin/change_form.html" %}
|
||||
|
||||
{% block field_sets %}
|
||||
{% for fieldset in adminform %}
|
||||
<fieldset class="module aligned {{ fieldset.classes }}">
|
||||
{% if fieldset.name %}<h2>{{ fieldset.name }}</h2>{% endif %}
|
||||
|
||||
{% if fieldset.description %}
|
||||
<div class="description">{{ fieldset.description|safe }}</div>
|
||||
{% endif %}
|
||||
|
||||
{% for line in fieldset %}
|
||||
<div class="form-row{% if line.fields|length == 1 and line.errors %} errors{% endif %}{% if not line.has_visible_field %} hidden{% endif %}{% for field in line %}{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% endfor %}">
|
||||
{% if line.fields|length == 1 %}{{ line.errors }}{% else %}<div class="flex-container form-multiline">{% endif %}
|
||||
|
||||
{% for field in line %}
|
||||
<div>
|
||||
{% if not line.fields|length == 1 and not field.is_readonly %}{{ field.errors }}{% endif %}
|
||||
|
||||
<div class="flex-container{% if not line.fields|length == 1 %} fieldBox{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% if not field.is_readonly and field.errors %} errors{% endif %}{% if field.field.is_hidden %} hidden{% endif %}{% elif field.is_checkbox %} checkbox-row{% endif %}">
|
||||
{% if field.is_checkbox %}
|
||||
{{ field.field }}{{ field.label_tag }}
|
||||
{% else %}
|
||||
{{ field.label_tag }}
|
||||
{% if field.is_readonly %}
|
||||
<div class="readonly">{{ field.contents }}</div>
|
||||
{% else %}
|
||||
{{ field.field }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if field.field.help_text %}
|
||||
<div class="help"{% if field.field.id_for_label %} id="{{ field.field.id_for_label }}_helptext"{% endif %}>
|
||||
<div>{{ field.field.help_text|safe }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
{% if not line.fields|length == 1 %}</div>{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</fieldset>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block after_field_sets %}{% endblock %}
|
@ -0,0 +1,3 @@
|
||||
{% load custom_css %}
|
||||
|
||||
{% custom_css_static 'allianceauth/custom-styles.css' %}
|
3
allianceauth/custom_css/templatetags/__init__.py
Normal file
3
allianceauth/custom_css/templatetags/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
"""
|
||||
Init file for custom_css templatetags
|
||||
"""
|
48
allianceauth/custom_css/templatetags/custom_css.py
Normal file
48
allianceauth/custom_css/templatetags/custom_css.py
Normal file
@ -0,0 +1,48 @@
|
||||
"""
|
||||
Custom template tags for custom_css app
|
||||
"""
|
||||
|
||||
# Alliance Auth Custom CSS
|
||||
from allianceauth.custom_css.models import CustomCSS
|
||||
|
||||
# Django
|
||||
from django.conf import settings
|
||||
from django.template.defaulttags import register
|
||||
from django.templatetags.static import static
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def custom_css_static(path: str) -> str:
|
||||
"""
|
||||
Versioned static URL
|
||||
This is to make sure to break the browser cache on CSS updates.
|
||||
|
||||
Example: /static/allianceauth/custom-styles.css?v=1234567890
|
||||
|
||||
:param path:
|
||||
:type path:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
|
||||
try:
|
||||
Path(f"{settings.STATIC_ROOT}{path}").resolve(strict=True)
|
||||
except FileNotFoundError:
|
||||
return ""
|
||||
else:
|
||||
try:
|
||||
custom_css = CustomCSS.objects.get(pk=1)
|
||||
except CustomCSS.DoesNotExist:
|
||||
return ""
|
||||
else:
|
||||
custom_css_changed = custom_css.timestamp.timestamp()
|
||||
custom_css_version = (
|
||||
str(custom_css_changed).replace(" ", "").replace(":", "").replace("-", "")
|
||||
) # remove spaces, colons, and dashes
|
||||
static_url = static(path)
|
||||
versioned_url = static_url + "?v=" + custom_css_version
|
||||
|
||||
return mark_safe(f'<link rel="stylesheet" href="{versioned_url}">')
|
38
allianceauth/custom_css/widgets.py
Normal file
38
allianceauth/custom_css/widgets.py
Normal file
@ -0,0 +1,38 @@
|
||||
"""
|
||||
Form widgets for custom_css app
|
||||
"""
|
||||
|
||||
# Django
|
||||
from django import forms
|
||||
|
||||
# Alliance Auth
|
||||
from allianceauth.custom_css.models import CustomCSS
|
||||
|
||||
|
||||
class CssEditorWidget(forms.Textarea):
|
||||
"""
|
||||
Widget for editing CSS
|
||||
"""
|
||||
|
||||
def __init__(self, attrs=None):
|
||||
default_attrs = {"class": "custom-css-editor"}
|
||||
|
||||
if attrs:
|
||||
default_attrs.update(attrs)
|
||||
|
||||
super().__init__(default_attrs)
|
||||
|
||||
# For when we want to add some sort of syntax highlight to it, which is not that
|
||||
# easy to do on a textarea field though.
|
||||
# `highlight.js` is just used as an example here, and doesn't work on a textarea field.
|
||||
# class Media:
|
||||
# css = {
|
||||
# "all": (
|
||||
# "/static/custom_css/libs/highlight.js/11.10.0/styles/github.min.css",
|
||||
# )
|
||||
# }
|
||||
# js = (
|
||||
# "/static/custom_css/libs/highlight.js/11.10.0/highlight.min.js",
|
||||
# "/static/custom_css/libs/highlight.js/11.10.0/languages/css.min.js",
|
||||
# "/static/custom_css/javascript/custom-css.min.js",
|
||||
# )
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-05-12 19:15+1000\n"
|
||||
"POT-Creation-Date: 2024-09-09 13:05+1000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -88,27 +88,31 @@ msgstr ""
|
||||
msgid "Ukrainian"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/models.py:96
|
||||
#: allianceauth/authentication/models.py:81
|
||||
msgid "Polish"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/models.py:97
|
||||
#: allianceauth/menu/templates/menu/menu-user.html:42
|
||||
msgid "Language"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/models.py:101
|
||||
#: allianceauth/authentication/models.py:102
|
||||
#: allianceauth/templates/allianceauth/night-toggle.html:6
|
||||
msgid "Night Mode"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/models.py:105
|
||||
#: allianceauth/authentication/models.py:106
|
||||
#: allianceauth/menu/templates/menu/menu-user.html:46
|
||||
msgid "Theme"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/models.py:122
|
||||
#: allianceauth/authentication/models.py:123
|
||||
#, python-format
|
||||
msgid "State changed to: %s"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/models.py:123
|
||||
#: allianceauth/authentication/models.py:124
|
||||
#, python-format
|
||||
msgid "Your user's state is now: %(state)s"
|
||||
msgstr ""
|
||||
@ -120,27 +124,27 @@ msgstr ""
|
||||
msgid "Dashboard"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:7
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:5
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:33
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:54
|
||||
msgid "Characters"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:13
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:14
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:11
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:12
|
||||
#: allianceauth/templates/allianceauth/top-menu-rh-default.html:4
|
||||
#: allianceauth/templates/allianceauth/top-menu-rh-default.html:6
|
||||
msgid "Add Character"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:16
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:17
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:14
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:15
|
||||
#: allianceauth/templates/allianceauth/top-menu-rh-default.html:10
|
||||
#: allianceauth/templates/allianceauth/top-menu-rh-default.html:12
|
||||
msgid "Change Main"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:24
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:22
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:89
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:31
|
||||
@ -149,12 +153,12 @@ msgstr ""
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:25
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:23
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:33
|
||||
msgid "Corp"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:26
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_characters.html:24
|
||||
#: allianceauth/corputils/templates/corputils/corpstats.html:125
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:63
|
||||
msgid "Alliance"
|
||||
@ -164,7 +168,7 @@ msgstr ""
|
||||
msgid "Membership"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_groups.html:8
|
||||
#: allianceauth/authentication/templates/authentication/dashboard_groups.html:10
|
||||
msgid "State:"
|
||||
msgstr ""
|
||||
|
||||
@ -395,6 +399,19 @@ msgstr ""
|
||||
msgid "Failed to gather corporation statistics with selected token."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/custom_css/apps.py:13 allianceauth/custom_css/models.py:36
|
||||
#: allianceauth/custom_css/models.py:37 allianceauth/custom_css/models.py:47
|
||||
msgid "Custom CSS"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/custom_css/models.py:25
|
||||
msgid "Your custom CSS"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/custom_css/models.py:26
|
||||
msgid "This CSS will be added to the site after the default CSS."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/fleetactivitytracking/auth_hooks.py:10
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html:10
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkcreate.html:11
|
||||
@ -487,8 +504,8 @@ msgstr ""
|
||||
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:37
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:42
|
||||
#: allianceauth/optimer/form.py:13 allianceauth/timerboard/form.py:59
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:16
|
||||
#: allianceauth/optimer/form.py:13 allianceauth/timerboard/form.py:37
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:17
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:9
|
||||
msgid "System"
|
||||
msgstr ""
|
||||
@ -807,7 +824,7 @@ msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||
#: allianceauth/optimer/templates/optimer/dashboard.ops.html:15
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:15
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:16
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
@ -899,7 +916,7 @@ msgid "Hidden"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:19
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:16
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
@ -1375,16 +1392,16 @@ msgstr ""
|
||||
msgid "Super User"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/menu/templates/menu/menu-user.html:68
|
||||
#: allianceauth/menu/templates/menu/menu-user.html:70
|
||||
#: allianceauth/templates/allianceauth/top-menu-admin.html:9
|
||||
msgid "Admin"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/menu/templates/menu/menu-user.html:80
|
||||
#: allianceauth/menu/templates/menu/menu-user.html:82
|
||||
msgid "Sign Out"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/menu/templates/menu/menu-user.html:84
|
||||
#: allianceauth/menu/templates/menu/menu-user.html:86
|
||||
#: allianceauth/templates/allianceauth/top-menu-rh-default.html:17
|
||||
#: allianceauth/templates/allianceauth/top-menu-rh-default.html:18
|
||||
msgid "Sign In"
|
||||
@ -1534,7 +1551,7 @@ msgid "Form Up System"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/optimer/templates/optimer/dashboard.ops.html:17
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:17
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:18
|
||||
msgid "EVE Time"
|
||||
msgstr ""
|
||||
|
||||
@ -1729,17 +1746,17 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:26
|
||||
#: allianceauth/services/modules/mumble/templates/services/mumble/mumble_service_ctrl.html:20
|
||||
#: allianceauth/services/modules/mumble/templates/services/mumble/mumble_service_ctrl.html:22
|
||||
msgid "Activate"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:32
|
||||
#: allianceauth/services/modules/mumble/templates/services/mumble/mumble_service_ctrl.html:32
|
||||
#: allianceauth/services/modules/mumble/templates/services/mumble/mumble_service_ctrl.html:34
|
||||
msgid "Reset Password"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:38
|
||||
#: allianceauth/services/modules/mumble/templates/services/mumble/mumble_service_ctrl.html:38
|
||||
#: allianceauth/services/modules/mumble/templates/services/mumble/mumble_service_ctrl.html:40
|
||||
msgid "Deactivate"
|
||||
msgstr ""
|
||||
|
||||
@ -1819,12 +1836,12 @@ msgstr ""
|
||||
msgid "Deactivated IPSuite4 account."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/services/modules/mumble/templates/services/mumble/mumble_service_ctrl.html:26
|
||||
#: allianceauth/services/modules/mumble/templates/services/mumble/mumble_service_ctrl.html:28
|
||||
#: allianceauth/services/templates/services/service_password.html:26
|
||||
msgid "Set Password"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/services/modules/mumble/templates/services/mumble/mumble_service_ctrl.html:44
|
||||
#: allianceauth/services/modules/mumble/templates/services/mumble/mumble_service_ctrl.html:46
|
||||
msgid "Connect"
|
||||
msgstr ""
|
||||
|
||||
@ -2386,56 +2403,56 @@ msgstr ""
|
||||
msgid "Your Server received an ESI error response code of "
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:11
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:8
|
||||
msgid "Alliance Auth Notifications"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:21
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:18
|
||||
msgid "Closed"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:27
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:24
|
||||
msgid "No notifications at this time"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:36
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:33
|
||||
msgid "Powered by GitLab"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:42
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:39
|
||||
msgid "Support Discord"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:59
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:63
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:53
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:57
|
||||
msgid "Software Version"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:66
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:60
|
||||
msgid "Current"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:73
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:67
|
||||
msgid "Latest Stable"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:78
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:72
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:86
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:80
|
||||
msgid "Latest Pre-Release"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:91
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:85
|
||||
msgid "Pre-Release available"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:102
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:95
|
||||
msgid "Task Queue"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:107
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:100
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
@ -2444,11 +2461,11 @@ msgid ""
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:123
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:116
|
||||
msgid "running"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:124
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:117
|
||||
msgid "queued"
|
||||
msgstr ""
|
||||
|
||||
@ -2477,105 +2494,203 @@ msgstr ""
|
||||
msgid "Select Theme"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:53
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:172
|
||||
msgid "Other"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:54
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:38
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:44
|
||||
msgid "Friendly"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:55
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:33
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:38
|
||||
msgid "Hostile"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:56
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:43
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:50
|
||||
msgid "Neutral"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:58
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:13
|
||||
#: allianceauth/timerboard/form.py:36
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:14
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:7
|
||||
msgid "Details"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:60
|
||||
#: allianceauth/timerboard/form.py:38
|
||||
msgid "Planet/Moon"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:61
|
||||
#: allianceauth/timerboard/form.py:39
|
||||
msgid "Structure Type"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:62
|
||||
#: allianceauth/timerboard/form.py:40
|
||||
msgid "Timer Type"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:63
|
||||
#: allianceauth/timerboard/form.py:41
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:8
|
||||
msgid "Objective"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:64
|
||||
#: allianceauth/timerboard/form.py:42
|
||||
msgid "Absolute Timer"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:65
|
||||
#: allianceauth/timerboard/form.py:43
|
||||
msgid "Date and Time"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:66
|
||||
#: allianceauth/timerboard/form.py:44
|
||||
msgid "Days Remaining"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:67
|
||||
#: allianceauth/timerboard/form.py:45
|
||||
msgid "Hours Remaining"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:69
|
||||
#: allianceauth/timerboard/form.py:47
|
||||
msgid "Minutes Remaining"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:71
|
||||
#: allianceauth/timerboard/form.py:48
|
||||
msgid "Important"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/form.py:72
|
||||
#: allianceauth/timerboard/form.py:49
|
||||
msgid "Corp-Restricted"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:13
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:39
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:36
|
||||
msgid "Friendly"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:14
|
||||
msgid "Not Specified"
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:34
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:34
|
||||
msgid "Hostile"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:15
|
||||
msgid "Shield"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:16
|
||||
msgid "Armor"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:17
|
||||
msgid "Hull"
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:44
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:38
|
||||
msgid "Neutral"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:18
|
||||
msgid "Final"
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:48
|
||||
msgid "POCO"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:19
|
||||
msgid "Anchoring"
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:50
|
||||
msgid "Orbital Skyhook"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:20
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:52
|
||||
msgid "I-HUB"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:21
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:54
|
||||
msgid "TCU"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:22
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:56
|
||||
msgid "POS [S]"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:23
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:58
|
||||
msgid "POS [M]"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:24
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:60
|
||||
msgid "POS [L]"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:25
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:62
|
||||
msgid "Astrahus"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:26
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:64
|
||||
msgid "Fortizar"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:27
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:66
|
||||
msgid "Keepstar"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:28
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:68
|
||||
msgid "Raitaru"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:29
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:70
|
||||
msgid "Azbel"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:30
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:72
|
||||
msgid "Sotiyo"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:31
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:74
|
||||
msgid "Athanor"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:32
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:76
|
||||
msgid "Tatara"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:33
|
||||
msgid "Pharolux Cyno Beacon"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:34
|
||||
msgid "Tenebrex Cyno Jammer"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:35
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:82
|
||||
msgid "Ansiblex Jump Gate"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:36
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:84
|
||||
msgid "Moon Mining Cycle"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:37
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:86
|
||||
msgid "Metenox Moon Drill"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:38
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:88
|
||||
msgid "Other"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:45
|
||||
msgid "Not Specified"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:46
|
||||
msgid "Shield"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:47
|
||||
msgid "Armor"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:48
|
||||
msgid "Hull"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:49
|
||||
msgid "Final"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:50
|
||||
msgid "Anchoring"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/models.py:51
|
||||
msgid "Unanchoring"
|
||||
msgstr ""
|
||||
|
||||
@ -2584,7 +2699,7 @@ msgstr ""
|
||||
msgid "Upcoming Timers"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:14
|
||||
#: allianceauth/timerboard/templates/timerboard/dashboard.timers.html:15
|
||||
msgid "Timer"
|
||||
msgstr ""
|
||||
|
||||
@ -2628,78 +2743,14 @@ msgstr ""
|
||||
msgid "Structure"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:64
|
||||
msgid "POCO"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:70
|
||||
msgid "I-HUB"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:76
|
||||
msgid "TCU"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:82
|
||||
msgid "POS [S]"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:88
|
||||
msgid "POS [M]"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:94
|
||||
msgid "POS [L]"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:100
|
||||
msgid "Astrahus"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:106
|
||||
msgid "Fortizar"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:112
|
||||
msgid "Keepstar"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:118
|
||||
msgid "Raitaru"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:124
|
||||
msgid "Azbel"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:130
|
||||
msgid "Sotiyo"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:136
|
||||
msgid "Athanor"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:142
|
||||
msgid "Tatara"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:148
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:78
|
||||
msgid "Cyno Beacon"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:154
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:80
|
||||
msgid "Cyno Jammer"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:160
|
||||
msgid "Ansiblex Jump Gate"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/timertable.html:166
|
||||
msgid "Moon Mining Cycle"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/timerboard/templates/timerboard/view.html:9
|
||||
msgid "Structure Timer Management"
|
||||
msgstr ""
|
||||
|
@ -22,6 +22,7 @@ INSTALLED_APPS = [
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.humanize',
|
||||
'django_celery_beat',
|
||||
'solo',
|
||||
'bootstrapform',
|
||||
'django_bootstrap5', # https://github.com/zostera/django-bootstrap5
|
||||
'sortedm2m',
|
||||
@ -39,6 +40,7 @@ INSTALLED_APPS = [
|
||||
'allianceauth.theme.darkly',
|
||||
'allianceauth.theme.flatly',
|
||||
'allianceauth.theme.materia',
|
||||
"allianceauth.custom_css",
|
||||
]
|
||||
|
||||
SECRET_KEY = "wow I'm a really bad default secret key"
|
||||
|
@ -35,6 +35,8 @@
|
||||
</style>
|
||||
|
||||
{% block extra_css %}{% endblock extra_css %}
|
||||
|
||||
{% include 'custom_css/bundles/custom-css.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -27,6 +27,7 @@ class BootstrapThemeHook(ThemeHook):
|
||||
self,
|
||||
"Bootstrap",
|
||||
"Powerful, extensible, and feature-packed frontend toolkit.",
|
||||
html_tags={"data-theme": "bootstrap"},
|
||||
css=CSS_STATICS,
|
||||
js=JS_STATICS,
|
||||
header_padding="3.5em"
|
||||
@ -44,9 +45,9 @@ class BootstrapDarkThemeHook(ThemeHook):
|
||||
self,
|
||||
"Bootstrap Dark",
|
||||
"Powerful, extensible, and feature-packed frontend toolkit.",
|
||||
html_tags={"data-theme": "bootstrap-dark"},
|
||||
css=CSS_STATICS,
|
||||
js=JS_STATICS,
|
||||
html_tags="data-bs-theme=dark",
|
||||
header_padding="3.5em"
|
||||
)
|
||||
|
||||
|
@ -13,6 +13,7 @@ class DarklyThemeHook(ThemeHook):
|
||||
self,
|
||||
"Darkly",
|
||||
"Flatly in night mode!",
|
||||
html_tags={"data-theme": "darkly"},
|
||||
css=[{
|
||||
"url": "https://cdnjs.cloudflare.com/ajax/libs/bootswatch/5.3.3/darkly/bootstrap.min.css",
|
||||
"integrity": "sha512-HDszXqSUU0om4Yj5dZOUNmtwXGWDa5ppESlX98yzbBS+z+3HQ8a/7kcdI1dv+jKq+1V5b01eYurE7+yFjw6Rdg=="
|
||||
|
@ -13,6 +13,7 @@ class FlatlyThemeHook(ThemeHook):
|
||||
self,
|
||||
"Flatly",
|
||||
"Flat and modern!",
|
||||
html_tags={"data-theme": "flatly"},
|
||||
css=[{
|
||||
"url": "https://cdnjs.cloudflare.com/ajax/libs/bootswatch/5.3.3/flatly/bootstrap.min.css",
|
||||
"integrity": "sha512-qoT4KwnRpAQ9uczPsw7GunsNmhRnYwSlE2KRCUPRQHSkDuLulCtDXuC2P/P6oqr3M5hoGagUG9pgHDPkD2zCDA=="
|
||||
|
@ -1,10 +1,10 @@
|
||||
from typing import List, Optional
|
||||
from typing import List, Optional, Union
|
||||
|
||||
|
||||
class ThemeHook:
|
||||
"""
|
||||
Theme hook for injecting a Bootstrap 5 Theme and associated JS into alliance auth.
|
||||
these can be local or CDN delivered
|
||||
Theme hook for injecting a Bootstrap 5 Theme and associated JS into alliance auth.
|
||||
These can be local or CDN delivered.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
@ -14,7 +14,7 @@ class ThemeHook:
|
||||
js: List[dict],
|
||||
css_template: Optional[str] = None,
|
||||
js_template: Optional[str] = None,
|
||||
html_tags: Optional[str] = "",
|
||||
html_tags: Optional[Union[dict, str]] = None,
|
||||
header_padding: Optional[str] = "4em"):
|
||||
"""
|
||||
:param name: Theme python name
|
||||
@ -29,6 +29,10 @@ class ThemeHook:
|
||||
:type css_template: Optional[str], optional
|
||||
:param js_template: _description_, defaults to None
|
||||
:type js_template: Optional[str], optional
|
||||
:param html_tags: Attributes added to the `<html>` tag, defaults to None
|
||||
:type html_tags: Optional[dict|str], optional
|
||||
:param header_padding: Top padding, defaults to "4em"
|
||||
:type header_padding: Optional[str], optional
|
||||
"""
|
||||
self.name = name
|
||||
self.description = description
|
||||
@ -41,7 +45,11 @@ class ThemeHook:
|
||||
self.css_template = css_template
|
||||
self.js_template = js_template
|
||||
|
||||
self.html_tags = html_tags
|
||||
self.html_tags = (
|
||||
" ".join([f"{key}={value}" for key, value in html_tags.items()])
|
||||
if isinstance(html_tags, dict)
|
||||
else html_tags
|
||||
)
|
||||
self.header_padding = header_padding
|
||||
def get_name(self):
|
||||
return f"{self.__class__.__module__}.{self.__class__.__name__}"
|
||||
|
@ -13,6 +13,7 @@ class MateriaThemeHook(ThemeHook):
|
||||
self,
|
||||
"Materia",
|
||||
"Material is the metaphor",
|
||||
html_tags={"data-theme": "materia"},
|
||||
css=[{
|
||||
"url": "https://cdnjs.cloudflare.com/ajax/libs/bootswatch/5.3.3/materia/bootstrap.min.css",
|
||||
"integrity": "sha512-2S9Do+uTmZmmJpdmAcOKdUrK/YslcvAuRfIF2ws8+BW9AvZXMRZM+o8Wq+PZrfISD6ZlIaeCWWZAdeprXIoYuQ=="
|
||||
|
@ -1,11 +1,12 @@
|
||||
import logging
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
from django import forms
|
||||
from django.utils import timezone
|
||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from .models import Timer, TimerType
|
||||
from .models import Timer
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -32,54 +33,28 @@ class TimerForm(forms.ModelForm):
|
||||
kwargs.update({'initial': initial})
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
structure_choices = [('POCO', 'POCO'),
|
||||
('I-HUB', 'I-HUB'),
|
||||
('TCU', 'TCU'),
|
||||
('POS[S]', 'POS[S]'),
|
||||
('POS[M]', 'POS[M]'),
|
||||
('POS[L]', 'POS[L]'),
|
||||
('Astrahus', 'Astrahus'),
|
||||
('Fortizar', 'Fortizar'),
|
||||
('Keepstar', 'Keepstar'),
|
||||
('Raitaru', 'Raitaru'),
|
||||
('Azbel', 'Azbel'),
|
||||
('Sotiyo', 'Sotiyo'),
|
||||
('Athanor', 'Athanor'),
|
||||
('Tatara', 'Tatara'),
|
||||
('Pharolux Cyno Beacon', 'Pharolux Cyno Beacon'),
|
||||
('Tenebrex Cyno Jammer', 'Tenebrex Cyno Jammer'),
|
||||
('Ansiblex Jump Gate', 'Ansiblex Jump Gate'),
|
||||
('Moon Mining Cycle', 'Moon Mining Cycle'),
|
||||
(_('Other'), _('Other'))]
|
||||
objective_choices = [('Friendly', _('Friendly')),
|
||||
('Hostile', _('Hostile')),
|
||||
('Neutral', _('Neutral'))]
|
||||
|
||||
details = forms.CharField(max_length=254, required=True, label=_('Details'))
|
||||
system = forms.CharField(max_length=254, required=True, label=_("System"))
|
||||
planet_moon = forms.CharField(max_length=254, label=_("Planet/Moon"), required=False, initial="")
|
||||
structure = forms.ChoiceField(choices=structure_choices, required=True, label=_("Structure Type"))
|
||||
timer_type = forms.ChoiceField(choices=TimerType.choices, label=_("Timer Type"))
|
||||
objective = forms.ChoiceField(choices=objective_choices, required=True, label=_("Objective"))
|
||||
structure = forms.ChoiceField(choices=Timer.Structure.choices, required=True, label=_("Structure Type"))
|
||||
timer_type = forms.ChoiceField(choices=Timer.TimerType.choices, label=_("Timer Type"))
|
||||
objective = forms.ChoiceField(choices=Timer.Objective.choices, required=True, label=_("Objective"))
|
||||
absolute_checkbox = forms.BooleanField(label=_("Absolute Timer"), required=False, initial=False)
|
||||
absolute_time = forms.CharField(required=False,label=_("Date and Time"))
|
||||
days_left = forms.IntegerField(required=False, label=_("Days Remaining"), validators=[MinValueValidator(0)])
|
||||
hours_left = forms.IntegerField(required=False, label=_("Hours Remaining"),
|
||||
validators=[MinValueValidator(0), MaxValueValidator(23)])
|
||||
minutes_left = forms.IntegerField(required=False, label=_("Minutes Remaining"),
|
||||
validators=[MinValueValidator(0), MaxValueValidator(59)])
|
||||
minutes_left = forms.IntegerField(required=False, label=_("Minutes Remaining"), validators=[MinValueValidator(0), MaxValueValidator(59)])
|
||||
important = forms.BooleanField(label=_("Important"), required=False)
|
||||
corp_timer = forms.BooleanField(label=_("Corp-Restricted"), required=False)
|
||||
|
||||
|
||||
def save(self, commit=True):
|
||||
timer = super().save(commit=False)
|
||||
|
||||
# Get character
|
||||
character = self.user.profile.main_character
|
||||
corporation = character.corporation
|
||||
logger.debug("Determined timer save request on behalf "
|
||||
"of character {} corporation {}".format(character, corporation))
|
||||
logger.debug(f"Determined timer save request on behalf of character {character} corporation {corporation}")
|
||||
|
||||
days_left = self.cleaned_data['days_left']
|
||||
hours_left = self.cleaned_data['hours_left']
|
||||
|
@ -0,0 +1,28 @@
|
||||
# Generated by Django 4.2 on 2024-09-09 03:45
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('timerboard', '0005_alter_timer_planet_moon'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='timer',
|
||||
name='objective',
|
||||
field=models.CharField(choices=[('Friendly', 'Friendly'), ('Hostile', 'Hostile'), ('Neutral', 'Neutral')], default='Neutral', max_length=254),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='timer',
|
||||
name='structure',
|
||||
field=models.CharField(choices=[('POCO', 'POCO'), ('Orbital Skyhook', 'Orbital Skyhook'), ('I-HUB', 'I-HUB'), ('TCU', 'TCU'), ('POS[S]', 'POS [S]'), ('POS[M]', 'POS [M]'), ('POS[L]', 'POS [L]'), ('Astrahus', 'Astrahus'), ('Fortizar', 'Fortizar'), ('Keepstar', 'Keepstar'), ('Raitaru', 'Raitaru'), ('Azbel', 'Azbel'), ('Sotiyo', 'Sotiyo'), ('Athanor', 'Athanor'), ('Tatara', 'Tatara'), ('Pharolux Cyno Beacon', 'Pharolux Cyno Beacon'), ('Tenebrex Cyno Jammer', 'Tenebrex Cyno Jammer'), ('Ansiblex Jump Gate', 'Ansiblex Jump Gate'), ('Moon Mining Cycle', 'Moon Mining Cycle'), ('Metenox Moon Drill', 'Metenox Moon Drill'), ('Other', 'Other')], default='Other', max_length=254),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='timer',
|
||||
name='timer_type',
|
||||
field=models.CharField(choices=[('UNSPECIFIED', 'Not Specified'), ('SHIELD', 'Shield'), ('ARMOR', 'Armor'), ('HULL', 'Hull'), ('FINAL', 'Final'), ('ANCHORING', 'Anchoring'), ('UNANCHORING', 'Unanchoring'), ('ABANDONED', 'Abandoned')], default='UNSPECIFIED', max_length=254),
|
||||
),
|
||||
]
|
@ -6,34 +6,63 @@ from allianceauth.eveonline.models import EveCharacter
|
||||
from allianceauth.eveonline.models import EveCorporationInfo
|
||||
|
||||
|
||||
class TimerType(models.TextChoices):
|
||||
"""
|
||||
Choices for Timer Type
|
||||
"""
|
||||
|
||||
UNSPECIFIED = "UNSPECIFIED", _("Not Specified")
|
||||
SHIELD = "SHIELD", _("Shield")
|
||||
ARMOR = "ARMOR", _("Armor")
|
||||
HULL = "HULL", _("Hull")
|
||||
FINAL = "FINAL", _("Final")
|
||||
ANCHORING = "ANCHORING", _("Anchoring")
|
||||
UNANCHORING = "UNANCHORING", _("Unanchoring")
|
||||
|
||||
|
||||
class Timer(models.Model):
|
||||
class Meta:
|
||||
ordering = ['eve_time']
|
||||
class Objective(models.TextChoices):
|
||||
"""
|
||||
Choices for Objective Type
|
||||
"""
|
||||
|
||||
FRIENDLY = "Friendly", _("Friendly")
|
||||
HOSTILE = "Hostile", _("Hostile")
|
||||
NEUTRAL = "Neutral", _("Neutral")
|
||||
|
||||
class Structure(models.TextChoices):
|
||||
"""
|
||||
Choices for Structure Type
|
||||
"""
|
||||
|
||||
POCO = "POCO", _("POCO")
|
||||
ORBITALSKYHOOK = "Orbital Skyhook", _("Orbital Skyhook")
|
||||
IHUB = "I-HUB", _("I-HUB")
|
||||
TCU = "TCU", _("TCU") # Pending Remval
|
||||
POSS = "POS[S]", _("POS [S]")
|
||||
POSM = "POS[M]", _("POS [M]")
|
||||
POSL = "POS[L]", _("POS [L]")
|
||||
ASTRAHUS = "Astrahus", _("Astrahus")
|
||||
FORTIZAR = "Fortizar", _("Fortizar")
|
||||
KEEPSTAR = "Keepstar", _("Keepstar")
|
||||
RAITARU = "Raitaru", _("Raitaru")
|
||||
AZBEL = "Azbel", _("Azbel")
|
||||
SOTIYO = "Sotiyo", _("Sotiyo")
|
||||
ATHANOR = "Athanor", _("Athanor")
|
||||
TATARA = "Tatara", _("Tatara")
|
||||
PHAROLUX = "Pharolux Cyno Beacon", _("Pharolux Cyno Beacon")
|
||||
TENEBREX = "Tenebrex Cyno Jammer", _("Tenebrex Cyno Jammer")
|
||||
ANSIBLEX = "Ansiblex Jump Gate", _("Ansiblex Jump Gate")
|
||||
MOONPOP = "Moon Mining Cycle", _("Moon Mining Cycle")
|
||||
METENOX = "Metenox Moon Drill", _("Metenox Moon Drill")
|
||||
OTHER = "Other", _("Other")
|
||||
|
||||
class TimerType(models.TextChoices):
|
||||
"""
|
||||
Choices for Timer Type
|
||||
"""
|
||||
|
||||
UNSPECIFIED = "UNSPECIFIED", _("Not Specified")
|
||||
SHIELD = "SHIELD", _("Shield")
|
||||
ARMOR = "ARMOR", _("Armor")
|
||||
HULL = "HULL", _("Hull")
|
||||
FINAL = "FINAL", _("Final")
|
||||
ANCHORING = "ANCHORING", _("Anchoring")
|
||||
UNANCHORING = "UNANCHORING", _("Unanchoring")
|
||||
ABANDONED = "ABANDONED", _("Abandoned")
|
||||
|
||||
details = models.CharField(max_length=254, default="")
|
||||
system = models.CharField(max_length=254, default="")
|
||||
planet_moon = models.CharField(max_length=254, blank=True, default="")
|
||||
structure = models.CharField(max_length=254, default="")
|
||||
timer_type = models.CharField(
|
||||
max_length=254,
|
||||
choices=TimerType.choices,
|
||||
default=TimerType.UNSPECIFIED,
|
||||
)
|
||||
objective = models.CharField(max_length=254, default="")
|
||||
structure = models.CharField(max_length=254,choices=Structure.choices,default=Structure.OTHER)
|
||||
timer_type = models.CharField(max_length=254,choices=TimerType.choices,default=TimerType.UNSPECIFIED)
|
||||
objective = models.CharField(max_length=254, choices=Objective.choices, default=Objective.NEUTRAL)
|
||||
eve_time = models.DateTimeField()
|
||||
important = models.BooleanField(default=False)
|
||||
eve_character = models.ForeignKey(EveCharacter, null=True, on_delete=models.SET_NULL)
|
||||
@ -41,5 +70,8 @@ class Timer(models.Model):
|
||||
corp_timer = models.BooleanField(default=False)
|
||||
user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
|
||||
|
||||
def __str__(self):
|
||||
def __str__(self) -> str:
|
||||
return str(self.system) + ' ' + str(self.details)
|
||||
|
||||
class Meta:
|
||||
ordering = ['eve_time']
|
||||
|
@ -40,7 +40,7 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if timer.objective == "Neutral" %}
|
||||
<div class="badge bg-default">
|
||||
<div class="badge bg-secondary">
|
||||
{% translate "Neutral" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@ -18,174 +18,85 @@
|
||||
</tr>
|
||||
|
||||
{% for timer in timers %}
|
||||
{% if timer.important == True %}
|
||||
<tr class="bg-danger bg-opacity-25">
|
||||
{% else %}
|
||||
<tr class="bg-info bg-opacity-25">
|
||||
{% endif %}
|
||||
<tr class="{% if timer.important == True %}bg-danger bg-opacity-25{% else %}bg-info bg-opacity-25{% endif %}">
|
||||
|
||||
<td style="width: 150px;" class="text-center">
|
||||
{{ timer.details }}
|
||||
|
||||
{% if timer.timer_type != 'UNSPECIFIED' %}
|
||||
<br>({{ timer.get_timer_type_display }})
|
||||
<br />
|
||||
({{ timer.get_timer_type_display }})
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
{% if timer.objective == "Hostile" %}
|
||||
<div class="badge bg-danger">
|
||||
{% translate "Hostile" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.objective == "Friendly" %}
|
||||
<div class="badge bg-primary">
|
||||
{% translate "Friendly" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.objective == "Neutral" %}
|
||||
<div class="badge bg-default">
|
||||
{% translate "Neutral" %}
|
||||
</div>
|
||||
<div class="badge bg-danger">{% translate "Hostile" %}</div>
|
||||
{% elif timer.objective == "Friendly" %}
|
||||
<div class="badge bg-primary">{% translate "Friendly" %}</div>
|
||||
{% elif timer.objective == "Neutral" %}
|
||||
<div class="badge bg-secondary">{% translate "Neutral" %}</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<a href="{{ timer.system|dotlan_solar_system_url }}">
|
||||
{{ timer.system }} {{ timer.planet_moon }}
|
||||
</a>
|
||||
<a href="{{ timer.system|dotlan_solar_system_url }}">{{ timer.system }} {{ timer.planet_moon }}</a>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
{% if timer.structure == "POCO" %}
|
||||
<div class="badge bg-info">
|
||||
{% translate "POCO" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "I-HUB" %}
|
||||
<div class="badge bg-warning">
|
||||
{% translate "I-HUB" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "TCU" %}
|
||||
<div class="badge bg-danger">
|
||||
{% translate "TCU" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "POS[S]" %}
|
||||
<div class="badge bg-info">
|
||||
{% translate "POS [S]" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "POS[M]" %}
|
||||
<div class="badge bg-info">
|
||||
{% translate "POS [M]" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "POS[L]" %}
|
||||
<div class="badge bg-info">
|
||||
{% translate "POS [L]" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "Citadel[M]" or timer.structure == "Astrahus" %}
|
||||
<div class="badge bg-danger">
|
||||
{% translate "Astrahus" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "Citadel[L]" or timer.structure == "Fortizar" %}
|
||||
<div class="badge bg-danger">
|
||||
{% translate "Fortizar" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "Citadel[XL]" or timer.structure == "Keepstar" %}
|
||||
<div class="badge bg-danger">
|
||||
{% translate "Keepstar" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "Engineering Complex[M]" or timer.structure == "Raitaru" %}
|
||||
<div class="badge bg-warning">
|
||||
{% translate "Raitaru" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "Engineering Complex[L]" or timer.structure == "Azbel" %}
|
||||
<div class="badge bg-warning">
|
||||
{% translate "Azbel" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "Engineering Complex[XL]" or timer.structure == "Sotiyo" %}
|
||||
<div class="badge bg-warning">
|
||||
{% translate "Sotiyo" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "Refinery[M]" or timer.structure == "Athanor" %}
|
||||
<div class="badge bg-warning">
|
||||
{% translate "Athanor" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "Refinery[L]" or timer.structure == "Tatara"%}
|
||||
<div class="badge bg-warning">
|
||||
{% translate "Tatara" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "Cyno Beacon" or timer.structure == "Pharolux Cyno Beacon" %}
|
||||
<div class="badge bg-warning">
|
||||
{% translate "Cyno Beacon" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "Cyno Jammer" or timer.structure == "Tenebrex Cyno Jammer" %}
|
||||
<div class="badge bg-warning">
|
||||
{% translate "Cyno Jammer" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "Jump Gate" or timer.structure == "Ansiblex Jump Gate" %}
|
||||
<div class="badge bg-warning">
|
||||
{% translate "Ansiblex Jump Gate" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "Moon Mining Cycle" %}
|
||||
<div class="badge bg-success">
|
||||
{% translate "Moon Mining Cycle" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if timer.structure == "Other" %}
|
||||
<div class="badge bg-default">
|
||||
{% translate "Other" %}
|
||||
</div>
|
||||
<div class="badge bg-info">{% translate "POCO" %}</div>
|
||||
{% elif timer.structure == "Orbital Skyhook" %}
|
||||
<div class="badge bg-warning">{% translate "Orbital Skyhook" %}</div>
|
||||
{% elif timer.structure == "I-HUB" %}
|
||||
<div class="badge bg-warning">{% translate "I-HUB" %}</div>
|
||||
{% elif timer.structure == "TCU" %} {% comment %} Pending Removal {% endcomment %}
|
||||
<div class="badge bg-secondary">{% translate "TCU" %}</div>
|
||||
{% elif timer.structure == "POS[S]" %}
|
||||
<div class="badge bg-info">{% translate "POS [S]" %}</div>
|
||||
{% elif timer.structure == "POS[M]" %}
|
||||
<div class="badge bg-info">{% translate "POS [M]" %}</div>
|
||||
{% elif timer.structure == "POS[L]" %}
|
||||
<div class="badge bg-info">{% translate "POS [L]" %}</div>
|
||||
{% elif timer.structure == "Citadel[M]" or timer.structure == "Astrahus" %}
|
||||
<div class="badge bg-danger">{% translate "Astrahus" %}</div>
|
||||
{% elif timer.structure == "Citadel[L]" or timer.structure == "Fortizar" %}
|
||||
<div class="badge bg-danger">{% translate "Fortizar" %}</div>
|
||||
{% elif timer.structure == "Citadel[XL]" or timer.structure == "Keepstar" %}
|
||||
<div class="badge bg-danger">{% translate "Keepstar" %}</div>
|
||||
{% elif timer.structure == "Engineering Complex[M]" or timer.structure == "Raitaru" %}
|
||||
<div class="badge bg-warning">{% translate "Raitaru" %}</div>
|
||||
{% elif timer.structure == "Engineering Complex[L]" or timer.structure == "Azbel" %}
|
||||
<div class="badge bg-warning">{% translate "Azbel" %}</div>
|
||||
{% elif timer.structure == "Engineering Complex[XL]" or timer.structure == "Sotiyo" %}
|
||||
<div class="badge bg-danger">{% translate "Sotiyo" %}</div>
|
||||
{% elif timer.structure == "Refinery[M]" or timer.structure == "Athanor" %}
|
||||
<div class="badge bg-warning">{% translate "Athanor" %}</div>
|
||||
{% elif timer.structure == "Refinery[L]" or timer.structure == "Tatara" %}
|
||||
<div class="badge bg-warning">{% translate "Tatara" %}</div>
|
||||
{% elif timer.structure == "Cyno Beacon" or timer.structure == "Pharolux Cyno Beacon" %}
|
||||
<div class="badge bg-warning">{% translate "Cyno Beacon" %}</div>
|
||||
{% elif timer.structure == "Cyno Jammer" or timer.structure == "Tenebrex Cyno Jammer" %}
|
||||
<div class="badge bg-warning">{% translate "Cyno Jammer" %}</div>
|
||||
{% elif timer.structure == "Jump Gate" or timer.structure == "Ansiblex Jump Gate" %}
|
||||
<div class="badge bg-warning">{% translate "Ansiblex Jump Gate" %}</div>
|
||||
{% elif timer.structure == "Moon Mining Cycle" %}
|
||||
<div class="badge bg-success">{% translate "Moon Mining Cycle" %}</div>
|
||||
{% elif timer.structure == "Metenox Moon Drill" %}
|
||||
<div class="badge bg-warning">{% translate "Metenox Moon Drill" %}</div>
|
||||
{% elif timer.structure == "Other" %}
|
||||
<div class="badge bg-secondary">{% translate "Other" %}</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td class="text-center" nowrap>
|
||||
{{ timer.eve_time | date:"Y-m-d H:i" }}
|
||||
</td>
|
||||
<td class="text-center" nowrap>{{ timer.eve_time | date:"Y-m-d H:i" }}</td>
|
||||
|
||||
<td class="text-center" nowrap>
|
||||
<div id="localtime{{ timer.id }}"></div>
|
||||
<div id="countdown{{ timer.id }}"></div>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
{{ timer.eve_character.character_name }}
|
||||
</td>
|
||||
<td class="text-center">{{ timer.eve_character.character_name }}</td>
|
||||
|
||||
{% if perms.auth.timer_management %}
|
||||
<td class="text-center">
|
||||
|
@ -167,8 +167,8 @@ class TimerboardViewsTestCase(WebTest):
|
||||
form['details'] = 'details'
|
||||
form['system'] = 'jita'
|
||||
form['planet_moon'] = '4-4'
|
||||
form['structure'] = TimerForm.structure_choices[0][0]
|
||||
form['objective'] = TimerForm.objective_choices[0][0]
|
||||
form['structure'] = Timer.Structure.choices[0][0]
|
||||
form['objective'] = Timer.Objective.choices[0][0]
|
||||
form['days_left'] = 1
|
||||
form['hours_left'] = 2
|
||||
form['minutes_left'] = 3
|
||||
@ -206,8 +206,8 @@ class TimerboardViewsTestCase(WebTest):
|
||||
form['details'] = 'detailsUNIQUE'
|
||||
form['system'] = 'jita'
|
||||
form['planet_moon'] = '4-4'
|
||||
form['structure'] = TimerForm.structure_choices[0][0]
|
||||
form['objective'] = TimerForm.objective_choices[0][0]
|
||||
form['structure'] = Timer.Structure.choices[0][0]
|
||||
form['objective'] = Timer.Objective.choices[0][0]
|
||||
form['days_left'] = 1
|
||||
form['hours_left'] = 2
|
||||
form['minutes_left'] = 3
|
||||
|
@ -1,7 +1,7 @@
|
||||
PROTOCOL=https://
|
||||
AUTH_SUBDOMAIN=%AUTH_SUBDOMAIN%
|
||||
DOMAIN=%DOMAIN%
|
||||
AA_DOCKER_TAG=registry.gitlab.com/allianceauth/allianceauth/auth:v4.2.2
|
||||
AA_DOCKER_TAG=registry.gitlab.com/allianceauth/allianceauth/auth:v4.3.0
|
||||
|
||||
# Nginx Proxy Manager
|
||||
PROXY_HTTP_PORT=80
|
||||
|
@ -1,5 +1,5 @@
|
||||
FROM python:3.11-slim
|
||||
ARG AUTH_VERSION=v4.2.2
|
||||
ARG AUTH_VERSION=v4.3.0
|
||||
ARG AUTH_PACKAGE=allianceauth==${AUTH_VERSION}
|
||||
ENV AUTH_USER=allianceauth
|
||||
ENV AUTH_GROUP=allianceauth
|
||||
|
@ -337,7 +337,7 @@ To deactivate, click on the debug icon to switch to the debug view. Then uncheck
|
||||
|
||||
### AA debug config
|
||||
|
||||
In VSC, click on Debug / Add Configuration and choose "Django". Should Django not appear as an option, make sure to first open a Django file (e.g., the local.py settings) to help VSC detect that you are using Django.
|
||||
In VSC, click on Debug / Add Configuration and choose "Django". Should Django not appear as an option, make sure to first open a Django file (e.g., the `local.py` settings) to help VSC detect that you are using Django.
|
||||
|
||||
The result should look something like this:
|
||||
|
||||
|
@ -4,9 +4,33 @@ Auto Groups allows you to automatically place users of certain states into corp
|
||||
|
||||
## Installation
|
||||
|
||||
This is an optional app that needs to be installed.
|
||||
- Add `'allianceauth.eveonline.autogroups',` to `INSTALLED_APPS` in your `local.py`
|
||||
|
||||
To install this app add `'allianceauth.eveonline.autogroups',` to your `INSTALLED_APPS` list and run migrations. All other settings are controlled via the admin panel under the `Eve_Autogroups` section.
|
||||
Perform Django Maintenance and restart our Web Service and Workers.
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Bare Metal
|
||||
|
||||
```shell
|
||||
python manage.py migrate
|
||||
python manage.py collectstatic --noinput
|
||||
supervisorctl restart myauth:
|
||||
```
|
||||
|
||||
:::
|
||||
:::{group-tab} Containerized
|
||||
|
||||
```shell
|
||||
docker compose --env-file=.env up -d
|
||||
docker compose exec allianceauth_gunicorn bash
|
||||
auth migrate
|
||||
auth collectstatic
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
All other settings are controlled via the admin panel under the `Eve_Autogroups` section.
|
||||
|
||||
## Configuring a group
|
||||
|
||||
|
@ -8,7 +8,31 @@ This module is used to check the registration status of Corp members and to dete
|
||||
|
||||
Corp Stats requires access to the `esi-corporations.read_corporation_membership.v1` SSO scope. Update your application on the [EVE Developers site](https://developers.eveonline.com) to ensure it is available.
|
||||
|
||||
Add `'allianceauth.corputils',` to your `INSTALLED_APPS` list in your auth project's settings file. Run migrations to complete installation.
|
||||
- Add `'allianceauth.corputils',` to `INSTALLED_APPS` in your `local.py`
|
||||
|
||||
Perform Django Maintenance and restart our Web Service and Workers.
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Bare Metal
|
||||
|
||||
```shell
|
||||
python manage.py migrate
|
||||
python manage.py collectstatic --noinput
|
||||
supervisorctl restart myauth:
|
||||
```
|
||||
|
||||
:::
|
||||
:::{group-tab} Containerized
|
||||
|
||||
```shell
|
||||
docker compose --env-file=.env up -d
|
||||
docker compose exec allianceauth_gunicorn bash
|
||||
auth migrate
|
||||
auth collectstatic
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
## Creating a Corp Stats
|
||||
|
||||
|
@ -8,7 +8,31 @@ The Fleet Activity Tracking (FAT) app allows you to track fleet participation.
|
||||
|
||||
Fleet Activity Tracking requires access to the `esi-location.read_location.v1`, `esi-location.read_ship_type.v1`, and `esi-universe.read_structures.v1` SSO scopes. Update your application on the [EVE Developers site](https://developers.eveonline.com) to ensure these are available.
|
||||
|
||||
Add `'allianceauth.fleetactivitytracking',` to your `INSTALLED_APPS` list in your auth project's settings file. Run migrations to complete installation.
|
||||
Add `'allianceauth.fleetactivitytracking',` to `INSTALLED_APPS` in your `local.py`
|
||||
|
||||
Perform Django Maintenance and restart our Web Service and Workers.
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Bare Metal
|
||||
|
||||
```shell
|
||||
python manage.py migrate
|
||||
python manage.py collectstatic --noinput
|
||||
supervisorctl restart myauth:
|
||||
```
|
||||
|
||||
:::
|
||||
:::{group-tab} Containerized
|
||||
|
||||
```shell
|
||||
docker compose --env-file=.env up -d
|
||||
docker compose exec allianceauth_gunicorn bash
|
||||
auth migrate
|
||||
auth collectstatic
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
## Permissions
|
||||
|
||||
|
@ -10,7 +10,31 @@ This app allows you to manage applications for multiple corporations in your all
|
||||
|
||||
## Installation
|
||||
|
||||
Add `'allianceauth.hrapplications',` to your `INSTALLED_APPS` list in your auth project's settings file. Run migrations to complete installation.
|
||||
- Add `'allianceauth.hrapplications',` to `INSTALLED_APPS` in your `local.py`
|
||||
|
||||
Perform Django Maintenance and restart our Web Service and Workers.
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Bare Metal
|
||||
|
||||
```shell
|
||||
python manage.py migrate
|
||||
python manage.py collectstatic --noinput
|
||||
supervisorctl restart myauth:
|
||||
```
|
||||
|
||||
:::
|
||||
:::{group-tab} Containerized
|
||||
|
||||
```shell
|
||||
docker compose --env-file=.env up -d
|
||||
docker compose exec allianceauth_gunicorn bash
|
||||
auth migrate
|
||||
auth collectstatic
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
## Management
|
||||
|
||||
|
@ -6,7 +6,31 @@ Fleet Operations is an app for organizing and communicating fleet schedules.
|
||||
|
||||
## Installation
|
||||
|
||||
Add `'allianceauth.optimer',` to your `INSTALLED_APPS` list in your auth project's settings file. Run migrations to complete installation.
|
||||
- Add `'allianceauth.optimer',` to `INSTALLED_APPS` in your `local.py`
|
||||
|
||||
Perform Django Maintenance and restart our Web Service and Workers.
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Bare Metal
|
||||
|
||||
```shell
|
||||
python manage.py migrate
|
||||
python manage.py collectstatic --noinput
|
||||
supervisorctl restart myauth:
|
||||
```
|
||||
|
||||
:::
|
||||
:::{group-tab} Containerized
|
||||
|
||||
```shell
|
||||
docker compose --env-file=.env up -d
|
||||
docker compose exec allianceauth_gunicorn bash
|
||||
auth migrate
|
||||
auth collectstatic
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
## Permissions
|
||||
|
||||
|
@ -2,9 +2,33 @@
|
||||
|
||||
Access to most of Alliance Auth's features is controlled by Django's permissions system. To help you secure your services, Alliance Auth provides a permission auditing tool.
|
||||
|
||||
This is an optional app that needs to be installed.
|
||||
## Installation
|
||||
|
||||
To install it add `'allianceauth.permissions_tool',` to your `INSTALLED_APPS` list in your auth project's settings file.
|
||||
- Add `'allianceauth.permissions_tool',` to `INSTALLED_APPS` in your `local.py`
|
||||
|
||||
Perform Django Maintenance and restart our Web Service and Workers.
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Bare Metal
|
||||
|
||||
```shell
|
||||
python manage.py migrate
|
||||
python manage.py collectstatic --noinput
|
||||
supervisorctl restart myauth:
|
||||
```
|
||||
|
||||
:::
|
||||
:::{group-tab} Containerized
|
||||
|
||||
```shell
|
||||
docker compose --env-file=.env up -d
|
||||
docker compose exec allianceauth_gunicorn bash
|
||||
auth migrate
|
||||
auth collectstatic
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
## Usage
|
||||
|
||||
|
@ -6,7 +6,31 @@ Ship Replacement helps you to organize ship replacement programs (SRP) for your
|
||||
|
||||
## Installation
|
||||
|
||||
Add `'allianceauth.srp',` to your `INSTALLED_APPS` list in your auth project's settings file. Run migrations to complete installation.
|
||||
- Add `'allianceauth.srp',` to `INSTALLED_APPS` in your `local.py`
|
||||
|
||||
Perform Django Maintenance and restart our Web Service and Workers.
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Bare Metal
|
||||
|
||||
```shell
|
||||
python manage.py migrate
|
||||
python manage.py collectstatic --noinput
|
||||
supervisorctl restart myauth:
|
||||
```
|
||||
|
||||
:::
|
||||
:::{group-tab} Containerized
|
||||
|
||||
```shell
|
||||
docker compose --env-file=.env up -d
|
||||
docker compose exec allianceauth_gunicorn bash
|
||||
auth migrate
|
||||
auth collectstatic
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
## Permissions
|
||||
|
||||
|
@ -6,7 +6,31 @@ Structure Timers helps you keep track of both offensive and defensive structure
|
||||
|
||||
## Installation
|
||||
|
||||
Add `'allianceauth.timerboard',` to your `INSTALLED_APPS` list in your auth project's settings file. Run migrations to complete installation.
|
||||
- Add `'allianceauth.timerboard',` to `INSTALLED_APPS` in your `local.py`
|
||||
|
||||
Perform Django Maintenance and restart our Web Service and Workers.
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Bare Metal
|
||||
|
||||
```shell
|
||||
python manage.py migrate
|
||||
python manage.py collectstatic --noinput
|
||||
supervisorctl restart myauth:
|
||||
```
|
||||
|
||||
:::
|
||||
:::{group-tab} Containerized
|
||||
|
||||
```shell
|
||||
docker compose --env-file=.env up -d
|
||||
docker compose exec allianceauth_gunicorn bash
|
||||
auth migrate
|
||||
auth collectstatic
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
## Permissions
|
||||
|
||||
|
@ -33,23 +33,6 @@ Our Daily Stats contain the following:
|
||||
- A task to send a List of Installed Apps
|
||||
- Each Task contains the UUID and Alliance Auth Version
|
||||
|
||||
Our Celery Events contain the following:
|
||||
|
||||
- Unique Identifier (The UUID)
|
||||
- Celery Namespace of the task e.g., allianceauth.eveonline
|
||||
- Celery Task
|
||||
- Task Success or Exception
|
||||
- A context number for bulk tasks or sometimes a binary True/False
|
||||
|
||||
Our Page Views contain the following:
|
||||
|
||||
- Unique Identifier (The UUID)
|
||||
- Page Path
|
||||
- Page Title
|
||||
- The locale of the users browser
|
||||
- The User-Agent of the user's browser
|
||||
- The Alliance Auth Version
|
||||
|
||||
## Why
|
||||
|
||||
This data allows Alliance Auth development to gather accurate statistics on our installation base, as well as how those installations are used.
|
||||
|
@ -4,9 +4,9 @@
|
||||
|
||||
It has the following key features:
|
||||
|
||||
- Automatically grants or revokes users access to external services (e.g. Discord, Mumble) and web apps (e.g. SRP requests) based on the user's current membership to [in-game organizations](/features/core/states) and [groups](/features/core/groups)
|
||||
- Automatically grants or revokes user access to external services (e.g. Discord, Mumble) and web apps (e.g. SRP requests) based on the user's current membership to [in-game organizations](/features/core/states) and [groups](/features/core/groups)
|
||||
|
||||
- Provides a central website where users can directly access web apps (e.g., SRP requests) and manage their access to external services and groups.
|
||||
- Provides a central web site where users can directly access web apps (e.g. SRP requests, Fleet Schedule) and manage their access to external services and groups.
|
||||
|
||||
- Includes a set of connectors (called ["services"](/features/services/index)) for integrating access management with many popular external services like Discord, Mumble, Teamspeak 3, SMF and others
|
||||
|
||||
@ -14,4 +14,4 @@ It has the following key features:
|
||||
|
||||
- It can be easily extended with additional services and apps. Many are provided by the [community](/features/community/index).
|
||||
|
||||
- Chinese, English, German and Spanish localization
|
||||
- English :flag_gb:, Chinese :flag_cn:, German :flag_de:, Spanish :flag_es:, Korean :flag_kr:, Russian :flag_ru:, Italian :flag_it:, French :flag_fr:, Japanese :flag_jp: and Ukrainian :flag_ua: Localization
|
||||
|
@ -6,13 +6,13 @@ Discord is a web-based instant messaging client with voice. Kind of like TeamSpe
|
||||
|
||||
Discord is very popular amongst ad-hoc small groups and larger organizations seeking a modern technology. Alternative voice communications should be investigated for larger than small-medium groups for more advanced features.
|
||||
|
||||
## Setup
|
||||
## Setup Auth
|
||||
|
||||
### Prepare Your Settings File
|
||||
|
||||
Make the following changes in your auth project's settings file (`local.py`):
|
||||
|
||||
- Add `'allianceauth.services.modules.discord',` to `INSTALLED_APPS`
|
||||
- Add `'allianceauth.services.modules.discord',` to `INSTALLED_APPS` in your `local.py`
|
||||
- Append the following to the bottom of the settings file:
|
||||
|
||||
```python
|
||||
@ -37,6 +37,34 @@ CELERYBEAT_SCHEDULE['discord.update_all_usernames'] = {
|
||||
You will have to add most of the values for these settings, e.g., your Discord server ID (aka guild ID), later in the setup process.
|
||||
:::
|
||||
|
||||
### Preparing Auth
|
||||
|
||||
Before continuing, it is essential to perform Django Maintenance and restart our Web Service and Workers.
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Bare Metal
|
||||
|
||||
```shell
|
||||
python manage.py migrate
|
||||
python manage.py collectstatic --noinput
|
||||
supervisorctl restart myauth:
|
||||
```
|
||||
|
||||
:::
|
||||
:::{group-tab} Containerized
|
||||
|
||||
```shell
|
||||
docker compose --env-file=.env up -d
|
||||
docker compose exec allianceauth_gunicorn bash
|
||||
auth migrate
|
||||
auth collectstatic
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
## Setup Discord
|
||||
|
||||
### Creating a Server
|
||||
|
||||
Navigate to the [Discord site](https://discord.com/) and register an account, or log in if you have one already.
|
||||
@ -67,10 +95,6 @@ Update your auth project's settings file with these pieces of information from t
|
||||
- From the OAuth2 > General panel, `DISCORD_APP_SECRET` is the Client Secret
|
||||
- From the Bot panel, `DISCORD_BOT_TOKEN` is the Token
|
||||
|
||||
### Preparing Auth
|
||||
|
||||
Before continuing, it is essential to run migrations and restart Gunicorn and Celery.
|
||||
|
||||
### Adding a Bot to the Server
|
||||
|
||||
Once created, navigate to the "Services" page of your Alliance Auth install as the superuser account. At the top there is a big green button labeled "Link Discord Server". Click it, then from the drop-down select the server you created, and then Authorize.
|
||||
|
@ -1,11 +1,13 @@
|
||||
# Discourse
|
||||
|
||||
## Prepare Your Settings
|
||||
## Setup Auth
|
||||
|
||||
### Prepare Your Settings File
|
||||
|
||||
In your auth project's settings file, do the following:
|
||||
|
||||
- Add `'allianceauth.services.modules.discourse',` to your `INSTALLED_APPS` list
|
||||
- Append the following to your local.py settings file:
|
||||
- Add `'allianceauth.services.modules.discourse',` to `INSTALLED_APPS` in your `local.py`
|
||||
- Append the following to your `local.py` settings file:
|
||||
|
||||
```python
|
||||
# Discourse Configuration
|
||||
@ -15,6 +17,32 @@ DISCOURSE_API_KEY = ''
|
||||
DISCOURSE_SSO_SECRET = ''
|
||||
```
|
||||
|
||||
### Preparing Auth
|
||||
|
||||
Before continuing, it is essential to perform Django Maintenance and restart our Web Service and Workers.
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Bare Metal
|
||||
|
||||
```shell
|
||||
python manage.py migrate
|
||||
python manage.py collectstatic --noinput
|
||||
supervisorctl restart myauth:
|
||||
```
|
||||
|
||||
:::
|
||||
:::{group-tab} Containerized
|
||||
|
||||
```shell
|
||||
docker compose --env-file=.env up -d
|
||||
docker compose exec allianceauth_gunicorn bash
|
||||
auth migrate
|
||||
auth collectstatic
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
## Install Docker
|
||||
|
||||
```shell
|
||||
|
@ -8,7 +8,7 @@ Mumble is a free voice chat server. While not as flashy as TeamSpeak, it has all
|
||||
|
||||
In your auth project's settings file (`aa-docker/conf/local.py`), do the following:
|
||||
|
||||
- Add `'allianceauth.services.modules.mumble',` to your `INSTALLED_APPS` list
|
||||
- Add `'allianceauth.services.modules.mumble',` to `INSTALLED_APPS` in your `local.py`
|
||||
- Append the following to your auth project's settings file:
|
||||
|
||||
```python
|
||||
|
@ -14,25 +14,38 @@ This guide is currently for Ubuntu only.
|
||||
|
||||
### Installing Mumble Server
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Ubuntu 2004, 2204
|
||||
|
||||
The mumble server package can be retrieved from a repository, which we need to add:
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Ubuntu 2004, 2204, 2404
|
||||
|
||||
```shell
|
||||
sudo apt-add-repository ppa:mumble/release
|
||||
```
|
||||
|
||||
```shell
|
||||
sudo apt-get update
|
||||
```
|
||||
:::
|
||||
:::{group-tab} CentOS 7, Stream 8, Stream 9
|
||||
|
||||
sudo yum install epel-release
|
||||
sudo yum update
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
Now three packages need to be installed:
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Ubuntu 2004, 2204, 2404
|
||||
|
||||
```shell
|
||||
sudo apt-get install python-software-properties mumble-server libqt5sql5-mysql
|
||||
sudo apt-get install software-properties-common mumble-server libqt5sql5-mysql
|
||||
```
|
||||
|
||||
:::
|
||||
:::{group-tab} CentOS 7, Stream 8, Stream 9
|
||||
|
||||
sudo yum install mumble-server
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
@ -58,17 +71,7 @@ pip install -r requirements.txt
|
||||
|
||||
## Configuring Mumble Server
|
||||
|
||||
The mumble server needs its own database. Open an SQL shell with `mysql -u root -p` and execute the SQL commands to create it:
|
||||
|
||||
```sql
|
||||
CREATE DATABASE alliance_mumble CHARACTER SET utf8mb4;
|
||||
```
|
||||
|
||||
```sql
|
||||
GRANT ALL PRIVILEGES ON alliance_mumble . * TO 'allianceserver'@'localhost';
|
||||
```
|
||||
|
||||
Mumble ships with a configuration file that needs customization. By default, it’s located at `/etc/mumble-server.ini`. Open it with your favorite text editor:
|
||||
Mumble ships with a configuration file that needs customization. By default, it's located at `/etc/mumble-server.ini`. Open it with your favorite text editor:
|
||||
|
||||
```shell
|
||||
sudo nano /etc/mumble-server.ini
|
||||
@ -79,15 +82,6 @@ We need to enable the ICE authenticator. Edit the following:
|
||||
- `icesecretwrite=MY_CLEVER_PASSWORD`, obviously choosing a secure password
|
||||
- ensure the line containing `Ice="tcp -h 127.0.0.1 -p 6502"` is uncommented
|
||||
|
||||
We also want to enable Mumble to use the previously created MySQL / MariaDB database, edit the following:
|
||||
|
||||
- uncomment the database line, and change it to `database=alliance_mumble`
|
||||
- `dbDriver=QMYSQL`
|
||||
- `dbUsername=allianceserver` or whatever you called the Alliance Auth MySQL user
|
||||
- `dbPassword=` that user’s password
|
||||
- `dbPort=3306`
|
||||
- `dbPrefix=murmur_`
|
||||
|
||||
To name your root channel, uncomment and set `registerName=` to whatever cool name you want
|
||||
|
||||
Save and close the file.
|
||||
@ -98,7 +92,7 @@ To get Mumble superuser account credentials, run the following:
|
||||
sudo dpkg-reconfigure mumble-server
|
||||
```
|
||||
|
||||
Set the password to something you’ll remember and write it down. This is your superuser password and later needed to manage ACLs.
|
||||
Set the password to something you'll remember and write it down. This is your superuser password and later needed to manage ACLs.
|
||||
|
||||
Now restart the server to see the changes reflected.
|
||||
|
||||
@ -106,7 +100,7 @@ Now restart the server to see the changes reflected.
|
||||
sudo service mumble-server restart
|
||||
```
|
||||
|
||||
That’s it! Your server is ready to be connected to at example.com:64738
|
||||
That's it! Your server is ready to be connected to at example.com:64738
|
||||
|
||||
## Configuring Mumble Authenticator
|
||||
|
||||
|
@ -8,7 +8,7 @@ Openfire is a Jabber (XMPP) server.
|
||||
|
||||
In your auth project's settings file (`aa-docker/conf/local.py`), do the following:
|
||||
|
||||
- Add `'allianceauth.services.modules.openfire',` to your `INSTALLED_APPS` list
|
||||
- Add `'allianceauth.services.modules.openfire',` to `INSTALLED_APPS` in your `local.py`
|
||||
- Append the following to your auth project's settings file:
|
||||
|
||||
```python
|
||||
|
@ -4,7 +4,7 @@ Openfire is a Jabber (XMPP) server.
|
||||
|
||||
## Prepare Your Settings
|
||||
|
||||
- Add `'allianceauth.services.modules.openfire',` to your `INSTALLED_APPS` list
|
||||
- Add `'allianceauth.services.modules.openfire',` to `INSTALLED_APPS` in your `local.py`
|
||||
- Append the following to your auth project's settings file:
|
||||
|
||||
```python
|
||||
@ -108,7 +108,7 @@ exit;
|
||||
|
||||
The remainder of the setup occurs through Openfire’s web interface. Navigate to <http://example.com:9090>, or if you’re behind CloudFlare, go straight to your server’s IP:9090.
|
||||
|
||||
Select your language. I sure hope it’s English if you’re reading this guide.
|
||||
Select your language.
|
||||
|
||||
Under Server Settings, set the Domain to `example.com` replacing it with your actual domain. Don’t touch the rest.
|
||||
|
||||
|
@ -12,7 +12,7 @@ phpBB3 requires PHP installed in your web server. Apache has `mod_php`, NGINX re
|
||||
|
||||
In your auth project's settings file, do the following:
|
||||
|
||||
- Add `'allianceauth.services.modules.phpbb3',` to your `INSTALLED_APPS` list
|
||||
- Add `'allianceauth.services.modules.phpbb3',` to `INSTALLED_APPS` in your `local.py`
|
||||
- Append the following to the bottom of the settings file:
|
||||
|
||||
```python
|
||||
@ -25,6 +25,7 @@ DATABASES['phpbb3'] = {
|
||||
'PASSWORD': 'password',
|
||||
'HOST': '127.0.0.1',
|
||||
'PORT': '3306',
|
||||
'OPTIONS': {'charset': 'utf8mb4'},
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -12,7 +12,7 @@ SMF requires PHP installed in your web server. Apache has `mod_php`, NGINX requi
|
||||
|
||||
In your auth project's settings file, do the following:
|
||||
|
||||
- Add `'allianceauth.services.modules.smf',` to your `INSTALLED_APPS` list
|
||||
- Add `'allianceauth.services.modules.smf',` to `INSTALLED_APPS` in your `local.py`
|
||||
- Append the following to the bottom of the settings file:
|
||||
|
||||
```python
|
||||
@ -25,6 +25,7 @@ DATABASES['smf'] = {
|
||||
'PASSWORD': 'password',
|
||||
'HOST': '127.0.0.1',
|
||||
'PORT': '3306',
|
||||
'OPTIONS': {'charset': 'utf8mb4'},
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -14,7 +14,7 @@ Sticking with TS3? Alright, I tried.
|
||||
|
||||
In your auth project's settings file (`aa-docker/conf/local.py`), do the following:
|
||||
|
||||
- Add `'allianceauth.services.modules.teamspeak',` to your `INSTALLED_APPS` list
|
||||
- Add `'allianceauth.services.modules.teamspeak',` to `INSTALLED_APPS` in your `local.py`
|
||||
- Append the following to your auth project's settings file:
|
||||
|
||||
```python
|
||||
@ -32,7 +32,7 @@ CELERYBEAT_SCHEDULE['run_ts3_group_update'] = {
|
||||
}
|
||||
```
|
||||
|
||||
Add the following lines to your `.env` file
|
||||
- Add the following lines to your `.env` file
|
||||
|
||||
```env
|
||||
# Temspeak
|
||||
@ -152,7 +152,7 @@ If you have SSH access to the server hosting it, you need to locate the teamspea
|
||||
|
||||
### `520 invalid loginname or password`
|
||||
|
||||
The serverquery account login specified in local.py is incorrect. Please verify `TEAMSPEAK3_SERVERQUERY_USER` and `TEAMSPEAK3_SERVERQUERY_PASSWORD`. The [installation section](#update-settings) describes where to get them.
|
||||
The serverquery account login specified in `local.py` is incorrect. Please verify `TEAMSPEAK3_SERVERQUERY_USER` and `TEAMSPEAK3_SERVERQUERY_PASSWORD`. The [installation section](#update-settings) describes where to get them.
|
||||
|
||||
### `2568 insufficient client permissions`
|
||||
|
||||
|
@ -14,7 +14,7 @@ Sticking with TS3? Alright, I tried.
|
||||
|
||||
In your auth project's settings file, do the following:
|
||||
|
||||
- Add `'allianceauth.services.modules.teamspeak3',` to your `INSTALLED_APPS` list
|
||||
- Add `'allianceauth.services.modules.teamspeak3',` to `INSTALLED_APPS` in your `local.py`
|
||||
- Append the following to the bottom of the settings file:
|
||||
|
||||
```python
|
||||
@ -170,7 +170,7 @@ If you have SSH access to the server hosting it, you need to locate the teamspea
|
||||
|
||||
### `520 invalid loginname or password`
|
||||
|
||||
The serverquery account login specified in local.py is incorrect. Please verify `TEAMSPEAK3_SERVERQUERY_USER` and `TEAMSPEAK3_SERVERQUERY_PASSWORD`. The [installation section](#update-settings) describes where to get them.
|
||||
The serverquery account login specified in `local.py` is incorrect. Please verify `TEAMSPEAK3_SERVERQUERY_USER` and `TEAMSPEAK3_SERVERQUERY_PASSWORD`. The [installation section](#update-settings) describes where to get them.
|
||||
|
||||
### `2568 insufficient client permissions`
|
||||
|
||||
|
@ -4,12 +4,14 @@
|
||||
|
||||
[XenForo](https://xenforo.com/) is a popular, paid forum. This guide will assume that you already have XenForo installed with a valid license (please keep in mind that XenForo is not free nor open-source, therefore, you need to purchase a license first). If you come across any problems related with the installation of XenForo please contact their support service.
|
||||
|
||||
## Prepare Your Settings
|
||||
## Setup Auth
|
||||
|
||||
### Prepare Your Settings
|
||||
|
||||
In your auth project's settings file, do the following:
|
||||
|
||||
- Add `'allianceauth.services.modules.xenforo',` to your `INSTALLED_APPS` list
|
||||
- Append the following to your local.py settings file:
|
||||
- Add `'allianceauth.services.modules.xenforo',` to `INSTALLED_APPS` in your `local.py`
|
||||
- Append the following to your `local.py` settings file:
|
||||
|
||||
```python
|
||||
# XenForo Configuration
|
||||
@ -18,6 +20,32 @@ XENFORO_DEFAULT_GROUP = 0
|
||||
XENFORO_APIKEY = 'yourapikey'
|
||||
```
|
||||
|
||||
### Preparing Auth
|
||||
|
||||
Before continuing, it is essential to perform Django Maintenance and restart our Web Service and Workers.
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Bare Metal
|
||||
|
||||
```shell
|
||||
python manage.py migrate
|
||||
python manage.py collectstatic --noinput
|
||||
supervisorctl restart myauth:
|
||||
```
|
||||
|
||||
:::
|
||||
:::{group-tab} Containerized
|
||||
|
||||
```shell
|
||||
docker compose --env-file=.env up -d
|
||||
docker compose exec allianceauth_gunicorn bash
|
||||
auth migrate
|
||||
auth collectstatic
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
## XenAPI
|
||||
|
||||
By default, XenForo does not support any kind of API, however, there is a third-party package called [XenAPI](https://github.com/Contex/XenAPI) which provides a simple REST interface by which we can access XenForo's functions to create and edit users.
|
||||
|
@ -14,7 +14,7 @@ Alliance Auth can be installed on any in-support *nix operating system.
|
||||
|
||||
Our install documentation targets the following operating systems.
|
||||
|
||||
- Ubuntu 20.04
|
||||
- Ubuntu 20.04 - Not Recommended for new installs
|
||||
- Ubuntu 22.04
|
||||
- Centos 7
|
||||
- CentOS Stream 8
|
||||
@ -27,7 +27,7 @@ To install on your favorite flavour of Linux, identify and install equivalent pa
|
||||
It is recommended to ensure your OS is fully up-to-date before proceeding. We may also add Package Repositories here, used later in the documentation.
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Ubuntu 2004, 2204
|
||||
:::{group-tab} Ubuntu 2004, 2204, 2404
|
||||
|
||||
```shell
|
||||
sudo apt-get update
|
||||
@ -70,7 +70,7 @@ Install Python 3.11 and related tools on your system.
|
||||
|
||||
::::{tabs}
|
||||
|
||||
:::{group-tab} Ubuntu 2004, 2204
|
||||
:::{group-tab} Ubuntu 2004, 2204, 2404
|
||||
|
||||
```shell
|
||||
sudo add-apt-repository ppa:deadsnakes/ppa
|
||||
@ -128,7 +128,7 @@ sudo make altinstall
|
||||
It's recommended to use a database service instead of SQLite. Many options are available, but this guide will use MariaDB 10.11
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Ubuntu 2004, 2204
|
||||
:::{group-tab} Ubuntu 2004, 2204, 2404
|
||||
Follow the instructions at <https://mariadb.org/download/?t=repo-config&d=20.04+%22focal%22&v=10.11&r_m=osuosl> to add the MariaDB repository to your host.
|
||||
|
||||
```shell
|
||||
@ -164,7 +164,7 @@ sudo dnf install mariadb mariadb-server mariadb-devel
|
||||
|
||||
:::::{important}
|
||||
::::{tabs}
|
||||
:::{group-tab} Ubuntu 2004, 2204
|
||||
:::{group-tab} Ubuntu 2004, 2204, 2404
|
||||
If you don't plan on running the database on the same server as auth you still need to install the `libmysqlclient-dev` package
|
||||
:::
|
||||
:::{group-tab} CentOS 7
|
||||
@ -185,7 +185,7 @@ A few extra utilities are also required for the installation of packages.
|
||||
|
||||
::::{tabs}
|
||||
|
||||
:::{group-tab} Ubuntu 2004, 2204
|
||||
:::{group-tab} Ubuntu 2004, 2204, 2404
|
||||
|
||||
```shell
|
||||
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
|
||||
@ -279,13 +279,13 @@ mysql_secure_installation
|
||||
|
||||
### User Account
|
||||
|
||||
For security and permissions, it’s highly recommended you create a separate user to install auth under. Do not log in as this account.
|
||||
For security and permissions, it's highly recommended you create a separate user to install auth under. Do not log in as this account.
|
||||
::::{tabs}
|
||||
|
||||
:::{group-tab} Ubuntu 2004, 2204
|
||||
:::{group-tab} Ubuntu 2004, 2204, 2404
|
||||
|
||||
```shell
|
||||
sudo adduser --disabled-login allianceserver
|
||||
sudo adduser --disabled-login allianceserver --shell /bin/bash
|
||||
```
|
||||
|
||||
:::
|
||||
@ -497,7 +497,7 @@ exit
|
||||
|
||||
::::{tabs}
|
||||
|
||||
:::{group-tab} Ubuntu 2004, 2204
|
||||
:::{group-tab} Ubuntu 2004, 2204, 2404
|
||||
|
||||
```shell
|
||||
sudo apt-get install supervisor
|
||||
@ -554,7 +554,7 @@ sudo systemctl start supervisord.service
|
||||
Once installed, it needs a configuration file to know which processes to watch. Your Alliance Auth project comes with a ready-to-use template which will ensure the Celery workers, Celery task scheduler and Gunicorn are all running.
|
||||
::::{tabs}
|
||||
|
||||
:::{group-tab} Ubuntu 2004, 2204
|
||||
:::{group-tab} Ubuntu 2004, 2204, 2404
|
||||
|
||||
```shell
|
||||
ln -s /home/allianceserver/myauth/supervisor.conf /etc/supervisor/conf.d/myauth.conf
|
||||
|
@ -10,7 +10,7 @@ If you're using a small VPS to host services with very limited memory, consider
|
||||
|
||||
::::{tabs}
|
||||
|
||||
:::{group-tab} Ubuntu 2004, 2204
|
||||
:::{group-tab} Ubuntu 2004, 2204, 2404
|
||||
|
||||
```shell
|
||||
apt-get install apache2
|
||||
@ -50,7 +50,7 @@ CentOS 7, Stream 8, Stream 9
|
||||
Apache needs to be able to read the folder containing your auth project's static files.
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Ubuntu 2004, 2204
|
||||
:::{group-tab} Ubuntu 2004, 2204, 2404
|
||||
|
||||
```shell
|
||||
chown -R www-data:www-data /var/www/myauth/static
|
||||
@ -87,7 +87,7 @@ Apache serves sites through defined virtual hosts. These are located in `/etc/ap
|
||||
A virtual host for auth needs only proxy requests to your WSGI server (Gunicorn if you followed the installation guide) and serve static files. Examples can be found below. Create your config in its own file e.g. `myauth.conf`
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Ubuntu 2004, 2204
|
||||
:::{group-tab} Ubuntu 2004, 2204, 2404
|
||||
To proxy and modify headers a few mods need to be enabled.
|
||||
|
||||
```shell
|
||||
|
@ -42,7 +42,7 @@ You will need to have [Gunicorn](gunicorn.md) or some other WSGI server setup fo
|
||||
## Install
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Ubuntu 2004, 2204
|
||||
:::{group-tab} Ubuntu 2004, 2204, 2404
|
||||
|
||||
```shell
|
||||
sudo apt-get install nginx
|
||||
|
@ -25,7 +25,7 @@ sudo dnf install python39 python39-devel
|
||||
:::
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Ubuntu 2004, 2204
|
||||
:::{group-tab} Ubuntu 2004, 2204, 2404
|
||||
|
||||
```shell
|
||||
sudo add-apt-repository ppa:deadsnakes/ppa
|
||||
|
@ -4,10 +4,25 @@
|
||||
|
||||
Your auth project is just a regular Django project - you can add in [other Django apps](https://djangopackages.org/) as desired. Most come with dedicated setup guides, but here is the general procedure:
|
||||
|
||||
1. add `'appname',` to your `INSTALLED_APPS` setting in `local.py`
|
||||
2. run `python manage.py migrate`
|
||||
3. run `python manage.py collectstatic --noinput`
|
||||
4. restart AA with `supervisorctl restart myauth:`
|
||||
::::{tabs}
|
||||
:::{group-tab} Bare Metal
|
||||
|
||||
1. Add `'appname',` to `INSTALLED_APPS` setting in `local.py`
|
||||
1. Run Migrations `python manage.py migrate`
|
||||
1. Collect Static Files `python manage.py collectstatic --noinput`
|
||||
1. Restart our Web Service and Workers `supervisorctl restart myauth:`
|
||||
|
||||
:::
|
||||
:::{group-tab} Containerized
|
||||
|
||||
1. Add `'appname',` to `INSTALLED_APPS` setting in `local.py`
|
||||
1. Restart our Web Service and Workers `docker compose --env-file=.env up -d`
|
||||
1. Enter a Docker Container `docker compose exec allianceauth_gunicorn bash`
|
||||
1. Run Migrations `auth migrate`
|
||||
1. Collect Static Files `auth collectstatic`
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
## Removing Apps
|
||||
|
||||
@ -25,20 +40,38 @@ First, we want to remove the app related tables from the database.
|
||||
|
||||
Let's first try the automatic approach by running the following command:
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Bare Metal
|
||||
|
||||
```shell
|
||||
python manage.py migrate appname zero
|
||||
```
|
||||
|
||||
:::
|
||||
:::{group-tab} Containerized
|
||||
|
||||
```shell
|
||||
docker compose exec allianceauth_gunicorn bash
|
||||
auth migrate appname zero
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
If that works, you'll get a confirmation message.
|
||||
|
||||
If that did not work, and you got error messages, you will need to remove the tables manually. This is pretty common btw, because many apps use sophisticated table setups, which cannot be removed automatically by Django.
|
||||
If that did not work, and you got error messages, you will need to remove the tables manually.
|
||||
> This is pretty common, because many apps use sophisticated table setups, which cannot be removed automatically by Django.
|
||||
|
||||
#### Manual table removal
|
||||
|
||||
::::{tabs}
|
||||
:::{group-tab} Bare Metal
|
||||
|
||||
First, tell Django that these migrations are no longer in effect (note the additional `--fake`):
|
||||
|
||||
```shell
|
||||
python manage.py migrate appname zero --fake
|
||||
python manage.py appname zero --fake
|
||||
```
|
||||
|
||||
Then, open the mysql tool and connect to your Alliance Auth database:
|
||||
@ -75,6 +108,53 @@ SET FOREIGN_KEY_CHECKS=1;
|
||||
exit;
|
||||
```
|
||||
|
||||
:::
|
||||
:::{group-tab} Containerized
|
||||
|
||||
First, tell Django that these migrations are no longer in effect (note the additional `--fake`):
|
||||
|
||||
```shell
|
||||
auth migrate appname zero --fake
|
||||
```
|
||||
|
||||
Here we need to swap containers, if you are still inside allianceauth_gunicorn, exit with `exit`
|
||||
|
||||
```shell
|
||||
docker compose exec auth_mysql bash
|
||||
sudo mysql -u root
|
||||
use alliance_auth;
|
||||
```
|
||||
|
||||
Next, disable foreign key check. This makes it much easier to drop tables in any order.
|
||||
|
||||
```shell
|
||||
SET FOREIGN_KEY_CHECKS=0;
|
||||
```
|
||||
|
||||
Then get a list of all tables. All tables belonging to the app in question will start with `appname_`.
|
||||
|
||||
```shell
|
||||
show tables;
|
||||
```
|
||||
|
||||
Now, drop the tables from the app one by one like so:
|
||||
|
||||
```shell
|
||||
drop table appname_model_1;
|
||||
drop table appname_model_2;
|
||||
...
|
||||
```
|
||||
|
||||
And finally, but very importantly, re-enable foreign key checks again and then exit:
|
||||
|
||||
```shell
|
||||
SET FOREIGN_KEY_CHECKS=1;
|
||||
exit;
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
### Step 2 - Remove the app from Alliance Auth
|
||||
|
||||
Once the tables have been removed, you can remove the app from Alliance Auth. This is done by removing the applabel from the `INSTALLED_APPS` list in your local settings file.
|
||||
|
@ -50,6 +50,7 @@ dependencies = [
|
||||
"django-esi>=5",
|
||||
"django-redis>=5.2",
|
||||
"django-registration<3.4,>=3.3",
|
||||
"django-solo",
|
||||
"django-sortedm2m",
|
||||
"dnspython",
|
||||
"mysqlclient>=2.1",
|
||||
|
@ -1,4 +1,5 @@
|
||||
import os
|
||||
|
||||
from celery import Celery
|
||||
|
||||
# set the default Django settings module for the 'celery' program.
|
||||
@ -12,6 +13,10 @@ app = Celery('devauth')
|
||||
# the configuration object to child processes.
|
||||
app.config_from_object('django.conf:settings')
|
||||
|
||||
# Automatically try to establish the connection to the AMQP broker on
|
||||
# Celery startup if it is unavailable.
|
||||
app.conf.broker_connection_retry_on_startup = True
|
||||
|
||||
# setup priorities ( 0 Highest, 9 Lowest )
|
||||
app.conf.broker_transport_options = {
|
||||
'priority_steps': list(range(10)), # setup que to have 10 steps
|
||||
|
Loading…
x
Reference in New Issue
Block a user