Releases: b1naryth1ef/disco
v0.0.11
Additions
- Added support for Guild audit logs, exposed via 
Guild.get_audit_log_entries,Guild.audit_logandGuild.audit_log_iter. For more information see theAuditLogEntrymodel - Added built-in Flask HTTP server which can be enabled via 
http_enabledand configured viahttp_host/http_portconfig options. The server allows plugins to define routes which can be called externally. - Added support for capturing the raw responses returned from API requests via the 
APIClient.capturecontextmanager - Added support for NSFW channels via 
Channel.nsfwandChannel.is_nsfw - Added initial support for channel categories via 
Channel.parent_idandChannel.parent - Added various setters for updating Channel properties, e.g. 
Channel.set_topic - Added support for audit log reasons, accessible through passing 
reasonto various methods - Added 
disco.util.snowflake.from_timestamp_ms - Added support for 
on_completecallback within DCADOpusEncoderPlayable - BREAKING Added new custom queue types 
BaseQueue/PlayableQueuefor use w/Player.queuecan be passed when creating aPlayer, should inherit from BaseQueue- Users who previously utilized the 
putmethod of the oldPlayer.queuemust move to usingPlayer.queue.append, or providing a custom queue implementation. 
 - Added 
Emoji.customproperty 
Fixes
- Fixed GuildRoleCreate missing guild_id, resulting in incorrect state
 - Fixed SimpleLimiter behaving incorrectly (causing GW socket to be ratelimited in some cases)
 - Fixed the shortest possible match for a single command being an empty string
 - Fixed group matching being overly greedy, which allowed for extra characters to be allowed at the end of a group match
 - Fixed errors thrown when not enabling manhole via cli
 - Fixed various warnings emitted due to useage of StopIteration
 - Fixed warnings about missing voice libs when importing 
disco.types.channel - Fixed 
Bot.get_commands_for_messagereturning None (instead of empty list) in some cases 
Etc
- Greatly imrpoved the performance of 
HashMap - BREAKING Increased the weight of group matches over command argument matches, and limited the number of commands executed per message to one.
 - Reuse a buffer in voice code to slightly improve performance
 
V0.0.11 RC1
Major Features
- Add support for built-in HTTP/Flask server
 - [BREAKING] #33 Increase the weight of group matches over command argument matches, and limit the number of commands executed per message to exactly one.
 
Cleanup/Etc
- Remove pyyaml requirement
 - Remove inflection requirement
 - Bump gevent from 1.2.1 to 1.2.2
 
Bug Fixes
- Fix the shortest possible match for a group being an empty string
 - Fix groups being overly greedy and matching past the end of the group.
 - Remove all usages of StopIteration to quiet warnings on Python 3
 
Docs, Cleanup, Tooling
This release brings a lot of needed updates to tooling, documentation, and the general flow/API.
Breaking
- Rewrite the majority of the storage module. This includes an entirely new interface.
 
Tooling
- Documentation w/ Biblio - This is very much an initial stab at a problem that requires much more work and effort, but for now there are at least some docs that can be parsed by a human.
 - Travis CI - CI and testing mean we will hopefully have less issues with breaking folks stuff. This also has a long way to go.
 
API
channels_messages_create/channels_messages_modifynow support message sanitization via the new moduledisco.util.sanitize. Most users will want to flip this on for any messages that contain user-generated or passed content.- Added support for multiple attachments when sending messages. This deprecates the 
attachmentkwarg in favor of anattachmentskwarg, holding an array of attachments. channels_messages_reactions_getsupports pagination- Added 
guilds_invites_list - Added 
users_me_guilds_delete - Move to API v7, which includes new errors array. Can be viewed within an 
APIExceptionvia theerrorsproperty. This also includes an update to the exception message format. - Complete implementation of 
Client.update_presence - Add support for NSFW channels
 - Added various new fields and functions to 
Guildtype Message.create_reactionrenamed to (the previous version being deprecated)Message.add_reaction
Bot
- Refactor of the way we implemented command groups. This fixes various errors and removes the hard cap of 100 commands.
 
ETC
- Add  
log-levelCLI flag - GatewayClient now keeps some state which allows introspection of resumes (and the number of events replayed)
 - Various fixes to state tracking
 
Obviously the above is a non-exhaustive list, this release included a ton of bug fixes and issues related to voice and other components.
Voice Send Support
The highlight of this release is fully-working voice transmission support, with many features and bug-fixes laying in the backdrop.
Features
- Add voice transmission support, with multiple builtin classes for streaming music using youtube-dl, ffmpeg, etc
 - Add support for opening DMs with users
 - Support loading bot level getter function from a module/function path
 - Add 
Plugin.wait_for_event, which waits for a specified event (and filters on it), useful for reaction interactions - Add support for updating managed emojis
 - Add support for modifying guild members
 - Add 
Message.get_reactorsfor fetching a list of all reactors for a given emoji - Better avatar support, incl. for users w/o avatars
 - Upgraded various dependencies
 
Bug Fixes
- Fix commands being strictly case-sensitive
 - Fix command edit detection triggering on embed updates
 - Fix some information being smashed upon 
GUILD_UPDATE's - Fix state handling of 
VOICE_STATE_UPDATE - Fix emojis losing their 
guild_idafter being updated - Fix some obscure typing issues
 - Fix bulk message deletion
 - Fix 
GuildMember.remove_role - Fix 
MessageEmbed.set_footer 
Cleanup / Stability
Version 0.0.7 has been a long time coming, and at this point mostly serves as a checkpoint for further progress. It includes a lot of additions and some breaking changes.
Changes
- Add support for sending attachments and embeds through 
APIClient.channels_messages_create - Add support for editing messages with embeds through 
APIClient.channels_messages_modify - Add reaction supports via:
APIClient.channels_messages_reactions_getAPIClient.channels_messages_reactions_createAPIClient.channels_messages_reactions_deleteMessageReactionMessageReactionEmojiMessageReactionAddMessageReactionRemoveMessageReactionRemoveAllMessage.reactionsMessage.create_reactionMessage.delete_reaction
 - Add support for creating a guild channel via 
APIClient.guilds_channels_createandGuild.create_channel APIClient.guild_members_listnow returns a hash- Add 
APIClient.guilds_members_roles_addandAPIClient.guilds_members_roles_removefor more determinisitc role adjustments - Add 
APIClient.guilds_members_me_nickfor setting the current users nick - Add 
GuildBan,APIClient.guild_bans_listnow returns aGuildBan - Added proper user agent to API requests
 - Improved 
APIException - Factor our some ingrained functionality from within 
Bot - Improved builtin argument parsing types
 - Added 
guildargument parsing type - Added tracking of spawned greenlets to plugins
 - Added configuration option 
max_reconnectsfor tweaking the max number of gateway reconnects attempted before giving up - Various event cleanup
 - Sharding cleanup
 - Typing cleanup/fixes
 - A lot of other stuff...
 
Almost There
Version 0.0.6 brings a set of stability features, and the introduction of a new feature set aimed at larger sharded bots.
Auto Sharding
A big motivation behind the original development of disco was to help support larger bots by providing a feature-rich toolset. The biggest tool in that set comes in this release, in the form of auto sharding. Auto sharding allows a bot developer to completely ignore the complexity of sharding, while having a stable and reliable way to roll it out. Auto sharding can be used by simply passing the --shard-auto flag at runtime.
Sharding IPC
The second big tool in our large-bot toolset comes with sharding IPC, an API for inter-shard communication. This API was built to work with auto sharding (and would require a bit of manual code to work outside of that context), and provides a very simple interface.
For example, calling a function on every shard and aggregating the result:
def on_all_shards(bot):
    return 103559217914318848 in bot.client.state.users
bot.shards.all(on_all_shards)
# {0: True, 1: True, 2: True, 3: False ,4: True ,5: True, 6: True, 7: False, 8: True, 9: True}Or, calling a function on a specific shard:
def on_shard(bot):
    return len(bot.client.state.users)
bot.shards.on(5, on_shard).wait()
# 83552Functions to be run on the shard should not have closures which bind any non-simple variables (e.g. serialize variables) and the same is true for their return values.
Plugin Context
This release introduces the concept of plugin contexts, which are just dictionaries passed from one instance of a plugin to another (during reload). The Plugin.load function is now called with its only argument being the context dictionary, and the Plugin.unload can now return a dictionary which will be passed to the Plugin.load function when reloading. Contexts are useful for storing plugin local state without using globals, and persist across reloads.
Minor Additions
- Added the bot gateway endpoint, exposed via 
APIClient.gateway_bot_get - Added typing endpoint, exposed via 
APIClient.channels_typing(channel_id). - Added the 
oobflag to the command definition, which will not track the command execution greenlet in the plugin object. This is very specifically intended for reloading the current plugin from within a command loaded from the plugin. - Added the 
conditionalargument toPlugin.listenandPlugin.listen_packetwhich allows for a callable conditional (which is checked before the event is passed on to the listener) taking the single event argument and returning a bool (true = event matches, call the event listener) - All command/listener execution greenlets are now bound to the plugin instance and will be terminated on unload
 - Added 
Client.update_presencefor updating the users presence - Added documentation for all gateway events
 - Added 
Channel.deleteandChannel.close - Added 
Guild.member_countandGuild.presencesfields (which where previously missing) - Added 
MessageTablefor building ASCII tables in messages 
Minor Changes
- SEND/RECV sentinels are now integers
 Model.to_dictnow has somewhat proper recursion and type conversion- Bumped holster to v1.0.8 for conditional predicates and some other various fixes
 
Fixes
- Fix 
APIClient.webhooks_token_deleteusing an invalid constant - Fixed the HTTP client retrying on a 400 response code
 - Fixed role mentions in bot command handling
 - Fixed newlines in command arguments not parsing correctly
 - Fixed subclassed method definitions smashing the base 
Pluginname space - Fixed bug where heartbeater tasks where not killed when the Gateway WS was closed, causing weird error spam and potentially heartbeat spam to discord.
 - Fixed missing 
guild_idonGuildBanAddandGuildIntegrationsUpdate - Fixed missing fields on 
GuildEmojisUpdate - Fixed incorrect type for 
TypingStart.timestamp - Fixed voice states not being tracked in 
State.voice_states - Fixed exception being thrown when a guild member is not in a guilds 
membersobject (onGuildMemberUpdate) - Fixed 
Channel.delete_messagesattempting to call bulk delete when it missed the required permissions to do so. It now properly falls back to individual message deletes when it cannot manage messages. - Fixed 
HashMap.filterandHashMap.mapbeing invalid 
Roadmap
V0.0.7
Full voice support
V0.0.8
A more complete API implementation for both the REST API and the Gateway API.
Some Progress
This release marks more types and APIs making their way into the library, improves performance in a few areas, adds a new custom HashMap type (replacing internal dictionaries), and various other changes/improvements/bugfixes.
Performance
This release introduces __slots__ usage on basically all stored model types. This improves memory usage, and also provides a more strict interface to the models (not allowing you to shimmy data into the model). There was also some improvements to the way gateway events are parsed which should result in faster event parsing.
Hash Map
This release also adds something very exciting, a custom dictionary type (using UserDict) which provides a whole set of utilities for working with stored data. Its easiest to see this interface with some simple examples:
guilds_with_15_users = state.guilds.find(lambda g: len(g.members) == 15)
first_guild_with_features = state.guilds.find_one(lambda g: len(g.features))
users_named_jeff = state.users.select(username="jeff")
user_named_joe = state.users.select_one(username="joe")The hash map also overrides the most common Python dict functions to behave in a Python 3 generator-fashion (e.g. values() will always return a generator).
Webhooks
A basic implementation of webhooks was also introduced. The interface to this is still rather immature, so there will likely be some change and additional helper methods soon.
The Mold Forms
This release marks the first set of solid internal API structures, that at this point are looking to make their way into the final version. There is a lot of random tidbits in here, but most of the important bits are outlined below
Big Changes
Modeling V2.0
The modeling system has been reworked to avoid magic as much as possible, while also providing a better API interface. Generally these changes should be invisible.
CLI Interface and Configuration
The command line interface has been refactored, its now geared much more towards users who want to get up and running with a simple bot quickly. Naturally, the interface was built in such a way that it shouldn't feel clunky or obtrusive to larger bot developers. 99% of users running a bot with discos builtin plugin system will now want to build a configuration file that looks something like:
token: 'MY_BOT_TOKEN'
manhole_enable: true
manhole_bind: localhost:1337
bot:
  levels:
    80351110224678912: owner
  plugins:
    - module.path.to.a.plugin.file
  storage_provider: rocksdbThis configuration can then be loaded, and the bot ran by running:
python -m disco.cli --config config.yaml
Command Changes
Commands now support a basic built-in permissions system, and some of the internal regexing was buffed to enable cool grouping abbreviation. Reloading is now fully supported, and some additional helper functions where added for loading plugins and their configurations. By default, plugin configuration is loaded from the config directory, in the format 'example.yaml' where example is parsed from ExamplePlugin. This release also includes the ability to parse user/role mentions within the argument format string.
Storage
Storage is another big feature of this release, which represents a still WIP interface that is shaping up nicely. The storage features of disco are meant to provide a simple to configure and use interface that gives developers the ability to save and query data. The storage system supports multiple storage providers (right now; memory, disk, rocksdb) and is meant more for ease of use than performance. Large bot developers will likely not want to use this for anything more than a simple key-value store.
ETC
- Its now possible to listen on both incoming and outgoing gateway packets
 - Fixes/improvements to the state module
 - More API method implementations
 - Added scheduling functionality to plugins
 
A New Hope
Version 0.0.1 marks the first official, public release of disco. This is very much an initial preview, with many missing features and likely a lot of bugs. Please open issues for anything you run across, and have fun messing with the library!