diff --git a/litecord/blueprints/guild/emoji.py b/litecord/blueprints/guild/emoji.py index db53c07..9f6bcf2 100644 --- a/litecord/blueprints/guild/emoji.py +++ b/litecord/blueprints/guild/emoji.py @@ -105,7 +105,7 @@ async def _put_emoji(guild_id): size=(128, 128), ) - if not icon: + if icon is None: return "", 400 # TODO: better way to detect animated emoji rather than just gifs, @@ -172,10 +172,11 @@ async def _del_emoji(guild_id, emoji_id): await app.db.execute( """ DELETE FROM guild_emoji - WHERE id = $2 + WHERE id = $1 """, emoji_id, ) await _dispatch_emojis(guild_id) return "", 204 + diff --git a/litecord/blueprints/guild/roles.py b/litecord/blueprints/guild/roles.py index 1709756..ce39197 100644 --- a/litecord/blueprints/guild/roles.py +++ b/litecord/blueprints/guild/roles.py @@ -65,7 +65,7 @@ async def _role_update_dispatch(role_id: int, guild_id: int): """Dispatch a GUILD_ROLE_UPDATE with updated information on a role.""" role = await app.storage.get_role(role_id, guild_id) - await maybe_lazy_guild_dispatch(guild_id, "role_pos_upd", role) + await maybe_lazy_guild_dispatch(guild_id, "role_position_update", role) await app.dispatcher.guild.dispatch( guild_id, ("GUILD_ROLE_UPDATE", {"guild_id": str(guild_id), "role": role}) @@ -170,7 +170,8 @@ def gen_pairs( } for blacklisted_id in blacklist: - preferred_state.pop(blacklisted_id) + if blacklisted_id in preferred_state.keys(): + preferred_state.pop(blacklisted_id) # for each change, we must find a matching change # in the same list, so we can make a swap pair @@ -310,3 +311,4 @@ async def delete_guild_role(guild_id, role_id): ) return "", 204 + diff --git a/litecord/blueprints/guilds.py b/litecord/blueprints/guilds.py index 546fe01..4b88a7b 100644 --- a/litecord/blueprints/guilds.py +++ b/litecord/blueprints/guilds.py @@ -297,12 +297,19 @@ async def _update_guild(guild_id): await _guild_update_icon("banner", guild_id, j["banner"]) + if to_update(j, guild, "discovery_splash"): + if not await app.storage.has_feature(guild_id, "PUBLIC"): + raise BadRequest("guild does not have PUBLIC feature") + + await _guild_update_icon("discovery_splash", guild_id, j["discovery_splash"]) + fields = [ "verification_level", "default_message_notifications", "explicit_content_filter", "afk_timeout", "description", + "preferred_locale", ] for field in [f for f in fields if f in j]: @@ -316,9 +323,9 @@ async def _update_guild(guild_id): guild_id, ) - channel_fields = ["afk_channel_id", "system_channel_id"] + channel_fields = ["afk_channel_id", "system_channel_id", "rules_channel_id", "public_updates_channel_id"] for field in [f for f in channel_fields if f in j]: - # setting to null should remove the link between the afk/sys channel + # setting to null should remove the link between the afk/sys/rules/public updates channel # to the guild. if j[field] is None: await app.db.execute( @@ -332,7 +339,7 @@ async def _update_guild(guild_id): continue - chan = await app.storage.get_channel(int(j[field])) + chan = await app.storage.get_channel(j[field]) if chan is None: raise BadRequest("invalid channel id") @@ -346,7 +353,7 @@ async def _update_guild(guild_id): SET {field} = $1 WHERE id = $2 """, - j[field], + int(j[field]), guild_id, ) diff --git a/litecord/blueprints/icons.py b/litecord/blueprints/icons.py index a01509e..9f4dbb5 100644 --- a/litecord/blueprints/icons.py +++ b/litecord/blueprints/icons.py @@ -31,7 +31,7 @@ async def send_icon(scope, key, icon_hash, **kwargs): """Send an icon.""" icon = await app.icons.generic_get(scope, key, icon_hash, **kwargs) - if not icon: + if icon is None: return "", 404 return await send_file(icon.as_path) @@ -44,8 +44,6 @@ def splitext_(filepath): @bp.route("/emojis/", methods=["GET"]) async def _get_raw_emoji(emoji_file): - # emoji = app.icons.get_emoji(emoji_id, ext=ext) - # just a test file for now emoji_id, ext = splitext_(emoji_file) return await send_icon("emoji", emoji_id, None, ext=ext) @@ -110,3 +108,8 @@ async def _get_guild_splash(guild_id: int, icon_file: str): async def _get_guild_banner(guild_id: int, icon_file: str): icon_hash, ext = splitext_(icon_file) return await send_icon("banner", guild_id, icon_hash, ext=ext) + +@bp.route("/discovery-splashes//", methods=["GET"]) +async def _get_discovery_splash(guild_id: int, icon_file: str): + icon_hash, ext = splitext_(icon_file) + return await send_icon("discovery_splash", guild_id, icon_hash, ext=ext) \ No newline at end of file diff --git a/litecord/common/guilds.py b/litecord/common/guilds.py index 25fe555..a45784d 100644 --- a/litecord/common/guilds.py +++ b/litecord/common/guilds.py @@ -158,7 +158,7 @@ async def _subscribe_users_new_channel(guild_id: int, channel_id: int) -> None: continue perms = await get_permissions(state.user_id, channel_id) - if perms.read_messages: + if perms.bits.read_messages: users_to_sub.append(state.user_id) for session_id in app.dispatcher.guild.state[guild_id]: diff --git a/litecord/enums.py b/litecord/enums.py index 0a2ddf3..78a394b 100644 --- a/litecord/enums.py +++ b/litecord/enums.py @@ -242,6 +242,7 @@ class Feature(EasyEnum): vanity = "VANITY_URL" emoji = "MORE_EMOJI" verified = "VERIFIED" + public = "PUBLIC" # unknown commerce = "COMMERCE" diff --git a/litecord/images.py b/litecord/images.py index 6b01327..97e9d92 100644 --- a/litecord/images.py +++ b/litecord/images.py @@ -181,6 +181,7 @@ def _gen_update_sql(scope: str) -> str: "user": "avatar", "guild": "icon", "splash": "splash", + "discovery_splash": "discovery_splash", "banner": "banner", "channel-icons": "icon", }[scope] @@ -189,6 +190,7 @@ def _gen_update_sql(scope: str) -> str: "user": "users", "guild": "guilds", "splash": "guilds", + "discovery_splash": "guilds", "banner": "guilds", "channel-icons": "group_dm_channels", }[scope] @@ -333,7 +335,7 @@ class IconManager: *args, ) - if not icon_row: + if icon_row is None: return None icon = Icon(icon_row["key"], icon_row["hash"], icon_row["mime"]) @@ -371,9 +373,6 @@ class IconManager: # get an extension for the given data uri extension = get_ext(mime) - if "bsize" in kwargs and len(raw_data) > kwargs["bsize"]: - return _invalid(kwargs) - # size management is different for gif files # as they're composed of multiple frames. if "size" in kwargs and mime == "image/gif": @@ -529,3 +528,4 @@ class IconManager: await self.delete(old_icon) return await self.put(scope, key, new_icon_data, **kwargs) + diff --git a/litecord/schemas.py b/litecord/schemas.py index 1d65837..1dc35b1 100644 --- a/litecord/schemas.py +++ b/litecord/schemas.py @@ -287,11 +287,15 @@ GUILD_UPDATE = { "verification_level": {"type": "verification_level", "required": False}, "default_message_notifications": {"type": "msg_notifications", "required": False}, "explicit_content_filter": {"type": "explicit", "required": False}, - "afk_channel_id": {"type": "snowflake", "required": False, "nullable": True}, + "afk_channel_id": {"type": "snowflake", "coerce": int, "required": False, "nullable": True}, "afk_timeout": {"type": "number", "required": False}, - "owner_id": {"type": "snowflake", "required": False}, - "system_channel_id": {"type": "snowflake", "required": False, "nullable": True}, + "owner_id": {"type": "snowflake", "coerce": int, "required": False}, + "system_channel_id": {"type": "snowflake", "coerce": int, "required": False, "nullable": True}, "features": {"type": "list", "required": False, "schema": {"type": "string"}}, + "rules_channel_id": {"type": "snowflake", "coerce": int, "required": False, "nullable": True}, + "public_updates_channel_id": {"type": "snowflake", "coerce": int, "required": False, "nullable": True}, + "preferred_locale": {"type": "string", "required": False, "nullable": True}, + "discovery_splash": {"type": "string", "required": False, "nullable": True}, } diff --git a/litecord/storage.py b/litecord/storage.py index 4c22980..6d70f99 100644 --- a/litecord/storage.py +++ b/litecord/storage.py @@ -201,8 +201,8 @@ class Storage: explicit_content_filter, mfa_level, embed_enabled, embed_channel_id::text, widget_enabled, widget_channel_id::text, - system_channel_id::text, features, - banner, description + system_channel_id::text, rules_channel_id::text, public_updates_channel_id::text, features, + banner, description, preferred_locale, discovery_splash FROM guilds WHERE guilds.id = $1 """, @@ -1310,5 +1310,6 @@ class Storage: """, guild_id, ) - + if features is None: + return False return feature.upper() in features diff --git a/manage/cmd/migration/scripts/5_add_rules_channel_id.sql b/manage/cmd/migration/scripts/5_add_rules_channel_id.sql new file mode 100644 index 0000000..25845da --- /dev/null +++ b/manage/cmd/migration/scripts/5_add_rules_channel_id.sql @@ -0,0 +1 @@ +ALTER TABLE guilds ADD COLUMN rules_channel_id bigint; \ No newline at end of file diff --git a/manage/cmd/migration/scripts/6_add_public_updates_channel_id.sql b/manage/cmd/migration/scripts/6_add_public_updates_channel_id.sql new file mode 100644 index 0000000..3c8b72a --- /dev/null +++ b/manage/cmd/migration/scripts/6_add_public_updates_channel_id.sql @@ -0,0 +1 @@ +ALTER TABLE guilds ADD COLUMN public_updates_channel_id bigint; \ No newline at end of file diff --git a/manage/cmd/migration/scripts/7_add_prefered_locale.sql b/manage/cmd/migration/scripts/7_add_prefered_locale.sql new file mode 100644 index 0000000..ce76150 --- /dev/null +++ b/manage/cmd/migration/scripts/7_add_prefered_locale.sql @@ -0,0 +1 @@ +ALTER TABLE guilds ADD COLUMN preferred_locale text; \ No newline at end of file diff --git a/manage/cmd/migration/scripts/8_add_discovery_splash.sql b/manage/cmd/migration/scripts/8_add_discovery_splash.sql new file mode 100644 index 0000000..405b864 --- /dev/null +++ b/manage/cmd/migration/scripts/8_add_discovery_splash.sql @@ -0,0 +1 @@ +ALTER TABLE guilds ADD COLUMN discovery_splash text; \ No newline at end of file