From 998ff503e3be68f9aede19f5a73614cfdb17b8a0 Mon Sep 17 00:00:00 2001 From: developomp Date: Sun, 8 Aug 2021 12:17:57 +0900 Subject: [PATCH] moved to a new repository --- .github/example.png | Bin 1801727 -> 0 bytes .github/logo.png | Bin 9530 -> 0 bytes .gitignore | 17 -- .vscode/settings.json | 12 - LICENSE | 21 -- README.md | 66 +----- bot/cogs/_admin.py | 318 --------------------------- bot/cogs/_logging.py | 195 ----------------- bot/cogs/_self_role.py | 258 ---------------------- bot/cogs/_util.py | 90 -------- bot/cogs/_war_brokers.py | 330 ---------------------------- bot/cogs/core.py | 158 -------------- bot/cogs/dm.py | 32 --- bot/cogs/fun.py | 223 ------------------- bot/cogs/pinning.py | 458 --------------------------------------- bot/cogs/util.py | 59 ----- bot/llama.py | 223 ------------------- bot/llama_firebase.py | 62 ------ requirements.txt | 4 - 19 files changed, 2 insertions(+), 2524 deletions(-) delete mode 100644 .github/example.png delete mode 100644 .github/logo.png delete mode 100644 .gitignore delete mode 100644 .vscode/settings.json delete mode 100644 LICENSE delete mode 100644 bot/cogs/_admin.py delete mode 100644 bot/cogs/_logging.py delete mode 100644 bot/cogs/_self_role.py delete mode 100644 bot/cogs/_util.py delete mode 100644 bot/cogs/_war_brokers.py delete mode 100644 bot/cogs/core.py delete mode 100644 bot/cogs/dm.py delete mode 100644 bot/cogs/fun.py delete mode 100644 bot/cogs/pinning.py delete mode 100644 bot/cogs/util.py delete mode 100755 bot/llama.py delete mode 100644 bot/llama_firebase.py delete mode 100644 requirements.txt diff --git a/.github/example.png b/.github/example.png deleted file mode 100644 index 08ac2afce87bf5ea62be1e9c38343f04ffb0484e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1801727 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 diff --git a/.github/logo.png b/.github/logo.png deleted file mode 100644 index 17d5d21c4f0411f39d9a36fe296d93699fddafa6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9530 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 z�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 Y04V7&Y+gA;6aWAK07*qoM6N<$f;5~^j{pDw diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 68f128b..0000000 --- a/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -_/ -secrets/ -__pycache__/ -config.json - -# Created by https://www.toptal.com/developers/gitignore/api/vscode -# Edit at https://www.toptal.com/developers/gitignore?templates=vscode - -### vscode ### -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json -*.code-workspace - -# End of https://www.toptal.com/developers/gitignore/api/vscode diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7532cdb..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "editor.formatOnSave": true, - "editor.formatOnPaste": true, - - "python.formatting.provider": "black", - "python.analysis.extraPaths": [ - "./bot" - ], - "cSpell.words": [ - "pinnable" - ] -} diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 027769e..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 developomp - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index 1d14a6a..6dfa2e9 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,2 @@ -# [llama bot](https://github.com/developomp/llama-bot) - -
- MIT License - Python version 3.9 - Code style: black -
-
- llama logo -
- -> **WARNING: THIS REPOSITORY CONTAINS NSFW CONTENT** - -llama bot is a [discord](https://discord.com) bot made for the LP community [server](https://discord.gg/2fsar34APa).
- -- Invitation of this bot to other server is blocked. You wll have to host the bot yourself if you want it on your discord server. -- The bot requires Python version 3.9 or greater. -- local configuration file and database does not exist. Everything is stored in google firebase. Portability ftw! - -Example: -![example image of bot usage](.github/example.png) - -# Setting up locally - -Steps: - -1. Clone this repository - - `git clone https://github.com/developomp/llama-bot.git` -2. Install dependencies ([requirements.txt](./requirements.txt) is in project root) - - - `pip install -r requirements.txt` - -3. create `secrets` directory under `bot` directory -4. Create a new discord bot - - https://discord.com/developers/applications -5. Create a firebase project and create firestore database (production mode is highly recommended) - - https://console.firebase.google.com -6. Generate and download service account key from firebase ([instruction](https://firebase.google.com/docs/admin/setup#initialize-sdk)), rename it to `firebase-adminsdk.json`, and put it in `secrets` directory. - - https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk -7. create `secret.json` in `secrets` directory and put the discord bot token - ```json - { - "token": "" - } - ``` -8. Start the bot (working directory must be set to `bot` directory) - - - `python llama.py` - -More info: - -- discord developers documentation: https://discord.com/developers/docs -- [discord python API](https://github.com/Rapptz/discord.py) documentation: https://discordpy.readthedocs.io -- firebase admin sdk documentation: https://firebase.google.com/docs - -# contributing - -- Usage of [vscode](https://code.visualstudio.com) is highly recommended -- Format python code using the [black](https://github.com/psf/black) formatter -- Format markdown file(s) with [prettier](https://prettier.io) formatter - -# Special thanks - -- `Davidisacookie#9888 (265697563280146433)` for making the bot icon +**ATTENTION!**
+The llama bot has found a new home: https://github.com/llama-bot/llama-bot diff --git a/bot/cogs/_admin.py b/bot/cogs/_admin.py deleted file mode 100644 index 02e991a..0000000 --- a/bot/cogs/_admin.py +++ /dev/null @@ -1,318 +0,0 @@ -from llama import Llama -import cogs._util as util - -import discord -from discord.ext import commands - -import json - - -class Admin(commands.Cog): - def __init__(self, bot): - self.bot: Llama = bot - - self.allowed_channels: list[discord.TextChannel] = [ - self.bot.LP_SERVER.get_channel(int(self.bot.VARS["channels"]["ADMIN_BOT"])), - ] - - self.draft_common_message = "required to create a new draft" - - async def cog_check(self, ctx: commands.Context): - if exception_or_bool := await util.on_pm(ctx.message, self.bot): - raise exception_or_bool - return not exception_or_bool - - def draft_id_required_error_message(self, draft_id): - """checks if draft id is passed in draft command""" - if not draft_id: - raise discord.ext.commands.errors.MissingRequiredArgument( - "draft id is" + self.draft_common_message - ) - - def draft_ids_are_required_error_message(self, draft_id, draft_id2): - """checks if draft id 1 and 2 are passed in draft command""" - if not (draft_id and draft_id2): - raise discord.ext.commands.errors.MissingRequiredArgument( - "draft ids are" + self.draft_common_message - ) - - async def error_if_not_in_admin_channel(self, ctx: discord.ext.commands.Context): - if ctx.message.channel not in self.allowed_channels: - allowed_in = ", ".join( - [channel_id.mention for channel_id in self.allowed_channels] - ) - raise util.NotAdminChannel( - f"Admin commands can only be executed in: {allowed_in}" - ) - - @commands.command( - aliases=[ - "m", - ], - help="Send and edit messages so other mods can change rules and stuff", - usage="""Build and edit messages using the draft feature. -Type `{prefix}help draft` for more information. -> {prefix}{command} -selector: message url, `CHANNEL_ID/MESSAGE_ID` path, channel id, channel mention, channel url -message draft id: type `{prefix}draft list` to list available ids - -Sending message: -> {prefix}{command} - -Deleting message: -> {prefix}{command} - -Replacing message: -> {prefix}{command} -""", - ) - @util.must_be_admin() - async def message(self, ctx, msg_or_channel_path: str = None, draft_id: str = None): - await self.error_if_not_in_admin_channel(ctx) - - await ctx.send( - embed=discord.Embed( - title="Not ready yet", - description="This feature is not implemented yet.", - ) - ) - - @commands.command( - aliases=[ - "d", - "drafts", - ], - help="Create and edit message drafts for the `message` command", - usage="""> {prefix}{command} -draft ids: string with no space (preferably separated by underscores `_`). - -Creating new draft: -> {prefix}{command} - -Removing draft: -> {prefix}{command} - -Editing draft: -> {prefix}{command} - -Duplicating draft: -> {prefix}{command} - -Renaming draft: -> {prefix}{command} - -Previewing draft: -> {prefix}{command} - -View raw data of a draft -> {prefix}{command} - -Listing available drafts: -> {prefix}{command} -""", - ) - @util.must_be_admin() - async def draft( - self, ctx, operation: str, draft_id: str = None, draft_id2: str = None - ): - """https://discord.com/developers/docs/resources/channel#embed-object""" - await self.error_if_not_in_admin_channel(ctx) - - if operation in ["create", "new", "c", "n"]: - self.draft_id_required_error_message(draft_id) - - try: # check if draft already exists - if self.bot.VARS["drafts"][draft_id]: - await ctx.send( - embed=discord.Embed( - title="Draft already exists", - description="A draft with the same id was found. Edit it, or delete and create a new one.", - ) - ) - return - except KeyError: - pass # draft does not exist. Can create a new one. - - # create new embed with default values - new_embed_data = dict() - new_embed_data["title"] = "title" - new_embed_data["description"] = "description" - new_embed_data["color"] = 0 - new_embed_data["fields"] = [ - {"name": "name1", "value": "value1", "inline": True}, - {"name": "name2", "value": "value2", "inline": True}, - ] - - # update local and database vars - json_embed_data = json.dumps(new_embed_data) - self.bot.VARS["drafts"][draft_id] = json_embed_data - self.bot.llama_firebase.create("vars", "drafts", draft_id, json_embed_data) - - # feedback - await ctx.send( - embed=discord.Embed( - title="Success!", - description=f"New draft `{draft_id}` has been created.", - ) - ) - elif operation in ["remove", "delete", "del"]: - self.draft_id_required_error_message(draft_id) - - try: - # delete draft from local variable - del self.bot.VARS["drafts"][draft_id] - except KeyError: # when draft id is not found - await ctx.send( - embed=discord.Embed( - title="Draft does not exist", - description=f"A draft with the id `{draft_id}` was not found. You're trying to delete a draft that does not exist.", - ) - ) - return - - # delete if it's not found in local variable - self.bot.llama_firebase.delete("vars", "drafts", draft_id) - - # feedback - await ctx.send( - embed=discord.Embed( - title="Success!", - description=f"Draft `{draft_id}` has been successfully removed.", - ) - ) - elif operation in ["edit", "e"]: - self.draft_id_required_error_message(draft_id) - - try: # check if draft exists - self.bot.VARS["drafts"][draft_id] - except KeyError: # draft does not exist. Show error message. - await ctx.send( - embed=discord.Embed( - title="Draft does not exists", - description=f"A draft with the id {draft_id} was not found. Create it first.", - ) - ) - return - - # create new embed with default values - new_embed_data = json.loads(self.bot.VARS["drafts"][draft_id]) - new_embed_data["title"] = "title" - new_embed_data["description"] = "description" - new_embed_data["color"] = 0 - new_embed_data["fields"] = [ - {"name": "name1", "value": "value1", "inline": True}, - {"name": "name2", "value": "value2", "inline": True}, - ] - - # update local and database vars - json_embed_data = json.dumps(new_embed_data) - self.bot.VARS["drafts"][draft_id] = json_embed_data - self.bot.llama_firebase.write("vars", "drafts", draft_id, json_embed_data) - - # feedback - await ctx.send( - embed=discord.Embed( - title="Success!", - description=f"Draft `{draft_id}` has been successfully edited.", - ) - ) - elif operation in ["duplicate", "copy", "cp"]: - self.draft_ids_are_required_error_message(draft_id, draft_id2) - - try: # check if draft id is available - if self.bot.VARS["drafts"][draft_id2]: - await ctx.send( - embed=discord.Embed( - title="Name not available", - description=f"A draft with the id `{draft_id2}` already exists. Choose another id.", - ) - ) - return - except KeyError: - pass # draft id is available. Can create a copy. - - # update local and database vars - self.bot.VARS["drafts"][draft_id2] = self.bot.VARS["drafts"][draft_id] - self.bot.llama_firebase.create( - "vars", "drafts", draft_id2, self.bot.VARS["drafts"][draft_id2] - ) - - # feedback - await ctx.send( - embed=discord.Embed( - title="Success!", - description=f"New draft `{draft_id2}` has been created from `{draft_id}`.", - ) - ) - elif operation in ["rename", "rn"]: - self.draft_ids_are_required_error_message(draft_id, draft_id2) - - try: # check if draft id is available - if self.bot.VARS["drafts"][draft_id2]: - await ctx.send( - embed=discord.Embed( - title="Name not available", - description=f"A draft with the id `{draft_id2}` already exists. Choose another id.", - ) - ) - return - except KeyError: - pass # draft id is available. Can rename draft. - - # update local and database vars - self.bot.VARS["drafts"][draft_id2] = self.bot.VARS["drafts"][draft_id] - del self.bot.VARS["drafts"][draft_id] - self.bot.llama_firebase.delete("vars", "drafts", draft_id) - self.bot.llama_firebase.create( - "vars", "drafts", draft_id2, self.bot.VARS["drafts"][draft_id2] - ) - - # feedback - await ctx.send( - embed=discord.Embed( - title="Success!", - description=f"Draft `{draft_id}` has been renamed to`{draft_id2}`.", - ) - ) - elif operation in ["preview", "p"]: - self.draft_id_required_error_message(draft_id) - - try: - await ctx.send( - f"> preview of draft **{draft_id}**", - embed=discord.Embed.from_dict( - json.loads(self.bot.VARS["drafts"][draft_id]) - ), - ) - except KeyError: - await ctx.send( - embed=discord.Embed( - title="Cannot find draft", - description=f"draft `{draft_id}` was not found in the draft database.", - ) - ) - elif operation in ["view", "v"]: - self.draft_id_required_error_message(draft_id) - - await ctx.send( - embed=discord.Embed( - title=draft_id, - description="```%s```" - % json.dumps( - json.loads(self.bot.VARS["drafts"][draft_id]), indent=4 - ), - ) - ) - elif operation in ["list", "l"]: - await ctx.send( - embed=discord.Embed( - title="List of drafts", - description="Nothing found" - if not self.bot.VARS["drafts"] - else "".join([f"\n- **{i}**" for i in self.bot.VARS["drafts"]]), - ) - ) - - -def setup(bot): - bot.add_cog(Admin(bot)) diff --git a/bot/cogs/_logging.py b/bot/cogs/_logging.py deleted file mode 100644 index 64c7ff7..0000000 --- a/bot/cogs/_logging.py +++ /dev/null @@ -1,195 +0,0 @@ -from llama import Llama -from . import _util as util - -import discord -from discord.ext import commands - -import datetime - - -class Logging(commands.Cog): - def __init__(self, bot): - self.bot: Llama = bot - - self.log_edit = True - self.remember_how_many = 3 # how many messages it will remember - - # {CHANNEL_ID: [MSG_UPDATE, ...], ..} - self.edits: dict[int, list[discord.RawMessageUpdateEvent]] = dict() - # {CHANNEL_ID: [[DELETE_TIME, MSG_DELETE], ...], ...} - self.deletes: dict[ - int, list[list[datetime.datetime, discord.RawMessageDeleteEvent]] - ] = dict() - # {CHANNEL_ID: [[DELETE_TIME, MSG_BULK_DELETE], ...], ...} - self.bulk_deletes: dict[ - int, list[list[datetime.datetime, discord.RawBulkMessageDeleteEvent]] - ] = dict() - # {AUTHOR_ID: {CHANNEL_ID: [MSG_UPDATE, ...], ...}, ...} - - # {AUTHOR_ID: {CHANNEL_ID: [MSG_UPDATE, ...], ...}, ...} - self.edits_per_user: dict[ - int, dict[int, list[discord.RawMessageUpdateEvent]] - ] = dict() - # {AUTHOR_ID: {CHANNEL_ID: [MSG_DELETE, ...], ...}, ...} - self.deletes_per_user: dict[ - int, dict[int, list[discord.RawMessageDeleteEvent]] - ] = dict() - - async def cog_check(self, ctx: commands.Context): - if exception_or_bool := await util.on_pm(ctx.message, self.bot): - raise exception_or_bool - return not exception_or_bool - - @commands.Cog.listener() - async def on_raw_message_edit(self, payload: discord.RawMessageUpdateEvent): - # channel level - if payload.channel_id not in self.edits.keys(): - self.edits[payload.channel_id] = [] - - self.edits[payload.channel_id].append(payload) - - if len(self.edits[payload.channel_id]) > self.remember_how_many: - del self.edits[payload.channel_id][0] - - # user level - try: - author_id: int = int(payload.data["author"]["id"]) - except KeyError: - return - - if author_id not in self.edits_per_user.keys(): - self.edits_per_user[author_id] = dict() - - if payload.channel_id not in self.edits_per_user[author_id].keys(): - self.edits_per_user[author_id][payload.channel_id] = [] - - self.edits_per_user[author_id][payload.channel_id].append(payload) - - if ( - len(self.edits_per_user[author_id][payload.channel_id]) - > self.remember_how_many - ): - # todo: queue task to prevent timing issue causing the deletion of the same message - del self.edits_per_user[author_id][payload.channel_id][0] - - @commands.Cog.listener() - async def on_raw_message_delete(self, payload: discord.RawMessageDeleteEvent): - # channel level - if payload.channel_id not in self.deletes.keys(): - self.deletes[payload.channel_id] = [] - - self.deletes[payload.channel_id].append([datetime.datetime.utcnow(), payload]) - - if len(self.deletes[payload.channel_id]) > self.remember_how_many: - del self.deletes[payload.channel_id][0] - - # user level - if payload.cached_message: - author_id = payload.cached_message.author.id - if author_id not in self.deletes_per_user.keys(): - self.deletes_per_user[author_id] = dict() - - if payload.channel_id not in self.deletes_per_user[author_id].keys(): - self.deletes_per_user[author_id][payload.channel_id] = [] - - self.deletes_per_user[author_id][payload.channel_id].append(payload) - - if ( - len(self.deletes_per_user[author_id][payload.channel_id]) - > self.remember_how_many - ): - # todo: queue task to prevent timing issue causing the deletion of the same message - del self.deletes_per_user[author_id][payload.channel_id][0] - - @commands.Cog.listener() - async def on_raw_bulk_message_delete( - self, payload: discord.RawBulkMessageDeleteEvent - ): - if payload.channel_id not in self.bulk_deletes.keys(): - self.bulk_deletes[payload.channel_id] = [] - - self.bulk_deletes[payload.channel_id].append( - [datetime.datetime.utcnow(), payload] - ) - - if len(self.bulk_deletes[payload.channel_id]) > self.remember_how_many: - del self.bulk_deletes[0] - - async def log_edit( - self, channel: discord.TextChannel, payload: discord.RawMessageUpdateEvent - ): - await channel.send( - embed=discord.Embed( - title="Message Edited", - description=f"""**@ Edited their message in: <#CHANNEL> -[jump to message](URL)**""", - ) - .add_field( - name="before", value=payload.cached_message.content, inline=False - ) - .add_field(name="after", value=payload.data["content"], inline=False) - ) - - async def log_delete( - self, channel: discord.TextChannel, payload: discord.RawMessageDeleteEvent - ): - await channel.send(embed=discord.Embed(title="Message Deleted", description="")) - - async def log_bulk_delete( - self, channel: discord.TextChannel, payload: discord.RawBulkMessageDeleteEvent - ): - await channel.send( - embed=discord.Embed(title="Bulk Message Deletion", description="") - ) - - -''' - @commands.command( - help="Shows recently deleted messages and its content. Memory does NOT get wiped after some time.", - usage="""> {prefix}{command} {?depth} -Use it after someone deleted their message. - -Show most recently deleted message -> {prefix}{command} - -Show second most recently deleted message -> {prefix}{command} 2""" - ) - async def snipe(self, ctx, depth=1): - if not self.last_del_message: - await ctx.send(f"There's no message deleted since last reboot!") - return - - author = self.last_del_message.author - await ctx.send( - embed=discord.Embed(description=f"**Message deleted in:** <#{self.last_del_message.channel.id}> [Jump to Message]({self.last_del_message.jump_url})") - .set_thumbnail(url=author.avatar_url) - .add_field(name="Author", value=f"{author.mention} ({author})", inline=False) - .add_field(name="Content", value=self.last_del_message.content, inline=False) - .set_footer(text=f"Deleted at: {self.last_del_time.strftime('%Y-%m-%d %H:%M:%S')} UTC") - ) - - @commands.command( - help="Shows most recently edited message and it's content before and after the edit. Memory gets wiped after some time.", - usage="""> {prefix}{command} {?depth} -Use it after someone edited their message.""" - ) - async def editsnipe(self, ctx, depth=1): - if not self.last_edit_after: - await ctx.send(f"There's no message edited since last reboot!") - return - - author = self.last_edit_after.author - await ctx.send( - embed=discord.Embed(description=f"**Message Edited in:** <#{self.last_edit_after.channel.id}> [Jump to Message]({self.last_edit_after.jump_url})") - .set_thumbnail(url=author.avatar_url) - .add_field(name="Author", value=f"{author.mention} ({author})", inline=False) - .add_field(name="Before", value=self.last_edit_before.content, inline=False) - .add_field(name="After", value=self.last_edit_after.content, inline=False) - .set_footer(text=f"Edited at: {self.last_edit_after.edited_at.strftime('%Y-%m-%d %H:%M:%S')} UTC") - ) -''' - - -def setup(bot): - bot.add_cog(Logging(bot)) diff --git a/bot/cogs/_self_role.py b/bot/cogs/_self_role.py deleted file mode 100644 index 6a078c4..0000000 --- a/bot/cogs/_self_role.py +++ /dev/null @@ -1,258 +0,0 @@ -from llama import Llama -from . import _util as util - -import discord -from discord.ext import commands - -import re - - -class SelfRole(commands.Cog): - def __init__(self, bot): - self.bot: Llama = bot - - # {"CHANNEL_ID/MESSAGE_ID": ["EMOJI_ID_OR_NAME;ROLE_ID", ...], ...} - self.binds: dict = self.bot.llama_firebase.read("vars", "selfrole_messages") - - self.help_msg = "" - self.main_help_fields = [ - ["Self role", "Only admins can create self role message"], - ] - - async def cog_check(self, ctx: commands.Context): - if exception_or_bool := await util.on_pm(ctx.message, self.bot): - raise exception_or_bool - return not exception_or_bool - - # self role add - @commands.Cog.listener() - async def on_raw_reaction_add(self, payload: discord.RawReactionActionEvent): - if ( - payload.member.id == self.bot.user.id - ): # ignore if the user who added the reaction is this bot - return - - try: # try to add get and add reaction - for emoji_role in self.binds[f"{payload.channel_id}/{payload.message_id}"]: - emoji_id_or_name, role_id = emoji_role.split(";") - assert emoji_id_or_name and role_id - if emoji_id_or_name in [payload.emoji.name, str(payload.emoji.id)]: - await payload.member.add_roles( - self.bot.LP_SERVER.get_role(int(role_id)) - ) - except KeyError: - pass # no reaction role bind found - - # self role remove - @commands.Cog.listener() - async def on_raw_reaction_remove(self, payload: discord.RawReactionActionEvent): - try: # try to get and remove reaction - for emoji_role in self.binds[f"{payload.channel_id}/{payload.message_id}"]: - emoji_id_or_name, role_id = emoji_role.split(";") - assert emoji_id_or_name and role_id - if emoji_id_or_name in [payload.emoji.name, str(payload.emoji.id)]: - await ( - await self.bot.LP_SERVER.fetch_member(payload.user_id) - ).remove_roles(self.bot.LP_SERVER.get_role(int(role_id))) - except KeyError: - pass # no reaction role bind found - - @commands.command( - aliases=[ - "rr", - ], - help="Add reactions for self role to a message.", - usage="""`MESSAGE_PATH`: can be `CHANNEL_ID`/`MESSAGE_ID` or a message jump url. - -Add (`EMOJI_1` -> `ROLE_1`) and (`EMOJI_2` -> `ROLE_2`) binds from reaction role message. -> {prefix}{command} `MESSAGE_PATH` `EMOJI_1` `ROLE_1` `EMOJI_2` `ROLE_2` - -Remove (`EMOJI_1` -> `ROLE_1`) and (`EMOJI_2` -> `ROLE_2`) binds from reaction role message. -> {prefix}{command} `MESSAGE_PATH` `EMOJI_1` `ROLE_1` `EMOJI_2` `ROLE_2`""", - ) - @util.must_be_admin() - async def reactrole( - self, ctx, mode, channel_id_or_message_path, *emojis_and_or_roles - ): - _mode = None # 0: create, 1: remove - if mode in ["add", "a"]: - _mode = 0 - elif mode in ["remove", "r"]: - _mode = 1 - else: - raise discord.ext.commands.errors.BadArgument( - f"Invalid input {mode}. Type `-help reactrole` for more information." - ) - - # parse url or message path - flag = 0 - try: - while True: # remove trailing slash(es) - if channel_id_or_message_path[-1] == "/": - channel_id_or_message_path = channel_id_or_message_path[:-1] - else: - break - - # get "CHANNEL_ID/MESSAGE_ID" part of the input - # regex: get the last two number/number pattern. - # regex returns the first pattern that it finds so I had to flip the input with [::-1] and flip it back. - # I know. Big brain. - message_path = re.findall(r"\d+/\d+", channel_id_or_message_path[::-1])[0][ - ::-1 - ] - channel_id, message_id = message_path.split("/") - flag = 1 - channel: discord.TextChannel = await self.bot.fetch_channel(channel_id) - flag = 2 - message: discord.Message = await channel.fetch_message(message_id) - except Exception: - title = "parsing message path" - if flag == 1: - title = "fetching channel" - if flag == 2: - title = "fetching message" - - await ctx.send( - embed=discord.Embed( - title=f"Error while {title}!", - description="Are you sure the inputs are correct?", - ) - ) - raise discord.ext.commands.errors.ArgumentParsingError - - # If can't pair emojis and roles in groups of 2 - if len(emojis_and_or_roles) % 2: - raise discord.ext.commands.errors.BadArgument( - "Failed to group emojis and roles. Number of emojis doesn't match the number of roles." - ) - - async def group_emojis_and_roles(): - """Pair list by groups of 2. - From: https://stackoverflow.com/a/1751478/12979111 - """ - - try: - emojis_and_roles_parsed = [] - emoji_and_role_ids = [] - for emoji_raw, role_raw in [ - emojis_and_or_roles[i : i + 2] - for i in range(0, len(emojis_and_or_roles), 2) - ]: - # convert raw emoji input to integer if it's a custom emoji. Leave it alone otherwise. - # only custom emojis have "<". (<:emojis_name:emoji_id>) - emoji_id = ( - emoji_raw - if "<" not in emoji_raw - else int(re.findall(r"\d+", emoji_raw)[0]) - ) - role_id = int(re.findall(r"\d+", role_raw)[0]) - - # check if role and emojis are valid - emoji = ( - emoji_raw - if emoji_id == emoji_raw - else self.bot.get_emoji(emoji_id) - ) - role = self.bot.LP_SERVER.get_role(role_id) - # todo: check if role is higher than bot - assert emoji, "emoji" - assert role, "role" - - emoji_and_role_ids.append([emoji_id, role_id]) - emojis_and_roles_parsed.append([emoji, role]) - except AssertionError as err: - err_msg = """{one} {two} might not a valid {three} that can be used by the bot. -Are you sure it's not a {three} from other server?""".format( - one=str(err).title(), - two=emoji_raw if err == "emoji" else role_raw, - three=err, - ) - - await ctx.send( - embed=discord.Embed( - title=f"Error while parsing {err}!", description=err_msg - ) - ) - raise discord.ext.commands.errors.BadArgument(err_msg) - return emojis_and_roles_parsed, emoji_and_role_ids - - if _mode == 0: # add bind - if message_path not in self.binds.keys(): - self.binds[message_path] = [] - - emojis_and_roles_parsed, emoji_and_role_ids = await group_emojis_and_roles() - - # add what's not already in the binds - self.binds[message_path] += list( - {f"{emoji};{role}" for emoji, role in emoji_and_role_ids} - - set(self.binds[message_path]) - ) - # push to firebase - self.bot.llama_firebase.write( - "vars", "selfrole_messages", message_path, self.binds[message_path] - ) - # add reaction - for emoji, _ in emojis_and_roles_parsed: - await message.add_reaction(emoji) - elif _mode == 1: # remove bind - if message_path not in self.binds.keys(): - await ctx.send( - embed=discord.Embed( - title=":no_entry_sign: Message does not have any reaction role emojis.", - description=f"No reaction role bind was found in the [message]({message.jump_url})", - ) - ) - - # todo: confirm (clear all existing reactions too or leave them?) - emojis_and_roles_parsed, emoji_and_role_ids = await group_emojis_and_roles() - - # remove binds - for emoji, role in emoji_and_role_ids: - emoji_role = f"{emoji};{role}" - if emoji_role not in self.binds[message_path]: - await ctx.send( - embed=discord.Embed( - title=":no_entry_sign: Reaction role does not exist", - description="Bind (%s -> %s) was not found in the [message](%s)" - % ( - self.bot.get_emoji(emoji), - self.bot.LP_SERVER.get_role(int(role)), - message.jump_url, - ), - ) - ) - continue - - self.binds[message_path].remove(emoji_role) - - await message.remove_reaction(emoji, self.bot.user) - await ctx.send( - embed=discord.Embed( - title=":white_check_mark: Reaction role bind removed!", - description="Reaction role bind (%s -> %s) has been successfully removed from the [message](%s)!" - % ( - self.bot.get_emoji(emoji), - self.bot.LP_SERVER.get_role(int(role)), - message.jump_url, - ), - ) - ) - - # remove list if empty - if not self.binds[message_path]: - self.binds.pop(message_path) - self.bot.llama_firebase.delete( - "vars", "selfrole_messages", message_path - ) - else: - self.bot.llama_firebase.write( - "vars", - "selfrole_messages", - message_path, - self.binds[message_path], - False, - ) - - -def setup(bot): - bot.add_cog(SelfRole(bot)) diff --git a/bot/cogs/_util.py b/bot/cogs/_util.py deleted file mode 100644 index 6d964d7..0000000 --- a/bot/cogs/_util.py +++ /dev/null @@ -1,90 +0,0 @@ -# I'm aware that I can use @commands.bot_has_permissions. It's a choice. -from discord import guild -from llama import Llama - -import discord -from discord.ext import commands - -from datetime import datetime -from typing import Union -import re - - -class NotAdminChannel(discord.ext.commands.errors.CheckFailure): - pass - - -def must_be_admin(): - """ - Discord bot command decorator. - Put it under @discord.ext.commands.command() - """ - - async def predicate(ctx: discord.ext.commands.Context): - if ctx.message.author.guild_permissions.administrator: - return True - await ctx.send( - embed=discord.Embed( - description=f"You need to be a server administrator to issue the command. Aborting." - ) - ) - return False - - return commands.check(predicate) - - -def lists_has_intersection(list1: list, list2: list) -> bool: - """ - Checks if any of the roles in roles1 is in roles2 - """ - return any(element in list1 for element in list2) - - -def url_from_str(string: str) -> list: - """ - Extract urls from string - https://daringfireball.net/2010/07/improved_regex_for_matching_urls - """ - url = re.findall( - r"(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))", - string, - ) - return [x[0] for x in url] - - -def snowflake_to_datetime(snowflake: int): - return datetime.utcfromtimestamp(((int(snowflake) >> 22) + 1420070400000) / 1000) - - -def convert_to_partial_emoji(raw: Union[str, int], bot: Llama) -> discord.PartialEmoji: - # test if raw is an integer - try: - emoji_id: int = int(raw) - - # check if emoji exists - emoji: discord.Emoji = bot.LP_SERVER.get_emoji(emoji_id) - if not emoji: - raise Exception(f"Cannot convert {raw} to discord Emoji.") - - return discord.PartialEmoji( - name=emoji.name, animated=emoji.animated, id=emoji_id - ) - except ValueError: # if emoji_raw is not a number - # todo: test if emoji is valid. - # todo: The checks that can be found online only works for custom emojis and not for emojis like 📌 or 📍. - return discord.PartialEmoji(name=raw.strip()) - - -async def on_pm(message: discord.Message, bot: Llama): - if not message.guild and message.author != bot.user: - err_msg = "DM commands are not supported." - await message.channel.send( - embed=discord.Embed( - title=":exclamation: " + err_msg, - description="react with a `:broom:` :broom: emoji to delete existing messages", - ), - delete_after=5.0, - ) - return commands.NoPrivateMessage(err_msg) - else: - return False diff --git a/bot/cogs/_war_brokers.py b/bot/cogs/_war_brokers.py deleted file mode 100644 index 321f1d5..0000000 --- a/bot/cogs/_war_brokers.py +++ /dev/null @@ -1,330 +0,0 @@ -import wbscraper.player -import wbscraper.commons -import wbscraper.data -import cogs._util as util - -import discord -from discord.ext import commands - - -# todo: add change/remove uid feature -class WarBrokers(commands.Cog): - def __init__(self, bot): - self.bot = bot - - self.LLAMA_BOT = self.bot.get_channel_from_vars("LLAMA_BOT") - self.ADMIN_BOT = self.bot.get_channel_from_vars("ADMIN_BOT") - self.BOT_WORK = [self.LLAMA_BOT, self.ADMIN_BOT] - - # list of string values of WB servers (ASIA, USA, etc.) - self.WB_GAME_SERVERS: list[str] = [ - i - for i in wbscraper.commons.class_to_value_list(wbscraper.data.Location) - if type(i) == str - ] - - self.help_msg = f"<#{self.bot.VARS['channels']['LLAMAS_AND_PYJAMAS_INFO']}> and <#{self.bot.VARS['channels']['ACTIVE']}> automatically updates when the contents of the database is changed." - - self.active_roster_channel = self.bot.LP_SERVER.get_channel( - int(self.bot.VARS["channels"]["ACTIVE"]) - ) - self.lp_info_channel = self.bot.LP_SERVER.get_channel( - int(self.bot.VARS["channels"]["LLAMAS_AND_PYJAMAS_INFO"]) - ) - - async def update_player(self, user_id: int): - """Update LP member list message""" - user_id = int(user_id) - player = self.bot.llama_firebase.read("players", user_id) - stat_page_url = wbscraper.URL.join( - wbscraper.URL.stat_root, "players/i", player["uid"] - ) - player_wb = wbscraper.player.get_player(stat_page_url) - - player_description = ( - f"User: {(await self.bot.LP_SERVER.fetch_member(user_id)).mention}\n" - ) - - try: - player_description += "Preferred Weapon: %s\n" % player["weapon"] - except KeyError: - player_description += "Preferred Weapon: %s\n" % "No Data" - - player_description += "K/D: %.4s\n" % player_wb.kdr - - try: - player_description += "Time Zone: %s\n" % player["time"] - except KeyError: - player_description += "Time Zone: %s\n" % "No Data" - - player_description += f"Stats page: {stat_page_url}\n" - - embed = discord.Embed(title=player_wb.nick, description=player_description) - - # update if stat message is in the database, add to the database otherwise. - try: # try assuming that the stat message exists already - stat_msg = await self.lp_info_channel.fetch_message(player["message_id"]) - await stat_msg.edit(embed=embed) - except (KeyError, discord.NotFound): - info_message = await self.lp_info_channel.send(embed=embed) - self.bot.llama_firebase.write( - "players", user_id, "message_id", info_message.id - ) - - async def update_active(self): - """Update active roster message""" - players = self.bot.llama_firebase.read_collection("players") - - description = "" - for game_server in self.WB_GAME_SERVERS: - description += f"{game_server}:\n" - region_is_empty = True - for player in players: - try: - if game_server in players[player]["server"]: - description += f"<@{player}>\n" - region_is_empty = False - except KeyError: - pass - if region_is_empty: - description += "-- Empty --\n" - description += "\n" - - emoji = discord.utils.get(self.bot.LP_SERVER.emojis, name="blobsalute") - embed = discord.Embed( - title=f"{emoji} LLAMA’S PYJAMAS ACTIVE ROSTER {emoji}", - description=description, - ) - - # make a new message if the active roster doesn't exist, edit otherwise. - try: # assume that the active roster message exists - active_msg = await self.active_roster_channel.fetch_message( - int(self.bot.VARS["messages"]["ACTIVE"]) - ) - await active_msg.edit(embed=embed) - except (KeyError, discord.NotFound): - active_msg = await self.active_roster_channel.send(embed=embed) - self.bot.llama_firebase.write("vars", "messages", "ACTIVE", active_msg.id) - - @commands.command( - help="Sets/updates data in the database.", - usage="""> {prefix}{command} -field: uid | weapon | time | server -data: anything that comes after the field - -> {prefix}{command} uid -**Must run this before running other set commands** -Correlates WB uid with your discord ID. Must be a valid WB uid. -Only correlates with one uid. Alt accounts are not supported yet. -ex: -> {prefix}{command} uid 5d2ead35d142affb05757778 - -> {prefix}{command} weapon -Sets your preferred weapon. No input specifications. -ex: -> {prefix}{command} weapon Sniper & AR - -> {prefix}{command} time