Example #1
0
async def searchMember(cls: "PhaazebotWeb", WebRequest: ExtendedRequest,
                       Data: WebRequestContent) -> Response:
    search_term: str = Data.getStr("term", "")
    guild_id: str = Data.getStr("guild_id", "", must_be_digit=True)

    if not guild_id:
        return await apiMissingData(cls,
                                    WebRequest,
                                    msg="invalid or missing 'guild_id'")

    Guild: discord.Guild = discord.utils.get(cls.BASE.Discord.guilds,
                                             id=int(guild_id))
    if not Guild:
        return await apiDiscordGuildUnknown(cls, WebRequest)

    Member: discord.Member = getDiscordMemberFromString(
        cls.BASE.Discord, Guild, search_term)
    if not Member: return await apiDiscordMemberNotFound(cls, WebRequest)

    data: dict = {
        "name": str(Member.name),
        "nick": Member.nick,
        "id": str(Member.id),
        "discriminator": Member.discriminator,
        "avatar": Member.avatar
    }

    return cls.response(text=json.dumps(dict(result=data, status=200)),
                        content_type="application/json",
                        status=200)
Example #2
0
async def pruneMessages(cls: "PhaazebotDiscord", Command: DiscordCommand,
                        CommandContext: DiscordCommandContext) -> dict:

    Perm: discord.Permissions = CommandContext.Message.channel.permissions_for(
        CommandContext.Message.guild.me)
    if not Perm.manage_messages:
        return {
            "content":
            ":no_entry_sign: Phaaze need the `Manage messages` permissions to execute prune"
        }

    search_by: str = " ".join([x for x in CommandContext.parts[1:]])

    if not search_by:
        return {
            "content":
            ":warning: Please add a message amount or a member query string"
        }

    elif search_by.isdigit() and len(search_by) < 5:
        # digits that are not a id
        return await pruneMessagesByAmount(cls, Command, CommandContext,
                                           int(search_by))

    else:
        SearchMember = getDiscordMemberFromString(
            cls,
            CommandContext.Message.guild,
            search_by,
            Message=CommandContext.Message)
        if not SearchMember:
            return {"content": ":warning: Could not find a member..."}

        return await pruneMessagesByMember(cls, Command, CommandContext,
                                           SearchMember)
Example #3
0
async def loggingOnLevelmedalDelete(cls: "PhaazebotDiscord",
                                    Settings: DiscordServerSettings,
                                    **kwargs) -> None:
    """
	Logs the event when someone deletes a discordmember medal via web.
	If track option `Levelmedal.delete` is active, it will send a message to discord

	Required keywords:
	------------------
	* `Deleter` - discord.Member
	* `medal_member_id` - str
	* `medal_name` - str
	"""
    logging_signature: str = "Levelmedal.delete"
    Deleter: discord.Member = kwargs["Deleter"]
    medal_member_id: str = kwargs["medal_member_id"]
    medal_name: str = kwargs["medal_name"]

    MedalMember: discord.Member = getDiscordMemberFromString(
        cls, Deleter.guild, medal_member_id)
    medal_member_name: str = MedalMember.name if MedalMember else "(Unknown)"

    new_log_id: int = cls.BASE.PhaazeDB.insertQuery(
        table="discord_log",
        content={
            "guild_id":
            Settings.server_id,
            "event_value":
            TRACK_OPTIONS[logging_signature],
            "initiator_id":
            str(Deleter.id),
            "content":
            f"{Deleter.name} removed a medal from: {medal_member_name}, old medal: {medal_name}"
        })

    if not (TRACK_OPTIONS[logging_signature] & Settings.track_value):
        return  # track option not active, skip message to discord server

    TargetChannel: discord.TextChannel = getDiscordChannelFromString(
        cls, Deleter.guild, Settings.track_channel, required_type="text")
    if not TargetChannel: return  # no channel found

    Emb: discord.Embed = discord.Embed(
        title=f"Log Event - [{logging_signature}]",
        description=f"{Deleter.name} removed a medal",
        timestamp=datetime.datetime.now(),
        color=EVENT_COLOR_NEGATIVE,
        url=makeWebAccessLink(cls, Deleter.guild.id, new_log_id))
    Emb.set_thumbnail(url=Deleter.avatar_url or Deleter.default_avatar_url)
    Emb.add_field(name="Target member:", value=medal_member_name, inline=False)
    Emb.add_field(name="Medal:", value=medal_name, inline=False)

    try:
        await TargetChannel.send(embed=Emb)
    except Exception as E:
        cls.BASE.Logger.warning(
            f"Can't log message: {E} {traceback.format_exc()}")
Example #4
0
async def levelStatus(cls:"PhaazebotDiscord", Command:DiscordCommand, CommandContext:DiscordCommandContext) -> dict:

	# other than, normal, mod or regular commands that get blocked in commands.py
	# we can not tell if that command is a level command until now, so we end it now

	# owner disabled level commands serverwide
	if CommandContext.ServerSettings.owner_disable_level:
		return {}

	# same as above just for a a specific channel
	if CommandContext.Message.channel.id in CommandContext.ServerSettings.disabled_levelchannels:
		return {}

	search_from:str = " ".join([x for x in CommandContext.parts[1:]])
	# no search use author
	if not search_from:
		Member:discord.Member = CommandContext.Message.author
	# try a search
	else:
		Member:Optional[discord.Member] = getDiscordMemberFromString(cls, Guild=CommandContext.Message.guild, search=search_from, Message=CommandContext.Message)
		if not Member:
			return {"content": ":warning: Could not find a user with your query"}

	users:list = await getDiscordServerUsers(cls, guild_id=Command.server_id, member_id=Member.id)

	if not users:
		return {"content": f":warning: Seems like there are no statistics for `{Member.name}`\nMaybe the user never typed anything or got deleted."}

	LevelUser:DiscordUserStats = users.pop(0)

	exp_current:int = LevelUser.exp
	lvl_current:int = LevelCalc.getLevel(exp_current)
	exp_next:int = LevelCalc.getExp(lvl_current+1)
	rank:str = prettifyNumbers(LevelUser.rank) if LevelUser.rank else "[N/A]"
	avatar:str = Member.avatar_url if Member.avatar_url else Member.default_avatar_url

	Emb:discord.Embed = discord.Embed(color=0x00ffdd)
	Emb.set_author(name=Member.name, icon_url=avatar)

	Emb.add_field(name="Level:", value=f"{prettifyNumbers(lvl_current)}", inline=True)
	Emb.add_field(name="Exp:", value=f"{prettifyNumbers(exp_current)} / {prettifyNumbers(exp_next)}", inline=True)
	Emb.add_field(name="Rank:", value=f"# {rank}", inline=True)

	if LevelUser.edited:
		Emb.add_field(name=":warning: EDITED",value="Exp value got edited.", inline=False)

	if LevelUser.medals:
		Emb.add_field(name="Medals:",value="\n".join(m for m in LevelUser.medals), inline=False)

	return {"embed": Emb}
Example #5
0
async def whois(cls:"PhaazebotDiscord", Command:DiscordCommand, CommandContext:DiscordCommandContext) -> dict:

	Member:discord.Member = None

	search_from:str = " ".join([x for x in CommandContext.parts[1:]])
	# no search use author
	if not search_from:
		Member = CommandContext.Message.author
	# try a search
	else:
		Member:discord.Member = getDiscordMemberFromString(cls, Guild=CommandContext.Message.guild, search=search_from, Message=CommandContext.Message)
		if not Member:
			return {"content": ":warning: Could not find a user with your query"}

	nickname:str = None
	status:str = None
	roles:list = list()

	# nickname
	if Member.nick:
		nickname = f"Nickname: {Member.nick}"

	# status
	if str(Member.status) == "online":
		status = "Online"
	elif str(Member.status) == "offline":
		status = "Offline"
	elif str(Member.status) == "idle":
		status = "AFK"
	elif str(Member.status) == "dnd":
		status = "Do not disturb"
	else:
		status = str(Member.status)

	for Role in sorted(Member.roles, key=lambda role: role.position, reverse=True):
		if Role.name != "@everyone":
			roles.append([Role.position, Role.name])

	Now:datetime.datetime = datetime.datetime.now()

	create_date:str = Member.created_at.strftime("%Y-%m-%d (%H:%M)")
	join_date:str = Member.joined_at.strftime("%Y-%m-%d (%H:%M)")
	create_days:str = (Now - Member.created_at).days
	join_days:str = (Now - Member.joined_at).days

	main_info:str = f"**ID**: {Member.id}\n"\
		f"**Discriminator**: {Member.discriminator}\n"\
		f"**Acc. created at**: {create_date} *[{create_days} days ago]*\n"\
		f"**Joined at**: {join_date} *[{join_days} days ago]*"

	Emb = discord.Embed (
		title=nickname,
		color=Member.color.value,
		description=main_info)

	Emb.set_author(name=f"Name: {Member.name}")
	Emb.add_field(name=":satellite: Status:",value=status,inline=True)

	if Member.activity:
		if type(Member.activity) == discord.activity.Game:
			Emb.add_field(name=":game_die: Playing:", value=str(Member.activity),inline=True)

		elif type(Member.activity) == discord.activity.Streaming:
			Emb.add_field(name=":video_camera: Currently Streaming:",value=str(Member.activity),inline=True)

	if Member.bot:
		Emb.add_field(name=":robot: Bot-account:",value="True",inline=True)

	if len(roles) >= 1:
		formated_list:str = tabulate.tabulate(roles, tablefmt="plain")
		Emb.add_field(name=":notepad_spiral: Roles:", value=f"```{formated_list}```", inline=False)
	else:
		Emb.add_field(name=":notepad_spiral: Roles:", value="None", inline=False)

	if Member.avatar_url:
		Emb.set_image(url=Member.avatar_url)
	else:
		Emb.set_image(url=Member.default_avatar_url)

	return {"embed": Emb}
Example #6
0
async def loggingOnLevelEdit(cls: "PhaazebotDiscord",
                             Settings: DiscordServerSettings,
                             **kwargs) -> None:
    """
	Logs the event when someone edits a discordmember-level via web.
	If track option `Level.edit` is active, it will send a message to discord

	Required keywords:
	------------------
	* `Remover` - discord.Member
	* `changed_member_id` - str
	* `changes` - dict
	"""
    logging_signature: str = "Level.edit"
    Editor: discord.Member = kwargs["Editor"]
    changed_member_id: str = kwargs["changed_member_id"]
    changes: dict = kwargs["changes"]

    LevelMember: discord.Member = getDiscordMemberFromString(
        cls, Editor.guild, changed_member_id)
    level_member_name: str = LevelMember.name if LevelMember else "(Unknown)"

    new_log_id: int = cls.BASE.PhaazeDB.insertQuery(
        table="discord_log",
        content={
            "guild_id":
            Settings.server_id,
            "event_value":
            TRACK_OPTIONS[logging_signature],
            "initiator_id":
            str(Editor.id),
            "content":
            f"{Editor.name} edited the level stats of: {level_member_name} changes: {str(changes)}"
        })

    if not (TRACK_OPTIONS[logging_signature] & Settings.track_value):
        return  # track option not active, skip message to discord server

    TargetChannel: discord.TextChannel = getDiscordChannelFromString(
        cls, Editor.guild, Settings.track_channel, required_type="text")
    if not TargetChannel: return  # no channel found

    Emb: discord.Embed = discord.Embed(
        title=f"Log Event - [{logging_signature}]",
        description=f"{Editor.name} edited level stats",
        timestamp=datetime.datetime.now(),
        color=EVENT_COLOR_WARNING,
        url=makeWebAccessLink(cls, Editor.guild.id, new_log_id))
    Emb.set_thumbnail(url=Editor.avatar_url or Editor.default_avatar_url)
    Emb.add_field(name="Edited member:", value=level_member_name, inline=False)
    if changes.get("edited", False):
        Emb.add_field(
            name="Warning:",
            value="EXP got changed, this member now has a [EDITED] mark",
            inline=False)

    try:
        await TargetChannel.send(embed=Emb)
    except Exception as E:
        cls.BASE.Logger.warning(
            f"Can't log message: {E} {traceback.format_exc()}")
Example #7
0
async def apiDiscordRegularsCreate(cls: "PhaazebotWeb",
                                   WebRequest: ExtendedRequest) -> Response:
    """
	Default url: /api/discord/regulars/create
	"""
    Data: WebRequestContent = WebRequestContent(WebRequest)
    await Data.load()

    # get required stuff
    Create: StorageTransformer = StorageTransformer()
    Create["guild_id"] = Data.getStr("guild_id", UNDEFINED, must_be_digit=True)
    Create["member_id"] = Data.getStr("member_id",
                                      UNDEFINED,
                                      must_be_digit=True)

    # checks
    if not Create["guild_id"]:
        return await cls.Tree.Api.errors.apiMissingData(
            cls, WebRequest, msg="missing or invalid 'guild_id'")

    if not Create["member_id"]:
        return await cls.Tree.Api.errors.apiMissingData(
            cls, WebRequest, msg="missing or invalid 'member_id'")

    # get/check discord
    PhaazeDiscord: "PhaazebotDiscord" = cls.BASE.Discord
    Guild: discord.Guild = discord.utils.get(PhaazeDiscord.guilds,
                                             id=int(Create["guild_id"]))
    if not Guild:
        return await cls.Tree.Api.Discord.errors.apiDiscordGuildUnknown(
            cls, WebRequest)

    ActionMember: discord.Member = getDiscordMemberFromString(
        PhaazeDiscord, Guild, Create["member_id"])
    if not ActionMember:
        return await cls.Tree.Api.Discord.errors.apiDiscordMemberNotFound(
            cls, WebRequest, user_id=Create["member_id"])

    # check if already exists and limits
    res: list = cls.BASE.PhaazeDB.selectQuery(
        """
		SELECT
			COUNT(*) AS `all`,
			SUM(
				CASE WHEN `discord_regular`.`member_id` = %s
				THEN 1 ELSE 0 END
			) AS `match`
		FROM `discord_regular`
		WHERE `discord_regular`.`guild_id` = %s""",
        (str(ActionMember.id), str(ActionMember.guild.id)))

    if res[0]["match"]:
        return await cls.Tree.Api.Discord.Regulars.errors.apiDiscordRegularExists(
            cls, WebRequest)

    if res[0]["all"] >= cls.BASE.Limit.discord_regular_amount:
        return await cls.Tree.Api.Discord.Regulars.errors.apiDiscordRegularLimit(
            cls, WebRequest)

    # get user info
    AuthDiscord: AuthDiscordWebUser = await authDiscordWebUser(cls, WebRequest)
    if not AuthDiscord.found:
        return await cls.Tree.Api.errors.apiMissingAuthorisation(
            cls, WebRequest)

    # get member
    CheckMember: discord.Member = Guild.get_member(
        int(AuthDiscord.User.user_id))
    if not CheckMember:
        return await cls.Tree.Api.Discord.errors.apiDiscordMemberNotFound(
            cls,
            WebRequest,
            guild_id=Create["guild_id"],
            user_id=AuthDiscord.User.user_id)

    # check permissions
    if not (CheckMember.guild_permissions.administrator
            or CheckMember.guild_permissions.manage_guild):
        return await cls.Tree.Api.Discord.errors.apiDiscordMissingPermission(
            cls,
            WebRequest,
            guild_id=Create["guild_id"],
            user_id=AuthDiscord.User.user_id)

    cls.BASE.PhaazeDB.insertQuery(table="discord_regular",
                                  content={
                                      "guild_id": str(ActionMember.guild.id),
                                      "member_id": str(ActionMember.id)
                                  })

    # logging
    GuildSettings: DiscordServerSettings = await getDiscordSeverSettings(
        PhaazeDiscord, Create["guild_id"], prevent_new=True)
    log_coro: Coroutine = loggingOnRegularCreate(PhaazeDiscord,
                                                 GuildSettings,
                                                 Creator=CheckMember,
                                                 NewRegular=ActionMember)
    asyncio.ensure_future(log_coro, loop=cls.BASE.DiscordLoop)

    cls.BASE.Logger.debug(
        f"(API/Discord) Regular: {Create['guild_id']=} added new entry {Create['member_id']=}",
        require="discord:regulars")
    return cls.response(text=json.dumps(
        dict(msg="Regulars: Added new entry",
             entry=ActionMember.name,
             status=200)),
                        content_type="application/json",
                        status=200)