Changelog

This document displays the differences between each release of curious.

0.8.0

  • Add the ability to customise the context class created by commands.

  • Major: Add audit log support.

    • Add AuditLogView, AuditLogEntry, etc.
    • Add method Guild.get_audit_log_entries().
  • Allow showing help for plugins.

  • Breaking: Rename role events.

    • ROLE_CREATE -> GUILD_ROLE_CREATE
    • ROLE_UPDATE -> GUILD_ROLE_UPDATE
    • ROLE_DELETE -> ROLE_DELETE
  • Breaking: Remove the MEMBER_UPDATE event and replace it with PRESENCE_UPDATE.

  • Breaking: Rewrite for the anyio library.

    • This removes all usage of the multio library.
    • This also means that the client must be created inside an async def function, not at the top-level.
    • Whilst anyio officially supports asyncio, curious does not; no support will be offered and any bots working on asyncio are purely incidental.
  • Add curious.core.get_current_client() to get the running client.

  • Remove all references to the client from dataclasses.

    • Instead they now use a context variable to get the running client instance.
  • Remove passing around the event context explicitly.

    • Instead, curious.core.events.current_event_context() is required to get the event context.
    • This will break every single event handler.
  • Make it so that bots can automatically re-shard themselves. This ensures bots are more stable.

  • Error out with a better error if an invalid token is provided.

  • Add support for viewing flags and user premium status.

  • Add PartialEmoji when full emoji data is not available.

  • Add UserStatus for user statuses.

  • Rename Game to BasicActivity.

  • Add RichActivity.

  • Make presence games a Union of (Basic|Rich)Activity.

  • Add Presence.activities.

  • Make commands context-variable based. Context is now stored in a contextvar and not passed to commands anymore.

  • Add magic variables for Context, Context.author, Context.guild, Context.message, and Context.channel.

0.7.9 (Released 2018-08-05)

Note

This will be the final release of the 0.7 branch. If you wish to use any more fixes, install directly from git.
  • Remove Channel.connect().

  • Make PRESENCE_UPDATE handling more robust.

  • Add Guild.voice_states and make Channel.voice_members more efficient.

  • Ignore hidden standalone commands in help.

  • Fix bug showing unavailable subcommands in help.

  • Fix unload_plugins_from.

  • Prevent changing the type of an existing channel.

  • Add convenient built-in conditions.

  • Speed up event creation in internal code massively by not performing needless stack introspection.

  • Make the behaviour of *args in a command more consistent.

    • *args will now return a list of arguments.
    • *args will now call converter(token) on each token it receives as part of the arg string.
  • Fix MESSAGE_UPDATE handling to be more sane.

0.7.8 (Released 2018-05-23)

  • Fix HTTPClient.leave_guild().
  • Fix a crash on MEMBER_UPDATE packets.
  • Make mentions in DMs return correctly (and also, not crash).
  • Fix new VoiceState objects not having a client object.
  • Add the ability to move members into a different voice channel.
  • Add zlib-stream as the compression method for the gateway.

0.7.7 (Released 2018-04-04)

  • Fix trying to convert a default.
  • Add a typing.Union converter.

0.7.6 (Released 2018-04-03)

  • Fix conversion with missing arguments on positional arguments.
  • Unwrap Nickname objects in the nickname setter.
  • Pass the value, not the Nickname object, to the nickname setter.

0.7.5 (Released 2018-04-01)

  • Don’t crash when trying to fill in guild fields without a cached guild.

0.7.4 (Released 2018-03-27)

  • Fix for negative ratelimit sleep times.
  • Don’t crash when copying a nickname incorrectly.

0.7.3 (Released 2018-03-27)

  • Don’t immediately disconnect on boot.

0.7.2 (Released 2018-03-27)

  • Changed Nickname to be a proper object, and not a string wrapper.
  • Fix Member.roles._sorted_roles to sort in reverse order.
  • Attempt at adding better reconnect logic.

0.7.1 (Released 2018-03-12)

  • Fixed Channel.permissions() (thanks PyCharm)

0.7.0 (Released 2018-03-11)

  • Add get-by-name to GuildChannelWrapper, and GuildRoleWrapper.

  • Add Invite.features.

  • Add GameType for game types.

  • Make Invite.inviter a property that returns a Member if one can be found.

  • Remove Client.boot_shard() amongst others, and create Client.handle_shard() to do all gateway-related handling functions.

  • Add Channel.overwrites for a key-value mapping of overwrites.

  • Add Nickname, and make Member.nickname an instance of Nickname.

  • Add EventManager.wait_for_manager().

  • Rename MEMBER_ events to GUILD_MEMBER_ events.

  • Add _MemberRoleContainer, and make Member.roles an instance of this.

  • Add Message.emojis.

  • Add ChannelMessagesWrapper, and move everything to point to it.

  • Rewrite the gateway code significantly.

    • Use Lomond in a thread instead of our own wrapper.
    • Make opening a gateway a context manager.
    • Use proper dataclasses for state.
  • Add AvatarUrl.

  • Add GuildBan, and make Guild.get_bans() return a list of those.

  • Move Guild._splash_hash and Guild._icon_hash to public attributes.

  • Add a permissions.pyi file for static introspection of the permissions class.

  • Add a GuildBanContainer.

  • Enable trio support.

  • Add autoplugin() which automatically assigns commands inside a plugin.

  • Add Plugin.spawn() for easy background task spawning.

  • Add Channel.children to get the children of a channel.

  • Deprivatize State.find_message().

  • Lookup messages in the cache to avoid a roundtrip when doing ChannelMessagesWrapper.get().

0.6.0 (Released 2017-11-05)

  • Bring voice code inline with the standard of the rest of the code.

    • Change the voice gateway to use an async thread, rather than a regular thread.
    • Document and make public VoiceClient.get_packet_header(), VoiceClient.get_voice_packet() and VoiceClient.get_ip_discovery_packet().
  • Make AppInfo a subclass of Dataclass.

  • Only sleep on shard creation until the last shard.

  • Move Channel.is_private() to Channel.private().

  • Move IDObject.timestamp() to IDObject.snowflake_timestamp().

  • Make some things use ID references rather than object references, and deprivatize the ID attributes on these objects.

  • Add support for channel categories in the API and the gateway.

  • Reorganize commands code significantly:

    • Move all of the commands code out of Client.
    • Add new CommandsManager.
    • Overhaul Context to do more, such as the actual processing.
    • Remove Command in favour of annotated functions.
  • Reorganize events code significantly:

    • Move all the events code out of Client.
    • Add new EventManager.
    • Add event hooks, which are called with every event the bot receives.
    • Overhaul EventManager.wait_for() so that it uses curio.Promise rather than terrible events.
    • Change temporary listeners to raising ListenerExit instead of returning a truthy/falsey value.
  • Reboot shards properly when they disconnect, using a while True loop inside the TaskGroup.

  • Add State.guilds_ordered.

  • Add a 5 second timeout to each request made.

  • Add Message.get_invites() and Message.invites to get invites that are inside a message object.

  • Retry on h11 errors.

  • Use asyncwebsockets instead of cuiows.

  • ReactionPaginator can now have an optional title that is added as the content for the message sent.

0.5.1 (Released 2017-08-19)

  • Switch to the asks HTTP library over the bundled HTTP library.
  • Add MessageType.
  • Add ChannelType.CATEGORY.
  • Separate out HTTP URLs into a Endpoints class.
  • Properly wait on shards in the start handler.

0.5.0 (Released 2017-07-31)

Warning

This is the last version of curious that supports Python 3.5.

  • Add HTTPClient.get_audit_logs().

  • Add gateway event dispatching.

  • Add HTTPClient.get_vanity_url() and HTTPClient.edit_vanity_url().

  • Add Guild.get_vanity_invite() and Guild.set_vanity_invite().

  • Guild.get_invites() will now return the vanity invite, if applicable.

  • Rearrange guild objects somewhat:

    • Turn Guild.channels into a GuildChannelWrapper.
    • Turn Guild.roles into a GuildRoleWrapper.
    • Move Guild.create_channel() to GuildChannelWrapper.create().
    • Move Guild.edit_channel() to Channel.edit().
    • Move Guild.delete_channel() to Channel.delete().
    • Move Guild.create_role() to GuildRoleWrapper.create().
    • Move Guild.edit_role() to Role.edit().
    • Move Guild.delete_role() to Role.delete().
  • Add a message_mentioned event.

  • Add User.static_avatar_url.

  • Guild.large now obeys a custom large_threshold.

  • Add counts to guild_chunk and guild_sync events.

  • Fix editing profile via User.edit().

  • Add HTTPClient.get_user_applications() and HTTPClient.get_application().

  • Don’t include @everyone when calculating role colours.

0.4.0 (Released 2017-04-27)

  • VoiceState now uses a property reference to the User object.

  • Add HTTPClient.get_mentions().

  • Add BotUser.authorized_apps which returns an async iterator that can be used to get the authorized apps for this bot.

  • Add BotUser.get_recent_mentions() and Guild.get_recent_mentions() to allow easy iteration of recent mentions.

  • Change statuses to new Presence, which are stored on Member and RelationshipUser instances.

  • Guild._large is now set by GUILD_SYNC handling for userbots.

  • Optimize State.make_message() slightly, by checking the cache before editing it.

  • _prepare_request() automatically stringifies all items in the query string before sending it.

  • Add search support:

    • HTTPClient.search_channel() and HTTPClient.search_guild() are the raw HTTP methods for searching.
    • SearchQuery, SearchResults and MessageGroup are the high level wrappers for searching.
  • Add AsyncIteratorWrapper.next() and AsyncIteratorWrapper.all().

  • Change Guild objects on dataclasses to mostly look up via property or weak reference rather than having a strong reference.

  • Change commands:

    • A callable that takes (bot, message) and returns (a) prefix(es) to match can now be provided for command_prefix.
    • Functions are unwrapped for the .factory attr if possible.
  • Add the ability to listen to multiple events with one function.

  • Add MFALevel, VerificationLevel, NotificationLevel, ContentFilterLevel, and update the relevant attributes on Guild.

  • Add HTTP downloading methods to Client.

  • Add Channel.nsfw.

0.3.0 (Released 2017-03-10)

  • Client.start() will now automatically reboot shards that return.

  • Add HTTPClient.get_authorized_apps() to get the authorized apps for this account.

  • Add HTTPClient.revoke_authorized_app() to revoke an application’s authorization.

  • Add BotUser.get_authorized_apps() as the high-level equivalent.

  • Add Message.channel_id and Message.author_id to access the raw IDs from Discord, even if the message author or channel is not cached.

  • Unprivatize State.find_channel() and add Client.find_channel() to use this method.

  • Unprivatize State.is_ready().

  • Change sharding slightly:

    • Client.boot_shard() will boot one shard and add its gateway to the internal list. This will allow finer control over shard booting.
    • Client.start() will now use boot_shard to load a shard, so overriding it in a subclass can customize shard creation.
  • The client will now wait for the gateway to be ready before firing any events.

  • Add BotType to more finely control how bots are defined.

  • Add EventContext.event_name, EventContext.handlers.

  • Add Client.events_handled and Gateway._dispatches_handled to show how many events have been handled during the lifetime of the bot.

  • Add GuildStore which tracks the order of guilds for user bots, and can be used to return the guilds in that order.

  • Change Channel for group DMs slightly:

    • New attributes have been added: Channel.owner, Channel.owner_id, Channel._icon_hash, Channel.icon_url.
    • Channel._recipients has been added to replace recipients as the backing store, and is now a dict.
    • Correspondingly, Channel.recipients is a mapping proxy for Channel._recipients, and can be used to access the recipients of the channel.
  • Add HTTPClient.update_user_settings() to update the settings of a user.

  • Add UserSettings to represent the settings of a user.

  • Add event handler for USER_SETTINGS_UPDATE.

0.2.1 (Released 2017-02-23)

  • Sync/chunk guilds when a GUILD_CREATE is received during the main bot lifecycle.
  • Decache users automatically when a GUILD_DELETE is received.
  • Fix the default role not being accounted for in permissions.
  • Fix GUILD_ROLE_DELETE handling.
  • Fix async threads hanging the bot on shutdown.
  • Add the ability to set afk in a presence change, to allow self-bots to not eat notifications.
  • Userbots will now ask for member chunks and then sync guilds once all chunks are received.
  • Make Guild.large a property rather than an attribute. Discord doesn’t always send this properly, so fallback to member_count >= 250.

0.2.0 (Released 2017-02-20)

  • Add user account logging in support.

  • Add _friends and _blocked to State to represent the friends and blocked users a client has.

  • Add friends and blocked properties to BotUser which can be used to access the State’s attributes.

  • Add a new type called RelationshipUser which represents either a friend or a blocked user.

  • Rearrange channel and guild handling in READY parsing.

  • Fix author inside private DMs being wrong sometimes.

  • Allow group DMs to work properly.

  • User cache has been redesigned:

    • Users are now cached indefinitely in _users.
    • Users are referred to by property on Member rather than by storing them. This should reduce some memory usage as duplicate members will no longer store multiple instances of a user.
    • Users are only decached on a guild member remove.
  • State.make_user() now takes a user_klass param which allows customization of the user class created when caching a user.

  • Users are now updated in PRESENCE_UPDATE rather than GUILD_MEMBER_UPDATE.

  • GUILD_SYNC is now supported for user bots.

  • Creating HTTPClient with bot=False will send a user authorization header rather than a bot authorization header.

  • Add HTTPClient.get_user_profile() to get a user’s profile.

  • Add HTTPClient.get_app_info() to get the application information for a specific app. This method will attempt to download the bot information alongside the app - failing this, it will only request the basic app info scope.

  • Remove HTTPClient.get_application_info(); call get_app_info with None to get the current app’s info.

  • Add HTTPClient.authorize_bot() to authorize a bot into a guild.

  • Move AppInfo into its own module.

  • Make AppInfo more useful than just the current application’s info.

  • Add bot attribute to AppInfo which returns the bot user associated with this app.

  • Add AppInfo.add_to_guild() which authorizes a bot into a guild. Only user accounts can call this.

  • Add Client.get_application() to get an AppInfo object referring to an application.

  • Add HTTPClient.send_friend_request(), HTTPClient.remove_relationship(), HTTPClient.block_user() for editing relationships with users.

  • Add User.send_friend_request(), User.block(), RelationshipUser.remove_friend() and RelationshipUser.unblock() to manage relationships between users.

  • BotUser cannot send friend requests to itself or block itself.

  • Add User.get_profile() to get a user’s profile.

  • Embed.set_image() now validates that the link is a HTTP[S] link.

0.1.4

  • Add Widget for support of widgets.
  • Add widget support inside the HTTPClient.
  • Fix events inside plugins.
  • Add new error code mapping to HTTPException. This provides clearer display as to what went wrong when performing a HTTP method.