122 lines
4.1 KiB
Python
122 lines
4.1 KiB
Python
from django.contrib import admin, messages
|
|
from django_object_actions import (
|
|
DjangoObjectActions,
|
|
action,
|
|
takes_instance_or_queryset,
|
|
)
|
|
|
|
from submissions.tasks import schedule_scope_sync, stop_scope_sync
|
|
|
|
from .models import EventGame, Game, PlanningSlot
|
|
from .tasks import refresh_steam_games_task
|
|
|
|
|
|
class EventGameInline(admin.TabularInline):
|
|
model = EventGame
|
|
extra = 0
|
|
|
|
|
|
@admin.register(Game)
|
|
class GameAdmin(admin.ModelAdmin):
|
|
list_display = ["name", "steam_app_id", "updated_at"]
|
|
search_fields = ["name", "steam_app_id"]
|
|
readonly_fields = [
|
|
"created_at",
|
|
"updated_at",
|
|
"steam_price_initial",
|
|
"steam_price_final",
|
|
"steam_discount_percent",
|
|
"steam_currency",
|
|
"steam_is_free",
|
|
"steam_short_description",
|
|
"steam_header_image",
|
|
"steam_info_updated_at",
|
|
]
|
|
inlines = [EventGameInline]
|
|
actions = ["refresh_steam_info"]
|
|
|
|
@admin.action(description="Refresh Steam store info")
|
|
def refresh_steam_info(self, request, queryset):
|
|
game_ids = list(
|
|
queryset.filter(steam_app_id__isnull=False).values_list("id", flat=True)
|
|
)
|
|
refresh_steam_games_task.enqueue(game_ids=game_ids)
|
|
self.message_user(
|
|
request, f"Queued Steam store refresh for {len(game_ids)} game(s)."
|
|
)
|
|
|
|
|
|
@admin.register(EventGame)
|
|
class EventGameAdmin(DjangoObjectActions, admin.ModelAdmin):
|
|
list_display = ["game", "event", "enabled", "has_apibot_token"]
|
|
list_filter = ["event", "enabled"]
|
|
search_fields = ["game__name", "event__name"]
|
|
actions = ["enable", "disable", "sync_scopes", "stop_scope_sync"]
|
|
change_actions = ["sync_scopes", "stop_scope_sync"]
|
|
|
|
@admin.display(description="AAndT token", boolean=True)
|
|
def has_apibot_token(self, obj):
|
|
return bool(obj.apibot_token)
|
|
|
|
def _set_enabled(self, request, queryset, enabled: bool):
|
|
# save() per row (not update()) so post_save fires, e.g. the clock heartbeat
|
|
changed = 0
|
|
for event_game in queryset.select_related("game").filter(enabled=not enabled):
|
|
event_game.enabled = enabled
|
|
event_game.save(update_fields=["enabled"])
|
|
changed += 1
|
|
|
|
self.message_user(
|
|
request,
|
|
f"{'Enabled' if enabled else 'Disabled'} {changed} EventGame(s)"
|
|
f" ({queryset.count() - changed} already {'enabled' if enabled else 'disabled'}).",
|
|
)
|
|
|
|
@admin.action(description="Enable selected EventGames")
|
|
def enable(self, request, queryset):
|
|
self._set_enabled(request, queryset, enabled=True)
|
|
|
|
@admin.action(description="Disable selected EventGames")
|
|
def disable(self, request, queryset):
|
|
self._set_enabled(request, queryset, enabled=False)
|
|
|
|
@action(
|
|
label="Sync scopes",
|
|
description="Sync scopes from AAndT for selected EventGames",
|
|
)
|
|
@takes_instance_or_queryset
|
|
def sync_scopes(self, request, queryset):
|
|
tokened = queryset.exclude(apibot_token__isnull=True).exclude(apibot_token="")
|
|
skipped = queryset.count() - tokened.count()
|
|
|
|
started = sum(schedule_scope_sync(event_game.id) for event_game in tokened)
|
|
|
|
self.message_user(
|
|
request,
|
|
f"Started scope sync for {started} EventGame(s)"
|
|
f" ({tokened.count() - started} already running).",
|
|
)
|
|
if skipped:
|
|
self.message_user(
|
|
request,
|
|
f"Skipped {skipped} EventGame(s) with no AAndT token configured.",
|
|
level=messages.WARNING,
|
|
)
|
|
|
|
@action(
|
|
label="Stop scope sync",
|
|
description="Stop the scope sync loop of selected EventGames",
|
|
)
|
|
@takes_instance_or_queryset
|
|
def stop_scope_sync(self, request, queryset):
|
|
stopped = sum(stop_scope_sync(event_game.id) for event_game in queryset)
|
|
|
|
self.message_user(request, f"Stopped scope sync for {stopped} EventGame(s).")
|
|
|
|
|
|
@admin.register(PlanningSlot)
|
|
class PlanningSlotAdmin(admin.ModelAdmin):
|
|
list_display = ["title", "event", "begin", "end", "column", "is_multi_anims"]
|
|
list_filter = ["event", "is_multi_anims"]
|
|
search_fields = ["title"]
|