Esempio n. 1
0
async def removeQuote(cls:"PhaazebotDiscord", Command:DiscordCommand, CommandContext:DiscordCommandContext) -> dict:

	specific_id:str = CommandContext.part(1)
	if specific_id:
		if not specific_id.isdigit():
			specific_id = ""

	if not specific_id:
		return {"content": ":warning: You need to define a numeric quote ID to remove."}

	quote:list = await getDiscordServerQuotes(cls, guild_id=Command.server_id, quote_id=specific_id)

	if not quote:
		return {"content": f":warning: There is no Quote with ID #{specific_id}"}

	DQuote:DiscordQuote = quote[0]

	cls.BASE.PhaazeDB.deleteQuery("""
		DELETE FROM `discord_quote`
		WHERE `discord_quote`.`guild_id` = %s
		AND `discord_quote`.`id` = %s""",
		(str(DQuote.guild_id), str(DQuote.quote_id))
	)

	log_coro:Coroutine = loggingOnQuoteDelete(cls, CommandContext.ServerSettings, Deleter=CommandContext.Message.author, quote_id=DQuote.quote_id, deleted_content=DQuote.content)
	asyncio.ensure_future(log_coro, loop=cls.BASE.DiscordLoop)

	return {"content": f":white_check_mark: Quote #{specific_id} removed"}
Esempio n. 2
0
async def formatVars(Command: DiscordCommand,
                     CommandContext: DiscordCommandContext) -> str:

    format_str: str = Command.content

    replace_index: dict = {
        "user-name": CommandContext.Message.author.name,
        "user-mention": CommandContext.Message.author.mention,
        "channel-name": CommandContext.Message.channel.name,
        "channel-mention": CommandContext.Message.channel.mention,
        "server-name": CommandContext.Message.guild.name,
        "member-count": str(CommandContext.Message.guild.member_count),
        "uses": str(Command.uses)
    }

    # check for and replace all [varname] [varname2] ...
    VarHits: Iterator = re.finditer(ReDiscord.CommandVariableString,
                                    format_str)
    for VarMatch in VarHits:
        name: str = VarMatch.group("name")

        if name in replace_index:
            format_str = format_str.replace(VarMatch.group(0),
                                            replace_index[name])

    # check for and replace all $0 $4 $5 ...
    PositionMatch: Iterator = re.finditer(ReDiscord.CommandPosString,
                                          format_str)
    for PosMatch in PositionMatch:
        rep: str = CommandContext.part(int(PosMatch.group("pos")))
        if not rep: rep = ""
        format_str = format_str.replace(PosMatch.group(0), rep)

    return format_str
Esempio n. 3
0
async def removeQuote(cls:"PhaazebotDiscord", Command:DiscordCommand, CommandContext:DiscordCommandContext) -> dict:

	specific_id:str = CommandContext.part(1)
	if specific_id:
		if not specific_id.isdigit():
			specific_id = ""

	if not specific_id:
		return {"content": ":warning: You need to define a numeric quote ID to remove."}

	quote:list = await getDiscordServerQuotes(cls, Command.server_id, quote_id=specific_id)

	if not quote:
		return {"content": f":warning: There is no Quote with ID #{specific_id}"}

	DQuote:DiscordQuote = quote[0]

	cls.BASE.PhaazeDB.deleteQuery("""
		DELETE FROM `discord_quote`
		WHERE `discord_quote`.`guild_id` = %s
		AND `discord_quote`.`id` = %s""",
		( str(DQuote.guild_id), str(DQuote.quote_id) )
	)

	return {"content": f":white_check_mark: Quote #{specific_id} removed"}
Esempio n. 4
0
async def showQuote(cls: "PhaazebotDiscord", Command: DiscordCommand,
                    CommandContext: DiscordCommandContext) -> dict:

    specific_id: str = CommandContext.part(1)
    if specific_id:
        if not specific_id.isdigit():
            specific_id = ""

    search: dict = dict()
    search["guild_id"] = Command.server_id
    search["quote_id"] = specific_id
    search["limit"] = 1

    if not specific_id:
        search["order_str"] = "ORDER BY RAND()"

    quote: list = await getDiscordServerQuotes(cls, **search)

    if not quote and not specific_id:
        return {
            "content": ":grey_exclamation: This server don't has any Quotes"
        }
    elif not quote and specific_id:
        return {
            "content":
            f":warning: No quote found with id {specific_id} on this server"
        }
    else:
        Quote: DiscordQuote = quote[0]

        Emb = discord.Embed(description=str(Quote.content))
        Emb.set_footer(text=f"ID: {str(Quote.quote_id)}")
        return {"embed": Emb}
Esempio n. 5
0
async def assignRole(cls: "PhaazebotDiscord", Command: DiscordCommand,
                     CommandContext: DiscordCommandContext) -> dict:

    Perm: discord.Permissions = CommandContext.Message.channel.permissions_for(
        CommandContext.Message.guild.me)
    if not Perm.manage_roles:
        return {
            "content":
            ":no_entry_sign: Phaaze don't has a role with the `Manage Roles` permission."
        }

    role_trigger: str = CommandContext.part(1)

    if not role_trigger:
        return {"content": ":warning: Missing a role-trigger"}

    roles: list = await getDiscordServerAssignRoles(cls,
                                                    Command.server_id,
                                                    trigger=role_trigger)

    if not roles:
        return {
            "content":
            f":warning: Could not find any assign role associated with: `{role_trigger}`"
        }

    WantedDiscordRole: discord.Role = CommandContext.Message.guild.get_role(
        int(roles.pop(0).role_id))

    if CommandContext.Message.guild.me.top_role < WantedDiscordRole:
        return {
            "content":
            f":no_entry_sign: The Role `{WantedDiscordRole.name}` is to high. Phaaze highest role has to be higher in hierarchy then `{WantedDiscordRole.name}`"
        }

    if WantedDiscordRole in CommandContext.Message.author.roles:
        await CommandContext.Message.author.remove_roles(
            WantedDiscordRole,
            reason=f"Removed via assignrole, trigger='{role_trigger}'")
        return {
            "content":
            f":white_check_mark: Successfull removed the role `{WantedDiscordRole.name}` from you."
        }

    else:
        await CommandContext.Message.author.add_roles(
            WantedDiscordRole,
            reason=f"Added via assignrole, trigger='{role_trigger}'")
        return {
            "content":
            f":white_check_mark: Successfull added you the role: `{WantedDiscordRole.name}`"
        }
Esempio n. 6
0
async def removeAssignRole(cls:"PhaazebotDiscord", Command:DiscordCommand, CommandContext:DiscordCommandContext) -> dict:

	specific_trigger:str = CommandContext.part(1)
	if not specific_trigger:
		return {"content": ":warning: You need to define the role-trigger to remove."}

	roles:list = await getDiscordServerAssignRoles(cls, Command.server_id, trigger=specific_trigger)

	if not roles:
		return {"content": f":warning: There is no assign role with trigger `{specific_trigger}`"}

	Role:DiscordAssignRole = roles[0]

	cls.BASE.PhaazeDB.deleteQuery("""
		DELETE FROM `discord_assignrole`
		WHERE `discord_assignrole`.`guild_id` = %s
		AND `discord_assignrole`.`trigger` = %s""",
		( str(Role.guild_id), str(Role.trigger) )
	)

	return {"content": f":white_check_mark: Assign role `{Role.trigger}` removed"}
Esempio n. 7
0
async def removeAssignRole(cls: "PhaazebotDiscord", Command: DiscordCommand,
                           CommandContext: DiscordCommandContext) -> dict:

    specific_trigger: str = CommandContext.part(1)
    if not specific_trigger:
        return {
            "content":
            ":warning: You need to define the role-trigger to remove."
        }

    roles: list = await getDiscordServerAssignRoles(cls,
                                                    guild_id=Command.server_id,
                                                    trigger=specific_trigger)

    if not roles:
        return {
            "content":
            f":warning: There is no assign role with trigger `{specific_trigger}`"
        }

    Role: DiscordAssignRole = roles[0]

    cls.BASE.PhaazeDB.deleteQuery(
        """
		DELETE FROM `discord_assignrole`
		WHERE `discord_assignrole`.`guild_id` = %s
		AND `discord_assignrole`.`trigger` = %s""",
        (str(Role.guild_id), str(Role.trigger)))

    # Log
    log_coro: Coroutine = loggingOnAssignroleDelete(
        cls,
        CommandContext.ServerSettings,
        Deleter=CommandContext.Message.author,
        assign_role_trigger=Role.trigger)
    asyncio.ensure_future(log_coro, loop=cls.BASE.DiscordLoop)

    return {
        "content": f":white_check_mark: Assign role `{Role.trigger}` removed"
    }
Esempio n. 8
0
async def showQuote(cls:"PhaazebotDiscord", Command:DiscordCommand, CommandContext:DiscordCommandContext) -> dict:

	specific_id:str = CommandContext.part(1)
	if specific_id:
		if not specific_id.isdigit():
			specific_id = ""

	if specific_id:
		random:bool = False
	else:
		random:bool = True

	quote:list = await getDiscordServerQuotes(cls, Command.server_id, quote_id=specific_id, random=random, limit=1)

	if not quote and not specific_id:
		return {"content": ":grey_exclamation: This server don't has any Quotes"}
	elif not quote and specific_id:
		return {"content": f":warning: No quote found with id {specific_id} on this server"}
	else:
		Quote:DiscordQuote = quote[0]

		Emb = discord.Embed(description=str(Quote.content))
		Emb.set_footer(text=f"ID: {str(Quote.quote_id)}")
		return {"embed": Emb}
Esempio n. 9
0
async def levelLeaderboard(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 {}

    specific_len: Union[int, str] = CommandContext.part(1)
    if specific_len:
        if not specific_len.isdigit():
            specific_len = DEFAULT_LEADERBOARD_LEN
        else:
            specific_len = int(specific_len)

    else:
        specific_len = DEFAULT_LEADERBOARD_LEN

    if not specific_len or specific_len > MAX_LEADERBOARD_LEN:
        return {
            "content":
            f":warning: `{specific_len}` is unsupported, length must be between 1 and 15"
        }

    users: list = await getDiscordServerUsers(cls,
                                              guild_id=Command.server_id,
                                              limit=specific_len,
                                              order_str="ORDER BY exp DESC")

    if not users:
        return {
            "content":
            ":question: Seems like there are no member with level for a leaderboard :("
        }

    # there are less member ín the return than the limit requests, very rare
    if len(users) < specific_len:
        specific_len = len(users)

    return_table: list = [["#", "|", "LVL", "|", "EXP", "|", "Name"],
                          ["---", "|", "---", "|", "---", "|", "---"]]

    for LevelUser in users:

        e: str = " [EDITED]" if LevelUser.edited else ""
        lvl: str = prettifyNumbers(LevelCalc.getLevel(LevelUser.exp))
        exp: str = prettifyNumbers(LevelUser.exp)
        Member: discord.Member = CommandContext.Message.guild.get_member(
            int(LevelUser.member_id))
        if Member:
            user_name: str = Member.name
        else:
            user_name: str = "[N/A]"

        return_table.append(
            [f"#{LevelUser.rank}", "|", lvl, "|", f"{exp}{e}", "|", user_name])

    table: str = tabulate(return_table, tablefmt="plain")

    return {
        "content":
        f"**Top: {specific_len} leaderboard** :link: {cls.BASE.Vars.web_root}/discord/level/{Command.server_id} ```{table}```"
    }
Esempio n. 10
0
async def addAssignRole(cls: "PhaazebotDiscord", Command: DiscordCommand,
                        CommandContext: DiscordCommandContext) -> dict:

    Perm: discord.Permissions = CommandContext.Message.channel.permissions_for(
        CommandContext.Message.guild.me)
    if not Perm.manage_roles:
        return {
            "content":
            ":no_entry_sign: Phaaze don't has a role with the `Manage Roles` permission."
        }

    trigger: str = CommandContext.part(1)
    query_str: str = " ".join(CommandContext.parts[2:])

    if not trigger or not query_str:
        return {
            "content":
            ":warning: You need to define a role-trigger and a role."
        }

    AssignRole: discord.Role = getDiscordRoleFromString(
        cls,
        CommandContext.Message.guild,
        query_str,
        Message=CommandContext.Message)
    if not AssignRole:
        return {
            "content":
            f":warning: Could not find any role matching: `{query_str}`"
        }

    res: list = cls.BASE.PhaazeDB.selectQuery(
        """
		SELECT
			COUNT(*) AS `all`,
			SUM(
				CASE WHEN `discord_assignrole`.`role_id` = %s OR LOWER(`discord_assignrole`.`trigger`) = LOWER(%s)
				THEN 1 ELSE 0 END
			) AS `match`
		FROM `discord_assignrole`
		WHERE `discord_assignrole`.`guild_id` = %s""",
        (str(AssignRole.id), trigger, str(Command.server_id)))

    if res[0]["all"] >= cls.BASE.Limit.DISCORD_ASSIGNROLE_AMOUNT:
        return {
            "content":
            ":no_entry_sign: This server hit the assign role limit, please remove some first."
        }

    if res[0]["match"] >= 1:
        return {
            "content":
            ":no_entry_sign: This Assignrole or the used trigger already exists."
        }

    if CommandContext.Message.guild.me.top_role < AssignRole:
        return {
            "content":
            f":no_entry_sign: The Role `{AssignRole.name}` is to high. Phaaze highest role has to be higher in hierarchy then `{AssignRole.name}`"
        }

    cls.BASE.PhaazeDB.insertQuery(table="discord_assignrole",
                                  content=dict(guild_id=str(Command.server_id),
                                               role_id=str(AssignRole.id),
                                               trigger=trigger))

    return {
        "content":
        f":white_check_mark: Successfull added assign role `{str(AssignRole)}` with trigger `{trigger}`"
    }
Esempio n. 11
0
async def checkCommands(cls: "PhaazebotDiscord", Message: discord.Message,
                        ServerSettings: DiscordServerSettings,
                        DiscordUser: DiscordUserStats) -> bool:
    """
	This function is run on every message and checks if there is a command to execute
	Returns True if a function is executed, else False
	(That's needed for level stats, because commands don't give exp)
	"""

    CommandContext: DiscordCommandContext = DiscordCommandContext(
        cls, Message, Settings=ServerSettings)

    # get permission object
    AuthorPermission: DiscordPermission = DiscordPermission(
        Message, DiscordUser)

    # random fact, even part 0 can be none, if a image is updated
    clean_nickname: str = (CommandContext.part(0) or '').replace('!', '')

    # direct call via @Phaazebot [command] (rest vars)
    # server owner only (for now)
    if AuthorPermission.rank >= DiscordConst.REQUIRE_OWNER and str(
            Message.guild.me.mention) == clean_nickname:

        CommandContext.parts.pop(0)
        CommandContext.Message.mentions.pop(0)

        command_data: dict = dict(command_id=0,
                                  guild_id=Message.guild.id,
                                  function=CommandContext.parts[0],
                                  require=3,
                                  cooldown=5,
                                  content="")

        Command: DiscordCommand = DiscordCommand(command_data)
        result: dict = await formatCommand(cls,
                                           Command,
                                           CommandContext,
                                           direct_call=True)
        if result: await Message.channel.send(**result)
        return True

    # a normal call, so we check first
    await CommandContext.check()

    if CommandContext.found:

        Command: DiscordCommand = CommandContext.Command

        if not Command.active: return False

        # check if command is in cooldown
        if GDCCS.check(Command): return False

        # check caller access level and command require level
        if not AuthorPermission.rank >= Command.require: return False

        # owner disables normal commands serverwide,
        if ServerSettings.owner_disable_normal and Command.require == DiscordConst.REQUIRE_EVERYONE:
            # no one except the owner can use them
            if AuthorPermission.rank != DiscordConst.REQUIRE_OWNER:
                return False

        # owner disables regular commands serverwide,
        if ServerSettings.owner_disable_regular and Command.require == DiscordConst.REQUIRE_REGULAR:
            # no one except the owner can use them
            if AuthorPermission.rank != DiscordConst.REQUIRE_OWNER:
                return False

        # owner disables mod commands serverwide,
        if ServerSettings.owner_disable_mod and Command.require == DiscordConst.REQUIRE_MOD:
            # no one except the owner can use them
            if AuthorPermission.rank != DiscordConst.REQUIRE_OWNER:
                return False

        # always have a minimum cooldown
        Command.cooldown = max(Command.cooldown,
                               cls.BASE.Limit.discord_commands_cooldown_min,
                               DiscordConst.COMMAND_COOLDOWN_MIN)

        # but also not be to long
        Command.cooldown = min(Command.cooldown,
                               cls.BASE.Limit.discord_commands_cooldown_max,
                               DiscordConst.COMMAND_COOLDOWN_MAX)

        # command requires a currency payment, check if user can afford it
        # except mods
        if Command.required_currency != 0 and AuthorPermission.rank < DiscordConst.REQUIRE_MOD:

            # not enough
            if not (DiscordUser.currency >= Command.required_currency):
                cls.BASE.Logger.debug(
                    f"(Discord) Skipping command call because of insufficient currency: ({DiscordUser.currency} < {Command.required_currency})",
                    require="discord:commands")
                return False

            await DiscordUser.editCurrency(
                cls, amount_by=-Command.required_currency)

        # add command to cooldown
        GDCCS.cooldown(Command)

        # increase use
        await Command.increaseUse(cls)

        # throw it to formatCommand and send the return values
        final_result: dict = await formatCommand(cls, Command, CommandContext)

        # there a commands that not have a direct return value,
        # but are still valid and successful
        if final_result:
            await Message.channel.send(**final_result)

        return True

    else:
        return False