Browse Source

Revert "Typo corrections, upgrades from Py2 to Py3-compatible formatting, patch yaml loader deprecation warning, Discord media proxy links (allows caching of possibly deleted images, relies less on the CDN)"

This reverts commit 5695eff8
pull/129/head
“elderlabs” 7 years ago
parent
commit
21ac37c54b
  1. 6
      disco/api/http.py
  2. 2
      disco/api/ratelimit.py
  3. 11
      disco/bot/bot.py
  4. 2
      disco/cli.py
  5. 21
      disco/gateway/client.py
  6. 2
      disco/state.py
  7. 2
      disco/types/base.py
  8. 6
      disco/types/channel.py
  9. 8
      disco/types/guild.py
  10. 6
      disco/types/user.py
  11. 44
      disco/voice/client.py
  12. 29
      disco/voice/udp.py
  13. 8
      setup.py

6
disco/api/http.py

@ -264,11 +264,11 @@ class HTTPClient(LoggingClass):
# Possibly wait if we're rate limited
response.rate_limited_duration = self.limiter.check(bucket)
self.log.debug('KW: {}'.format(kwargs))
self.log.debug('KW: %s', kwargs)
# Make the actual request
url = self.BASE_URL + route[1].format(**args)
self.log.info('{} {} ({})'.format(route[0].value, url, kwargs.get('params')))
self.log.info('%s %s (%s)', route[0].value, url, kwargs.get('params'))
r = self.session.request(route[0].value, url, **kwargs)
if self.after_request:
@ -282,7 +282,7 @@ class HTTPClient(LoggingClass):
if r.status_code < 400:
return r
elif r.status_code != 429 and 400 <= r.status_code < 500:
self.log.warning('Request failed with code {}: {}'.format(r.status_code, r.content))
self.log.warning('Request failed with code %s: %s', r.status_code, r.content)
response.exception = APIException(r)
raise response.exception
else:

2
disco/api/ratelimit.py

@ -99,7 +99,7 @@ class RouteState(LoggingClass):
self.event = gevent.event.Event()
delay = (self.reset_time - time.time()) + .5
self.log.debug('Cooling down bucket {} for {} seconds'.format(self, delay))
self.log.debug('Cooling down bucket %s for %s seconds', self, delay)
gevent.sleep(delay)
self.event.set()
self.event = None

11
disco/bot/bot.py

@ -154,8 +154,7 @@ class Bot(LoggingClass):
except ImportError:
self.log.warning('Failed to enable HTTP server, Flask is not installed')
else:
self.log.info('Starting HTTP server bound to {}:{}'.format(self.config.http_host,
self.config.http_port))
self.log.info('Starting HTTP server bound to %s:%s', self.config.http_host, self.config.http_port)
self.http = Flask('disco')
self.http_server = WSGIServer((self.config.http_host, self.config.http_port), self.http)
self.http_server_greenlet = gevent.spawn(self.http_server.serve_forever)
@ -245,7 +244,7 @@ class Bot(LoggingClass):
else:
possible[current] = group
# Now, we want to compute the actual shortest abbreviation out of the
# Now, we want to compute the actual shortest abbreivation out of the
# possible ones
result = {}
for abbrev, group in six.iteritems(possible):
@ -450,7 +449,7 @@ class Bot(LoggingClass):
inst = inst(self, config)
if inst.__class__.__name__ in self.plugins:
self.log.warning('Attempted to add already added plugin {}'.format(inst.__class__.__name__))
self.log.warning('Attempted to add already added plugin %s', inst.__class__.__name__)
raise Exception('Cannot add already added plugin: {}'.format(inst.__class__.__name__))
self.ctx['plugin'] = self.plugins[inst.__class__.__name__] = inst
@ -468,7 +467,7 @@ class Bot(LoggingClass):
Plugin class to unload and remove.
"""
if cls.__name__ not in self.plugins:
raise Exception('Cannot remove non-existent plugin: {}'.format(cls.__name__))
raise Exception('Cannot remove non-existant plugin: {}'.format(cls.__name__))
ctx = {}
self.plugins[cls.__name__].unload(ctx)
@ -496,7 +495,7 @@ class Bot(LoggingClass):
"""
Adds and loads a plugin, based on its module path.
"""
self.log.info('Adding plugin module at path "{}"'.format(path))
self.log.info('Adding plugin module at path "%s"', path)
mod = importlib.import_module(path)
loaded = False

2
disco/cli.py

@ -103,7 +103,7 @@ def disco_main(run=False):
if run:
(bot or client).run_forever()
return bot or client
return (bot or client)
if __name__ == '__main__':

21
disco/gateway/client.py

@ -75,7 +75,7 @@ class GatewayClient(LoggingClass):
return self._send(op, data)
def _send(self, op, data):
self.log.debug('GatewayClient.send {}'.format(op))
self.log.debug('GatewayClient.send %s', op)
self.packets.emit((SEND, op), data)
self.ws.send(self.encoder.encode({
'op': op.value,
@ -96,7 +96,7 @@ class GatewayClient(LoggingClass):
def handle_dispatch(self, packet):
obj = GatewayEvent.from_dispatch(self.client, packet)
self.log.debug('GatewayClient.handle_dispatch {}'.format(obj.__class__.__name__))
self.log.debug('GatewayClient.handle_dispatch %s', obj.__class__.__name__)
self.client.events.emit(obj.__class__.__name__, obj)
if self.replaying:
self.replayed_events += 1
@ -119,7 +119,7 @@ class GatewayClient(LoggingClass):
self.ws.close()
def handle_hello(self, packet):
self.log.info('Received HELLO, starting heartbeat...')
self.log.info('Received HELLO, starting heartbeater...')
self._heartbeat_task = gevent.spawn(self.heartbeat_task, packet['d']['heartbeat_interval'])
def on_ready(self, ready):
@ -128,7 +128,7 @@ class GatewayClient(LoggingClass):
self.reconnects = 0
def on_resumed(self, _):
self.log.info('RESUME completed, replayed {} events'.format(self.replayed_events))
self.log.info('RESUME completed, replayed %s events', self.replayed_events)
self.reconnects = 0
self.replaying = False
@ -144,7 +144,7 @@ class GatewayClient(LoggingClass):
if self.zlib_stream_enabled:
gateway_url += '&compress=zlib-stream'
self.log.info('Opening websocket connection to URL `{}`'.format(gateway_url))
self.log.info('Opening websocket connection to URL `%s`', gateway_url)
self.ws = Websocket(gateway_url)
self.ws.emitter.on('on_open', self.on_open)
self.ws.emitter.on('on_error', self.on_error)
@ -194,14 +194,14 @@ class GatewayClient(LoggingClass):
if isinstance(error, KeyboardInterrupt):
self.shutting_down = True
self.ws_event.set()
raise Exception('WS received error: {}'.format(error))
raise Exception('WS recieved error: %s', error)
def on_open(self):
if self.zlib_stream_enabled:
self._zlib = zlib.decompressobj()
if self.seq and self.session_id:
self.log.info('WS Opened: attempting resume w/ SID: {} SEQ: {}'.format(self.session_id, self.seq))
self.log.info('WS Opened: attempting resume w/ SID: %s SEQ: %s', self.session_id, self.seq)
self.replaying = True
self.send(OPCode.RESUME, {
'token': self.client.config.token,
@ -230,7 +230,7 @@ class GatewayClient(LoggingClass):
# Make sure we cleanup any old data
self._buffer = None
# Kill heartbeat, a reconnect/resume will trigger a HELLO which will
# Kill heartbeater, a reconnect/resume will trigger a HELLO which will
# respawn it
if self._heartbeat_task:
self._heartbeat_task.kill()
@ -244,7 +244,7 @@ class GatewayClient(LoggingClass):
# Track reconnect attempts
self.reconnects += 1
self.log.info('WS Closed: [{}] {} ({})'.format(code, reason, self.reconnects))
self.log.info('WS Closed: [%s] %s (%s)', code, reason, self.reconnects)
if self.max_reconnects and self.reconnects > self.max_reconnects:
raise Exception('Failed to reconnect after {} attempts, giving up'.format(self.max_reconnects))
@ -254,8 +254,7 @@ class GatewayClient(LoggingClass):
self.session_id = None
wait_time = self.reconnects * 5
self.log.info('Will attempt to {} after {} seconds'.format('resume' if self.session_id else 'reconnect',
wait_time))
self.log.info('Will attempt to %s after %s seconds', 'resume' if self.session_id else 'reconnect', wait_time)
gevent.sleep(wait_time)
# Reconnect

2
disco/state.py

@ -214,7 +214,7 @@ class State(object):
def on_guild_delete(self, event):
if event.id in self.guilds:
# Just delete the guild, channel references will fail
# Just delete the guild, channel references will fall
del self.guilds[event.id]
if event.id in self.voice_clients:

2
disco/types/base.py

@ -215,7 +215,7 @@ def datetime(data):
except (ValueError, TypeError):
continue
raise ValueError('Failed to convert `{}` to datetime'.format(data))
raise ValueError('Failed to conver `{}` to datetime'.format(data))
def text(obj):

6
disco/types/channel.py

@ -457,21 +457,21 @@ class Channel(SlottedModel, Permissible):
"""
Sets the channels bitrate.
"""
assert self.is_voice
assert (self.is_voice)
return self.client.api.channels_modify(self.id, bitrate=bitrate, reason=reason)
def set_user_limit(self, user_limit, reason=None):
"""
Sets the channels user limit.
"""
assert self.is_voice
assert (self.is_voice)
return self.client.api.channels_modify(self.id, user_limit=user_limit, reason=reason)
def set_parent(self, parent, reason=None):
"""
Sets the channels parent.
"""
assert self.is_guild
assert (self.is_guild)
return self.client.api.channels_modify(
self.id,
parent_id=to_snowflake(parent) if parent else parent,

8
disco/types/guild.py

@ -75,7 +75,7 @@ class GuildEmoji(Emoji):
@property
def url(self):
return 'https://media.discordapp.net/emojis/{}.{}'.format(self.id, 'gif' if self.animated else 'png')
return 'https://discordapp.com/api/emojis/{}.{}'.format(self.id, 'gif' if self.animated else 'png')
@cached_property
def guild(self):
@ -505,19 +505,19 @@ class Guild(SlottedModel, Permissible):
if not self.icon:
return ''
return 'https://media.discordapp.net/icons/{}/{}.{}?size={}'.format(self.id, self.icon, fmt, size)
return 'https://cdn.discordapp.com/icons/{}/{}.{}?size={}'.format(self.id, self.icon, fmt, size)
def get_splash_url(self, fmt='webp', size=1024):
if not self.splash:
return ''
return 'https://media.discordapp.net/splashes/{}/{}.{}?size={}'.format(self.id, self.splash, fmt, size)
return 'https://cdn.discordapp.com/splashes/{}/{}.{}?size={}'.format(self.id, self.splash, fmt, size)
def get_banner_url(self, fmt='webp', size=1024):
if not self.banner:
return ''
return 'https://media.discordapp.net/banners/{}/{}.{}?size={}'.format(self.id, self.banner, fmt, size)
return 'https://cdn.discordapp.com/banners/{}/{}.{}?size={}'.format(self.id, self.banner, fmt, size)
@property
def icon_url(self):

6
disco/types/user.py

@ -26,11 +26,11 @@ class User(SlottedModel, with_equality('id'), with_hash('id')):
if not self.avatar:
return 'https://cdn.discordapp.com/embed/avatars/{}.png'.format(self.default_avatar.value)
if fmt is not None:
return 'https://media.discordapp.net/avatars/{}/{}.{}?size={}'.format(self.id, self.avatar, fmt, size)
return 'https://cdn.discordapp.com/avatars/{}/{}.{}?size={}'.format(self.id, self.avatar, fmt, size)
if self.avatar.startswith('a_'):
return 'https://media.discordapp.net/avatars/{}/{}.gif?size={}'.format(self.id, self.avatar, size)
return 'https://cdn.discordapp.com/avatars/{}/{}.gif?size={}'.format(self.id, self.avatar, size)
else:
return 'https://media.discordapp.net/avatars/{}/{}.webp?size={}'.format(self.id, self.avatar, size)
return 'https://cdn.discordapp.com/avatars/{}/{}.webp?size={}'.format(self.id, self.avatar, size)
@property
def default_avatar(self):

44
disco/voice/client.py

@ -143,7 +143,7 @@ class VoiceClient(LoggingClass):
return self.ssrc + 3
def set_state(self, state):
self.log.debug('[{}] state {} -> {}'.format(self, self.state, state))
self.log.debug('[%s] state %s -> %s', self, self.state, state)
prev_state = self.state
self.state = state
self.state_emitter.emit(state, prev_state)
@ -154,8 +154,7 @@ class VoiceClient(LoggingClass):
return
self.log.info(
'[{}] Set endpoint from VOICE_SERVER_UPDATE (state = {} / endpoint = {})'.format(self, self.state,
endpoint))
'[%s] Set endpoint from VOICE_SERVER_UPDATE (state = %s / endpoint = %s)', self, self.state, endpoint)
self.endpoint = endpoint
@ -211,13 +210,13 @@ class VoiceClient(LoggingClass):
def send(self, op, data):
if self.ws and self.ws.sock and self.ws.sock.connected:
self.log.debug('[{}] sending OP {} (data = {})'.format(self, op, data))
self.log.debug('[%s] sending OP %s (data = %s)', self, op, data)
self.ws.send(self.encoder.encode({
'op': op.value,
'd': data,
}), self.encoder.OPCODE)
else:
self.log.debug('[{}] dropping because ws is closed OP {} (data = {})'.format(self, op, data))
self.log.debug('[%s] dropping because ws is closed OP %s (data = %s)', self, op, data)
def on_voice_client_connect(self, data):
user_id = int(data['user_id'])
@ -242,13 +241,12 @@ class VoiceClient(LoggingClass):
self.udp.set_audio_codec(data['audio_codec'])
def on_voice_hello(self, data):
self.log.info('[{}] Received Voice HELLO payload, starting heartbeat'.format(self))
self.log.info('[%s] Received Voice HELLO payload, starting heartbeater', self)
self._heartbeat_task = gevent.spawn(self._heartbeat, data['heartbeat_interval'])
self.set_state(VoiceState.AUTHENTICATED)
def on_voice_ready(self, data):
self.log.info('[{}] Received Voice READY payload, attempting to negotiate voice connection w/ remote'.format(
self))
self.log.info('[%s] Received Voice READY payload, attempting to negotiate voice connection w/ remote', self)
self.set_state(VoiceState.CONNECTING)
self.ssrc = data['ssrc']
self.ip = data['ip']
@ -258,12 +256,12 @@ class VoiceClient(LoggingClass):
for mode in self.SUPPORTED_MODES:
if mode in data['modes']:
self.mode = mode
self.log.debug('[{}] Selected mode {}'.format(self, mode))
self.log.debug('[%s] Selected mode %s', self, mode)
break
else:
raise Exception('Failed to find a supported voice mode')
self.log.debug('[{}] Attempting IP discovery over UDP to {}:{}'.format(self, self.ip, self.port))
self.log.debug('[%s] Attempting IP discovery over UDP to %s:%s', self, self.ip, self.port)
self.udp = UDPVoiceClient(self)
ip, port = self.udp.connect(self.ip, self.port)
@ -283,8 +281,7 @@ class VoiceClient(LoggingClass):
'payload_type': RTPPayloadTypes.get(codec).value,
})
self.log.debug('[{}] IP discovery completed (ip = {}, port = {}), sending SELECT_PROTOCOL'.format(self, ip,
port))
self.log.debug('[%s] IP discovery completed (ip = %s, port = %s), sending SELECT_PROTOCOL', self, ip, port)
self.send(VoiceOPCode.SELECT_PROTOCOL, {
'protocol': 'udp',
'data': {
@ -301,11 +298,11 @@ class VoiceClient(LoggingClass):
})
def on_voice_resumed(self, data):
self.log.info('[{}] Received resumed'.format(self))
self.log.info('[%s] Received resumed', self)
self.set_state(VoiceState.CONNECTED)
def on_voice_sdp(self, sdp):
self.log.info('[{}] Received session description, connection completed'.format(self))
self.log.info('[%s] Received session description, connection completed', self)
self.mode = sdp['mode']
self.audio_codec = sdp['audio_codec']
@ -344,7 +341,7 @@ class VoiceClient(LoggingClass):
self.log.exception('Failed to parse voice gateway message: ')
def on_error(self, err):
self.log.error('[{}] Voice websocket error: {}'.format(self, err))
self.log.error('[%s] Voice websocket error: %s', self, err)
def on_open(self):
if self._identified:
@ -363,7 +360,7 @@ class VoiceClient(LoggingClass):
})
def on_close(self, code, reason):
self.log.warning('[{}] Voice websocket closed: [{}] {} ({})'.format(self, code, reason, self._reconnects))
self.log.warning('[%s] Voice websocket closed: [%s] %s (%s)', self, code, reason, self._reconnects)
if self._heartbeat_task:
self._heartbeat_task.kill()
@ -375,7 +372,7 @@ class VoiceClient(LoggingClass):
if self.state == VoiceState.DISCONNECTED:
return
self.log.info('[{}] Attempting Websocket Resumption'.format(self))
self.log.info('[%s] Attempting Websocket Resumption', self)
self.set_state(VoiceState.RECONNECTING)
@ -399,8 +396,7 @@ class VoiceClient(LoggingClass):
wait_time = 1
self.log.info(
'[{}] Will attempt to {} after {} seconds'.format(self, 'resume' if self._identified else 'reconnect',
wait_time))
'[%s] Will attempt to %s after %s seconds', self, 'resume' if self._identified else 'reconnect', wait_time)
gevent.sleep(wait_time)
self._connect_and_run()
@ -410,17 +406,17 @@ class VoiceClient(LoggingClass):
channel_id = self.server_id
if not channel_id:
raise VoiceException('[{}] cannot connect to an empty channel id'.format(self))
raise VoiceException('[%s] cannot connect to an empty channel id', self)
if self.channel_id == channel_id:
if self.state == VoiceState.CONNECTED:
self.log.debug('[{}] Already connected to {}, returning'.format(self, self.channel))
self.log.debug('[%s] Already connected to %s, returning', self, self.channel)
return self
else:
if self.state == VoiceState.CONNECTED:
self.log.debug('[{}] Moving to channel {}'.format(self, channel_id))
self.log.debug('[%s] Moving to channel %s', self, channel_id)
else:
self.log.debug('[{}] Attempting connection to channel id {}'.format(self, channel_id))
self.log.debug('[%s] Attempting connection to channel id %s', self, channel_id)
self.set_state(VoiceState.AWAITING_ENDPOINT)
self.set_voice_state(channel_id, **kwargs)
@ -435,7 +431,7 @@ class VoiceClient(LoggingClass):
if self.state == VoiceState.DISCONNECTED:
return
self.log.debug('[{}] disconnect called'.format(self))
self.log.debug('[%s] disconnect called', self)
self.set_state(VoiceState.DISCONNECTED)
del self.client.state.voice_clients[self.server_id]

29
disco/voice/udp.py

@ -7,7 +7,7 @@ from collections import namedtuple
try:
import nacl.secret
except ImportError:
print('WARNING: PyNaCl is not installed, voice support is disabled')
print('WARNING: nacl is not installed, voice support is disabled')
from holster.enum import Enum
@ -103,8 +103,7 @@ class UDPVoiceClient(LoggingClass):
ptype = RTPPayloadTypes.get(codec)
self._rtp_audio_header[1] = ptype.value
self.log.debug('[{}] Set UDP\'s Audio Codec to {}, RTP payload type {}'.format(self.vc, ptype.name,
ptype.value))
self.log.debug('[%s] Set UDP\'s Audio Codec to %s, RTP payload type %s', self.vc, ptype.name, ptype.value)
def increment_timestamp(self, by):
self.timestamp += by
@ -169,7 +168,7 @@ class UDPVoiceClient(LoggingClass):
# Data cannot be less than the bare minimum, just ignore
if len(data) <= 12:
self.log.debug('[{}] [VoiceData] Received voice data under 13 bytes'.format(self.vc))
self.log.debug('[%s] [VoiceData] Received voice data under 13 bytes', self.vc)
continue
first, second = struct.unpack_from('>BB', data)
@ -221,16 +220,14 @@ class UDPVoiceClient(LoggingClass):
# Check if rtp version is 2
if rtp.version != 2:
self.log.debug('[{}] [VoiceData] Received an invalid RTP packet version, {}'.format(self.vc,
rtp.version))
self.log.debug('[%s] [VoiceData] Received an invalid RTP packet version, %s', self.vc, rtp.version)
continue
payload_type = RTPPayloadTypes.get(rtp.payload_type)
# Unsupported payload type received
if not payload_type:
self.log.debug('[{}] [VoiceData] Received unsupported payload type, {}'.format(self.vc,
rtp.payload_type))
self.log.debug('[%s] [VoiceData] Received unsupported payload type, %s', self.vc, rtp.payload_type)
continue
nonce = bytearray(24)
@ -243,13 +240,13 @@ class UDPVoiceClient(LoggingClass):
elif self.vc.mode == 'xsalsa20_poly1305':
nonce[:12] = data[:12]
else:
self.log.debug('[{}] [VoiceData] Unsupported Encryption Mode, {}'.format(self.vc, self.vc.mode))
self.log.debug('[%s] [VoiceData] Unsupported Encryption Mode, %s', self.vc, self.vc.mode)
continue
try:
data = self._secret_box.decrypt(bytes(data[12:]), bytes(nonce))
except Exception:
self.log.debug('[{}] [VoiceData] Failed to decode data from ssrc {}'.format(self.vc, rtp.ssrc))
self.log.debug('[%s] [VoiceData] Failed to decode data from ssrc %s', self.vc, rtp.ssrc)
continue
# RFC3550 Section 5.1 (Padding)
@ -271,11 +268,11 @@ class UDPVoiceClient(LoggingClass):
first_byte, = struct.unpack_from('>B', data[:offset])
offset += 1
rtp_extension_identifier = first_byte & 0xF
rtp_extension_identifer = first_byte & 0xF
rtp_extension_len = ((first_byte >> 4) & 0xF) + 1
# Ignore data if identifier == 15, so skip if this is set as 0
if rtp_extension_identifier:
# Ignore data if identifer == 15, so skip if this is set as 0
if rtp_extension_identifer:
fields.append(data[offset:offset + rtp_extension_len])
offset += rtp_extension_len
@ -293,7 +290,7 @@ class UDPVoiceClient(LoggingClass):
# RFC3550 Section 5.3: Profile-Specific Modifications to the RTP Header
# clients send it sometimes, definitely on fresh connects to a server, dunno what to do here
if rtp.marker:
self.log.debug('[{}] [VoiceData] Received RTP data with the marker set, skipping'.format(self.vc))
self.log.debug('[%s] [VoiceData] Received RTP data with the marker set, skipping', self.vc)
continue
payload = VoiceData(
@ -331,7 +328,7 @@ class UDPVoiceClient(LoggingClass):
try:
data, addr = gevent.spawn(lambda: self.conn.recvfrom(70)).get(timeout=timeout)
except gevent.Timeout:
return None, None
return (None, None)
# Read IP and port
ip = str(data[4:]).split('\x00', 1)[0]
@ -341,4 +338,4 @@ class UDPVoiceClient(LoggingClass):
self.connected = True
self._run_task = gevent.spawn(self.run)
return ip, port
return (ip, port)

8
setup.py

@ -10,16 +10,16 @@ with open('README.md') as f:
readme = f.read()
extras_require = {
'voice': ['pynacl>=1.2.1'],
'http': ['flask>=0.12.2'],
'yaml': ['pyyaml>=3.12'],
'voice': ['pynacl==1.2.1'],
'http': ['flask==0.12.2'],
'yaml': ['pyyaml==3.12'],
'music': ['youtube_dl>=2018.1.21'],
'performance': [
'erlpack==0.3.2' if sys.version_info.major == 2 else 'earl-etf==2.1.2',
'ujson==1.35',
'wsaccel==0.6.2',
],
'sharding': ['gipc>=0.6.0'],
'sharding': ['gipc==0.6.0'],
'docs': ['biblio==0.0.4'],
}

Loading…
Cancel
Save