async def get_member_activity(ctx, member_db, count=250, full_sync=False, mode=0): platform_id, member_id, _ = get_primary_membership(member_db) characters = await get_characters(ctx, member_id, platform_id) if not characters: log.error(f"Could not get character data for {platform_id}-{member_id} - {characters}") else: return await get_activity_list(ctx, platform_id, member_id, characters, count, full_sync, mode)
async def get_inactive_members(self, ctx, clan_db): inactive_members_filtered = [] query = Role.filter(guild__guild_id=ctx.guild.id, is_protected_clanmember=True) protected_roles = [role.role_id for role in await query] inactive_members = await self.bot.database.get_clan_members_inactive(clan_db) if len(inactive_members) > 0: for clanmember in inactive_members: time_delta = ( datetime.now(pytz.utc) - clanmember.last_active ).total_seconds() platform_id, membership_id, username = get_primary_membership( clanmember.member ) member_discord = ctx.guild.get_member(clanmember.member.discord_id) if member_discord: member_roles = [role.id for role in member_discord.roles] if any(role in protected_roles for role in member_roles): continue inactive_members_filtered.append( (time_delta, platform_id, membership_id, username) ) inactive_members_filtered.sort(reverse=True) return inactive_members_filtered
async def get_inactive_members(self, ctx, clan_db): inactive_members_filtered = [] # pylama:ignore=E712 query = Role.select().join( Guild).where((Guild.guild_id == ctx.guild.id) & (Role.is_protected_clanmember == True)) protected_roles = [ role.role_id for role in await self.bot.database.execute(query) ] inactive_members = await self.bot.database.get_clan_members_inactive( clan_db.id) if len(inactive_members) > 0: for member in inactive_members: time_delta = (datetime.now(pytz.utc) - member.clanmember.last_active).total_seconds() platform_id, membership_id, username = get_primary_membership( member) member_discord = ctx.guild.get_member(member.discord_id) if member_discord: member_roles = [role.id for role in member_discord.roles] if any(role in protected_roles for role in member_roles): continue inactive_members_filtered.append( (time_delta, platform_id, membership_id, username)) inactive_members_filtered.sort(reverse=True) return inactive_members_filtered
async def get_last_active(ctx, member_db=None, platform_id=None, member_id=None): acct_last_active = None if member_db and not platform_id and not member_id: platform_id, member_id, _ = get_primary_membership(member_db) profile = await execute_pydest( ctx["destiny"].api.get_profile, platform_id, member_id, [constants.COMPONENT_PROFILES], return_type=DestinyProfileResponse, ) if not profile.response: log.error( f"Could not get character data for {platform_id}-{member_id}: {profile.message}" ) else: acct_last_active = profile.response.profile.data.date_last_played log.debug( f"Found last active date for {platform_id}-{member_id}: {acct_last_active}" ) return acct_last_active
async def kick(self, ctx, *args): manager = MessageManager(ctx) username = '******'.join(args) admin_db = await self.bot.database.get_member_by_discord_id( ctx.author.id) member_db = await self.get_member_db(ctx, username, include_clan=True) if not member_db: return await manager.send_and_clean( f"Could not find username `{username}`") platform_id, membership_id, username = get_primary_membership( member_db) confirm = { constants.EMOJI_CHECKMARK: True, constants.EMOJI_CROSSMARK: False } confirm_res = await manager.send_message_react( f"Kick **{username}**?", reactions=confirm.keys(), clean=False) if confirm_res == constants.EMOJI_CROSSMARK: return await manager.send_and_clean("Canceling command") await execute_pydest_auth(self.bot.ext_conns, self.bot.destiny.api.group_kick_member, admin_db, manager, group_id=admin_db.clanmember.clan.clan_id, membership_type=platform_id, membership_id=membership_id, access_token=admin_db.bungie_access_token) await self.bot.database.delete(member_db.clanmember) return await manager.send_message( f"Member **{username}** has been kicked from {admin_db.clanmember.clan.name}" )
async def ack_clan_application(ctx, payload): is_approved = payload.emoji.name == constants.EMOJI_CHECKMARK approver_id = payload.user_id message_id = payload.message_id approver_user = payload.member guild = approver_user.guild try: # pylama:ignore=E712 query = ClanMemberApplication.select().join( MemberDb).where((ClanMemberApplication.message_id == message_id) & (ClanMemberApplication.approved == False)) application_db = await ctx.ext_conns['database'].get(query) except DoesNotExist: return try: approver_db = await ctx.ext_conns['database'].get( MemberDb.select( MemberDb, ClanMember, Clan).join(ClanMember).join(Clan).where( (ClanMember.member_type >= constants.CLAN_MEMBER_ADMIN) & (MemberDb.discord_id == approver_id))) except DoesNotExist: raise InvalidAdminError application_db.approved = is_approved application_db.approved_by_id = approver_db.id await ctx.ext_conns['database'].update(application_db) admin_channel = ctx.get_channel( ctx.guild_map[payload.guild_id].admin_channel) applicant_user = guild.get_member(application_db.member.discord_id) if is_approved: ack_message = 'Approved' else: ack_message = 'Denied' admin_message = await admin_channel.send( f"Application for {applicant_user.display_name} was {ack_message} by {approver_user.display_name}." ) await applicant_user.send( f"Your application to join {approver_db.clanmember.clan.name} has been {ack_message}." ) if is_approved: admin_context = await ctx.get_context(admin_message) manager = MessageManager(admin_context) platform_id, membership_id, username = get_primary_membership( application_db.member) res = await execute_pydest_auth( ctx.ext_conns, ctx.ext_conns['destiny'].api.group_approve_pending_member, approver_db, manager, group_id=approver_db.clanmember.clan.clan_id, membership_type=platform_id, membership_id=membership_id, message=f"Join my clan {approver_db.clanmember.clan.name}!", access_token=approver_db.bungie_access_token) if res.error_status == 'ClanTargetDisallowsInvites': message = f"User **{applicant_user.display_name}** ({username}) has disabled clan invites" elif res.error_status != 'Success': message = f"Could not invite **{applicant_user.display_name}** ({username})" log.info( f"Could not invite '{applicant_user.display_name}' ({username}): {res}" ) else: message = ( f"Invited **{applicant_user.display_name}** ({username}) " f"to clan **{approver_db.clanmember.clan.name}**") await manager.send_message(message, mention=False, clean=False) await ctx.ext_conns['redis_cache'].delete( f'{ctx.guild.id}-clan-application-{application_db.member_id}')
async def ack_clan_application(ctx, payload): is_approved = payload.emoji.name == constants.EMOJI_CHECKMARK approver_id = payload.user_id message_id = payload.message_id approver_user = payload.member guild = approver_user.guild application_db = await ClanMemberApplication.get_or_none( message_id=message_id, approved=False).prefetch_related("member") if not application_db: log.debug(f"Application not found for {payload}") return approver_db = await ClanMember.get_or_none( member_type__gte=constants.CLAN_MEMBER_ADMIN, member__discord_id=approver_id).prefetch_related("member", "clan") if not approver_db: raise InvalidAdminError application_db.approved = is_approved application_db.approved_by_id = approver_db.member.id admin_channel = ctx.get_channel( ctx.guild_map[payload.guild_id].admin_channel) applicant_user = guild.get_member(application_db.member.discord_id) if is_approved: ack_message = "Approved" else: ack_message = "Denied" admin_message = await admin_channel.send( f"Application for {applicant_user.display_name} was {ack_message} by {approver_user.display_name}." ) await applicant_user.send( f"Your application to join {approver_db.clan.name} has been {ack_message}." ) if is_approved: admin_context = await ctx.get_context(admin_message) manager = MessageManager(admin_context) platform_id, membership_id, username = get_primary_membership( application_db.member) res = await execute_pydest_auth( ctx.ext_conns, ctx.ext_conns["destiny"].api.group_invite_member, approver_db.member, manager, group_id=approver_db.clan.clan_id, membership_type=platform_id, membership_id=membership_id, message=f"Join my clan {approver_db.clan.name}!", access_token=approver_db.member.bungie_access_token, ) if res.error_status == "ClanTargetDisallowsInvites": message = f"User **{applicant_user.display_name}** ({username}) has disabled clan invites" elif res.error_status != "Success": message = f"Could not invite **{applicant_user.display_name}** ({username})" log.info( f"Could not invite '{applicant_user.display_name}' ({username}): {res}" ) else: message = ( f"Invited **{applicant_user.display_name}** ({username}) " f"to clan **{approver_db.clan.name}**") await manager.send_message(message, mention=False, clean=False) await application_db.save() await ctx.ext_conns["redis_cache"].delete( f"{payload.guild_id}-clan-application-{application_db.member_id}")
async def create_application_embed(self, ctx, requestor_db, guild_db): redis_cache = self.bot.ext_conns["redis_cache"] if requestor_db.bungie_username: membership_name = requestor_db.bungie_username platform_id, membership_id, _ = get_primary_membership(requestor_db) group_id = None group_name = None groups_info = await execute_pydest( self.bot.destiny.api.get_groups_for_member, platform_id, membership_id, return_type=DestinyMemberGroupResponse, ) if len(groups_info.response.results) > 0: for group in groups_info.response.results: if group.member.destiny_user_info.membership_id == membership_id: group_id = group.group.group_id group_name = group.group.name if group_id and group_name: group_url = f"https://www.bungie.net/en/ClanV2/Index?groupId={group_id}" group_link = f"[{group_name}]({group_url})" else: group_link = "None" last_active = await get_last_active( self.bot.ext_conns, platform_id=platform_id, member_id=membership_id ) embed = discord.Embed( colour=constants.BLUE, title=f"Clan Application for {ctx.author.display_name}", ) bungie_url = f"https://www.bungie.net/en/Profile/{platform_id}/{membership_id}" bungie_link = f"[{membership_name}]({bungie_url})" if requestor_db.discord_id: member_discord = await commands.MemberConverter().convert( ctx, str(requestor_db.discord_id) ) discord_username = str(member_discord) embed.add_field(name="Last Active Date", value=date_as_string(last_active)) embed.add_field(name="Bungie Username", value=bungie_link) embed.add_field(name="Current Clan", value=group_link) embed.add_field(name="Xbox Gamertag", value=requestor_db.xbox_username) embed.add_field(name="PSN Username", value=requestor_db.psn_username) embed.add_field(name="Steam Username", value=requestor_db.steam_username) embed.add_field(name="Stadia Username", value=requestor_db.stadia_username) embed.add_field(name="Discord Username", value=discord_username) embed.set_footer(text="All times shown in UTC") embed.set_thumbnail(url=str(ctx.author.avatar_url)) await redis_cache.set( f"{ctx.guild.id}-clan-application-{requestor_db.id}", serializer(embed) ) return embed