Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cogs/repl.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import textwrap
import traceback
from contextlib import redirect_stdout
from typing import Set
from typing import Callable, Set, cast

import discord
from discord.ext import commands
Expand Down Expand Up @@ -60,7 +60,7 @@ async def _eval(self, ctx: Context, *, body: str):
except SyntaxError as e:
return await ctx.send(self.get_syntax_error(e))

func = env['func']
func = cast(Callable, env['func'])
try:
with redirect_stdout(stdout):
ret = await func()
Expand Down
118 changes: 67 additions & 51 deletions commandListener.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@
from discord import Member
from discord.channel import TextChannel
from discord.emoji import Emoji
from discord.ext.commands import (BadArgument, Cog, Context,
MissingRequiredArgument, command)
from discord.ext.commands.errors import CommandError, CommandInvokeError
from discord.ext.commands import BadArgument, Cog, Context, command
from discord.ext.commands.errors import (CommandError, CommandInvokeError,
MissingRequiredArgument)

import config as cfg
import messageFunctions as msgFnc
from converters import (ArgArchivedEvent, ArgDate, ArgDateTime, ArgEvent,
ArgMessage, ArgRole, ArgTime, UnquotedStr)
from errors import MessageNotFound, RoleError, UnexpectedRole
ArgMessages, ArgRole, ArgTime, UnquotedStr)
from errors import (ExtraMessagesFound, MessageNotFound, RoleError,
UnexpectedRole)
from event import Event
from eventDatabase import EventDatabase
from operationbot import OperationBot
Expand Down Expand Up @@ -153,7 +154,7 @@ async def _create_event(self, ctx: Context, _date: datetime,
# Create event and sort events, export
event: Event = EventDatabase.createEvent(_date, sideop=sideop,
platoon_size=platoon_size)
await msgFnc.createEventMessage(event, self.bot.eventchannel)
await msgFnc.get_or_create_messages(event, self.bot.eventchannel)
if not batch:
await msgFnc.sortEventMessages(self.bot)
EventDatabase.toJson() # Update JSON file
Expand All @@ -165,8 +166,8 @@ async def _create_event(self, ctx: Context, _date: datetime,
async def show(self, ctx: Context, event: ArgEvent):
message = await msgFnc.getEventMessage(event, self.bot)
await ctx.send(message.jump_url)
await msgFnc.createEventMessage(event, cast(TextChannel, ctx.channel),
update_id=False)
await msgFnc.get_or_create_messages(event, cast(TextChannel,
ctx.channel), update_id=False)

# Create event command
@command(aliases=['c'])
Expand Down Expand Up @@ -447,7 +448,8 @@ async def _add_role(self, event: Event, rolename: str, batch=False):
# Adding the latest role failed, saving previously added roles
await self._update_event(event, reorder=False)
raise e
await self._update_event(event, reorder=False, export=(not batch))
if not batch:
await self._update_event(event, reorder=False)

@command(aliases=['ar'])
async def addrole(self, ctx: Context, event: ArgEvent, *,
Expand Down Expand Up @@ -481,19 +483,33 @@ async def addrole(self, ctx: Context, event: ArgEvent, *,
await self._add_role(event, rolename)
await ctx.send(f"Role {rolename} added to event {event}")

async def _remove_role(self, ctx: Context, event: ArgEvent, role: ArgRole,
check_additional=True):
role_name = role.name
event.remove_role(role, check_additional)
await self._update_event(event, reorder=False)
await ctx.send(f"Role {role_name} removed from {event}")

# Remove additional role from event command
@command(aliases=['rr'])
@command(aliases=['rr', 'removeadditionalrole', 'rar'])
async def removerole(self, ctx: Context, event: ArgEvent, *,
role: ArgRole):
"""
Remove an additional role from the event.

Example: removerole 1 Y1 (Bradley) Driver
"""
role_name = role.name
event.removeAdditionalRole(role)
await self._update_event(event, reorder=False)
await ctx.send(f"Role {role_name} removed from {event}")
await self._remove_role(ctx, event, role, check_additional=True)

@command(aliases=['rmr'])
async def removemainrole(self, ctx: Context, event: ArgEvent,
role: ArgRole):
"""
Remove a main role from the event.

Example: removerole 1 B2
"""
await self._remove_role(ctx, event, role, check_additional=False)

@command(aliases=['rnr', 'rename'])
async def renamerole(self, ctx: Context, event: ArgEvent,
Expand All @@ -512,41 +528,34 @@ async def renamerole(self, ctx: Context, event: ArgEvent,

@command(aliases=['rra'])
async def removereaction(self, ctx: Context, event: ArgEvent,
reaction: str):
role: ArgRole):
"""
Removes a role and the corresponding reaction from the event and updates the message.
""" # NOQA
self._find_remove_reaction(reaction, event)
await self._update_event(event, reorder=False)
await ctx.send(f"Reaction {reaction} removed from {event}")
DEPRECATED. Removes a role and the corresponding reaction from the event and updates the message.

def _find_remove_reaction(self, reaction: str, event: Event):
for group in event.roleGroups.values():
for role in group.roles:
if role.name == reaction:
group.roles.remove(role)
return
raise BadArgument("No reaction found")
Deprecated: use removemainrole and removerole instead.
""" # NOQA
await ctx.send("This command is deprecated. Use `removerole` (`rr`) "
"and `removemainrole` (`rmr`) instead.")
await self._remove_role(ctx, event, role, check_additional=False)

@command(aliases=['rg'])
async def removegroup(self, ctx: Context, eventMessage: ArgMessage, *,
async def removegroup(self, ctx: Context, eventMessages: ArgMessages, *,
groupName: UnquotedStr):
"""
Remove a role group from the event.

Example: removegroup 1 Bravo
"""
event = EventDatabase.getEventByMessage(eventMessage.id)
event = EventDatabase.getEventByMessage(eventMessages[0].id)

if not event.hasRoleGroup(groupName):
await ctx.send(f"No role group found with name {groupName}")
return

# Remove reactions, remove role, update event, add reactions, export
for reaction in event.getReactionsOfGroup(groupName):
await eventMessage.remove_reaction(reaction, self.bot.user)
event.removeRoleGroup(groupName)
await msgFnc.updateMessageEmbed(eventMessage, event)
await msgFnc.updateMessageEmbeds(eventMessages, event,
self.bot.eventchannel)
EventDatabase.toJson() # Update JSON file
await ctx.send(f"Group {groupName} removed from {event}")

Expand Down Expand Up @@ -609,7 +618,7 @@ async def setterrain(self, ctx: Context, event: ArgEvent, *,
"""
Set event terrain.

Example: settime 1 Takistan
Example: setterrain 1 Takistan
"""
# Change terrain, update event, export
event.setTerrain(terrain)
Expand Down Expand Up @@ -816,29 +825,32 @@ async def archive(self, ctx: Context, event: ArgEvent):
# Archive event and export
EventDatabase.archiveEvent(event)
try:
eventMessage = await msgFnc.getEventMessage(event, self.bot)
eventMessageList = await msgFnc.getEventMessages(event, self.bot)
except MessageNotFound:
await ctx.send(f"Internal error: event {event} without "
"a message found")
else:
await eventMessage.delete()
for eventMessage in eventMessageList:
await eventMessage.delete()

# Create new message
await msgFnc.createEventMessage(event, self.bot.eventarchivechannel)
# Create messages
await msgFnc.get_or_create_messages(
event, self.bot.eventarchivechannel)

await ctx.send(f"Event {event} archived")

async def _delete(self, event: Event, archived=False):
# TODO: Move to a more appropriate location
EventDatabase.removeEvent(event.id, archived=archived)
try:
eventMessage = await msgFnc.getEventMessage(
eventMessageList = await msgFnc.getEventMessages(
event, self.bot, archived=archived)
except MessageNotFound:
# Message already deleted, nothing to be done
pass
else:
await eventMessage.delete()
for eventMessage in eventMessageList:
await eventMessage.delete()
EventDatabase.toJson(archive=archived)

# Delete event command
Expand Down Expand Up @@ -960,7 +972,7 @@ async def _load(self, _: Context, event: Event, data: str,
raise ValueError("Malformed data")
if target:
# Display the loaded event in the command channel
await msgFnc.createEventMessage(event, target, update_id=False)
await msgFnc.get_or_create_messages(event, target, update_id=False)
await self._update_event(event)

# @command()
Expand All @@ -972,23 +984,27 @@ async def _load(self, _: Context, event: Event, data: str,
# await ctx.send("Event messages created")

async def _update_event(self, event: Event, import_db=False,
reorder=True, export=True):
reorder=True, export=True, exact_number=True):
# TODO: Move to a more appropriate location
if import_db:
await self.bot.import_database()
# Event instance might have changed because of DB import, get again
event = EventDatabase.getEventByMessage(event.messageID)
event = EventDatabase.getEventByMessage(event.messageIDList[0])

try:
message = await msgFnc.getEventMessage(event, self.bot)
except MessageNotFound:
message = await msgFnc.createEventMessage(event,
self.bot.eventchannel)
messages = await msgFnc.getEventMessages(event, self.bot,
exact_number=exact_number)
except (MessageNotFound, ExtraMessagesFound) as e:
messages = await msgFnc.get_or_create_messages(
event, self.bot.eventchannel)
if isinstance(e, MessageNotFound):
# New messages were created, we need to reorder the messages
await msgFnc.sortEventMessages(self.bot)
else:
await msgFnc.updateMessageEmbeds(messages, event,
self.bot.eventchannel)
await msgFnc.updateReactions(event, bot=self.bot, reorder=reorder)

await msgFnc.updateMessageEmbed(eventMessage=message,
updatedEvent=event)
await msgFnc.updateReactions(event=event, message=message,
reorder=reorder)
if export:
EventDatabase.toJson()

Expand Down Expand Up @@ -1020,7 +1036,7 @@ async def shutdown(self, ctx: Context):
@Cog.listener()
@staticmethod
async def on_command_error(ctx: Context, error: Exception):
# pylint: disable=no-self-use, no-else-return
# pylint: disable=no-else-return
if isinstance(error, MissingRequiredArgument):
await ctx.send(f"Missing argument. See: `{CMD}help {ctx.command}`")
return
Expand Down
16 changes: 16 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,22 @@
"\N{REGIONAL INDICATOR SYMBOL LETTER H}",
"\N{REGIONAL INDICATOR SYMBOL LETTER I}",
"\N{REGIONAL INDICATOR SYMBOL LETTER J}",
"\N{REGIONAL INDICATOR SYMBOL LETTER K}",
"\N{REGIONAL INDICATOR SYMBOL LETTER L}",
"\N{REGIONAL INDICATOR SYMBOL LETTER M}",
"\N{REGIONAL INDICATOR SYMBOL LETTER N}",
"\N{REGIONAL INDICATOR SYMBOL LETTER O}",
"\N{REGIONAL INDICATOR SYMBOL LETTER P}",
"\N{REGIONAL INDICATOR SYMBOL LETTER Q}",
"\N{REGIONAL INDICATOR SYMBOL LETTER R}",
"\N{REGIONAL INDICATOR SYMBOL LETTER S}",
"\N{REGIONAL INDICATOR SYMBOL LETTER T}",
"\N{REGIONAL INDICATOR SYMBOL LETTER U}",
"\N{REGIONAL INDICATOR SYMBOL LETTER V}",
"\N{REGIONAL INDICATOR SYMBOL LETTER W}",
"\N{REGIONAL INDICATOR SYMBOL LETTER X}",
"\N{REGIONAL INDICATOR SYMBOL LETTER Y}",
"\N{REGIONAL INDICATOR SYMBOL LETTER Z}",
]

ADDITIONAL_ROLE_NAMES = [
Expand Down
12 changes: 10 additions & 2 deletions converters.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import re
from datetime import date, datetime, time
from typing import cast
from typing import List, Union, cast

from discord import Message
from discord.ext.commands.context import Context
Expand Down Expand Up @@ -184,7 +184,7 @@ async def convert(cls, _: Context, arg: str) -> time:

class ArgMessage(Message):
@classmethod
async def convert(cls, ctx: Context, arg: str) -> Message:
async def convert(cls, ctx: Context, arg: Union[str, int]) -> Message:
try:
event_id = int(arg)
except ValueError as e:
Expand All @@ -198,3 +198,11 @@ async def convert(cls, ctx: Context, arg: str) -> Message:
raise BadArgument(str(e)) from e

return message


class ArgMessages(list):
@classmethod
async def convert(cls, ctx: Context, arg: str) -> List[Message]:
event = await ArgEvent.convert(ctx, arg)
return [await ArgMessage.convert(ctx, id)
for id in event.messageIDList]
4 changes: 4 additions & 0 deletions errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ class MessageNotFound(Exception):
pass


class ExtraMessagesFound(Exception):
pass


class UnexpectedRole(Exception):
pass

Expand Down
Loading