diff --git a/litecord/blueprints/guild/mod.py b/litecord/blueprints/guild/mod.py index 92a427f..0e8c817 100644 --- a/litecord/blueprints/guild/mod.py +++ b/litecord/blueprints/guild/mod.py @@ -3,6 +3,8 @@ from quart import Blueprint, request, current_app as app, jsonify from litecord.blueprints.auth import token_check from litecord.blueprints.checks import guild_owner_check +from litecord.schemas import validate, GUILD_PRUNE + bp = Blueprint('guild_moderation', __name__) @@ -110,3 +112,50 @@ async def remove_ban(guild_id, banned_id): }) return '', 204 + + +async def get_prune(guild_id: int, days: int) -> list: + """Get all members in a guild that: + + - did not login in ``days`` days. + - don't have any roles. + """ + # a good solution would be in pure sql. + member_ids = await app.storage.fetch(f""" + SELECT id + FROM users + JOIN members + ON member.guild_id = $1 AND member.user_id = users.id + WHERE users.last_session < (now() - (interval '{days} days')) + """, guild_id) + + member_ids = [r['id'] for r in member_ids] + members = [] + + for member_id in member_ids: + role_count = await app.db.fetchval(""" + SELECT COUNT(*) + FROM member_roles + WHERE guild_id = $1 AND user_id = $2 + """, guild_id, member_id) + + if role_count == 0: + members.append(member_id) + + return members + + +@bp.route('//prune', methods=['GET']) +async def get_guild_prune_count(guild_id): + user_id = await token_check() + + # TODO: check KICK_MEMBERS + await guild_owner_check(user_id, guild_id) + + j = validate(await request.get_json(), GUILD_PRUNE) + days = j['days'] + member_ids = await get_prune(guild_id, days) + + return jsonify({ + 'pruned': len(member_ids), + }) diff --git a/litecord/blueprints/users.py b/litecord/blueprints/users.py index 8ab4706..49d8cb6 100644 --- a/litecord/blueprints/users.py +++ b/litecord/blueprints/users.py @@ -219,9 +219,11 @@ async def get_me_guilds(): partial = await app.db.fetchrow(""" SELECT id::text, name, icon, owner_id FROM guilds - WHERE guild_id = $1 + WHERE guilds.id = $1 """, guild_id) + partial = dict(partial) + # TODO: partial['permissions'] partial['owner'] = partial['owner_id'] == user_id partial.pop('owner_id') diff --git a/litecord/schemas.py b/litecord/schemas.py index 822e7b6..182420c 100644 --- a/litecord/schemas.py +++ b/litecord/schemas.py @@ -508,3 +508,7 @@ GUILD_SETTINGS = { 'required': False, } } + +GUILD_PRUNE = { + 'days': {'type': 'number', 'coerce': int, 'min': 1} +} diff --git a/run.py b/run.py index e52002b..2144937 100644 --- a/run.py +++ b/run.py @@ -19,7 +19,7 @@ from litecord.blueprints import ( # for code readability if people want to dig through # the codebase. from litecord.blueprints.guild import ( - guild_roles, guild_members, guild_channels, mod + guild_roles, guild_members, guild_channels, guild_mod ) from litecord.gateway import websocket_handler @@ -65,8 +65,7 @@ bps = { guild_roles: '/guilds', guild_members: '/guilds', guild_channels: '/guilds', - # mod for moderation - mod: '/guilds', + guild_mod: '/guilds', channels: '/channels', webhooks: None,