* Resolve dictionary changed size during iteration while converting levels mapping and remove non-converted entry to avoid duplicate entires (str and int index).
Add default for premium sub count.
* Update disco/bot/bot.py
Co-Authored-By: Andrei Zbikowski <[email protected]>
* Patch get_icon_url
Nice try, but don't copy+paste without testing whomever PR'd this 😉
* Patch status in update_presence payload
No more Enum, no more `.value`
* Added end points + fixed typo
* mixup fixed
* oauth user add
* typo
* removed "return User.create(self.client, r.json())" from guilds_members_add due to lack of json response when user already in guild and switched name to mandatory arg in guilds_create
* formatting + removed roles/channels in guilds_create
* formatting 2.0, with even less random spaces
* remove guild.create on guilds_delete as no content is returned by Discord's api + reinstate roles and channels in guild_create
* spaces v tabs... FIGHT
* disco/api/client.py:410:9: F841
* Update client.py
* naming and create guilds args
This commit cleans up a mess I created when I originally added the
`Guild.sync` functionality. The original intention of this function
was to provide a simple interface to ensuring the local state of a
guild was "up to date". This abstraction turned out to be a bad idea
for the following reasons;
- Its completely unclear what "sync" means in the context of a Guild.
Hiding the way syncing guild members works (which is a pretty "developer
unfriendly" as it is) just results in more confusion for very little
value.
- Discord technically supports sending multiple guild ids in a single
`REQUEST_GUILD_MEMBERS` op which this interface didn't support or
handle. Using this function as it was intended on a largeish bot would
result in your gateway client getting rate limited for quite a bit on
startup (which is lame).
- This implementation of guild member syncing resulted in a `synced`
flag on guilds, which is basically completely useless and doesn't mean
anything much at all (since REQUEST_GUILD_MEMBERS is purely async and
there is no correct way to confirm a request was fulfilled.
To cleanup this mess I've made the following changes;
- Entirely deprecate `Guild.sync`. This is just a bad function name and
should die in a fire to save our future children from pain and
frustration.
- Add `Guild.request_guild_members`. This function now properly conveys
what it does and provides a more correct interface to this Discord
functionality (nb: Guild.sync now calls this function, which does not
prevent multiple calls from firing requests).
- Add `GatewayClient.request_guild_members`. This function provides an
alternative interface for sending the request guild members op without
low-level GatewayClient interfacing. Ideally users who need to avoid
being rate limited and/or want better guild member syncing performance
can use this function which accepts multiple guild ids.
TL;DR;
- If you don't call `Guild.sync`; you don't need to worry about
anything.
- If you call `Guild.sync` anywhere at all and you don't really care
about the performance impact of syncing guild members one-by-one; just
change your code to call `Guild.request_guild_members`.
- If you call `Guild.sync` in a `GUILD_CREATE` handler or you care about
the performance impact of syncing multiple Guilds; move to using the
underlying GatewayClient interface and sync multiple guilds at once
(likely in batches).
Previously to update a role you would update attributes of the role
object, and then call save. This was very much an anti-pattern when
compared to the way things work elsewhere, and had the following
annoyances attached to it;
- Updating attributes of the object actually smashes state, we aren't
guarenteed that the user will call save nor that the API will accept our
save, and thus attributes on the object (which could be shared within
the state module) are smashed and innaccurate.
- Guild.update_role is effectively useless in this case, we can only
ever pass a role object in. This makes partial updates impossible, and
forces us to match the OO interface to use it.
The new style follows along with how we do things elsewhere, there is
still likely some additional work that can be done here to allow passing
in the role, but for now we'll just call this a deprecation
This commit is a fairly large chunk of code that fixes a previously
annoying and nasty bug causing cached_properties to not be cleared.
Alongside this bug fix I took the opportunity to refactor the entire
methdology behind cached properties, and bind them more strictly to the
behavior of models.
Prior to this commit, cached_properties where not be properly reset upon
a model's `update` method being called due to some invalid code. Along
with this issue, the actual behavior of cached properties landed in a
weird in-between/gray area where they had to support both non-model and
model use cases.
The new version of cached_property is strictly for use with models, and
another version `simple_cached_property` was added to support other use
cases. The new cached_property simply builds an actual `property` within
the metaclass. This is fairly efficient, and also reduces the surface
area of behavior.
When writing this I messed around with a few ideas, including allowing
the user of `cached_property` to define a linkage between the property
and fields that should invalidate its cached value, but this was both
messy and introduced massive cognitive load on understand when a
cached_property should be cleared. Although this version is slighty less
efficient, I'm very much in favor of it vs the alternatives I tried.
For some reason when I initially built disco I made these types binary.
They are not binary. They are ascii hash-strings. So lets make them
strings. This fixes the Python 3 oddities described in #29 related to
formatting byte strings into normal strings.
There where various oddities and bugs here, namely:
- Guild kept its initial `presences` list even though this is basically
useless, and was never kept up-to-date
- State did not properly use all the fields of presence_update, and was
creating some annoying recursive oddities w/ user and presence binding