Compare commits

...

1 Commits

Author SHA1 Message Date
Andrei 2f37dbb10e Start working on Sendable / better message builders 8 years ago
  1. 64
      disco/types/message.py
  2. 57
      disco/util/message.py
  3. 4
      requirements.txt
  4. 2
      setup.py
  5. 17
      tests/test_message.py

64
disco/types/message.py

@ -2,7 +2,6 @@ import re
import six
import warnings
import functools
import unicodedata
from holster.enum import Enum
@ -443,53 +442,26 @@ class Message(SlottedModel):
return content
class MessageTable(object):
def __init__(self, sep=' | ', codeblock=True, header_break=True, language=None):
self.header = []
self.entries = []
self.size_index = {}
self.sep = sep
self.codeblock = codeblock
self.header_break = header_break
self.language = language
def recalculate_size_index(self, cols):
for idx, col in enumerate(cols):
size = len(unicodedata.normalize('NFC', col))
if idx not in self.size_index or size > self.size_index[idx]:
self.size_index[idx] = size
def set_header(self, *args):
args = list(map(six.text_type, args))
self.header = args
self.recalculate_size_index(args)
def add(self, *args):
args = list(map(six.text_type, args))
self.entries.append(args)
self.recalculate_size_index(args)
def compile_one(self, cols):
data = self.sep.lstrip()
for idx, col in enumerate(cols):
padding = ' ' * (self.size_index[idx] - len(col))
data += col + padding + self.sep
return data.rstrip()
class Sendable(object):
"""
Base class which implements an entity that can be sent as a message to Discord.
"""
def compile(self):
data = []
if self.header:
data = [self.compile_one(self.header)]
if self.header and self.header_break:
data.append('-' * (sum(self.size_index.values()) + (len(self.header) * len(self.sep)) + 1))
"""
Should return a valid (e.g. properly sized, < 2000 length) message that
can be sent to Discord.
"""
for row in self.entries:
data.append(self.compile_one(row))
@staticmethod
def fit(contents, head='```', tail='```', length=2000):
contents = Sendable.truncate(contents, tail='', length=length - (len(head) + len(tail)))
return u'{}{}{}'.format(head, contents, tail)
if self.codeblock:
return '```{}'.format(self.language if self.language else '') + '\n'.join(data) + '```'
@staticmethod
def truncate(contents, tail='...', length=2000):
if len(contents) <= length:
return contents
return '\n'.join(data)
to_truncate = len(contents) - length + len(tail)
return contents[:-to_truncate] + tail

57
disco/util/message.py

@ -0,0 +1,57 @@
import six
import unicodedata
from disco.types.message import Sendable
class MessageTable(Sendable):
def __init__(self, sep=' | ', codeblock=True, header_break=True, language=None):
self.header = []
self.entries = []
self.size_index = {}
self.sep = sep
self.codeblock = codeblock
self.header_break = header_break
self.language = language
def recalculate_size_index(self, cols):
for idx, col in enumerate(cols):
size = len(unicodedata.normalize('NFC', col))
if idx not in self.size_index or size > self.size_index[idx]:
self.size_index[idx] = size
def set_header(self, *args):
args = list(map(six.text_type, args))
self.header = args
self.recalculate_size_index(args)
def add(self, *args):
args = list(map(six.text_type, args))
self.entries.append(args)
self.recalculate_size_index(args)
def compile_one(self, cols):
data = self.sep.lstrip()
for idx, col in enumerate(cols):
padding = ' ' * (self.size_index[idx] - len(col))
data += col + padding + self.sep
return data.rstrip()
def compile(self):
data = []
if self.header:
data = [self.compile_one(self.header)]
if self.header and self.header_break:
data.append('-' * (sum(self.size_index.values()) + (len(self.header) * len(self.sep)) + 1))
for row in self.entries:
data.append(self.compile_one(row))
if self.codeblock:
return self.fit((self.lanague if self.language else '') + '\n'.join(data))
# TODO: truncate by line
return self.truncate('\n'.join(data), tail='')

4
requirements.txt

@ -1,5 +1,5 @@
gevent==1.2.2
holster==1.0.15
requests==2.13.0
requests==2.18.1
six==1.10.0
websocket-client==0.40.0
websocket-client==0.44.0

2
setup.py

@ -13,7 +13,7 @@ extras_require = {
'voice': ['pynacl==1.1.2'],
'http': ['flask==0.12.2'],
'yaml': ['pyyaml==3.12'],
'music': ['youtube_dl==2017.4.26'],
'music': ['youtube_dl==2017.7.2'],
'performance': ['erlpack==0.3.2', 'ujson==1.35'],
'sharding': ['gipc==0.6.0'],
'docs': ['biblio==0.0.2'],

17
tests/test_message.py

@ -0,0 +1,17 @@
from unittest import TestCase
from disco.types.message import Sendable
class TestSendable(TestCase):
def test_sendable_truncate(self):
self.assertEqual(Sendable.truncate('*' * 2001), ('*' * 1997) + '...')
self.assertEqual(Sendable.truncate('*' * 1999), '*' * 1999)
self.assertEqual(Sendable.truncate(u'\U0001F947' * 20), u'\U0001F947' * 20)
self.assertEqual(Sendable.truncate(u'\U0001F947' * 3000, tail=''), u'\U0001F947' * 2000)
def test_sendable_fit(self):
self.assertEqual(Sendable.fit('*' * 3000), '```{}```'.format('*' * 1994))
self.assertEqual(Sendable.fit('test'), '```test```')
self.assertEqual(Sendable.fit('test', '`', '`'), '`test`')
self.assertEqual(Sendable.fit(u'\U0001F947'), u'```\U0001F947```')
Loading…
Cancel
Save