-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: wip definition of models for new server management
- Loading branch information
Showing
12 changed files
with
266 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
from django.contrib import admin | ||
|
||
from .models import ( | ||
AccountModerationInfo, | ||
CodeScanInformation, | ||
ServerAdmonition, | ||
ServerInformation, | ||
) | ||
|
||
|
||
class ServerAdmonitionInline(admin.TabularInline): | ||
model = ServerAdmonition | ||
extra = 1 | ||
raw_id_fields = ["server"] | ||
fields = ["server", "created_at", "reason", "severity"] | ||
readonly_fields = ["created_at"] | ||
|
||
|
||
@admin.register(CodeScanInformation) | ||
class CodeScanInformationAdmin(admin.ModelAdmin): | ||
list_display = ["version"] | ||
|
||
|
||
@admin.register(ServerInformation) | ||
class ServerInformationAdmin(admin.ModelAdmin): | ||
list_display = ["name", "owner", "is_18_plus", "is_delisted"] | ||
search_fields = ["name", "owner__username"] | ||
list_filter = ["is_18_plus", "is_delisted"] | ||
raw_id_fields = ["owner", "code_scan_version"] | ||
|
||
|
||
@admin.register(AccountModerationInfo) | ||
class AccountModerationInfoAdmin(admin.ModelAdmin): | ||
list_display = ["account", "can_create_servers", "can_list_servers"] | ||
search_fields = ["account__username"] | ||
list_filter = ["can_create_servers", "can_list_servers"] | ||
raw_id_fields = ["account"] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
app_name = "server" |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from django.apps import AppConfig | ||
|
||
|
||
class ServerConfig(AppConfig): | ||
default_auto_field = "django.db.models.BigAutoField" | ||
name = "server" |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from django.core.management.base import BaseCommand | ||
|
||
from accounts.models import Account | ||
from server.models import AccountModerationInfo | ||
|
||
|
||
class Command(BaseCommand): | ||
help = "creates AccountModerationInfo for existing accounts" | ||
|
||
def handle(self, *args, **options): | ||
for account in Account.objects.all(): | ||
AccountModerationInfo.objects.get_or_create(account=account) | ||
self.stdout.write(self.style.SUCCESS("Successfully created AccountModerationInfo for all accounts")) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# Generated by Django 3.2.24 on 2024-06-19 10:17 | ||
|
||
from django.conf import settings | ||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='AccountModerationInfo', | ||
fields=[ | ||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('can_create_servers', models.BooleanField(default=True)), | ||
('can_list_servers', models.BooleanField(default=True)), | ||
('account', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='moderation_info', to=settings.AUTH_USER_MODEL)), | ||
], | ||
), | ||
migrations.CreateModel( | ||
name='CodeScanInformation', | ||
fields=[ | ||
('version', models.TextField(primary_key=True, serialize=False)), | ||
], | ||
), | ||
migrations.CreateModel( | ||
name='ServerInformation', | ||
fields=[ | ||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('name', models.TextField(help_text='Name this server uses to present itself in the servers list', max_length=50, verbose_name='Name')), | ||
('description', models.TextField(help_text='A brief description of what this server is about', max_length=200, verbose_name='Description')), | ||
('icon', models.URLField(blank=True, help_text='URL of the image this server uses to present itself in the servers list', verbose_name='Icon')), | ||
('rules', models.TextField(blank=True, help_text='The rules that players must follow on this server', verbose_name='Rules')), | ||
('motd', models.TextField(help_text='Message displayed to players when they join the server', verbose_name='Message of the Day (MOTD)')), | ||
('is_18_plus', models.BooleanField(default=False, help_text='Indicates if this server is intended for players aged 18 and above', verbose_name='18+')), | ||
('is_delisted', models.BooleanField(help_text='Indicates if this server is delisted from the servers list', verbose_name='Is Delisted')), | ||
('listing_key', models.TextField(blank=True, help_text='A unique key used for listing this server. Do not lose this key!', null=True, unique=True, verbose_name='Listing Key')), | ||
('code_scan_version', models.ForeignKey(help_text='What version should this build of the game be tested against in CodeScan', on_delete=django.db.models.deletion.PROTECT, to='server.codescaninformation', verbose_name='CodeScan Version')), | ||
('owner', models.ForeignKey(help_text='Who created and/or is responsible for this server', on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Owner')), | ||
], | ||
), | ||
migrations.CreateModel( | ||
name='ServerAdmonition', | ||
fields=[ | ||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('created_at', models.DateTimeField(auto_now_add=True, help_text='When was this admonition created', verbose_name='Created at')), | ||
('reason', models.TextField(help_text='Why was this server warned?', verbose_name='Reason')), | ||
('severity', models.CharField(choices=[('low', 'Low'), ('medium', 'Medium'), ('high', 'High')], default='low', help_text='The severity level of the admonition', max_length=6)), | ||
('owner_moderation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='admonitions', to='server.accountmoderationinfo')), | ||
('server', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='admonitions', to='server.serverinformation')), | ||
], | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import secrets | ||
import string | ||
|
||
from django.db import models | ||
from django.db.models.signals import pre_save | ||
from django.dispatch import receiver | ||
|
||
from accounts.models import Account | ||
|
||
|
||
class CodeScanInformation(models.Model): | ||
version = models.TextField(primary_key=True) | ||
|
||
def __str__(self): | ||
return self.version | ||
|
||
|
||
def generate_listing_key(): | ||
alphabet = string.ascii_letters + string.digits + "-_" | ||
return "".join(secrets.choice(alphabet) for _ in range(30)) | ||
|
||
|
||
class ServerInformation(models.Model): | ||
owner = models.ForeignKey( | ||
verbose_name="Owner", | ||
to=Account, | ||
on_delete=models.CASCADE, | ||
help_text="Who created and/or is responsible for this server", | ||
) | ||
name = models.TextField( | ||
verbose_name="Name", | ||
max_length=50, | ||
help_text="Name this server uses to present itself in the servers list", | ||
) | ||
description = models.TextField( | ||
verbose_name="Description", | ||
max_length=200, | ||
help_text="A brief description of what this server is about", | ||
) | ||
icon = models.URLField( | ||
verbose_name="Icon", | ||
blank=True, | ||
help_text="URL of the image this server uses to present itself in the servers list", | ||
) | ||
rules = models.TextField( | ||
verbose_name="Rules", | ||
blank=True, | ||
help_text="The rules that players must follow on this server", | ||
) | ||
motd = models.TextField( | ||
verbose_name="Message of the Day (MOTD)", | ||
help_text="Message displayed to players when they join the server", | ||
) | ||
is_18_plus = models.BooleanField( | ||
verbose_name="18+", | ||
default=False, | ||
help_text="Indicates if this server is intended for players aged 18 and above", | ||
) | ||
code_scan_version = models.ForeignKey( | ||
verbose_name="CodeScan Version", | ||
to=CodeScanInformation, | ||
on_delete=models.PROTECT, | ||
help_text="What version should this build of the game be tested against in CodeScan", | ||
) | ||
is_delisted = models.BooleanField( | ||
verbose_name="Is Delisted", | ||
help_text="Indicates if this server is delisted from the servers list", | ||
) | ||
listing_key = models.TextField( | ||
unique=True, | ||
verbose_name="Listing Key", | ||
null=True, | ||
blank=True, | ||
help_text="A unique key used for listing this server. Do not lose this key!", | ||
) | ||
|
||
def __str__(self): | ||
return f"Server: {self.name} by: {self.owner.unique_identifier}" | ||
|
||
|
||
@receiver(pre_save, sender=ServerInformation) | ||
def set_listing_key(sender, instance: ServerInformation, **kwargs): | ||
if not instance.listing_key: | ||
unique_key_found = False | ||
while not unique_key_found: | ||
new_key = generate_listing_key() | ||
if not ServerInformation.objects.filter(listing_key=new_key).exists(): | ||
instance.listing_key = new_key | ||
unique_key_found = True | ||
|
||
|
||
# class ServerStatus(models.Model): | ||
# server = models.ForeignKey( | ||
# ServerInformation, related_name="status", on_delete=models.CASCADE | ||
# ) | ||
# is_passworded = models.BooleanField() | ||
# fork_name = models.TextField() | ||
# build_version = models.TextField() | ||
# current_map = models.TextField() | ||
# game_mode = models.TextField() | ||
# ingame_time = models.TextField() | ||
# round_time = models.TextField() | ||
# player_count = models.PositiveSmallIntegerField() | ||
# player_count_max = models.PositiveSmallIntegerField() | ||
# ip = models.TextField() | ||
# port = models.PositiveSmallIntegerField() | ||
# windows_download = models.URLField() | ||
# osx_download = models.URLField() | ||
# linux_download = models.URLField() | ||
# fps = models.PositiveSmallIntegerField() | ||
|
||
|
||
class AccountModerationInfo(models.Model): | ||
account = models.OneToOneField(to=Account, related_name="moderation_info", on_delete=models.CASCADE) | ||
can_create_servers = models.BooleanField(default=True) | ||
can_list_servers = models.BooleanField(default=True) | ||
|
||
def __str__(self): | ||
return f"Moderation for {self.account.unique_identifier}" | ||
|
||
|
||
class ServerAdmonition(models.Model): | ||
SEVERITY_LEVELS = [ | ||
("low", "Low"), | ||
("medium", "Medium"), | ||
("high", "High"), | ||
] | ||
|
||
owner_moderation = models.ForeignKey(AccountModerationInfo, related_name="admonitions", on_delete=models.CASCADE) | ||
server = models.ForeignKey( | ||
ServerInformation, | ||
related_name="admonitions", | ||
on_delete=models.SET_NULL, | ||
null=True, | ||
) | ||
created_at = models.DateTimeField( | ||
verbose_name="Created at", | ||
auto_now_add=True, | ||
help_text="When was this admonition created", | ||
) | ||
reason = models.TextField(verbose_name="Reason", help_text="Why was this server warned?") | ||
severity = models.CharField( | ||
max_length=6, | ||
choices=SEVERITY_LEVELS, | ||
default="low", | ||
help_text="The severity level of the admonition", | ||
) | ||
|
||
def __str__(self): | ||
return f"[{self.get_severity_display()}]: {self.reason}" |