Basic utils for models, added some stuff to the bot
This commit is contained in:
parent
fb9744a93a
commit
b3eefa1266
@ -78,6 +78,7 @@ class Geeksbot(commands.Bot):
|
||||
self.config_dir = 'geeksbot/config/'
|
||||
self.config_file = 'bot_config.json'
|
||||
self.extension_dir = 'exts'
|
||||
self.api_token = os.environ['API_TOKEN']
|
||||
self.aio_session = aiohttp.ClientSession(loop=self.loop)
|
||||
with open(f'{self.config_dir}{self.config_file}') as f:
|
||||
self.bot_config = json.load(f)
|
||||
@ -90,6 +91,16 @@ class Geeksbot(commands.Bot):
|
||||
self.git_url = 'https://github.com/dustinpianalto/geeksbot_v2'
|
||||
self.load_default_extensions()
|
||||
|
||||
self.book_emojis = {
|
||||
'unlock': '🔓',
|
||||
'start': '⏮',
|
||||
'back': '◀',
|
||||
'hash': '#\N{COMBINING ENCLOSING KEYCAP}',
|
||||
'forward': '▶',
|
||||
'end': '⏭',
|
||||
'close': '🇽',
|
||||
}
|
||||
|
||||
async def load_ext(self, mod):
|
||||
self.load_extension(f'geeksbot.{self.extension_dir}.{mod}')
|
||||
logger.info(f'Extension Loaded: {mod}')
|
||||
|
||||
@ -64,9 +64,9 @@ class Exec(commands.Cog):
|
||||
ret = await func()
|
||||
except Exception:
|
||||
pag.add(stdout.getvalue())
|
||||
pag.add(traceback.format_exc())
|
||||
for page in pag.pages():
|
||||
await ctx.send(page)
|
||||
pag.add(f'\n\uFFF8{traceback.format_exc()}')
|
||||
book = Book(pag, (None, ctx.channel, ctx.bot, ctx.message))
|
||||
await book.create_book()
|
||||
else:
|
||||
value = stdout.getvalue()
|
||||
# noinspection PyBroadException
|
||||
@ -76,10 +76,10 @@ class Exec(commands.Cog):
|
||||
pass
|
||||
value = format_output(value)
|
||||
pag.add(value)
|
||||
pag.add(f'\nReturned: {ret}')
|
||||
pag.add(f'\n\uFFF8Returned: {ret}')
|
||||
self._last_result = ret
|
||||
for page in pag.pages():
|
||||
await ctx.send(page)
|
||||
book = Book(pag, (None, ctx.channel, ctx.bot, ctx.message))
|
||||
await book.create_book()
|
||||
|
||||
@commands.command(hidden=True)
|
||||
async def repl(self, ctx):
|
||||
@ -161,8 +161,8 @@ class Exec(commands.Cog):
|
||||
body = self.cleanup_code(body)
|
||||
pag = Paginator(self.bot)
|
||||
pag.add(await asyncio.wait_for(self.bot.loop.create_task(run_command(body)), 120))
|
||||
for page in pag.pages():
|
||||
await ctx.send(page)
|
||||
book = Book(pag, (None, ctx.channel, ctx.bot, ctx.message))
|
||||
await book.create_book()
|
||||
await ctx.message.add_reaction('✅')
|
||||
except asyncio.TimeoutError:
|
||||
await ctx.send(f"Command did not complete in the time allowed.")
|
||||
|
||||
@ -156,7 +156,7 @@ class Paginator:
|
||||
|
||||
if not self._embed:
|
||||
for part in [str(p) for p in self._parts]:
|
||||
if part == self._page_break:
|
||||
if part.startswith(self._page_break):
|
||||
close_page()
|
||||
|
||||
new_chars = len(_page) + len(part)
|
||||
@ -185,9 +185,8 @@ class Paginator:
|
||||
open_field('\uFFF0')
|
||||
|
||||
for part in [str(p) for p in self._parts]:
|
||||
if part.strip() == self._page_break:
|
||||
if part.strip().startswith(self._page_break):
|
||||
close_page()
|
||||
continue
|
||||
elif part == self._field_break:
|
||||
if len(_fields) + 1 < 25:
|
||||
close_field(next_name='\uFFF0')
|
||||
|
||||
0
geeksbot_v2/channels/__init__.py
Normal file
0
geeksbot_v2/channels/__init__.py
Normal file
3
geeksbot_v2/channels/admin.py
Normal file
3
geeksbot_v2/channels/admin.py
Normal file
@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
5
geeksbot_v2/channels/apps.py
Normal file
5
geeksbot_v2/channels/apps.py
Normal file
@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ChannelsConfig(AppConfig):
|
||||
name = 'channels'
|
||||
0
geeksbot_v2/channels/migrations/__init__.py
Normal file
0
geeksbot_v2/channels/migrations/__init__.py
Normal file
46
geeksbot_v2/channels/models.py
Normal file
46
geeksbot_v2/channels/models.py
Normal file
@ -0,0 +1,46 @@
|
||||
from django.db import models
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from rest_framework import status
|
||||
|
||||
from geeksbot_v2.guilds.models import Guild
|
||||
from .utils import create_error_response
|
||||
from .utils import create_success_response
|
||||
|
||||
# Create your models here.
|
||||
|
||||
|
||||
class Channel(models.Model):
|
||||
id = models.CharField(max_length=30, primary_key=True)
|
||||
guild = models.ForeignKey(Guild, on_delete=models.CASCADE)
|
||||
|
||||
@classmethod
|
||||
def add_new_channel(cls, data):
|
||||
id = data.get('id')
|
||||
if id and cls.get_channel_by_id(id):
|
||||
return create_error_response('Channel Already Exists',
|
||||
status=status.HTTP_409_CONFLICT)
|
||||
guild_id = data.get('guild')
|
||||
if not (id and guild_id):
|
||||
return create_error_response('Id and Guild are required',
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
guild = Guild.get_guild_by_id(guild_id)
|
||||
if not isinstance(guild, Guild):
|
||||
return create_error_response('Guild Does Not Exist',
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
channel = cls(
|
||||
id=id,
|
||||
guild=guild
|
||||
)
|
||||
channel.save()
|
||||
return create_success_response(channel, status.HTTP_201_CREATED, many=False)
|
||||
|
||||
@classmethod
|
||||
def get_channel_by_id(cls, id):
|
||||
try:
|
||||
return cls.objects.get(id=id)
|
||||
except ObjectDoesNotExist:
|
||||
return None
|
||||
|
||||
def __str__(self):
|
||||
return str(id)
|
||||
9
geeksbot_v2/channels/serializers.py
Normal file
9
geeksbot_v2/channels/serializers.py
Normal file
@ -0,0 +1,9 @@
|
||||
from rest_framework import serializers
|
||||
|
||||
from .models import Channel
|
||||
|
||||
|
||||
class ChannelSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Channel
|
||||
fields = "__all__"
|
||||
3
geeksbot_v2/channels/tests.py
Normal file
3
geeksbot_v2/channels/tests.py
Normal file
@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
14
geeksbot_v2/channels/utils.py
Normal file
14
geeksbot_v2/channels/utils.py
Normal file
@ -0,0 +1,14 @@
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
|
||||
|
||||
def create_error_response(msg, status=status.HTTP_404_NOT_FOUND):
|
||||
return Response({'details': msg},
|
||||
status=status)
|
||||
|
||||
|
||||
def create_success_response(channel_data, status, many: bool = False):
|
||||
from .serializers import ChannelSerializer
|
||||
|
||||
return Response(ChannelSerializer(channel_data, many=many).data,
|
||||
status=status)
|
||||
3
geeksbot_v2/channels/views.py
Normal file
3
geeksbot_v2/channels/views.py
Normal file
@ -0,0 +1,3 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
@ -43,6 +43,7 @@ LOCALE_PATHS = [ROOT_DIR.path("locale")]
|
||||
# https://docs.djangoproject.com/en/dev/ref/settings/#databases
|
||||
DATABASES = {"default": env.db("DATABASE_URL")}
|
||||
DATABASES["default"]["ATOMIC_REQUESTS"] = True
|
||||
DATABASES['default']['CONN_MAX_AGE'] = 0
|
||||
|
||||
# URLS
|
||||
# ------------------------------------------------------------------------------
|
||||
@ -263,6 +264,9 @@ ACCOUNT_EMAIL_VERIFICATION = "optional"
|
||||
ACCOUNT_ADAPTER = "geeksbot_v2.users.adapters.AccountAdapter"
|
||||
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
||||
SOCIALACCOUNT_ADAPTER = "geeksbot_v2.users.adapters.SocialAccountAdapter"
|
||||
ACCOUNT_FORMS = {
|
||||
'signup': 'geeksbot_v2.users.forms.UserCreateForm',
|
||||
}
|
||||
|
||||
|
||||
# Your stuff...
|
||||
@ -275,6 +279,9 @@ REST_FRAMEWORK = {
|
||||
"DEFAULT_RENDERER_CLASSES": [
|
||||
"rest_framework.renderers.JSONRenderer",
|
||||
],
|
||||
"DEFAULT_PARSER_CLASSES": [
|
||||
'rest_framework.parsers.JSONParser',
|
||||
],
|
||||
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
|
||||
"PAGE_SIZE": 100,
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
"""
|
||||
To understand why this file is here, please read:
|
||||
|
||||
http://cookiecutter-django.readthedocs.io/en/latest/faq.html#why-is-there-a-django-contrib-sites-directory-in-cookiecutter-django
|
||||
"""
|
||||
from django.conf import settings
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Generated by Django 2.2.4 on 2019-09-16 05:23
|
||||
# Generated by Django 2.2.4 on 2019-09-17 19:31
|
||||
|
||||
from django.conf import settings
|
||||
import django.contrib.postgres.fields
|
||||
@ -11,8 +11,8 @@ class Migration(migrations.Migration):
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('guilds', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
|
||||
@ -1,8 +1,18 @@
|
||||
from datetime import datetime
|
||||
|
||||
from django.db import models
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.contrib.postgres.fields import ArrayField
|
||||
from rest_framework import status
|
||||
|
||||
from geeksbot_v2.guilds.models import Guild
|
||||
from geeksbot_v2.guilds.models import Role
|
||||
from geeksbot_v2.users.models import User
|
||||
from geeksbot_v2.channels.models import Channel
|
||||
from .utils import create_error_response
|
||||
from .utils import create_success_response
|
||||
from .utils import create_request_success_response
|
||||
from .utils import create_comment_success_response
|
||||
|
||||
# Create your models here.
|
||||
|
||||
@ -11,18 +21,124 @@ class Message(models.Model):
|
||||
id = models.CharField(max_length=30, primary_key=True)
|
||||
author = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
guild = models.ForeignKey(Guild, on_delete=models.CASCADE)
|
||||
channel = models.CharField(max_length=30)
|
||||
channel = models.ForeignKey(Channel, on_delete=models.CASCADE)
|
||||
created_at = models.DateTimeField()
|
||||
modified_at = models.DateTimeField(null=True)
|
||||
deleted_at = models.DateTimeField(null=True)
|
||||
modified_at = models.DateTimeField(null=True, blank=True)
|
||||
deleted_at = models.DateTimeField(null=True, blank=True)
|
||||
content = models.CharField(max_length=2000)
|
||||
previous_content = ArrayField(models.CharField(max_length=2000))
|
||||
tagged_users = ArrayField(models.CharField(max_length=30))
|
||||
tagged_channels = ArrayField(models.CharField(max_length=30))
|
||||
tagged_roles = ArrayField(models.CharField(max_length=30))
|
||||
previous_content = ArrayField(models.CharField(max_length=2000), default=[])
|
||||
tagged_users = models.ManyToManyField(User)
|
||||
tagged_channels = models.ManyToManyField(Channel)
|
||||
tagged_roles = models.ManyToManyField(Role)
|
||||
tagged_everyone = models.BooleanField()
|
||||
embeds = ArrayField(models.TextField())
|
||||
previous_embeds = ArrayField(ArrayField(models.TextField()))
|
||||
embeds = ArrayField(models.TextField(), default=[])
|
||||
previous_embeds = ArrayField(ArrayField(models.TextField()), default=[])
|
||||
|
||||
@classmethod
|
||||
def add_new_message(cls, data):
|
||||
id = data.get('id')
|
||||
if id and cls.get_message_by_id(id):
|
||||
return create_error_response("Message Already Exists",
|
||||
status=status.HTTP_409_CONFLICT)
|
||||
author_id = data.get('author')
|
||||
guild_id = data.get('guild')
|
||||
channel_id = data.get('channel')
|
||||
created_at = data.get('created_at')
|
||||
content = data.get('content')
|
||||
tagged_everyone = data.get('tagged_everyone')
|
||||
if not (id and author_id and guild_id and channel_id and created_at and content and tagged_everyone):
|
||||
return create_error_response("One or more required fields are missing.",
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
author = User.get_user_by_id(author_id)
|
||||
if not isinstance(author, User):
|
||||
return create_error_response("Author Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
guild = Guild.get_guild_by_id(guild_id)
|
||||
if not isinstance(guild, Guild):
|
||||
return create_error_response("Guild Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
channel = Channel.get_channel_by_id(channel_id)
|
||||
if not isinstance(channel, Channel):
|
||||
return create_error_response("Channel Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
created_at = datetime.fromtimestamp(created_at)
|
||||
|
||||
message = cls(
|
||||
id=id,
|
||||
author=author,
|
||||
guild=guild,
|
||||
channel=channel,
|
||||
created_at=created_at,
|
||||
tagged_everyone=tagged_everyone or False,
|
||||
content=content or '',
|
||||
embeds=data.get('embeds') or []
|
||||
)
|
||||
message.save()
|
||||
if data.get('tagged_users'):
|
||||
tagged_users = data.get('tagged_users')
|
||||
for user_id in tagged_users:
|
||||
user = User.get_user_by_id(user_id)
|
||||
if user:
|
||||
message.tagged_users.add(user)
|
||||
if data.get('tagged_roles'):
|
||||
tagged_roles = data.get('tagged_roles')
|
||||
for role_id in tagged_roles:
|
||||
role = Role.get_role_by_id(role_id)
|
||||
if role:
|
||||
message.tagged_roles.add(role)
|
||||
if data.get('tagged_channels'):
|
||||
tagged_channels = data.get('tagged_channels')
|
||||
for channel_id in tagged_channels:
|
||||
channel = Channel.get_channel_by_id(channel_id)
|
||||
if channel:
|
||||
message.tagged_channels.add(channel)
|
||||
|
||||
return create_success_response(message, status.HTTP_201_CREATED, many=False)
|
||||
|
||||
def update_message(self, data):
|
||||
if data.get('modified_at'):
|
||||
self.modified_at = data.get('modified_at')
|
||||
if data.get('deleted_at'):
|
||||
self.modified_at = data.get('deleted_at')
|
||||
if data.get('content'):
|
||||
content = data.get('content')
|
||||
if content != self.content:
|
||||
self.previous_content.append(self.content)
|
||||
self.content = content
|
||||
if data.get('embeds'):
|
||||
embeds = data.get('embeds')
|
||||
if embeds != self.embeds:
|
||||
self.previous_embeds.append(self.embeds)
|
||||
self.embeds = embeds
|
||||
if data.get('tagged_everyone'):
|
||||
tagged_everyone = data.get('tagged_everyone')
|
||||
if self.tagged_everyone or tagged_everyone:
|
||||
self.tagged_everyone = True
|
||||
if data.get('tagged_users'):
|
||||
tagged_users = data.get('tagged_users')
|
||||
for user in tagged_users:
|
||||
if user not in self.tagged_users:
|
||||
self.tagged_users.append(user)
|
||||
if data.get('tagged_roles'):
|
||||
tagged_roles = data.get('tagged_roles')
|
||||
for role in tagged_roles:
|
||||
if role not in self.tagged_roles:
|
||||
self.tagged_roles.append(role)
|
||||
if data.get('tagged_channels'):
|
||||
tagged_channels = data.get('tagged_channels')
|
||||
for channel in tagged_channels:
|
||||
if channel not in self.tagged_channels:
|
||||
self.tagged_channels.append(channel)
|
||||
|
||||
self.save()
|
||||
return create_success_response(self, status.HTTP_202_ACCEPTED, many=False)
|
||||
|
||||
@classmethod
|
||||
def get_message_by_id(cls, id):
|
||||
try:
|
||||
return cls.objects.get(id=id)
|
||||
except ObjectDoesNotExist:
|
||||
return None
|
||||
|
||||
def __str__(self):
|
||||
return (f'{self.created_at} | '
|
||||
@ -48,11 +164,113 @@ class GuildInfo(models.Model):
|
||||
|
||||
class AdminRequest(models.Model):
|
||||
guild = models.ForeignKey(Guild, on_delete=models.CASCADE)
|
||||
author = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
message = models.ForeignKey(Message, on_delete=models.CASCADE)
|
||||
completed = models.BooleanField()
|
||||
requested_at = models.DateTimeField()
|
||||
completed_at = models.DateTimeField()
|
||||
author = models.ForeignKey(User, on_delete=models.DO_NOTHING)
|
||||
message = models.ForeignKey(Message, on_delete=models.DO_NOTHING)
|
||||
channel = models.ForeignKey(Channel, on_delete=models.DO_NOTHING)
|
||||
completed = models.BooleanField(default=False)
|
||||
requested_at = models.DateTimeField(auto_now_add=True, blank=True)
|
||||
completed_at = models.DateTimeField(null=True, blank=True, default=None)
|
||||
completed_by = models.ForeignKey(User, on_delete=models.DO_NOTHING, null=True, blank=True, default=None)
|
||||
completed_message = models.CharField(max_length=1000, null=True, blank=True, default=None)
|
||||
content = models.CharField(max_length=2000)
|
||||
|
||||
def update_request(self, data):
|
||||
completed = data.get('completed', False)
|
||||
completed_by_id = data.get('completed_by')
|
||||
completed_message = data.get('message')
|
||||
if not self.completed and completed:
|
||||
self.completed_at = datetime.now()
|
||||
self.completed_message = completed_message
|
||||
user = User.get_user_by_id(completed_by_id)
|
||||
if not isinstance(user, User):
|
||||
return create_error_response('User Does Not Exist',
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
self.completed_by = user
|
||||
self.save()
|
||||
return create_request_success_response(self, status.HTTP_202_ACCEPTED)
|
||||
|
||||
@classmethod
|
||||
def add_new_request(cls, data):
|
||||
guild_id = data.get('guild')
|
||||
author_id = data.get('author')
|
||||
message_id = data.get('message')
|
||||
channel_id = data.get('channel')
|
||||
content = data.get('content')
|
||||
if not (guild_id and author_id and message_id and channel_id and content):
|
||||
return create_error_response("One or more of the required fields are missing.",
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
guild = Guild.get_guild_by_id(guild_id)
|
||||
if not isinstance(guild, Guild):
|
||||
return create_error_response('Guild Does Not Exist',
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
author = User.get_author_by_id(author_id)
|
||||
if not isinstance(author, User):
|
||||
return create_error_response('Author Does Not Exist',
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
message = Message.get_message_by_id(message_id)
|
||||
if not isinstance(message, Message):
|
||||
return create_error_response('Message Does Not Exist',
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
channel = Channel.get_channel_by_id(channel_id)
|
||||
if not isinstance(channel, Channel):
|
||||
return create_error_response('Channel Does Not Exist',
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
request = cls(
|
||||
guild=guild,
|
||||
author=author,
|
||||
message=message,
|
||||
channel=channel,
|
||||
content=content
|
||||
)
|
||||
request.save()
|
||||
return create_request_success_response(request, status.HTTP_201_CREATED, many=False)
|
||||
|
||||
@classmethod
|
||||
def get_request_by_id(cls, id):
|
||||
try:
|
||||
return cls.objects.get(id=id)
|
||||
except ObjectDoesNotExist:
|
||||
return None
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.guild.id} | {self.requested_at} | By {self.author.id}"
|
||||
|
||||
|
||||
class AdminComment(models.Model):
|
||||
request = models.ForeignKey(AdminRequest, on_delete=models.CASCADE)
|
||||
author = models.ForeignKey(User, on_delete=models.DO_NOTHING)
|
||||
content = models.CharField(max_length=1000)
|
||||
updated_at = models.DateTimeField(auto_now_add=True, blank=True)
|
||||
|
||||
@classmethod
|
||||
def add_new_comment(cls, data):
|
||||
request_id = data.get('request')
|
||||
author_id = data.get('author')
|
||||
content = data.get('content')
|
||||
if not (request_id and author_id and content):
|
||||
return create_error_response('Request, Author, and Content are required fields',
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
request = AdminRequest.get_request_by_id(request_id)
|
||||
if not isinstance(request, AdminRequest):
|
||||
return create_error_response("Admin Request Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
author = User.get_user_by_id(author_id)
|
||||
if not isinstance(author, User):
|
||||
return create_error_response("Author Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
comment = cls(
|
||||
request=request,
|
||||
author=author,
|
||||
content=content
|
||||
)
|
||||
comment.save()
|
||||
return create_comment_success_response(comment, status.HTTP_201_CREATED, many=False)
|
||||
|
||||
@classmethod
|
||||
def get_comment_by_id(cls, id):
|
||||
try:
|
||||
return cls.objects.get(id=id)
|
||||
except ObjectDoesNotExist:
|
||||
return None
|
||||
|
||||
@ -3,6 +3,7 @@ from rest_framework import serializers
|
||||
from .models import Message
|
||||
from .models import GuildInfo
|
||||
from .models import AdminRequest
|
||||
from .models import AdminComment
|
||||
|
||||
|
||||
class MessageSerializer(serializers.ModelSerializer):
|
||||
@ -10,6 +11,7 @@ class MessageSerializer(serializers.ModelSerializer):
|
||||
model = Message
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class GuildInfoSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = GuildInfo
|
||||
@ -20,3 +22,9 @@ class AdminRequestSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = AdminRequest
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class AdminCommentSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = AdminComment
|
||||
fields = "__all__"
|
||||
|
||||
28
geeksbot_v2/dmessages/utils.py
Normal file
28
geeksbot_v2/dmessages/utils.py
Normal file
@ -0,0 +1,28 @@
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
|
||||
|
||||
def create_error_response(msg, status=status.HTTP_404_NOT_FOUND):
|
||||
return Response({'details': msg},
|
||||
status=status)
|
||||
|
||||
|
||||
def create_success_response(message_data, status, many: bool = False):
|
||||
from .serializers import MessageSerializer
|
||||
|
||||
return Response(MessageSerializer(message_data, many=many).data,
|
||||
status=status)
|
||||
|
||||
|
||||
def create_request_success_response(request_data, status, many: bool = False):
|
||||
from .serializers import AdminRequestSerializer
|
||||
|
||||
return Response(AdminRequestSerializer(request_data, many=many).data,
|
||||
status=status)
|
||||
|
||||
|
||||
def create_comment_success_response(comment_data, status, many: bool = False):
|
||||
from .serializers import AdminCommentSerializer
|
||||
|
||||
return Response(AdminCommentSerializer(comment_data, many=many).data,
|
||||
status=status)
|
||||
@ -1,8 +1,9 @@
|
||||
from django.urls import path
|
||||
|
||||
from .views import GuildsAPI
|
||||
from .views import GuildsAPI, GuildDetail
|
||||
|
||||
app_name = "users_api"
|
||||
urlpatterns = [
|
||||
path("/", view=GuildsAPI.as_view(), name="list")
|
||||
path("/", view=GuildsAPI.as_view(), name="list"),
|
||||
path("/<str:id>/", view=GuildDetail.as_view(), name='detail')
|
||||
]
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Generated by Django 2.2.4 on 2019-09-16 05:23
|
||||
# Generated by Django 2.2.4 on 2019-09-17 19:31
|
||||
|
||||
import django.contrib.postgres.fields
|
||||
from django.db import migrations, models
|
||||
@ -17,10 +17,10 @@ class Migration(migrations.Migration):
|
||||
name='Guild',
|
||||
fields=[
|
||||
('id', models.CharField(max_length=30, primary_key=True, serialize=False)),
|
||||
('admin_chat', models.CharField(max_length=30)),
|
||||
('new_patron_message', models.TextField(blank=True, max_length=1000)),
|
||||
('admin_chat', models.CharField(blank=True, max_length=30, null=True)),
|
||||
('new_patron_message', models.TextField(blank=True, max_length=1000, null=True)),
|
||||
('default_channel', models.CharField(max_length=30)),
|
||||
('new_patron_channel', models.CharField(max_length=30)),
|
||||
('new_patron_channel', models.CharField(blank=True, max_length=30, null=True)),
|
||||
('prefixes', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=10), size=None)),
|
||||
],
|
||||
),
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
# Generated by Django 2.2.4 on 2019-09-17 05:08
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('guilds', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='guild',
|
||||
name='admin_chat',
|
||||
field=models.CharField(blank=True, max_length=30, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='guild',
|
||||
name='new_patron_channel',
|
||||
field=models.CharField(blank=True, max_length=30, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='guild',
|
||||
name='new_patron_message',
|
||||
field=models.TextField(blank=True, max_length=1000, null=True),
|
||||
),
|
||||
]
|
||||
@ -1,5 +1,14 @@
|
||||
import os
|
||||
|
||||
from django.db import models
|
||||
from django.contrib.postgres.fields import ArrayField
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from rest_framework import status
|
||||
|
||||
from .utils import create_error_response
|
||||
from .utils import create_success_response
|
||||
from .utils import create_role_success_response
|
||||
|
||||
|
||||
# Create your models here.
|
||||
|
||||
@ -15,11 +24,113 @@ class Guild(models.Model):
|
||||
def __str__(self):
|
||||
return self.id
|
||||
|
||||
def update_guild(self, data):
|
||||
if data.get('admin_chat'):
|
||||
self.admin_chat = data.get('admin_chat')
|
||||
if data.get('new_patron_message'):
|
||||
self.new_patron_message = data.get('new_patron_message')
|
||||
if data.get('default_channel'):
|
||||
self.default_channel = data.get('default_channel')
|
||||
if data.get('new_patron_channel'):
|
||||
self.new_patron_channel = data.get('new_patron_channel')
|
||||
if data.get('add_prefix'):
|
||||
if data.get('add_prefix') not in self.prefixes:
|
||||
self.prefixes.append(data.get('add_prefix'))
|
||||
if data.get('remove_prefix'):
|
||||
if data.get('remove_prefix') in self.prefixes:
|
||||
self.prefixes.remove(data.get('remove_prefix'))
|
||||
if len(self.prefixes) <= 0:
|
||||
self.prefixes = [os.environ['DISCORD_DEFAULT_PREFIX'], ]
|
||||
|
||||
self.save()
|
||||
return self
|
||||
|
||||
@classmethod
|
||||
def get_guild_by_id(cls, id):
|
||||
try:
|
||||
return cls.objects.get(id=id)
|
||||
except ObjectDoesNotExist:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def create_guild(cls, data):
|
||||
id = data.get('id')
|
||||
default_channel = data.get('default_channel')
|
||||
if not (id and default_channel):
|
||||
return create_error_response('id and default_channel are required',
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
if cls.get_guild_by_id(id):
|
||||
return create_error_response('That Guild already exists',
|
||||
status.HTTP_409_CONFLICT)
|
||||
|
||||
guild = cls(
|
||||
id=id,
|
||||
default_channel=default_channel,
|
||||
prefixes=data.get('prefixes'),
|
||||
admin_chat=data.get('admin_chat'),
|
||||
new_patron_message=data.get('new_patron_message'),
|
||||
new_patron_channel=data.get('new_patron_channel')
|
||||
)
|
||||
guild.save()
|
||||
return create_success_response(guild, status.HTTP_201_CREATED, many=False)
|
||||
|
||||
|
||||
class Role(models.Model):
|
||||
id = models.CharField(max_length=30, primary_key=True)
|
||||
guild = models.ForeignKey(Guild, on_delete=models.CASCADE, null=False)
|
||||
type = models.PositiveSmallIntegerField()
|
||||
role_type = models.PositiveSmallIntegerField()
|
||||
|
||||
def update_role(self, data):
|
||||
if data.get('role_type'):
|
||||
self.role_type = data.get('role_type')
|
||||
|
||||
self.save()
|
||||
return create_role_success_response(self, status=status.HTTP_202_ACCEPTED, many=False)
|
||||
|
||||
@classmethod
|
||||
def add_new_role(cls, data):
|
||||
id = data.get('id')
|
||||
guild_id = data.get('guild')
|
||||
role_type = data.get('role_type')
|
||||
if not (id and guild_id and role_type):
|
||||
return create_error_response("The Role ID, Guild, and Role Type are required",
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
if cls.get_role_by_id(id):
|
||||
return create_error_response("That Role Already Exists",
|
||||
status=status.HTTP_409_CONFLICT)
|
||||
guild = Guild.get_guild_by_id(guild_id)
|
||||
if not isinstance(guild, Guild):
|
||||
return create_error_response("Guild Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
try:
|
||||
role_type = int(role_type)
|
||||
except ValueError:
|
||||
return create_error_response("Role Type must be a positive number",
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
if role_type < 0:
|
||||
return create_error_response("Role Type must be a positive number",
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
elif 1000 < role_type:
|
||||
return create_error_response("Role Type must be less than 1000",
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
role = cls(
|
||||
id=id,
|
||||
guild=guild,
|
||||
role_type=role_type
|
||||
)
|
||||
role.save()
|
||||
return create_role_success_response(role, status.HTTP_201_CREATED, many=False)
|
||||
|
||||
@classmethod
|
||||
def get_role_by_id(cls, id):
|
||||
try:
|
||||
return cls.objects.get(id=id)
|
||||
except ObjectDoesNotExist:
|
||||
return None
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.guild.id} | {self.id}"
|
||||
|
||||
8
geeksbot_v2/guilds/permissions.py
Normal file
8
geeksbot_v2/guilds/permissions.py
Normal file
@ -0,0 +1,8 @@
|
||||
from rest_framework.permissions import BasePermission
|
||||
|
||||
class GuildPermissions(BasePermission):
|
||||
def has_permission(self, request, view):
|
||||
return super().has_permission(request, view)
|
||||
|
||||
def has_object_permission(self, request, view, obj):
|
||||
return super().has_object_permission(request, view, obj)
|
||||
21
geeksbot_v2/guilds/utils.py
Normal file
21
geeksbot_v2/guilds/utils.py
Normal file
@ -0,0 +1,21 @@
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
|
||||
|
||||
def create_error_response(msg, status=status.HTTP_404_NOT_FOUND):
|
||||
return Response({'details': msg},
|
||||
status=status)
|
||||
|
||||
|
||||
def create_success_response(guild_data, status, many: bool = False):
|
||||
from .serializers import GuildSerializer
|
||||
|
||||
return Response(GuildSerializer(guild_data, many=many).data,
|
||||
status=status)
|
||||
|
||||
|
||||
def create_role_success_response(role_data, status, many: bool = False):
|
||||
from .serializers import RoleSerializer
|
||||
|
||||
return Response(RoleSerializer(role_data, many=many).data,
|
||||
status=status)
|
||||
@ -1,13 +1,12 @@
|
||||
import os
|
||||
|
||||
from django.shortcuts import render
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import status
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
from geeksbot_v2.utils.api_utils import PaginatedAPIView
|
||||
from .models import Guild
|
||||
from .serializers import GuildSerializer
|
||||
from .utils import create_error_response
|
||||
from .utils import create_success_response
|
||||
|
||||
# Create your views here.
|
||||
|
||||
@ -15,37 +14,56 @@ from .serializers import GuildSerializer
|
||||
|
||||
|
||||
class GuildsAPI(PaginatedAPIView):
|
||||
def get(self, request, format=None):
|
||||
users = Guild.objects.all()
|
||||
page = self.paginate_queryset(users)
|
||||
if page is not None:
|
||||
serialized_users = GuildSerializer(users, many=True)
|
||||
return self.get_paginated_response(serialized_users.data)
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
serialized_users = GuildSerializer(users, many=True)
|
||||
return Response(serialized_users.data)
|
||||
def get(self, request, format=None):
|
||||
guilds = Guild.objects.all()
|
||||
page = self.paginate_queryset(guilds)
|
||||
if page is not None:
|
||||
return create_success_response(page, status.HTTP_200_OK, many=True)
|
||||
|
||||
return create_success_response(guilds, status.HTTP_200_OK, many=True)
|
||||
|
||||
def post(self, request, format=None):
|
||||
data = dict(request.data)
|
||||
print(data)
|
||||
id = data.get('id')
|
||||
default_channel = data.get('default_channel')
|
||||
if not (id and default_channel):
|
||||
return Response({'msg': 'id and default_channel are required'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
return Guild.create_guild(data)
|
||||
|
||||
admin_chat = data.get('admin_chat')
|
||||
new_patron_message = data.get('new_patron_message')
|
||||
default_prefix = os.environ['DISCORD_DEFAULT_PREFIX']
|
||||
prefixes = data.get('prefixes', [default_prefix, ])
|
||||
print(prefixes)
|
||||
|
||||
guild = Guild(
|
||||
id=id[0] if isinstance(id, list) else id,
|
||||
default_channel=default_channel[0] if isinstance(default_channel, list) else default_channel,
|
||||
prefixes=prefixes,
|
||||
admin_chat=admin_chat[0] if isinstance(admin_chat, list) else admin_chat,
|
||||
new_patron_message=new_patron_message[0] if isinstance(new_patron_message, list) else new_patron_message
|
||||
)
|
||||
guild.save()
|
||||
class GuildDetail(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
return Response(GuildSerializer(guild).data, status=status.HTTP_201_CREATED)
|
||||
def get(self, request, id, format=None):
|
||||
try:
|
||||
guild = Guild.objects.get(id=id)
|
||||
except ObjectDoesNotExist:
|
||||
return create_error_response("Guild Does not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
else:
|
||||
return create_success_response(guild,
|
||||
status=status.HTTP_200_OK)
|
||||
|
||||
def put(self, request, id, format=None):
|
||||
guild = Guild.get_guild_by_id(id)
|
||||
|
||||
if guild:
|
||||
data = dict(request.data)
|
||||
guild = guild.update_guild(data)
|
||||
return create_success_response(guild,
|
||||
status=status.HTTP_202_ACCEPTED)
|
||||
else:
|
||||
return create_error_response('Guild Does Not Exist',
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def delete(self, request, id, format=None):
|
||||
guild = Guild.get_guild_by_id(id)
|
||||
|
||||
if guild:
|
||||
# data = dict(request.data)
|
||||
# TODO Add a check to verify user is allowed to delete...
|
||||
# Possibly in object permissions...
|
||||
guild.delete()
|
||||
return create_success_response(guild,
|
||||
status=status.HTTP_200_OK)
|
||||
else:
|
||||
return create_error_response('Guild Does Not Exist',
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Generated by Django 2.2.4 on 2019-09-16 05:23
|
||||
# Generated by Django 2.2.4 on 2019-09-17 19:31
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
@ -1,15 +1,63 @@
|
||||
from django.db import models
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from rest_framework import status
|
||||
|
||||
from geeksbot_v2.guilds.models import Guild
|
||||
from geeksbot_v2.guilds.models import Role
|
||||
from .utils import create_error_response
|
||||
from .utils import create_success_creator_response
|
||||
from .utils import create_success_tier_response
|
||||
|
||||
# Create your models here.
|
||||
|
||||
|
||||
class PatreonCreator(models.Model):
|
||||
guild = models.ForeignKey(Guild, on_delete=models.CASCADE, null=False)
|
||||
creator = models.CharField(max_length=50, null=False)
|
||||
link = models.CharField(max_length=100, null=False)
|
||||
guilds = models.ManyToManyField(Guild)
|
||||
creator = models.CharField(max_length=50, null=False, primary_key=True)
|
||||
link = models.CharField(max_length=100, null=False, unique=True)
|
||||
|
||||
def update_creator(self, data):
|
||||
if data.get('guild'):
|
||||
guild = Guild.get_guild_by_id(data.get('guild'))
|
||||
if not isinstance(guild, Guild):
|
||||
return create_error_response('Guild Does Not Exist',
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
self.guilds.add(guild)
|
||||
if data.get('link'):
|
||||
self.link = data.get('link')
|
||||
|
||||
self.save()
|
||||
return create_success_creator_response(self, status.HTTP_202_ACCEPTED, many=False)
|
||||
|
||||
@classmethod
|
||||
def add_new_creator(cls, data):
|
||||
creator = data.get('creator')
|
||||
if PatreonCreator.get_creator_by_name(creator):
|
||||
return create_error_response('That Creator already exists',
|
||||
status=status.HTTP_409_CONFLICT)
|
||||
link = data.get('link')
|
||||
if not (creator and link):
|
||||
return create_error_response('Creator and Link are both required fields',
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
guild = Guild.get_guild_by_id(data.get('guild'))
|
||||
if not guild:
|
||||
return create_error_response('A Valid Guild is required',
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
new_creator = cls(
|
||||
creator=creator,
|
||||
link=link
|
||||
)
|
||||
new_creator.save()
|
||||
new_creator.guilds.add(guild)
|
||||
return create_success_creator_response(new_creator, status.HTTP_201_CREATED, many=False)
|
||||
|
||||
@classmethod
|
||||
def get_creator_by_name(cls, name):
|
||||
try:
|
||||
return cls.objects.get(creator=name)
|
||||
except ObjectDoesNotExist:
|
||||
return None
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.guild.id} | {self.creator}"
|
||||
@ -17,11 +65,100 @@ class PatreonCreator(models.Model):
|
||||
|
||||
class PatreonTier(models.Model):
|
||||
creator = models.ForeignKey(PatreonCreator, on_delete=models.CASCADE)
|
||||
guild = models.ForeignKey(Guild, on_delete=models.CASCADE)
|
||||
guild = models.ManyToManyField(Guild)
|
||||
name = models.CharField(max_length=50)
|
||||
description = models.TextField()
|
||||
role = models.ForeignKey(Role, on_delete=models.CASCADE)
|
||||
amount = models.IntegerField(null=True)
|
||||
next_lower_tier = models.ForeignKey('self', null=True, blank=True)
|
||||
|
||||
def update_tier(self, data):
|
||||
if data.get('guild'):
|
||||
guild = Guild.get_guild_by_id(data.get('guild'))
|
||||
if not isinstance(guild, Guild):
|
||||
return create_error_response('Guild Does Not Exist',
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
self.guilds.add(guild)
|
||||
if data.get('name'):
|
||||
self.name = data.get('name')
|
||||
if data.get('description'):
|
||||
self.description = data.get('description')
|
||||
if data.get('role'):
|
||||
role = Role.get_role_by_id(data.get('role'))
|
||||
if not isinstance(role, Role):
|
||||
return create_error_response('Role Does Not Exist',
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
self.role = role
|
||||
if data.get('amount'):
|
||||
self.amount = data.get('amount')
|
||||
if data.get('next_lower_tier'):
|
||||
tier = self.get_tier_by_id(data.get('next_lower_tier'))
|
||||
if not isinstance(tier, self.__class__):
|
||||
return create_error_response('Next Lower Tier Does Not Exist',
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
self.next_lower_tier = tier
|
||||
|
||||
self.save()
|
||||
return create_success_tier_response(tier, status.HTTP_202_ACCEPTED, many=False)
|
||||
|
||||
@classmethod
|
||||
def get_tier_by_id(cls, id):
|
||||
try:
|
||||
return cls.objects.get(id=id)
|
||||
except ObjectDoesNotExist:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def add_new_tier(cls, data):
|
||||
creator_str = data.get('creator')
|
||||
guild_id = data.get('guild')
|
||||
name = data.get('name')
|
||||
description = data.get('description')
|
||||
role_id = data.get('role')
|
||||
next_lower_tier_id = data.get('next_lower_tier')
|
||||
if not (creator_str and guild_id and name and description and role_id):
|
||||
return create_error_response("The Creator's name, Guild, Tier name, Description, "
|
||||
"and Discord Role are all required.",
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
creator = PatreonCreator.get_creator_by_name(creator_str)
|
||||
if not isinstance(creator, PatreonCreator):
|
||||
return create_error_response("Creator Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
guild = Guild.get_guild_by_id(guild_id)
|
||||
if not isinstance(guild, Guild):
|
||||
return create_error_response("Guild Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
role = Role.get_role_by_id(role_id)
|
||||
if not isinstance(role, Role):
|
||||
return create_error_response("Role Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
if next_lower_tier_id:
|
||||
next_lower_tier = cls.get_tier_by_id(next_lower_tier_id)
|
||||
if not isinstance(next_lower_tier, cls):
|
||||
return create_error_response("Next Lower Tier Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
if next_lower_tier.guild != guild:
|
||||
return create_error_response("The given next lower tier is not for the same guild.",
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
if next_lower_tier.creator != creator:
|
||||
return create_error_response("The given next lower tier is not for the same creator.",
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
try:
|
||||
PatreonTier.objects.filter(creator=creator, guilds__id=guild.id).get(name=name)
|
||||
except ObjectDoesNotExist:
|
||||
tier = cls(
|
||||
creator=creator,
|
||||
name=name,
|
||||
description=description,
|
||||
role=role,
|
||||
amount=data.get('amount'),
|
||||
next_lower_tier=next_lower_tier if next_lower_tier_id else None
|
||||
)
|
||||
tier.save()
|
||||
return create_success_tier_response(tier, status.HTTP_201_CREATED, many=False)
|
||||
else:
|
||||
return create_error_response("A Tier with that name already exists for that creator in this guild.",
|
||||
status=status.HTTP_409_CONFLICT)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.guild.id} | {self.creator.creator} | {self.name}"
|
||||
|
||||
21
geeksbot_v2/patreon/utils.py
Normal file
21
geeksbot_v2/patreon/utils.py
Normal file
@ -0,0 +1,21 @@
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
|
||||
|
||||
def create_error_response(msg, status=status.HTTP_404_NOT_FOUND):
|
||||
return Response({'details': msg},
|
||||
status=status)
|
||||
|
||||
|
||||
def create_success_creator_response(creator_data, status, many: bool = False):
|
||||
from .serializers import PatreonCreatorSerializer
|
||||
|
||||
return Response(PatreonCreatorSerializer(creator_data, many=many).data,
|
||||
status=status)
|
||||
|
||||
|
||||
def create_success_tier_response(tier_data, status, many: bool = False):
|
||||
from .serializers import PatreonTierSerializer
|
||||
|
||||
return Response(PatreonTierSerializer(tier_data, many=many).data,
|
||||
status=status)
|
||||
@ -1,4 +1,4 @@
|
||||
# Generated by Django 2.2.4 on 2019-09-16 05:23
|
||||
# Generated by Django 2.2.4 on 2019-09-17 19:31
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
@ -10,9 +10,9 @@ class Migration(migrations.Migration):
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('guilds', '0001_initial'),
|
||||
('dmessages', '0001_initial'),
|
||||
('guilds', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
|
||||
@ -1,8 +1,13 @@
|
||||
from django.db import models
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from rest_framework import status
|
||||
|
||||
from geeksbot_v2.guilds.models import Guild
|
||||
from geeksbot_v2.dmessages.models import Message
|
||||
from geeksbot_v2.users.models import User
|
||||
from geeksbot_v2.channels.models import Channel
|
||||
from .utils import create_error_response
|
||||
from .utils import create_success_response
|
||||
|
||||
# Create your models here.
|
||||
|
||||
@ -14,16 +19,110 @@ class RconServer(models.Model):
|
||||
port = models.PositiveIntegerField()
|
||||
password = models.CharField(max_length=50)
|
||||
monitor_chat = models.BooleanField()
|
||||
monitor_chat_channel = models.CharField(max_length=30, blank=True)
|
||||
alerts_channel = models.CharField(max_length=30, blank=True)
|
||||
info_channel = models.CharField(max_length=30, blank=True)
|
||||
monitor_chat_channel = models.ForeignKey(
|
||||
Channel, on_delete=models.DO_NOTHING, related_name="+", null=True, blank=True, default=None
|
||||
)
|
||||
alerts_channel = models.ForeignKey(
|
||||
Channel, on_delete=models.DO_NOTHING, related_name="+", null=True, blank=True, default=None
|
||||
)
|
||||
info_channel = models.ForeignKey(
|
||||
Channel, on_delete=models.DO_NOTHING, related_name="+", null=True, blank=True, default=None
|
||||
)
|
||||
info_message = models.ForeignKey(
|
||||
Message, on_delete=models.CASCADE, related_name="+", blank=True
|
||||
Message, on_delete=models.DO_NOTHING, related_name="+", null=True, blank=True, default=None
|
||||
)
|
||||
settings_message = models.ForeignKey(
|
||||
Message, on_delete=models.CASCADE, related_name="+", blank=True
|
||||
Message, on_delete=models.DO_NOTHING, related_name="+", null=True, blank=True, default=None
|
||||
)
|
||||
whitelist = models.ManyToManyField(User, blank=True)
|
||||
|
||||
def update_server(self, data):
|
||||
if data.get('name'):
|
||||
self.name = data.get('name')
|
||||
if data.get('ip'):
|
||||
self.ip = data.get('ip')
|
||||
if data.get('port'):
|
||||
self.port = data.get('port')
|
||||
if data.get('password'):
|
||||
self.password = data.get('password')
|
||||
if data.get('monitor_chat'):
|
||||
self.monitor_chat = data.get('monitor_chat')
|
||||
if 'monitor_chat_channel' in data.keys():
|
||||
self.monitor_chat_channel = Channel.get_channel_by_id(data.get('monitor_chat_channel'))
|
||||
if 'alerts_channel' in data.keys():
|
||||
self.alerts_channel = Channel.get_channel_by_id(data.get('alerts_channel'))
|
||||
if 'info_channel' in data.keys():
|
||||
self.alerts_channel = Channel.get_channel_by_id(data.get('info_channel'))
|
||||
if 'info_message' in data.keys():
|
||||
self.info_message = Message.get_message_by_id(data.get('info_message'))
|
||||
if 'settings_message' in data.keys():
|
||||
self.settings_message = Message.get_message_by_id(data.get('settings_message'))
|
||||
|
||||
self.save()
|
||||
return create_success_response(self, status.HTTP_202_ACCEPTED, many=False)
|
||||
|
||||
def add_whitelist(self, user_id):
|
||||
user = User.get_user_by_id(user_id)
|
||||
if not isinstance(user, User):
|
||||
return create_error_response("User Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
if not user.steam_id:
|
||||
return create_error_response("User does not have a Steam 64ID attached to their account",
|
||||
status=status.HTTP_406_NOT_ACCEPTABLE)
|
||||
self.whitelist.add(user)
|
||||
return create_error_response("User has been added to the whitelist",
|
||||
status=status.HTTP_200_OK)
|
||||
|
||||
def remove_from_whitelist(self, user_id):
|
||||
user = User.get_user_by_id(user_id)
|
||||
if not isinstance(user, User):
|
||||
return create_error_response("User Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
self.whitelist.remove(user)
|
||||
return create_error_response("User has been removed from the whitelist",
|
||||
status=status.HTTP_200_OK)
|
||||
|
||||
@classmethod
|
||||
def add_new_server(cls, data):
|
||||
guild_id = data.get('guild')
|
||||
name = data.get('name')
|
||||
ip = data.get('ip')
|
||||
port = data.get('port')
|
||||
password = data.get('password')
|
||||
if not (guild_id and name and ip and port and password):
|
||||
return create_error_response("One or more of the required fields are missing",
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
guild = Guild.get_guild_by_id(guild_id)
|
||||
if not isinstance(guild, Guild):
|
||||
return create_error_response("Guild Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
server = cls(
|
||||
guild=guild,
|
||||
name=name,
|
||||
ip=ip,
|
||||
port=port,
|
||||
password=password,
|
||||
monitor_chat=data.get('monitor_chat', False)
|
||||
)
|
||||
server.save()
|
||||
return create_success_response(server, status.HTTP_201_CREATED, many=False)
|
||||
|
||||
@classmethod
|
||||
def get_server(cls, guild_id, name):
|
||||
guild_servers = cls.get_guild_servers(guild_id)
|
||||
if guild_servers:
|
||||
try:
|
||||
return guild_servers.get(name=name)
|
||||
except ObjectDoesNotExist:
|
||||
return None
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def get_guild_servers(cls, guild_id):
|
||||
guild = Guild.get_guild_by_id(guild_id)
|
||||
if not isinstance(guild, guild):
|
||||
return None
|
||||
return cls.objects.filter(guild=guild)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.guild.id} | {self.name}"
|
||||
|
||||
14
geeksbot_v2/rcon/utils.py
Normal file
14
geeksbot_v2/rcon/utils.py
Normal file
@ -0,0 +1,14 @@
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
|
||||
|
||||
def create_error_response(msg, status=status.HTTP_404_NOT_FOUND):
|
||||
return Response({'details': msg},
|
||||
status=status)
|
||||
|
||||
|
||||
def create_success_response(rcon_data, status, many: bool = False):
|
||||
from .serializers import RconServerSerializer
|
||||
|
||||
return Response(RconServerSerializer(rcon_data, many=many).data,
|
||||
status=status)
|
||||
@ -13,7 +13,7 @@
|
||||
{% if object.name %}
|
||||
<p>{{ object.name }}</p>
|
||||
{% endif %}
|
||||
{{ user.id }}
|
||||
{{ user.auth_token }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,13 +1,17 @@
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth import admin as auth_admin
|
||||
|
||||
from .forms import UserChangeForm
|
||||
from .forms import UserChangeForm, UserCreateForm
|
||||
from .models import User
|
||||
|
||||
|
||||
class UserAdmin(auth_admin.UserAdmin):
|
||||
model = User
|
||||
form = UserChangeForm
|
||||
add_form = UserCreateForm
|
||||
add_fieldsets = auth_admin.UserAdmin.add_fieldsets + (
|
||||
(None, {'fields': ('id')}),
|
||||
)
|
||||
|
||||
|
||||
admin.site.register(User, UserAdmin)
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
from django.urls import path
|
||||
|
||||
from geeksbot_v2.users.views import UsersAPI
|
||||
from geeksbot_v2.users.views import UsersAPI, UserDetail
|
||||
|
||||
app_name = "users_api"
|
||||
urlpatterns = [
|
||||
path("users/", view=UsersAPI.as_view(), name="list")
|
||||
path("/", view=UsersAPI.as_view(), name="list"),
|
||||
path("/<str:id>/", view=UserDetail.as_view(), name="detail"),
|
||||
]
|
||||
|
||||
@ -1,8 +1,20 @@
|
||||
from django.contrib.auth import forms
|
||||
from django.forms import CharField
|
||||
from allauth.account.forms import SignupForm
|
||||
|
||||
from .models import User
|
||||
|
||||
|
||||
class UserCreateForm(SignupForm):
|
||||
id = CharField(max_length=30, label='Discord ID')
|
||||
|
||||
def save(self, request):
|
||||
user = super(UserCreateForm, self).save(request)
|
||||
user.id = self.cleaned_data['id']
|
||||
user.save()
|
||||
return user
|
||||
|
||||
|
||||
class UserChangeForm(forms.UserChangeForm):
|
||||
class Meta(forms.UserChangeForm.Meta):
|
||||
model = User
|
||||
|
||||
70
geeksbot_v2/users/migrations/0001_initial.py
Normal file
70
geeksbot_v2/users/migrations/0001_initial.py
Normal file
@ -0,0 +1,70 @@
|
||||
# Generated by Django 2.2.4 on 2019-09-17 19:38
|
||||
|
||||
from django.conf import settings
|
||||
import django.contrib.auth.models
|
||||
import django.contrib.auth.validators
|
||||
import django.contrib.postgres.fields
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('auth', '0011_update_proxy_permissions'),
|
||||
('guilds', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='User',
|
||||
fields=[
|
||||
('password', models.CharField(max_length=128, verbose_name='password')),
|
||||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
||||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
||||
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
|
||||
('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')),
|
||||
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
|
||||
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
|
||||
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
|
||||
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
|
||||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
||||
('name', models.CharField(blank=True, max_length=255, verbose_name='Name of User')),
|
||||
('id', models.CharField(max_length=30, primary_key=True, serialize=False)),
|
||||
('discord_username', models.CharField(max_length=100, null=True)),
|
||||
('previous_discord_usernames', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=100), blank=True, null=True, size=None)),
|
||||
('discriminator', models.IntegerField(null=True)),
|
||||
('previous_discriminators', django.contrib.postgres.fields.ArrayField(base_field=models.IntegerField(), blank=True, null=True, size=None)),
|
||||
('steam_id', models.CharField(blank=True, max_length=30, null=True)),
|
||||
('animated', models.BooleanField(blank=True, null=True)),
|
||||
('avatar', models.CharField(blank=True, max_length=100, null=True)),
|
||||
('bot', models.BooleanField(blank=True, null=True)),
|
||||
('banned', models.BooleanField(default=False)),
|
||||
('logging_enabled', models.BooleanField(default=True)),
|
||||
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
|
||||
('guilds', models.ManyToManyField(blank=True, null=True, to='guilds.Guild')),
|
||||
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'user',
|
||||
'verbose_name_plural': 'users',
|
||||
'abstract': False,
|
||||
},
|
||||
managers=[
|
||||
('objects', django.contrib.auth.models.UserManager()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserLog',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('time', models.DateTimeField()),
|
||||
('action', models.IntegerField()),
|
||||
('description', models.CharField(max_length=100)),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
19
geeksbot_v2/users/migrations/0002_auto_20190917_2109.py
Normal file
19
geeksbot_v2/users/migrations/0002_auto_20190917_2109.py
Normal file
@ -0,0 +1,19 @@
|
||||
# Generated by Django 2.2.4 on 2019-09-17 21:09
|
||||
|
||||
import django.contrib.auth.validators
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='user',
|
||||
name='username',
|
||||
field=models.CharField(help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username'),
|
||||
),
|
||||
]
|
||||
24
geeksbot_v2/users/migrations/0003_auto_20190918_0554.py
Normal file
24
geeksbot_v2/users/migrations/0003_auto_20190918_0554.py
Normal file
@ -0,0 +1,24 @@
|
||||
# Generated by Django 2.2.4 on 2019-09-18 05:54
|
||||
|
||||
import django.contrib.postgres.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0002_auto_20190917_2109'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='user',
|
||||
name='discriminator',
|
||||
field=models.CharField(max_length=4, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='user',
|
||||
name='previous_discriminators',
|
||||
field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=4), blank=True, null=True, size=None),
|
||||
),
|
||||
]
|
||||
0
geeksbot_v2/users/migrations/__init__.py
Normal file
0
geeksbot_v2/users/migrations/__init__.py
Normal file
@ -1,4 +1,5 @@
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.contrib.auth.validators import UnicodeUsernameValidator
|
||||
from django.db.models import CharField
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
@ -8,8 +9,14 @@ from django.conf import settings
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
from rest_framework.authtoken.models import Token
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from rest_framework import status
|
||||
|
||||
from geeksbot_v2.guilds.models import Guild
|
||||
from .utils import verify_user_data
|
||||
from .utils import create_error_response
|
||||
from .utils import create_log_success_response
|
||||
from .utils import create_success_response
|
||||
|
||||
|
||||
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
|
||||
@ -23,11 +30,18 @@ class User(AbstractUser):
|
||||
# First Name and Last Name do not cover name patterns
|
||||
# around the globe.
|
||||
name = CharField(_("Name of User"), blank=True, max_length=255)
|
||||
username = models.CharField(
|
||||
_('username'),
|
||||
max_length=150,
|
||||
unique=False,
|
||||
help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
|
||||
validators=[UnicodeUsernameValidator()],
|
||||
)
|
||||
id = models.CharField(max_length=30, primary_key=True)
|
||||
discord_username = models.CharField(max_length=100, null=True)
|
||||
previous_discord_usernames = ArrayField(models.CharField(max_length=100), blank=True, null=True)
|
||||
discriminator = models.IntegerField(null=True)
|
||||
previous_discriminators = ArrayField(models.IntegerField(), blank=True, null=True)
|
||||
discriminator = models.CharField(max_length=4, null=True)
|
||||
previous_discriminators = ArrayField(models.CharField(max_length=4), blank=True, null=True)
|
||||
guilds = models.ManyToManyField(Guild, blank=True, null=True)
|
||||
steam_id = models.CharField(max_length=30, blank=True, null=True)
|
||||
animated = models.BooleanField(blank=True, null=True)
|
||||
@ -36,15 +50,158 @@ class User(AbstractUser):
|
||||
banned = models.BooleanField(default=False)
|
||||
logging_enabled = models.BooleanField(default=True)
|
||||
|
||||
@classmethod
|
||||
def add_new_user(cls, data):
|
||||
if not verify_user_data(data):
|
||||
return create_error_response("Not all required fields are present.",
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
id = data.get('id')
|
||||
if id:
|
||||
if User.objects.filter(id=id).exists():
|
||||
return create_error_response("User Exists please update instead of create",
|
||||
status=status.HTTP_409_CONFLICT)
|
||||
discord_username = data.get('username')
|
||||
discriminator = data.get('discriminator')
|
||||
guild_id = data.get('guild')
|
||||
try:
|
||||
guild = Guild.objects.get(id=str(guild_id))
|
||||
except ObjectDoesNotExist:
|
||||
return create_error_response("That is not a valid Guild",
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
animated = data.get('animated')
|
||||
avatar = data.get('avatar')
|
||||
bot = data.get('bot')
|
||||
banned = data.get('banned')
|
||||
logging = data.get('logging')
|
||||
if not (avatar and (animated is not None) and (bot is not None)):
|
||||
return create_error_response("All required fields must contain a value",
|
||||
status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
user = User(
|
||||
id=id,
|
||||
discord_username=discord_username,
|
||||
discriminator=discriminator,
|
||||
animated=animated,
|
||||
avatar=avatar,
|
||||
bot=bot,
|
||||
banned=banned or False,
|
||||
logging_enabled=logging or True
|
||||
)
|
||||
user.save()
|
||||
user.guilds.add(guild)
|
||||
return create_success_response(user, status.HTTP_201_CREATED, many=False)
|
||||
|
||||
def update_user(self, data):
|
||||
if data.get('username') and data.get('username') != self.discord_username:
|
||||
if isinstance(self.previous_discord_usernames, list):
|
||||
self.previous_discord_usernames.append(self.discord_username)
|
||||
else:
|
||||
self.previous_discord_usernames = [self.discord_username, ]
|
||||
self.discord_username = data.get('username')
|
||||
if data.get('discriminator') and data.get('discriminator') != self.discriminator:
|
||||
if isinstance(self.previous_discriminators, list):
|
||||
self.previous_discriminators.append(self.discriminator)
|
||||
else:
|
||||
self.previous_discriminators = [self.discriminator, ]
|
||||
self.discriminator = data.get('discriminator')
|
||||
if data.get('guild'):
|
||||
guild = Guild.get_guild_by_id(data.get('guild'))
|
||||
if not isinstance(guild, Guild):
|
||||
return create_error_response("That is not a valid Guild",
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
self.guilds.add(guild)
|
||||
if data.get('steam_id'):
|
||||
self.steam_id = data.get('steam_id')
|
||||
if data.get('animated'):
|
||||
self.animated = data.get('animated')
|
||||
if data.get('avatar'):
|
||||
self.avatar = data.get('avatar')
|
||||
if data.get('bot'):
|
||||
self.bot = data.get('bot')
|
||||
if data.get('banned'):
|
||||
self.banned = data.get('banned')
|
||||
if data.get('logging'):
|
||||
self.logging_enabled = data.get('logging')
|
||||
|
||||
self.save()
|
||||
return create_success_response(self, status.HTTP_202_ACCEPTED, many=False)
|
||||
|
||||
@classmethod
|
||||
def get_user_by_id(cls, id):
|
||||
try:
|
||||
return cls.objects.get(id=id)
|
||||
except ObjectDoesNotExist:
|
||||
return None
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("users:detail", kwargs={"username": self.username})
|
||||
|
||||
|
||||
class UserLog(models.Model):
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
time = models.DateTimeField()
|
||||
time = models.DateTimeField(auto_now_add=True, blank=True)
|
||||
action = models.IntegerField()
|
||||
description = models.CharField(max_length=100)
|
||||
description = models.CharField(max_length=100, null=True, blank=True)
|
||||
|
||||
@classmethod
|
||||
def add_new_log(cls, user, data):
|
||||
user_id = data.get('user')
|
||||
action = data.get('action')
|
||||
description = data.get('description')
|
||||
if not (user_id and action):
|
||||
return create_error_response("User and Action are required.",
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
user = User.get_user_by_id(user_id)
|
||||
if not isinstance(user, User):
|
||||
return create_error_response("User Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
try:
|
||||
action = int(action)
|
||||
except ValueError:
|
||||
return create_error_response("The Action must be a number",
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
log = cls(
|
||||
user=user,
|
||||
action=action,
|
||||
description=description
|
||||
)
|
||||
log.save()
|
||||
return create_log_success_response(log, status.HTTP_201_CREATED, many=False)
|
||||
|
||||
@classmethod
|
||||
def get_log_by_id(cls, id):
|
||||
try:
|
||||
return cls.objects.get(id=id)
|
||||
except ObjectDoesNotExist:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def get_logs_by_user(cls, user_id, count: int = None):
|
||||
user = User.get_user_by_id(user_id)
|
||||
if isinstance(user, User):
|
||||
user_logs = cls.objects.filter(user=user).order_by('-time')
|
||||
if count:
|
||||
user_logs = user_logs[:count]
|
||||
if len(user_logs) > 0:
|
||||
return user_logs
|
||||
else:
|
||||
return []
|
||||
else:
|
||||
return []
|
||||
|
||||
@classmethod
|
||||
def get_logs_by_user_action(cls, user_id, action, count: int = None):
|
||||
user = User.get_user_by_id(user_id)
|
||||
if isinstance(user, User):
|
||||
user_logs = cls.objects.filter(user=user, action=action).order_by('-time')
|
||||
if count:
|
||||
user_logs = user_logs[:count]
|
||||
if len(user_logs) > 0:
|
||||
return user_logs
|
||||
else:
|
||||
return []
|
||||
else:
|
||||
return []
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.time} | {self.user.id} | {self.action}"
|
||||
|
||||
@ -7,7 +7,22 @@ from geeksbot_v2.users.models import UserLog
|
||||
class UserSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = "__all__"
|
||||
fields = [
|
||||
'id',
|
||||
'username',
|
||||
'name',
|
||||
'discord_username',
|
||||
'previous_discord_usernames',
|
||||
'discriminator',
|
||||
'previous_discriminators',
|
||||
'guilds',
|
||||
'steam_id',
|
||||
'animated',
|
||||
'avatar',
|
||||
'bot',
|
||||
'banned',
|
||||
'logging_enabled'
|
||||
]
|
||||
|
||||
|
||||
class UserLogSerializer(serializers.ModelSerializer):
|
||||
|
||||
36
geeksbot_v2/users/utils.py
Normal file
36
geeksbot_v2/users/utils.py
Normal file
@ -0,0 +1,36 @@
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
|
||||
|
||||
def create_error_response(msg, status=status.HTTP_404_NOT_FOUND):
|
||||
return Response({'details': msg},
|
||||
status=status)
|
||||
|
||||
|
||||
def create_success_response(user_data, status, many: bool = False):
|
||||
from .serializers import UserSerializer
|
||||
|
||||
return Response(UserSerializer(user_data, many=many).data,
|
||||
status=status)
|
||||
|
||||
|
||||
def create_log_success_response(log_data, status, many: bool = False):
|
||||
from .serializers import UserLogSerializer
|
||||
|
||||
return Response(UserLogSerializer(log_data, many=many).data,
|
||||
status=status)
|
||||
|
||||
|
||||
required_fields = [
|
||||
'id',
|
||||
'username',
|
||||
'discriminator',
|
||||
'guild',
|
||||
'animated',
|
||||
'avatar',
|
||||
'bot',
|
||||
]
|
||||
|
||||
|
||||
def verify_user_data(data):
|
||||
return all([field in data.keys() for field in required_fields])
|
||||
@ -1,19 +1,19 @@
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.urls import reverse
|
||||
from django.views.generic import DetailView, RedirectView, UpdateView
|
||||
from django.contrib import messages
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework import status
|
||||
|
||||
|
||||
from geeksbot_v2.users.serializers import UserSerializer
|
||||
from geeksbot_v2.users.serializers import UserLogSerializer
|
||||
from geeksbot_v2.users.models import UserLog
|
||||
from .models import UserLog
|
||||
from geeksbot_v2.utils.api_utils import PaginatedAPIView
|
||||
|
||||
User = get_user_model()
|
||||
from .models import User
|
||||
from .utils import create_error_response
|
||||
from .utils import create_success_response
|
||||
from .utils import create_log_success_response
|
||||
|
||||
|
||||
class UserDetailView(LoginRequiredMixin, DetailView):
|
||||
@ -24,6 +24,7 @@ class UserDetailView(LoginRequiredMixin, DetailView):
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
|
||||
context = self.get_context_data(object=self.object, user=request.user)
|
||||
return self.render_to_response(context)
|
||||
|
||||
@ -66,44 +67,72 @@ user_redirect_view = UserRedirectView.as_view()
|
||||
|
||||
|
||||
class UsersAPI(PaginatedAPIView):
|
||||
def get(self, request, guild, format=None):
|
||||
users = User.objects.filter(guilds__id=guild)
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, guild=None, format=None):
|
||||
if guild:
|
||||
users = User.objects.filter(guilds__id=guild)
|
||||
else:
|
||||
users = User.objects.all()
|
||||
page = self.paginate_queryset(users)
|
||||
if page is not None:
|
||||
serialized_users = UserSerializer(users, many=True)
|
||||
return self.get_paginated_response(serialized_users.data)
|
||||
return create_success_response(page, status.HTTP_200_OK, many=True)
|
||||
|
||||
serialized_users = UserSerializer(users, many=True)
|
||||
return Response(serialized_users.data)
|
||||
return create_success_response(users, status.HTTP_200_OK, many=True)
|
||||
|
||||
def post(self, request, format=None):
|
||||
data = dict(request.data)
|
||||
return User.add_new_user(data)
|
||||
|
||||
|
||||
class UserDetail(APIView):
|
||||
def get(self, request, guild, id, format=None):
|
||||
user = User.objects.filter(guilds__id=guild).get(id=id)
|
||||
return Response(UserSerializer(user).data)
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, id, format=None):
|
||||
user = User.get_user_by_id(id)
|
||||
if not isinstance(user, User):
|
||||
return create_error_response("User Does not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
return create_success_response(user,
|
||||
status=status.HTTP_200_OK)
|
||||
|
||||
def put(self, request, id, format=None):
|
||||
user = User.get_user_by_id(id)
|
||||
if isinstance(user, User):
|
||||
data = dict(request.data)
|
||||
return user.update_user(data)
|
||||
else:
|
||||
return create_error_response("User Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
|
||||
class UserLogList(PaginatedAPIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, user, action=None, format=None):
|
||||
if action:
|
||||
user_logs = (
|
||||
UserLog.objects.filter(user=user)
|
||||
.filter(action=action)
|
||||
.order_by("-time")
|
||||
)
|
||||
user_logs = UserLog.get_logs_by_user_action(user, action)
|
||||
else:
|
||||
user_logs = UserLog.objects.filter(user=user).order_by("-time")
|
||||
user_logs = UserLog.get_logs_by_user(user)
|
||||
|
||||
page = self.paginate_queryset(user_logs)
|
||||
if page is not None:
|
||||
serialized_logs = UserLogSerializer(page, many=True)
|
||||
return self.get_paginated_response(serialized_logs.data)
|
||||
return create_log_success_response(page, status.HTTP_200_OK, many=True)
|
||||
|
||||
serialized_logs = UserLogSerializer(user_logs, many=True)
|
||||
return Response(serialized_logs.data)
|
||||
return create_log_success_response(user_logs, status.HTTP_200_OK, many=True)
|
||||
|
||||
def post(self, request, user, format=None):
|
||||
data = dict(request.data)
|
||||
return UserLog.add_new_log(user, data)
|
||||
|
||||
|
||||
class UserLogDetail(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, id, format=None):
|
||||
user_log = UserLog.objects.get(id=id)
|
||||
return Response(UserLogSerializer(user_log).data)
|
||||
user_log = UserLog.get_log_by_id(id)
|
||||
if isinstance(user_log, UserLog):
|
||||
return create_log_success_response(user_log, status.HTTP_200_OK, many=False)
|
||||
else:
|
||||
return create_error_response("Log Does Not Exist",
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
@ -61,7 +61,7 @@ listen_addresses = '*'
|
||||
# defaults to 'localhost'; use '*' for all
|
||||
# (change requires restart)
|
||||
#port = 5432 # (change requires restart)
|
||||
#max_connections = 100 # (change requires restart)
|
||||
max_connections = 1000 # (change requires restart)
|
||||
#superuser_reserved_connections = 3 # (change requires restart)
|
||||
#unix_socket_directories = '/tmp' # comma-separated list of directories
|
||||
# (change requires restart)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user