diff --git a/CHANGELOG.md b/CHANGELOG.md index b2e0d73..6316a19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # CHANGELOG +## v0.0.12-rc.3 + +### Additions + +- **BREAKING** Updated holster to v2.0.0 which changes the way emitters work (and removes the previous priorities). A migration guide will be provided post-RC cycle. +- Added the concept of a `shared_config` which propgates its options to all plugin configs (@enkoder) + +### Fixes + +- Fixed using the ETF encoder while also using zlib-stream +- Fixed overwrite calculations in `Channel.get_permissions` (@cookkkie) + +### Etc + +- Cleaned up various documentation +- Removed some outdated storage/etc examples + ## v0.0.12-rc.2 ### Fixes diff --git a/disco/__init__.py b/disco/__init__.py index 6c6b101..cbf0cc2 100644 --- a/disco/__init__.py +++ b/disco/__init__.py @@ -1 +1 @@ -VERSION = '0.0.12-rc.2' +VERSION = '0.0.12-rc.3' diff --git a/disco/bot/bot.py b/disco/bot/bot.py index f90b882..b4c2393 100644 --- a/disco/bot/bot.py +++ b/disco/bot/bot.py @@ -506,7 +506,7 @@ class Bot(LoggingClass): data = {} if self.config.shared_config: - data.update(self.config.shared) + data.update(self.config.shared_config) if name in self.config.plugin_config: data.update(self.config.plugin_config[name]) diff --git a/disco/cli.py b/disco/cli.py index 201b068..edddbed 100644 --- a/disco/cli.py +++ b/disco/cli.py @@ -42,7 +42,6 @@ def disco_main(run=False): from disco.client import Client, ClientConfig from disco.bot import Bot, BotConfig - from disco.util.token import is_valid_token from disco.util.logging import setup_logging if os.path.exists(args.config): @@ -60,10 +59,6 @@ def disco_main(run=False): if hasattr(config, k) and v is not None: setattr(config, k, v) - if not is_valid_token(config.token): - print('Invalid token passed') - return - if args.shard_auto: from disco.gateway.sharder import AutoSharder AutoSharder(config).run() diff --git a/disco/types/channel.py b/disco/types/channel.py index 2419bec..edaaef1 100644 --- a/disco/types/channel.py +++ b/disco/types/channel.py @@ -518,6 +518,8 @@ class MessageIterator(object): def fill(self): """ Fills the internal buffer up with :class:`disco.types.message.Message` objects from the API. + + Returns a boolean indicating whether items were added to the buffer. """ self._buffer = self.client.api.channels_messages_list( self.channel.id, @@ -526,7 +528,7 @@ class MessageIterator(object): limit=self.chunk_size) if not len(self._buffer): - return + return False self.after = None self.before = None @@ -538,6 +540,8 @@ class MessageIterator(object): self._buffer.reverse() self.after = self._buffer[-1].id + return True + def next(self): return self.__next__() @@ -546,7 +550,9 @@ class MessageIterator(object): def __next__(self): if not len(self._buffer): - self.fill() + filled = self.fill() + if not filled: + raise StopIteration if self.bulk: res = self._buffer diff --git a/disco/types/guild.py b/disco/types/guild.py index 5c2a0d7..d72e2f9 100644 --- a/disco/types/guild.py +++ b/disco/types/guild.py @@ -54,6 +54,8 @@ class GuildEmoji(Emoji): Whether this emoji is managed by an integration. roles : list(snowflake) Roles this emoji is attached to. + animated : bool + Whether this emoji is animated. """ id = Field(snowflake) guild_id = Field(snowflake) @@ -61,9 +63,10 @@ class GuildEmoji(Emoji): require_colons = Field(bool) managed = Field(bool) roles = ListField(snowflake) + animated = Field(bool) def __str__(self): - return u'<:{}:{}>'.format(self.name, self.id) + return u'<{}:{}:{}>'.format('a' if self.animated else '', self.name, self.id) def update(self, **kwargs): return self.client.api.guilds_emojis_modify(self.guild_id, self.id, **kwargs) @@ -73,7 +76,7 @@ class GuildEmoji(Emoji): @property def url(self): - return 'https://discordapp.com/api/emojis/{}.png'.format(self.id) + return 'https://discordapp.com/api/emojis/{}.{}'.format(self.id, 'gif' if self.animated else 'png') @cached_property def guild(self): diff --git a/disco/types/message.py b/disco/types/message.py index dcac07e..b97a5e0 100644 --- a/disco/types/message.py +++ b/disco/types/message.py @@ -37,9 +37,12 @@ class Emoji(SlottedModel): The emoji ID (will be none if this is not a custom emoji). name : str The name of this emoji. + animated : bool + Whether this emoji is animated. """ id = Field(snowflake) name = Field(text) + animated = Field(bool) @cached_property def custom(self): diff --git a/disco/util/token.py b/disco/util/token.py deleted file mode 100644 index d71b93d..0000000 --- a/disco/util/token.py +++ /dev/null @@ -1,10 +0,0 @@ -import re - -TOKEN_RE = re.compile(r'M\w{23}\.[\w-]{6}\..{27}') - - -def is_valid_token(token): - """ - Validates a Discord authentication token, returning true if valid. - """ - return bool(TOKEN_RE.match(token)) diff --git a/docs/bot_tutorial/first_steps.md b/docs/bot_tutorial/first_steps.md index 02f05a8..6b6b961 100644 --- a/docs/bot_tutorial/first_steps.md +++ b/docs/bot_tutorial/first_steps.md @@ -21,7 +21,7 @@ The \_\_init\_\_.py file is required for Python to find your plugin, but it can {% endhint %} -Now lets setup the configuration file. To start off with we'll paste the following template in and modify our token key (`MY_BOT_TOKEN_HERE`) to be the token we obtained above. The plugins section tells disco what plugins to load, based on a module path (similar to how Python imports work). In this example we're asking disco to load the plugin contained in the tutorial file within the plugins directory (or "module"). Disco by default loads the first plugin it finds within the module, so you want to make sure each plugin class is contained within its own file. +Now let's setup the configuration file. To start off with we'll paste the following template in and modify our token key (`MY_BOT_TOKEN_HERE`) to be the token we obtained above. The plugins section tells disco what plugins to load, based on a module path (similar to how Python imports work). In this example we're asking disco to load the plugin contained in the tutorial file within the plugins directory (or "module"). Disco by default loads the first plugin it finds within the module, so you want to make sure each plugin class is contained within its own file. ```yaml token: 'MY_BOT_TOKEN_HERE' diff --git a/setup.py b/setup.py index d6ab450..4c5a8a9 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ extras_require = { 'voice': ['pynacl==1.2.1'], 'http': ['flask==0.12.2'], 'yaml': ['pyyaml==3.12'], - 'music': ['youtube_dl>=2017.12.31'], + 'music': ['youtube_dl>=2018.1.14'], 'performance': ['erlpack==0.3.2' if sys.version_info.major == 2 else 'earl-etf==2.1.2', 'ujson==1.35'], 'sharding': ['gipc==0.6.0'], 'docs': ['biblio==0.0.4'], diff --git a/tests/imports.py b/tests/imports.py index 8257c0a..2d00f68 100644 --- a/tests/imports.py +++ b/tests/imports.py @@ -33,7 +33,6 @@ from disco.util.limiter import * from disco.util.logging import * from disco.util.serializer import * from disco.util.snowflake import * -from disco.util.token import * from disco.util.websocket import * from disco.voice.client import * from disco.voice.opus import *