Beispiel #1
0
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)
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
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
Beispiel #5
0
    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}"
        )
Beispiel #6
0
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}')
Beispiel #7
0
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}")
Beispiel #8
0
    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