diff --git a/aiarena/core/migrations/0025_delete_websitenotice.py b/aiarena/core/migrations/0025_delete_websitenotice.py new file mode 100644 index 00000000..43d3d0f7 --- /dev/null +++ b/aiarena/core/migrations/0025_delete_websitenotice.py @@ -0,0 +1,16 @@ +# Generated by Django 3.0.8 on 2021-02-18 23:38 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0024_auto_20210217_0927'), + ] + + operations = [ + migrations.DeleteModel( + name='WebsiteNotice', + ), + ] diff --git a/aiarena/core/models/__init__.py b/aiarena/core/models/__init__.py index aaa49dfc..a9cddc38 100644 --- a/aiarena/core/models/__init__.py +++ b/aiarena/core/models/__init__.py @@ -19,4 +19,3 @@ from .trophy import TrophyIcon from .tag import Tag from .user import User -from .website_notice import WebsiteNotice diff --git a/aiarena/core/models/website_notice.py b/aiarena/core/models/website_notice.py deleted file mode 100644 index b0fc0bf8..00000000 --- a/aiarena/core/models/website_notice.py +++ /dev/null @@ -1,16 +0,0 @@ -import logging - -from django.db import models - -from .user import User - -logger = logging.getLogger(__name__) - - -class WebsiteNotice(models.Model): - """ Represents a notice to be displayed on the website """ - title = models.CharField(max_length=20) - description = models.TextField() - created = models.DateTimeField(auto_now_add=True) - display = models.BooleanField(default=True) - posted_by = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True) diff --git a/aiarena/frontend/admin.py b/aiarena/frontend/admin.py index d9e72d5b..bda68cc7 100644 --- a/aiarena/frontend/admin.py +++ b/aiarena/frontend/admin.py @@ -2,7 +2,8 @@ from django.http import HttpResponseRedirect from aiarena.core.models import ArenaClient, Bot, Map, Match, MatchParticipation, Result, Round, Competition, \ - CompetitionBotMatchupStats, CompetitionParticipation, Trophy, TrophyIcon, User, News, MapPool, MatchTag, Tag + CompetitionBotMatchupStats, CompetitionParticipation, Trophy, TrophyIcon, User, News, MapPool, MatchTag, Tag, \ + ArenaClientStatus from aiarena.core.models.game import Game from aiarena.core.models.game_mode import GameMode from aiarena.patreon.models import PatreonAccountBind @@ -20,38 +21,9 @@ class BotInline(StackedItemInline): model = Bot -@admin.register(User) -class UserAdmin(admin.ModelAdmin): - search_fields = ('username',) - list_display = ( - 'id', - 'password', - 'last_login', - 'is_superuser', - 'username', - 'first_name', - 'last_name', - 'is_staff', - 'is_active', - 'date_joined', - 'email', - 'patreon_level', - 'type', - 'extra_active_competition_participations', - 'extra_periodic_match_requests', - 'receive_email_comms', - 'can_request_games_for_another_authors_bot', - ) - list_filter = ( - 'last_login', - 'is_superuser', - 'is_staff', - 'is_active', - 'date_joined', - 'receive_email_comms', - 'can_request_games_for_another_authors_bot', - ) - raw_id_fields = ('groups', 'user_permissions') +################################################################## +# PLEASE ORDER THESE ALPHABETICALLY # +################################################################## @admin.register(ArenaClient) @@ -59,36 +31,36 @@ class ArenaClientAdmin(admin.ModelAdmin): search_fields = ('username',) ordering = ['username'] list_display = ( - 'username', - 'id', - 'password', - 'last_login', - 'is_superuser', - 'first_name', - 'last_name', - 'is_staff', - 'is_active', - 'date_joined', - 'email', - 'patreon_level', - 'type', - 'owner', - 'extra_active_competition_participations', - 'extra_periodic_match_requests', - 'receive_email_comms', - 'can_request_games_for_another_authors_bot', - 'trusted', + 'username', + 'id', + 'password', + 'last_login', + 'is_superuser', + 'first_name', + 'last_name', + 'is_staff', + 'is_active', + 'date_joined', + 'email', + 'patreon_level', + 'type', + 'owner', + 'extra_active_competition_participations', + 'extra_periodic_match_requests', + 'receive_email_comms', + 'can_request_games_for_another_authors_bot', + 'trusted', ) list_filter = ( - 'last_login', - 'is_superuser', - 'is_staff', - 'is_active', - 'date_joined', - 'owner', - 'receive_email_comms', - 'can_request_games_for_another_authors_bot', - 'trusted', + 'last_login', + 'is_superuser', + 'is_staff', + 'is_active', + 'date_joined', + 'owner', + 'receive_email_comms', + 'can_request_games_for_another_authors_bot', + 'trusted', ) actions = ['activate', 'deactivate'] @@ -114,37 +86,63 @@ def deactivate(self, request, queryset): deactivate.short_description = "Deactivate ArenaClient/s" -@admin.register(Map) -class MapAdmin(admin.ModelAdmin): - search_fields = ('name',) - list_display = ('id', 'name', 'file') - list_filter = () +@admin.register(ArenaClientStatus) +class ArenaClientStatusAdmin(admin.ModelAdmin): + search_fields = ('arenaclient', 'status', 'logged_at',) + ordering = ('arenaclient', 'status', 'logged_at',) + list_display = ('arenaclient', 'status', 'logged_at',) + list_filter = ('arenaclient', 'status',) -@admin.register(MapPool) -class MapPoolAdmin(admin.ModelAdmin): - search_fields = ('name',) - list_display = ('id', 'name') - list_filter = () +@admin.register(Bot) +class BotAdmin(admin.ModelAdmin): + search_fields = ('name', 'user__username') + list_display = ( + 'id', + 'user', + 'name', + 'created', + 'bot_zip', + 'bot_zip_updated', + 'bot_zip_md5hash', + 'bot_zip_publicly_downloadable', + 'bot_data_enabled', + 'bot_data', + 'bot_data_md5hash', + 'bot_data_publicly_downloadable', + 'plays_race', + 'type', + 'game_display_id', + 'wiki_article', + ) + list_filter = ( + 'user', + 'created', + 'bot_zip_updated', + 'bot_zip_publicly_downloadable', + 'bot_data_enabled', + 'bot_data_publicly_downloadable', + 'wiki_article', + ) @admin.register(Competition) class CompetitionAdmin(admin.ModelAdmin): list_display = ( - 'id', - 'name', - 'type', - 'game_mode', - 'date_created', - 'date_opened', - 'date_closed', - 'status', - 'max_active_rounds', + 'id', + 'name', + 'type', + 'game_mode', + 'date_created', + 'date_opened', + 'date_closed', + 'status', + 'max_active_rounds', ) list_filter = ( - 'date_created', - 'date_opened', - 'date_closed', + 'date_created', + 'date_opened', + 'date_closed', ) # Add the close competition button change_form_template = "admin/change_form_competition.html" @@ -174,30 +172,86 @@ def response_change(self, request, obj): return super().response_change(request, obj) -@admin.register(Round) -class RoundAdmin(admin.ModelAdmin): +@admin.register(CompetitionBotMatchupStats) +class CompetitionBotMatchupStatsAdmin(admin.ModelAdmin): list_display = ( - 'id', - 'number', - 'competition', - 'started', - 'finished', - 'complete', + 'id', + 'bot', + 'opponent', + 'match_count', + 'win_count', + 'win_perc', + 'loss_count', + 'loss_perc', + 'tie_count', + 'tie_perc', + 'crash_count', + 'crash_perc', ) - list_filter = ('competition', 'started', 'finished', 'complete') + list_filter = ('bot', 'opponent') + + +@admin.register(CompetitionParticipation) +class CompetitionParticipationAdmin(admin.ModelAdmin): + list_display = ( + 'id', + 'competition', + 'bot', + 'elo', + 'match_count', + 'win_perc', + 'win_count', + 'loss_perc', + 'loss_count', + 'tie_perc', + 'tie_count', + 'crash_perc', + 'crash_count', + 'elo_graph', + 'highest_elo', + 'slug', + ) + list_filter = ('competition', 'bot') + search_fields = ('slug',) + + +@admin.register(Game) +class GameAdmin(admin.ModelAdmin): + list_display = ('name',) + search_fields = ('name',) + + +@admin.register(GameMode) +class GameModeAdmin(admin.ModelAdmin): + list_display = ('name', 'game') + search_fields = ('name', 'game') + + +@admin.register(Map) +class MapAdmin(admin.ModelAdmin): + search_fields = ('name',) + list_display = ('id', 'name', 'file') + list_filter = () + + +@admin.register(MapPool) +class MapPoolAdmin(admin.ModelAdmin): + search_fields = ('name',) + list_display = ('id', 'name') + list_filter = () @admin.register(Match) class MatchAdmin(admin.ModelAdmin): list_display = ( - 'id', - 'map', - 'created', - 'started', - 'assigned_to', - 'round', - 'requested_by', - 'require_trusted_arenaclient', + 'id', + 'map', + 'created', + 'started', + 'assigned_to', + 'round', + 'requested_by', + 'require_trusted_arenaclient', ) list_filter = ('created', 'started', 'require_trusted_arenaclient') search_fields = ['id'] @@ -218,125 +272,96 @@ def cancel_matches(self, request, queryset): cancel_matches.short_description = "Cancel selected matches" -@admin.register(Bot) -class BotAdmin(admin.ModelAdmin): - search_fields = ('name', 'user__username') +@admin.register(MatchParticipation) +class MatchParticipationAdmin(admin.ModelAdmin): list_display = ( - 'id', - 'user', - 'name', - 'created', - 'bot_zip', - 'bot_zip_updated', - 'bot_zip_md5hash', - 'bot_zip_publicly_downloadable', - 'bot_data_enabled', - 'bot_data', - 'bot_data_md5hash', - 'bot_data_publicly_downloadable', - 'plays_race', - 'type', - 'game_display_id', - 'wiki_article', - ) - list_filter = ( - 'user', - 'created', - 'bot_zip_updated', - 'bot_zip_publicly_downloadable', - 'bot_data_enabled', - 'bot_data_publicly_downloadable', - 'wiki_article', + 'id', + 'match', + 'participant_number', + 'bot', + 'starting_elo', + 'resultant_elo', + 'elo_change', + 'match_log', + 'avg_step_time', + 'result', + 'result_cause', + 'use_bot_data', + 'update_bot_data', ) + list_filter = ('use_bot_data', 'update_bot_data') -@admin.register(MatchParticipation) -class MatchParticipationAdmin(admin.ModelAdmin): +@admin.register(MatchTag) +class MatchTagAdmin(admin.ModelAdmin): list_display = ( - 'id', - 'match', - 'participant_number', - 'bot', - 'starting_elo', - 'resultant_elo', - 'elo_change', - 'match_log', - 'avg_step_time', - 'result', - 'result_cause', - 'use_bot_data', - 'update_bot_data', + 'id', + 'user', + 'tag', ) - list_filter = ('use_bot_data', 'update_bot_data') + list_filter = ( + 'user', + ) + search_fields = ('tag__name',) + + +@admin.register(News) +class NewsAdmin(admin.ModelAdmin): + list_display = ('created', 'title', 'text', 'yt_link') + search_fields = ('title',) + + +@admin.register(PatreonAccountBind) +class PatreonAccountBindAdmin(admin.ModelAdmin): + list_display = [field.name for field in PatreonAccountBind._meta.fields] @admin.register(Result) class ResultAdmin(admin.ModelAdmin): list_display = ( - 'id', - 'match', - 'winner', - 'type', - 'created', - 'replay_file', - 'game_steps', - 'submitted_by', - 'arenaclient_log', - 'interest_rating', - 'date_interest_rating_calculated', - 'replay_file_has_been_cleaned', + 'id', + 'match', + 'winner', + 'type', + 'created', + 'replay_file', + 'game_steps', + 'submitted_by', + 'arenaclient_log', + 'interest_rating', + 'date_interest_rating_calculated', + 'replay_file_has_been_cleaned', ) list_filter = ( - 'match', - 'winner', - 'created', - 'submitted_by', - 'date_interest_rating_calculated', - 'replay_file_has_been_cleaned', + 'match', + 'winner', + 'created', + 'submitted_by', + 'date_interest_rating_calculated', + 'replay_file_has_been_cleaned', ) -@admin.register(CompetitionParticipation) -class CompetitionParticipationAdmin(admin.ModelAdmin): +@admin.register(Round) +class RoundAdmin(admin.ModelAdmin): list_display = ( - 'id', - 'competition', - 'bot', - 'elo', - 'match_count', - 'win_perc', - 'win_count', - 'loss_perc', - 'loss_count', - 'tie_perc', - 'tie_count', - 'crash_perc', - 'crash_count', - 'elo_graph', - 'highest_elo', - 'slug', + 'id', + 'number', + 'competition', + 'started', + 'finished', + 'complete', ) - list_filter = ('competition', 'bot') - search_fields = ('slug',) + list_filter = ('competition', 'started', 'finished', 'complete') -@admin.register(CompetitionBotMatchupStats) -class CompetitionBotMatchupStatsAdmin(admin.ModelAdmin): +@admin.register(Tag) +class TagAdmin(admin.ModelAdmin): list_display = ( - 'id', - 'bot', - 'opponent', - 'match_count', - 'win_count', - 'win_perc', - 'loss_count', - 'loss_perc', - 'tie_count', - 'tie_perc', - 'crash_count', - 'crash_perc', + 'id', + 'name', ) - list_filter = ('bot', 'opponent') + search_fields = ('name',) @admin.register(Trophy) @@ -352,46 +377,35 @@ class TrophyIconAdmin(admin.ModelAdmin): search_fields = ('name',) -@admin.register(PatreonAccountBind) -class PatreonAccountBindAdmin(admin.ModelAdmin): - list_display = [field.name for field in PatreonAccountBind._meta.fields] - - -@admin.register(News) -class NewsAdmin(admin.ModelAdmin): - list_display = ('created', 'title', 'text', 'yt_link') - search_fields = ('title',) - - -@admin.register(Game) -class GameAdmin(admin.ModelAdmin): - list_display = ('name',) - search_fields = ('name',) - - -@admin.register(GameMode) -class GameModeAdmin(admin.ModelAdmin): - list_display = ('name', 'game') - search_fields = ('name', 'game') - - -@admin.register(MatchTag) -class MatchTagAdmin(admin.ModelAdmin): +@admin.register(User) +class UserAdmin(admin.ModelAdmin): + search_fields = ('username',) list_display = ( - 'id', - 'user', - 'tag', + 'id', + 'password', + 'last_login', + 'is_superuser', + 'username', + 'first_name', + 'last_name', + 'is_staff', + 'is_active', + 'date_joined', + 'email', + 'patreon_level', + 'type', + 'extra_active_competition_participations', + 'extra_periodic_match_requests', + 'receive_email_comms', + 'can_request_games_for_another_authors_bot', ) list_filter = ( - 'user', + 'last_login', + 'is_superuser', + 'is_staff', + 'is_active', + 'date_joined', + 'receive_email_comms', + 'can_request_games_for_another_authors_bot', ) - search_fields = ('tag__name',) - - -@admin.register(Tag) -class TagAdmin(admin.ModelAdmin): - list_display = ( - 'id', - 'name', - ) - search_fields = ('name',) + raw_id_fields = ('groups', 'user_permissions') diff --git a/aiarena/frontend/static/style.css b/aiarena/frontend/static/style.css index 4c949fa3..7ddb3a7e 100644 --- a/aiarena/frontend/static/style.css +++ b/aiarena/frontend/static/style.css @@ -1391,3 +1391,40 @@ input[type=text], input[type=password], input[type=email], input[type=number], i content: "\6b"; color: #800000; } + +.collapsible { + background-color: rgba(97, 137, 47, 0.7); + color: white; + cursor: pointer; + padding: 9px; + width: 90.1%; + border: none; + text-align: left; + outline: none; + font-family: 'Quicksand', sans-serif; + font-weight: bold; + font-size: 16px; +} + +.collapsible:after { + content: '\02795'; /* Unicode character for "plus" sign (+) */ + float: right; + margin-left: 5px; +} + +.collapsible-active:after { + content: "\2796"; /* Unicode character for "minus" sign (-) */ +} + +.collapsible-active, .collapsible:hover { + background-color: rgba(97, 137, 47, 1); +} + +.collapsible-content { + padding: 0 30px; + background-color: rgba(0,0,0,0.25); + max-height: 0; + width: 84.5%; + overflow: hidden; + transition: max-height 0.2s ease-out +} \ No newline at end of file diff --git a/aiarena/frontend/templates/bot.html b/aiarena/frontend/templates/bot.html index 28e97293..52e7020b 100644 --- a/aiarena/frontend/templates/bot.html +++ b/aiarena/frontend/templates/bot.html @@ -212,60 +212,79 @@