Skip to content
This repository has been archived by the owner on Aug 1, 2021. It is now read-only.

Commit

Permalink
Refactor modeling to avoid magic as much as possible
Browse files Browse the repository at this point in the history
My previous stab at implementing the simple-modeling-orm-thing-tm failed
in the aspect that there was a lot of duplicated code doing runtime
inspection of stuff. This was due mostly to having no extra place to
store information on types, making it hard to introspect how the type
expected to be built, whether it had a default, etc.

This commit refactors the modeling code to actually have a Field type,
which wraps some information up in a simple class and allows extremely
easy conversion without having to do (more) expensive runtime
inspection. This also gives us the benefits of a much more
readable/cleaner code, expandable field options, and not having to fuck
with sphinx to get docs working correctly (it was duping attributes
because they where aliases...)
  • Loading branch information
b1naryth1ef committed Oct 7, 2016
1 parent c297d45 commit ffe5a6f
Show file tree
Hide file tree
Showing 10 changed files with 322 additions and 220 deletions.
169 changes: 128 additions & 41 deletions disco/gateway/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import six

from disco.types import Guild, Channel, User, GuildMember, Role, Message, VoiceState
from disco.types.base import Model, snowflake, alias, listof, text
from disco.types.base import Model, Field, snowflake, listof, text


# TODO: clean this... use BaseType, etc
Expand All @@ -29,164 +29,251 @@ def create(cls, obj, client):

return cls(obj, client)

def __getattr__(self, name):
if hasattr(self, '_wraps_model'):
modname, _ = self._wraps_model
if hasattr(self, modname) and hasattr(getattr(self, modname), name):
return getattr(getattr(self, modname), name)
return object.__getattr__(self, name)


def wraps_model(model, alias=None):
alias = alias or model.__name__.lower()

def deco(cls):
cls._fields[alias] = model
cls._fields[alias] = Field(model)
cls._fields[alias].set_name(alias)
cls._wraps_model = (alias, model)
return cls
return deco


class Ready(GatewayEvent):
version = alias(int, 'v')
session_id = str
user = User
guilds = listof(Guild)
"""
Sent after the initial gateway handshake is complete. Contains data required
for bootstrapping the clients states.
"""
version = Field(int, alias='v')
session_id = Field(str)
user = Field(User)
guilds = Field(listof(Guild))


class Resumed(GatewayEvent):
"""
Sent after a resume completes.
"""
pass


@wraps_model(Guild)
class GuildCreate(GatewayEvent):
unavailable = bool
"""
Sent when a guild is created, or becomes available.
"""
unavailable = Field(bool)


@wraps_model(Guild)
class GuildUpdate(GatewayEvent):
"""
Sent when a guild is updated.
"""
pass


class GuildDelete(GatewayEvent):
id = snowflake
unavailable = bool
"""
Sent when a guild is deleted, or becomes unavailable.
"""
id = Field(snowflake)
unavailable = Field(bool)


@wraps_model(Channel)
class ChannelCreate(GatewayEvent):
@property
def guild(self):
return self.channel.guild
"""
Sent when a channel is created.
"""


@wraps_model(Channel)
class ChannelUpdate(ChannelCreate):
"""
Sent when a channel is updated.
"""
pass


@wraps_model(Channel)
class ChannelDelete(ChannelCreate):
"""
Sent when a channel is deleted.
"""
pass


class ChannelPinsUpdate(GatewayEvent):
channel_id = snowflake
last_pin_timestamp = int
"""
Sent when a channels pins are updated.
"""
channel_id = Field(snowflake)
last_pin_timestamp = Field(int)


@wraps_model(User)
class GuildBanAdd(GatewayEvent):
"""
Sent when a user is banned from a guild.
"""
pass


@wraps_model(User)
class GuildBanRemove(GuildBanAdd):
"""
Sent when a user is unbanned from a guild.
"""
pass


class GuildEmojisUpdate(GatewayEvent):
"""
Sent when a guilds emojis are updated.
"""
pass


class GuildIntegrationsUpdate(GatewayEvent):
"""
Sent when a guilds integrations are updated.
"""
pass


class GuildMembersChunk(GatewayEvent):
guild_id = snowflake
members = listof(GuildMember)
"""
Sent in response to a members chunk request.
"""
guild_id = Field(snowflake)
members = Field(listof(GuildMember))


@wraps_model(GuildMember, alias='member')
class GuildMemberAdd(GatewayEvent):
"""
Sent when a user joins a guild.
"""
pass


class GuildMemberRemove(GatewayEvent):
guild_id = snowflake
user = User
"""
Sent when a user leaves a guild (via leaving, kicking, or banning).
"""
guild_id = Field(snowflake)
user = Field(User)


@wraps_model(GuildMember, alias='member')
class GuildMemberUpdate(GatewayEvent):
"""
Sent when a guilds member is updated.
"""
pass


class GuildRoleCreate(GatewayEvent):
guild_id = snowflake
role = Role
"""
Sent when a role is created.
"""
guild_id = Field(snowflake)
role = Field(Role)


class GuildRoleUpdate(GuildRoleCreate):
"""
Sent when a role is updated.
"""
pass


class GuildRoleDelete(GuildRoleCreate):
"""
Sent when a role is deleted.
"""
pass


@wraps_model(Message)
class MessageCreate(GatewayEvent):
@property
def channel(self):
return self.message.channel
"""
Sent when a message is created.
"""


@wraps_model(Message)
class MessageUpdate(MessageCreate):
"""
Sent when a message is updated/edited.
"""
pass


class MessageDelete(GatewayEvent):
id = snowflake
channel_id = snowflake
"""
Sent when a message is deleted.
"""
id = Field(snowflake)
channel_id = Field(snowflake)


class MessageDeleteBulk(GatewayEvent):
channel_id = snowflake
ids = listof(snowflake)
"""
Sent when multiple messages are deleted from a channel.
"""
channel_id = Field(snowflake)
ids = Field(listof(snowflake))


class PresenceUpdate(GatewayEvent):
"""
Sent when a users presence is updated.
"""
class Game(Model):
# TODO enum
type = int
name = text
url = text
type = Field(int)
name = Field(text)
url = Field(text)

user = User
guild_id = snowflake
roles = listof(snowflake)
game = Game
status = text
user = Field(User)
guild_id = Field(snowflake)
roles = Field(listof(snowflake))
game = Field(Game)
status = Field(text)


class TypingStart(GatewayEvent):
channel_id = snowflake
user_id = snowflake
timestamp = snowflake
"""
Sent when a user begins typing in a channel.
"""
channel_id = Field(snowflake)
user_id = Field(snowflake)
timestamp = Field(snowflake)


@wraps_model(VoiceState, alias='state')
class VoiceStateUpdate(GatewayEvent):
"""
Sent when a users voice state changes.
"""
pass


class VoiceServerUpdate(GatewayEvent):
token = str
endpoint = str
guild_id = snowflake
"""
Sent when a voice server is updated.
"""
token = Field(str)
endpoint = Field(str)
guild_id = Field(snowflake)

0 comments on commit ffe5a6f

Please sign in to comment.