generate channels view
This commit is contained in:
parent
6127233c0f
commit
9002eaf807
@ -3,10 +3,10 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
|
|
||||||
from .views import IndexView, GuildsView, CheckBotPermissionView
|
from .views import IndexView, GuildsView, ChannelsView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", login_required(IndexView.as_view()), name="index"),
|
path("", login_required(IndexView.as_view()), name="index"),
|
||||||
path("generate-servers/", GuildsView.as_view(), name="generate-servers"),
|
path("generate-servers/", GuildsView.as_view(), name="generate-servers"),
|
||||||
path("bot-permissions/", CheckBotPermissionView.as_view(), name="bot-permissions")
|
path("generate-channels/", ChannelsView.as_view(), name="generate-channels"),
|
||||||
]
|
]
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -9,10 +10,13 @@ from asgiref.sync import sync_to_async
|
|||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
from django.http import JsonResponse, HttpResponse
|
from django.http import JsonResponse, HttpResponse
|
||||||
from django.views.generic import TemplateView, View
|
from django.views.generic import TemplateView, View
|
||||||
|
from django.core.exceptions import PermissionDenied
|
||||||
|
|
||||||
from apps.home.models import Server
|
from apps.home.models import Server, DiscordChannel
|
||||||
from apps.authentication.models import DiscordUser, ServerMember
|
from apps.authentication.models import DiscordUser, ServerMember
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class IndexView(TemplateView):
|
class IndexView(TemplateView):
|
||||||
"""
|
"""
|
||||||
@ -22,13 +26,22 @@ class IndexView(TemplateView):
|
|||||||
template_name = "home/index.html"
|
template_name = "home/index.html"
|
||||||
|
|
||||||
|
|
||||||
|
@sync_to_async
|
||||||
|
def get_user_access_token(user: DiscordUser) -> str:
|
||||||
|
return user.access_token
|
||||||
|
|
||||||
|
@sync_to_async
|
||||||
|
def is_user_authenticated(user: DiscordUser) -> bool:
|
||||||
|
return user.is_authenticated
|
||||||
|
|
||||||
|
|
||||||
class GuildsView(View):
|
class GuildsView(View):
|
||||||
|
|
||||||
async def get(self, request, *args, **kwargs):
|
async def get(self, request, *args, **kwargs):
|
||||||
if not await self.is_user_authenticated(request.user):
|
if not await is_user_authenticated(request.user):
|
||||||
return redirect("/oauth2/login")
|
return redirect("/oauth2/login")
|
||||||
|
|
||||||
access_token = await self.get_user_access_token(request.user)
|
access_token = await get_user_access_token(request.user)
|
||||||
|
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
response = await client.get(
|
response = await client.get(
|
||||||
@ -51,16 +64,6 @@ class GuildsView(View):
|
|||||||
|
|
||||||
return JsonResponse(cleaned_guild_data, safe=False)
|
return JsonResponse(cleaned_guild_data, safe=False)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@sync_to_async
|
|
||||||
def get_user_access_token(user: DiscordUser) -> str:
|
|
||||||
return user.access_token
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@sync_to_async
|
|
||||||
def is_user_authenticated(user: DiscordUser) -> bool:
|
|
||||||
return user.is_authenticated
|
|
||||||
|
|
||||||
async def setup_server(self, user: DiscordUser, data: dict):
|
async def setup_server(self, user: DiscordUser, data: dict):
|
||||||
is_owner = data["owner"]
|
is_owner = data["owner"]
|
||||||
permissions = data["permissions"]
|
permissions = data["permissions"]
|
||||||
@ -99,7 +102,80 @@ class GuildsView(View):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CheckBotPermissionView(View):
|
class ChannelsView(View):
|
||||||
|
|
||||||
async def get(self, request, *args, **kwargs):
|
async def get(self, request, *args, **kwargs):
|
||||||
return JsonResponse({"test": ""})
|
if not await is_user_authenticated(request.user):
|
||||||
|
return redirect("/oauth2/login")
|
||||||
|
|
||||||
|
guild_id = request.GET.get("guild")
|
||||||
|
server = await Server.objects.aget(pk=guild_id)
|
||||||
|
|
||||||
|
if not ServerMember.objects.filter(server=server, user=request.user).aexists():
|
||||||
|
raise PermissionDenied("You aren't a member of this server.")
|
||||||
|
|
||||||
|
channels_data, status = await self._get_channel_data(guild_id)
|
||||||
|
if status != 200:
|
||||||
|
return JsonResponse(channels_data, status=status, safe=False)
|
||||||
|
|
||||||
|
cleaned_channels_data = await self._clean_channels_data(server, channels_data)
|
||||||
|
await self._cleanup_dead_channels(server, cleaned_channels_data)
|
||||||
|
|
||||||
|
return JsonResponse(cleaned_channels_data, safe=False)
|
||||||
|
|
||||||
|
async def _get_channel_data(self, guild_id: int) -> tuple[list[dict], int]:
|
||||||
|
"""
|
||||||
|
Returns the raw channel data and a response status code
|
||||||
|
from the Discord API.
|
||||||
|
"""
|
||||||
|
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
response = await client.get(
|
||||||
|
url=f"{settings.DISCORD_API_URL}/guilds/{guild_id}/channels",
|
||||||
|
headers={"Authorization": f"Bot {settings.BOT_TOKEN}"}
|
||||||
|
)
|
||||||
|
return response.json(), response.status_code
|
||||||
|
|
||||||
|
async def _clean_channels_data(self, server: Server, channels_data) -> list[dict]:
|
||||||
|
"""
|
||||||
|
Returns a sorted & cleaned list of channel data, also performs a
|
||||||
|
database setup for each channel to be stored.
|
||||||
|
"""
|
||||||
|
|
||||||
|
cleaned_channels_data = []
|
||||||
|
|
||||||
|
for item in channels_data:
|
||||||
|
cleaned_data = await self._setup_channel(server, item)
|
||||||
|
if cleaned_data:
|
||||||
|
cleaned_channels_data.append(cleaned_data)
|
||||||
|
|
||||||
|
cleaned_channels_data.sort(key=lambda ch: ch.get("position"))
|
||||||
|
return cleaned_channels_data
|
||||||
|
|
||||||
|
async def _setup_channel(self, server: Server, data: dict) -> dict:
|
||||||
|
"""
|
||||||
|
Create or update an instance of DiscordChannel representing the given
|
||||||
|
`data` dictionary, returns the data or `NoneType` if `data['type'] != 0`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if data.get("type") != 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
await DiscordChannel.objects.aupdate_or_create(
|
||||||
|
id=data["id"],
|
||||||
|
server=server,
|
||||||
|
defaults={
|
||||||
|
"name": data["name"],
|
||||||
|
"is_nsfw": data["nsfw"]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return data
|
||||||
|
|
||||||
|
async def _cleanup_dead_channels(self, server: Server, channel_data: list[dict]):
|
||||||
|
"""
|
||||||
|
Deletes any unused instances of `DiscordChannel` against the given server.
|
||||||
|
"""
|
||||||
|
|
||||||
|
channel_ids = [item["id"] for item in channel_data]
|
||||||
|
count, _ = await DiscordChannel.objects.exclude(server=server, id__in=channel_ids).adelete()
|
||||||
|
log.info("Deleted %s dead DiscordChannel object(s)", count)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user