Browse Source

APIClient fixes, emitter priority support, etc fixes

pull/5/head
Andrei 9 years ago
parent
commit
2c8f73f63c
  1. 8
      disco/api/client.py
  2. 15
      disco/bot/plugin.py
  3. 3
      disco/gateway/client.py
  4. 13
      disco/gateway/events.py
  5. 6
      disco/state.py
  6. 14
      disco/types/base.py
  7. 19
      disco/types/guild.py
  8. 2
      requirements.txt

8
disco/api/client.py

@ -144,17 +144,17 @@ class APIClient(LoggingClass):
return GuildMember.create_map(self.client, r.json()) return GuildMember.create_map(self.client, r.json())
def guilds_members_get(self, guild, member): def guilds_members_get(self, guild, member):
r = self.http(Routes.GUILD_MEMBERS_GET, dict(guild=guild, member=member)) r = self.http(Routes.GUILDS_MEMBERS_GET, dict(guild=guild, member=member))
return GuildMember.create(self.client, r.json()) return GuildMember.create(self.client, r.json())
def guilds_members_modify(self, guild, member, **kwargs): def guilds_members_modify(self, guild, member, **kwargs):
self.http(Routes.GUILD_MEMBERS_MODIFY, dict(guild=guild, member=member), json=kwargs) self.http(Routes.GUILDS_MEMBERS_MODIFY, dict(guild=guild, member=member), json=kwargs)
def guilds_members_kick(self, guild, member): def guilds_members_kick(self, guild, member):
self.http(Routes.GUILD_MEMBERS_KICK, dict(guild=guild, member=member)) self.http(Routes.GUILDS_MEMBERS_KICK, dict(guild=guild, member=member))
def guilds_bans_list(self, guild): def guilds_bans_list(self, guild):
r = self.http(Routes.GUILD_BANS_LIST, dict(guild=guild)) r = self.http(Routes.GUILDS_BANS_LIST, dict(guild=guild))
return User.create_map(self.client, r.json()) return User.create_map(self.client, r.json())
def guilds_bans_create(self, guild, user, delete_message_days): def guilds_bans_create(self, guild, user, delete_message_days):

15
disco/bot/plugin.py

@ -1,6 +1,8 @@
import inspect import inspect
import functools import functools
from holster.emitter import Priority
from disco.util.logging import LoggingClass from disco.util.logging import LoggingClass
from disco.bot.command import Command, CommandError from disco.bot.command import Command, CommandError
@ -10,6 +12,8 @@ class PluginDeco(object):
A utility mixin which provides various function decorators that a plugin A utility mixin which provides various function decorators that a plugin
author can use to create bound event/command handlers. author can use to create bound event/command handlers.
""" """
Prio = Priority
@staticmethod @staticmethod
def add_meta_deco(meta): def add_meta_deco(meta):
def deco(f): def deco(f):
@ -22,13 +26,14 @@ class PluginDeco(object):
return deco return deco
@classmethod @classmethod
def listen(cls, event_name): def listen(cls, event_name, priority=None):
""" """
Binds the function to listen for a given event name Binds the function to listen for a given event name
""" """
return cls.add_meta_deco({ return cls.add_meta_deco({
'type': 'listener', 'type': 'listener',
'event_name': event_name, 'event_name': event_name,
'priority': priority
}) })
@classmethod @classmethod
@ -118,7 +123,7 @@ class Plugin(LoggingClass, PluginDeco):
if hasattr(member, 'meta'): if hasattr(member, 'meta'):
for meta in member.meta: for meta in member.meta:
if meta['type'] == 'listener': if meta['type'] == 'listener':
self.register_listener(member, meta['event_name']) self.register_listener(member, meta['event_name'], meta['priority'])
elif meta['type'] == 'command': elif meta['type'] == 'command':
self.register_command(member, *meta['args'], **meta['kwargs']) self.register_command(member, *meta['args'], **meta['kwargs'])
elif meta['type'].startswith('pre_') or meta['type'].startswith('post_'): elif meta['type'].startswith('pre_') or meta['type'].startswith('post_'):
@ -155,7 +160,7 @@ class Plugin(LoggingClass, PluginDeco):
return True return True
def register_listener(self, func, name): def register_listener(self, func, name, priority):
""" """
Registers a listener Registers a listener
@ -165,9 +170,11 @@ class Plugin(LoggingClass, PluginDeco):
The function to be registered. The function to be registered.
name : string name : string
Name of event to listen for. Name of event to listen for.
priority : Priority
The priority of this listener.
""" """
func = functools.partial(self._dispatch, 'listener', func) func = functools.partial(self._dispatch, 'listener', func)
self.listeners.append(self.bot.client.events.on(name, func)) self.listeners.append(self.bot.client.events.on(name, func, priority=priority or Priority.NONE))
def register_command(self, func, *args, **kwargs): def register_command(self, func, *args, **kwargs):
""" """

3
disco/gateway/client.py

@ -1,6 +1,7 @@
import gevent import gevent
import zlib import zlib
import six import six
import ssl
from disco.gateway.packets import OPCode from disco.gateway.packets import OPCode
from disco.gateway.events import GatewayEvent from disco.gateway.events import GatewayEvent
@ -99,7 +100,7 @@ class GatewayClient(LoggingClass):
self.ws.emitter.on('on_close', self.on_close) self.ws.emitter.on('on_close', self.on_close)
self.ws.emitter.on('on_message', self.on_message) self.ws.emitter.on('on_message', self.on_message)
self.ws.run_forever() self.ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
def on_message(self, msg): def on_message(self, msg):
# Detect zlib and decompress # Detect zlib and decompress

13
disco/gateway/events.py

@ -2,7 +2,7 @@ import inflection
import six import six
from disco.types import Guild, Channel, User, GuildMember, Role, Message, VoiceState from disco.types import Guild, Channel, User, GuildMember, Role, Message, VoiceState
from disco.types.base import Model, snowflake, alias, listof from disco.types.base import Model, snowflake, alias, listof, text
# TODO: clean this... use BaseType, etc # TODO: clean this... use BaseType, etc
@ -121,10 +121,9 @@ class GuildMemberRemove(GatewayEvent):
user = User user = User
@wraps_model(GuildMember, alias='member')
class GuildMemberUpdate(GatewayEvent): class GuildMemberUpdate(GatewayEvent):
guild_id = snowflake pass
user = User
roles = listof(snowflake)
class GuildRoleCreate(GatewayEvent): class GuildRoleCreate(GatewayEvent):
@ -166,14 +165,14 @@ class PresenceUpdate(GatewayEvent):
class Game(Model): class Game(Model):
# TODO enum # TODO enum
type = int type = int
name = str name = text
url = str url = text
user = User user = User
guild_id = snowflake guild_id = snowflake
roles = listof(snowflake) roles = listof(snowflake)
game = Game game = Game
status = str status = text
class TypingStart(GatewayEvent): class TypingStart(GatewayEvent):

6
disco/state.py

@ -219,11 +219,11 @@ class State(object):
self.guilds[event.member.guild_id].members[event.member.id] = event.member self.guilds[event.member.guild_id].members[event.member.id] = event.member
def on_guild_member_update(self, event): def on_guild_member_update(self, event):
if event.guild_id not in self.guilds: if event.member.guild_id not in self.guilds:
return return
self.guilds[event.guild_id].members[event.user.id].roles = event.roles event.member.guild = self.guilds[event.member.guild_id]
self.guilds[event.guild_id].members[event.user.id].user.update(event.user) self.guilds[event.member.guild_id].members[event.member.id].update(event.member)
def on_guild_member_remove(self, event): def on_guild_member_remove(self, event):
if event.guild_id not in self.guilds: if event.guild_id not in self.guilds:

14
disco/types/base.py

@ -15,6 +15,10 @@ def _make(typ, data, client):
args, _, _, _ = inspect.getargspec(typ) args, _, _, _ = inspect.getargspec(typ)
if 'client' in args: if 'client' in args:
return typ(data, client) return typ(data, client)
elif issubclass(typ, Model):
if not client:
raise Exception()
return typ(data, client)
return typ(data) return typ(data)
@ -125,15 +129,14 @@ class Model(six.with_metaclass(ModelMeta)):
v = typ(obj[name], client) v = typ(obj[name], client)
else: else:
v = typ(obj[name]) v = typ(obj[name])
elif inspect.isclass(typ) and issubclass(typ, Model):
v = typ(obj[name], client)
else: else:
v = typ(obj[name]) v = typ(obj[name])
except Exception: except Exception:
print('Failed during parsing of field {} => {} (`{}`)'.format(name, typ, obj[name])) print('Failed during parsing of field {} => {}'.format(name, typ))
raise raise
if client and isinstance(v, Model):
v.client = client
setattr(self, dest_name, v) setattr(self, dest_name, v)
def update(self, other): def update(self, other):
@ -145,7 +148,10 @@ class Model(six.with_metaclass(ModelMeta)):
# Clear cached properties # Clear cached properties
for name in dir(type(self)): for name in dir(type(self)):
if isinstance(getattr(type(self), name), property): if isinstance(getattr(type(self), name), property):
try:
delattr(self, name) delattr(self, name)
except:
pass
@classmethod @classmethod
def create(cls, client, data): def create(cls, client, data):

19
disco/types/guild.py

@ -2,6 +2,7 @@ from holster.enum import Enum
from disco.api.http import APIException from disco.api.http import APIException
from disco.util import to_snowflake from disco.util import to_snowflake
from disco.util.functional import cached_property
from disco.types.base import Model, snowflake, listof, dictof, datetime, text, binary, enum from disco.types.base import Model, snowflake, listof, dictof, datetime, text, binary, enum
from disco.types.user import User from disco.types.user import User
from disco.types.voice import VoiceState from disco.types.voice import VoiceState
@ -82,6 +83,8 @@ class GuildMember(Model):
The user object of this member. The user object of this member.
guild_id : snowflake guild_id : snowflake
The guild this member is part of. The guild this member is part of.
nick : str
The nickname of the member.
mute : bool mute : bool
Whether this member is server voice-muted. Whether this member is server voice-muted.
deaf : bool deaf : bool
@ -93,6 +96,7 @@ class GuildMember(Model):
""" """
user = User user = User
guild_id = snowflake guild_id = snowflake
nick = text
mute = bool mute = bool
deaf = bool deaf = bool
joined_at = datetime joined_at = datetime
@ -125,6 +129,21 @@ class GuildMember(Model):
""" """
self.client.api.guilds_bans_create(self.guild.id, self.user.id, delete_message_days) self.client.api.guilds_bans_create(self.guild.id, self.user.id, delete_message_days)
def set_nickname(self, nickname=None):
"""
Sets the members nickname (or clears it if None).
Args
----
nickname : Optional[str]
The nickname (or none to reset) to set.
"""
self.client.api.guilds_members_modify(self.guild.id, self.user.id, nick=nickname or '')
@cached_property
def guild(self):
return self.client.state.guilds.get(self.guild_id)
@property @property
def id(self): def id(self):
""" """

2
requirements.txt

@ -1,5 +1,5 @@
gevent==1.1.2 gevent==1.1.2
holster==1.0.1 holster==1.0.3
inflection==0.3.1 inflection==0.3.1
requests==2.11.1 requests==2.11.1
six==1.10.0 six==1.10.0

Loading…
Cancel
Save