Browse Source

use skema, etc

pull/3/head
Andrei 9 years ago
parent
commit
9dac272f0b
  1. 67
      disco/gateway/client.py
  2. 22
      disco/gateway/events.py
  3. 16
      disco/gateway/packets.py
  4. 0
      disco/types/__init__.py
  5. 7
      disco/types/guild.py
  6. 5
      disco/types/user.py
  7. 25
      requirements.txt

67
disco/gateway/client.py

@ -1,10 +1,13 @@
import websocket
import gevent
import json
import zlib
from disco.gateway.packets import (
Packet, DispatchPacket, HeartbeatPacket, ReconnectPacket, InvalidSessionPacket, HelloPacket, HeartbeatAckPacket,
ResumePacket, IdentifyPacket)
from holster.emitter import Emitter
# from holster.util import SimpleObject
from disco.gateway.packets import OPCode, HeartbeatPacket, ResumePacket, IdentifyPacket
from disco.gateway.events import GatewayEvent
from disco.util.logging import LoggingClass
GATEWAY_VERSION = 6
@ -24,6 +27,7 @@ class GatewayClient(LoggingClass):
def __init__(self, client):
super(GatewayClient, self).__init__()
self.client = client
self.emitter = Emitter(gevent.spawn)
# Websocket connection
self.ws = None
@ -51,9 +55,25 @@ class GatewayClient(LoggingClass):
self.send(HeartbeatPacket(data=self.seq))
gevent.sleep(interval / 1000)
def handle_dispatch(self, packet):
obj = GatewayEvent.from_dispatch(packet)
self.log.info('Got dispatch for %s', obj.user.id)
def handle_heartbeat(self, packet):
pass
def handle_reconnect(self, packet):
pass
def handle_invalid_session(self, packet):
pass
def handle_hello(self, packet):
self.log.info('Recieved HELLO, starting heartbeater...')
self._heartbeat_task = gevent.spawn(self.heartbeat_task, packet.heartbeat_interval)
self._heartbeat_task = gevent.spawn(self.heartbeat_task, packet['d']['heartbeat_interval'])
def handle_heartbeat_ack(self, packet):
pass
def connect(self):
if not self._cached_gateway_url:
@ -69,30 +89,35 @@ class GatewayClient(LoggingClass):
)
def on_message(self, ws, msg):
# TODO: ZLIB
# Check if we're JSON
if msg[0] != '{':
print 'zlib'
msg = zlib.decompress(msg)
try:
packet = Packet.load_json(json.loads(msg))
if packet.seq and packet.seq > self.seq:
self.seq = packet.seq
data = json.loads(msg)
except:
self.log.exception('Failed to load dispatch:')
return
if isinstance(packet, DispatchPacket):
self.handle_dispatch(packet)
elif isinstance(packet, HeartbeatPacket):
self.handle_heartbeat(packet)
elif isinstance(packet, ReconnectPacket):
self.handle_reconnect(packet)
elif isinstance(packet, InvalidSessionPacket):
self.handle_invalid_session(packet)
elif isinstance(packet, HelloPacket):
self.handle_hello(packet)
elif isinstance(packet, HeartbeatAckPacket):
self.handle_heartbeat_ack(packet)
# Update sequence
if data['s'] and data['s'] > self.seq:
self.seq = data['s']
if data['op'] == OPCode.DISPATCH:
self.handle_dispatch(data)
elif data['op'] == OPCode.HEARTBEAT:
self.handle_heartbeat(data)
elif data['op'] == OPCode.RECONNECT:
self.handle_reconnect(data)
elif data['op'] == OPCode.INVALID_SESSION:
self.handle_invalid_session(data)
elif data['op'] == OPCode.HELLO:
self.handle_hello(data)
elif data['op'] == OPCode.HEARTBEAT_ACK:
self.handle_heartbeat_ack(data)
else:
raise Exception('Unknown packet: {}'.format(packet))
raise Exception('Unknown packet: {}'.format(data['op']))
def on_error(self, ws, error):
print 'error', error

22
disco/gateway/events.py

@ -0,0 +1,22 @@
import inflection
import skema
from disco.types.user import User
from disco.types.guild import Guild
class GatewayEvent(skema.Model):
@staticmethod
def from_dispatch(obj):
cls = globals().get(inflection.camelize(obj['t'].lower()))
if not cls:
raise Exception('Could not find cls for {}'.format(obj['t']))
return cls(obj['d'])
class Ready(GatewayEvent):
version = skema.IntType(stored_name='v')
session_id = skema.StringType()
user = skema.ModelType(User)
guilds = skema.ListType(skema.ModelType(Guild))

16
disco/gateway/packets.py

@ -20,21 +20,7 @@ OPCode = Enum(
class Packet(TypedClass):
@classmethod
def load_json(cls, obj):
if not obj['op']:
raise Exception('Packet struct missing op key: {}'.format(obj))
cls = PACKETS.get(obj['op'])
if not cls:
raise Exception('Unknown OPCode: {}'.format(obj['op']))
obj.update(obj['d'])
del obj['d']
inst = cls.from_dict(obj)
inst.seq = obj['s']
return inst
pass
class DispatchPacket(Packet):

0
disco/types/__init__.py

7
disco/types/guild.py

@ -0,0 +1,7 @@
import skema
from disco.util.oop import TypedClass
class Guild(skema.Model):
id = skema.SnowflakeType()

5
disco/types/user.py

@ -0,0 +1,5 @@
import skema
class User(skema.Model):
id = skema.SnowflakeType()

25
requirements.txt

@ -0,0 +1,25 @@
backports.ssl-match-hostname==3.5.0.1
cffi==1.8.3
click==6.6
cryptography==1.5
enum34==1.1.6
Flask==0.11.1
gevent==1.1.2
greenlet==0.4.10
holster==0.0.7
idna==2.1
inflection==0.3.1
ipaddress==1.0.17
itsdangerous==0.24
Jinja2==2.8
MarkupSafe==0.23
ndg-httpsclient==0.4.2
pyasn1==0.1.9
pycparser==2.14
pyOpenSSL==16.1.0
requests==2.11.1
six==1.10.0
skema==0.0.1
websocket-client==0.37.0
Werkzeug==0.11.11
wheel==0.24.0
Loading…
Cancel
Save