Releases: b1naryth1ef/disco
v0.0.11
Additions
- Added support for Guild audit logs, exposed via
Guild.get_audit_log_entries
,Guild.audit_log
andGuild.audit_log_iter
. For more information see theAuditLogEntry
model - Added built-in Flask HTTP server which can be enabled via
http_enabled
and configured viahttp_host
/http_port
config 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.capture
contextmanager - Added support for NSFW channels via
Channel.nsfw
andChannel.is_nsfw
- Added initial support for channel categories via
Channel.parent_id
andChannel.parent
- Added various setters for updating Channel properties, e.g.
Channel.set_topic
- Added support for audit log reasons, accessible through passing
reason
to various methods - Added
disco.util.snowflake.from_timestamp_ms
- Added support for
on_complete
callback within DCADOpusEncoderPlayable - BREAKING Added new custom queue types
BaseQueue
/PlayableQueue
for use w/Player
.queue
can be passed when creating aPlayer
, should inherit from BaseQueue- Users who previously utilized the
put
method of the oldPlayer.queue
must move to usingPlayer.queue.append
, or providing a custom queue implementation.
- Added
Emoji.custom
property
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_message
returning 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_modify
now 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
attachment
kwarg in favor of anattachments
kwarg, holding an array of attachments. channels_messages_reactions_get
supports pagination- Added
guilds_invites_list
- Added
users_me_guilds_delete
- Move to API v7, which includes new errors array. Can be viewed within an
APIException
via theerrors
property. 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
Guild
type Message.create_reaction
renamed 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-level
CLI 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_reactors
for 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_id
after 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_get
APIClient.channels_messages_reactions_create
APIClient.channels_messages_reactions_delete
MessageReaction
MessageReactionEmoji
MessageReactionAdd
MessageReactionRemove
MessageReactionRemoveAll
Message.reactions
Message.create_reaction
Message.delete_reaction
- Add support for creating a guild channel via
APIClient.guilds_channels_create
andGuild.create_channel
APIClient.guild_members_list
now returns a hash- Add
APIClient.guilds_members_roles_add
andAPIClient.guilds_members_roles_remove
for more determinisitc role adjustments - Add
APIClient.guilds_members_me_nick
for setting the current users nick - Add
GuildBan
,APIClient.guild_bans_list
now 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
guild
argument parsing type - Added tracking of spawned greenlets to plugins
- Added configuration option
max_reconnects
for 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()
# 83552
Functions 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
oob
flag 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
conditional
argument toPlugin.listen
andPlugin.listen_packet
which 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_presence
for updating the users presence - Added documentation for all gateway events
- Added
Channel.delete
andChannel.close
- Added
Guild.member_count
andGuild.presences
fields (which where previously missing) - Added
MessageTable
for building ASCII tables in messages
Minor Changes
- SEND/RECV sentinels are now integers
Model.to_dict
now 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_delete
using 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
Plugin
name 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_id
onGuildBanAdd
andGuildIntegrationsUpdate
- 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
members
object (onGuildMemberUpdate
) - Fixed
Channel.delete_messages
attempting 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.filter
andHashMap.map
being 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: rocksdb
This 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!