Browse Source

Add presence tracking

pull/5/head
Andrei 9 years ago
parent
commit
fc534965f4
  1. 19
      disco/gateway/events.py
  2. 5
      disco/state.py
  3. 15
      disco/types/base.py
  4. 30
      disco/types/user.py

19
disco/gateway/events.py

@ -3,8 +3,13 @@ from __future__ import print_function
import inflection
import six
from disco.types import Guild, Channel, User, GuildMember, Role, Message, VoiceState
from disco.types.base import Model, Field, snowflake, listof, text
from disco.types.user import User, Presence
from disco.types.channel import Channel
from disco.types.message import Message
from disco.types.voice import VoiceState
from disco.types.guild import Guild, GuildMember, Role
from disco.types.base import Model, Field, snowflake, listof
class GatewayEvent(Model):
@ -267,21 +272,13 @@ class MessageDeleteBulk(GatewayEvent):
ids = Field(listof(snowflake))
@wraps_model(Presence)
class PresenceUpdate(GatewayEvent):
"""
Sent when a users presence is updated.
"""
class Game(Model):
# TODO enum
type = Field(int)
name = Field(text)
url = Field(text)
user = Field(User)
guild_id = Field(snowflake)
roles = Field(listof(snowflake))
game = Field(Game)
status = Field(text)
class TypingStart(GatewayEvent):

5
disco/state.py

@ -80,6 +80,7 @@ class State(object):
'Ready', 'GuildCreate', 'GuildUpdate', 'GuildDelete', 'GuildMemberAdd', 'GuildMemberRemove',
'GuildMemberUpdate', 'GuildMembersChunk', 'GuildRoleCreate', 'GuildRoleUpdate', 'GuildRoleDelete',
'ChannelCreate', 'ChannelUpdate', 'ChannelDelete', 'VoiceStateUpdate', 'MessageCreate',
'PresenceUpdate'
]
def __init__(self, client, config=None):
@ -262,3 +263,7 @@ class State(object):
return
del self.guilds[event.guild_id].roles[event.role.id]
def on_presence_update(self, event):
if event.user.id in self.users:
self.users[event.user.id].presence = event.presence

15
disco/types/base.py

@ -2,6 +2,7 @@ import six
import inspect
import functools
from holster.enum import BaseEnumMeta
from datetime import datetime as real_datetime
DATETIME_FORMATS = [
@ -10,10 +11,19 @@ DATETIME_FORMATS = [
]
class ConversionError(Exception):
def __init__(self, field, raw, e):
super(ConversionError, self).__init__(
'Failed to convert `{}` (`{}`) to {}: {}'.format(
raw, field.src_name, field.typ, e))
class FieldType(object):
def __init__(self, typ):
if isinstance(typ, FieldType) or inspect.isclass(typ) and issubclass(typ, Model):
self.typ = typ
elif isinstance(typ, BaseEnumMeta):
self.typ = lambda raw, _: typ.get(raw)
else:
self.typ = lambda raw, _: typ(raw)
@ -48,7 +58,10 @@ class Field(FieldType):
return self.default is not None
def try_convert(self, raw, client):
return self.typ(raw, client)
try:
return self.typ(raw, client)
except Exception as e:
raise ConversionError(self, raw, e)
class _Dict(FieldType):

30
disco/types/user.py

@ -1,3 +1,5 @@
from holster.enum import Enum
from disco.types.base import Model, Field, snowflake, text, binary, with_equality, with_hash
@ -9,6 +11,8 @@ class User(Model, with_equality('id'), with_hash('id')):
verified = Field(bool)
email = Field(str)
presence = None
@property
def mention(self):
return '<@{}>'.format(self.id)
@ -21,3 +25,29 @@ class User(Model, with_equality('id'), with_hash('id')):
def on_create(self):
self.client.state.users[self.id] = self
GameType = Enum(
DEFAULT=0,
STREAMING=1,
)
Status = Enum(
'ONLINE',
'IDLE',
'DND',
'INVISIBLE',
'OFFLINE'
)
class Game(Model):
type = Field(GameType)
name = Field(text)
url = Field(text)
class Presence(Model):
user = Field(User)
game = Field(Game)
status = Field(Status)

Loading…
Cancel
Save