Skip to content
This repository was archived by the owner on Aug 28, 2021. It is now read-only.
Open
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
5 changes: 4 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@ An example for when subscribing to the on_member_kick event.

import discord
from discord.ext import commands, events
from discord.ext.events import member_kick
from discord.ext.events import EventsMixin, CustomEventDispatcher


class MyBot(commands.Bot, events.EventsMixin):
dispatcher = CustomEventDispatcher([
'member_kick',
])

async def on_ready(self):
print('Logged in!')
Expand Down
1 change: 1 addition & 0 deletions discord/ext/events/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from collections import namedtuple

from .mixins import EventsMixin
from .dispatcher import CustomEventDispatcher
from . import utils


Expand Down
5 changes: 0 additions & 5 deletions discord/ext/events/_events.py

This file was deleted.

5 changes: 5 additions & 0 deletions discord/ext/events/custom_events/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from typing import Callable, Dict

# Filled at run time
_ALL: Dict[str, Callable] = {}

Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
import discord

from ._events import _ALL
from .utils import fetch_recent_audit_log_entry, listens_for


EVENT_NAME = 'member_kick'
from ..utils import fetch_recent_audit_log_entry, listens_for


@listens_for('member_remove')
async def check_member_kick(client: discord.Client, member: discord.Member):
guild = member.guild

print('!RAN')

if not guild.me.guild_permissions.view_audit_log:
return

entry = await fetch_recent_audit_log_entry(client, member.guild, target=member, action=discord.AuditLogAction.kick, retry=3)
if entry is None:
return

client.dispatch(EVENT_NAME, member, entry)


_ALL[EVENT_NAME] = check_member_kick
return member, entry
27 changes: 27 additions & 0 deletions discord/ext/events/dispatcher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import asyncio
from typing import List, Optional

import discord

from .custom_events import _ALL
from .errors import InvalidEvent


class CustomEventDispatcher:
def __init__(self, listening_to: Optional[List[str]]=None):
valid_handlers = _ALL

if listening_to:
try:
valid_handlers = {name: _ALL[name] for name in listening_to}
except KeyError as e:
raise InvalidEvent('no registered handler for {!r}'.format(e.args[0]))

self.valid_handlers = valid_handlers

def handle(self, client: discord.Client, event: str, *args, **kwargs):
if event in self.valid_handlers:
return

for event_check in self.valid_handlers.values():
asyncio.ensure_future(event_check(client, event, *args, **kwargs))
7 changes: 7 additions & 0 deletions discord/ext/events/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from discord.errors import DiscordException

class EventsException(DiscordException):
pass

class InvalidEvent(EventsException):
pass
11 changes: 3 additions & 8 deletions discord/ext/events/mixins.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import asyncio

import discord

from ._events import _ALL
from .dispatcher import CustomEventDispatcher


class EventsMixin(discord.Client):

async def on__event(self, event, *args, **kwargs):
for event_name, event_check in _ALL.items():
asyncio.ensure_future(event_check(self, event, *args, **kwargs))
dispatcher = CustomEventDispatcher()

def dispatch(self, event, *args, **kwargs):
super().dispatch(event, *args, **kwargs) # type: ignore
super().dispatch('_event', event, *args, **kwargs)
self.dispatcher.handle(self, event, *args, **kwargs)
11 changes: 9 additions & 2 deletions discord/ext/events/utils.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import asyncio
import datetime

from functools import wraps
from typing import Callable, Optional

import discord

from .custom_events import _ALL


SLEEP_FOR = 2.5

Expand Down Expand Up @@ -68,11 +69,17 @@ def listens_for(*events: str) -> Callable:
"""

def decorator(func: Callable) -> Callable:
event_name = func.__name__[6:]
_ALL[event_name] = func

@wraps(func)
async def wrapper(client, event, *args, **kwargs):
if event in events:
await func(client, *args, **kwargs)
result = await func(client, *args, **kwargs)
if result is not None:
if not isinstance(result, tuple):
result = (result,)
client.dispatch(event_name, *result)

return wrapper

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
python_requires=">=3.5.3",
url="https://github.com/Ext-Creators/discord-ext-events",
version=version,
packages=["discord.ext.events"],
packages=["discord.ext.events", "discord.ext.events.custom_events"],
license="Apache Software License",
description="Custom events derived from events dispatched by Discord. ",
long_description=readme,
Expand Down