Advertisement
MrShandy

Untitled

Jan 23rd, 2022
693
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.79 KB | None | 0 0
  1. import configparser
  2.  
  3. import discord
  4. from discord.ext import commands
  5.  
  6. import cache
  7. import database
  8. import errors
  9. from reports import Reports
  10.  
  11. config = configparser.ConfigParser()
  12. config.read("config.ini", encoding='utf-8')
  13.  
  14. db = database.Database(
  15.     host=config["DB"]["server"],
  16.     user=config["DB"]["login"],
  17.     database=config["DB"]["database"],
  18.     password=config["DB"]["password"],
  19.     port=config["DB"].getint("port")
  20. )
  21.  
  22. cache = cache.Cache()
  23.  
  24. auth_guilds = [560201762196422666, 489527439710617612]  # сервера, на которые бот может зайти
  25.  
  26.  
  27. class ReportButtons(discord.ui.View):
  28.     def __init__(self):
  29.         super().__init__(timeout=None)
  30.  
  31.     @discord.ui.button(
  32.         label="Закрыть",
  33.         style=discord.ButtonStyle.danger,
  34.         custom_id="sgb:report_close",
  35.         emoji="❌"
  36.     )
  37.     async def close(self, button: discord.ui.Button, interaction: discord.Interaction):
  38.         message = await interaction.response.send_message(f"Button clicked {button.custom_id}", ephemeral=True,
  39.                                                           delete_after=10)
  40.         print(message)
  41.  
  42.     @discord.ui.button(
  43.         label="Переназначить МД",
  44.         style=discord.ButtonStyle.blurple,
  45.         custom_id="sgb:report_reassign_moderator",
  46.         emoji="🔨"
  47.     )
  48.     async def reassign_md(self, button: discord.ui.Button, interaction: discord.Interaction):
  49.         message = await interaction.response.send_message(f"Button clicked {button.custom_id}", ephemeral=True,
  50.                                                           delete_after=10)
  51.         print(message)
  52.  
  53.     @discord.ui.button(
  54.         label="Закрыть успешно",
  55.         style=discord.ButtonStyle.success,
  56.         custom_id="sgb:report_close_successfully",
  57.         emoji="✅"
  58.     )
  59.     async def close_success(self, button: discord.ui.Button, interaction: discord.Interaction):
  60.         message = await interaction.response.send_message(f"Button clicked {button.custom_id}", ephemeral=True,
  61.                                                           delete_after=10)
  62.         print(message)
  63.  
  64.  
  65. class Bot(commands.Bot):
  66.     def __init__(self, ):
  67.         super().__init__(command_prefix='some prefix', help_command=None,
  68.                          intents=discord.Intents(guilds=True, members=True, presences=True),
  69.                          message_commands=False, slash_commands=True, slash_command_guilds=[489527439710617612])
  70.  
  71.         self.persistent_views_added = False
  72.  
  73.     async def on_ready(self):
  74.         if not self.persistent_views_added:
  75.             self.add_view(ReportButtons())
  76.             self.add_view(ModeratorsDropdown())
  77.  
  78.  
  79. bot = Bot()
  80. bot.add_cog(Reports(bot, cache, db, ReportButtons))
  81.  
  82.  
  83. @bot.event
  84. async def on_ready():
  85.     cache.cache_data()
  86.     # проверка серверов бота и выход из ненужных
  87.     for guild in bot.guilds:
  88.         if guild.id not in auth_guilds:
  89.             await guild.leave()
  90.     print(f"Bot start as {bot.user}")
  91.  
  92.  
  93. @bot.event
  94. async def on_guild_join(guild: discord.Guild):
  95.     # выход из сервера, если его нет в списке
  96.     if guild.id not in auth_guilds:
  97.         await guild.leave()
  98.  
  99.  
  100. @bot.event
  101. async def on_command_error(ctx: commands.Context, exception: commands.CommandError):
  102.     print(type(exception), exception)
  103.     if isinstance(exception, errors.ReportAlreadyOpen):
  104.         embed = discord.Embed(title="❌ У вас уже есть открытый репорт!",
  105.                               description="Нельзя иметь больше одного открытого репорта, дождитесь решения предыдущего")
  106.         await ctx.send(embed=embed, ephemeral=True)
  107.     elif isinstance(exception, commands.MissingPermissions):
  108.         embed = discord.Embed(title="❌ У вас нет прав!",
  109.                               description="Вы не можете использовать эту команду, так как у вас нет прав")
  110.         await ctx.send(embed=embed, ephemeral=True)
  111.  
  112.  
  113. @bot.command()
  114. @commands.has_permissions(administrator=True)
  115. async def settings(ctx: commands.Context, channels_category: discord.CategoryChannel, moderators_role: discord.Role,
  116.                    logs_channel: discord.TextChannel):
  117.     """Установить категорию и роль модераторов"""
  118.     server = cache.get_server(ctx.guild.id)
  119.     webhook = await logs_channel.create_webhook(name="SG Bot logs")
  120.     try:
  121.         old_webhook = await bot.fetch_webhook(server.webhook_id)
  122.         await old_webhook.delete(reason="Был выпущен новый")
  123.     except discord.NotFound:
  124.         print("webhook not found")
  125.     server.webhook_id = webhook.id
  126.     server.moderators_role_id = moderators_role.id
  127.     server.channels_category_id = channels_category.id
  128.     server.sync_data()
  129.     embed = discord.Embed(title="Данные изменены ✅",
  130.                           description="Вы успешно изменили данные сервера.\nТеперь установлены следующие:")
  131.     embed.add_field(name="ID категории", value=channels_category.id, inline=True)
  132.     embed.add_field(name="ID роли модераторов", value=moderators_role.id, inline=True)
  133.     embed.add_field(name="Webhook ID", value=webhook.id)
  134.     await ctx.send(embed=embed, ephemeral=True)
  135.  
  136.  
  137. bot.run(config["Config"]["token"])
  138.  
  139. ### reports.py
  140. import datetime
  141. import random
  142. from typing import Optional, Literal
  143.  
  144. import discord
  145. from discord.ext import commands
  146.  
  147. import errors
  148. from cache import Cache
  149. from database import Database
  150.  
  151.  
  152. class Reports(commands.Cog):
  153.     def __init__(self, bot, cache, database, report_buttons):
  154.         self.bot: commands.Bot = bot
  155.         self.cache: Cache = cache
  156.         self.db: Database = database
  157.         self.report_buttons = report_buttons
  158.  
  159.     @commands.Cog.listener()
  160.     async def on_guild_channel_delete(self, channel: discord.abc.GuildChannel):
  161.         if channel.category_id != self.cache.get_server(channel.guild.id).channels_category_id:
  162.             return
  163.         report: Cache.Report = self.cache.get_report(channel_id=channel.id)
  164.         if report is None:
  165.             return
  166.         report.status = "Closed: channel deleted"
  167.         report.closing_time = datetime.datetime.now()
  168.         report.closed_moderator_id = report.assigned_moderator_id  # нельзя узнать кто удалил канал без лишних запросов
  169.         report.sync_data()
  170.  
  171.  
  172.     @commands.group(name="report")
  173.     async def report(self, ctx):
  174.         """report"""
  175.         pass
  176.  
  177.     @report.command(name="member")
  178.     async def report_member(
  179.             self,
  180.             ctx: commands.Context,
  181.             member: discord.Member = commands.Option(description="Участник, на которого вы подаете жалобу"),
  182.             title: str = commands.Option(description="Краткое описание ситуации", name="title"),
  183.             description: str = commands.Option(description="Подробное описание ситуации", name="description"),
  184.             rule: Optional[
  185.                 Literal[
  186.                     "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "1.12", "1.13", "2.1", "2.2", "2.3", "2.4"]
  187.             ] = commands.Option(description="Правило, которое нарушил пользователь"),
  188.             proof: Optional[str] = commands.Option(
  189.                 description="Доказательство (картинка или другой файл). Вставьте прямую ссылку на файл")
  190.     ):
  191.         """Отправить жалобу на пользователя"""
  192.         await self.create_report(ctx, "member", title, description, member, rule, proof)
  193.  
  194.     @report.command(name="other")
  195.     async def report_other(
  196.             self,
  197.             ctx: commands.Context,
  198.             title: str = commands.Option(description="Краткое описание ситуации", name="title"),
  199.             description: str = commands.Option(description="Подробное описание ситуации", name="description"),
  200.             rule: Optional[
  201.                 Literal[
  202.                     "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "1.12", "1.13", "2.1", "2.2", "2.3", "2.4"]
  203.             ] = commands.Option(description="Правило, которое нарушил пользователь"),
  204.             proof: Optional[str] = commands.Option(
  205.                 description="Доказательство (картинка или другой файл). Вставьте прямую ссылку на файл")
  206.     ):
  207.         """Отправить жалобу по другой причине"""
  208.         await self.create_report(ctx, "other", title, description, None, rule, proof)
  209.  
  210.     async def create_report(self, ctx: commands.Context, type: str, title: str, description: str,
  211.                             member: discord.Member = None,
  212.                             rule: str = None, proof: str = None):
  213.         """The function that the /report commands use to create reports"""
  214.  
  215.         async def choice_moderator(excluded_member: discord.Member = None) -> discord.Member:
  216.             moderators_role = ctx.guild.get_role(self.cache.get_server(ctx.guild.id).moderators_role_id)
  217.             moderators = list()
  218.             moderators_online = list()
  219.             for moder in moderators_role.members:
  220.                 if excluded_member is not None:
  221.                     if moder.id is excluded_member.id:
  222.                         continue
  223.                 if moder.status is not discord.Status.offline:
  224.                     moderators_online.append(moder)
  225.                     moderators.append(moder)
  226.                 else:
  227.                     moderators.append(moder)
  228.             if moderators_online:
  229.                 return random.choice(moderators_online)
  230.             else:
  231.                 return random.choice(moderators)
  232.  
  233.         for report in self.cache.reports.values():
  234.             if report.applicant_id == ctx.author.id and report.status == "Open":
  235.                 raise errors.ReportAlreadyOpen("You already have an open report #%s" % report.id)
  236.  
  237.         embed = discord.Embed(
  238.             title=title,
  239.             description=description,
  240.             color=0xff9900,
  241.             timestamp=datetime.datetime.now()
  242.         )
  243.         embed.set_author(name=ctx.author, icon_url=ctx.author.avatar.url)
  244.         embed.set_footer(text=f"Тип обращения: {type}")
  245.         embed.add_field(name='Истец', value=ctx.author.mention, inline=True)
  246.         if member is not None:
  247.             embed.add_field(name='Ответчик', value=member.mention, inline=True)
  248.         moderator = await choice_moderator(member)
  249.         embed.add_field(name="Назначенный модератор", value=moderator.mention, inline=True)
  250.         if rule is not None:
  251.             embed.add_field(name="Нарушенное правило", value=rule, inline=False)
  252.         if proof is not None:
  253.             embed.add_field(name="Доказательство", value=proof, inline=True)
  254.         created_report = self.cache.add_report(
  255.             applicant_id=ctx.author.id,
  256.             respondent_id=member.id if member is not None else None,
  257.             title=title,
  258.             description=description,
  259.             rule=rule,
  260.             proof=proof,
  261.             assigned_moderator_id=moderator.id,
  262.             creation_time=datetime.datetime.now(),
  263.             type=type,
  264.             current_moderator_id=moderator.id
  265.         )
  266.         overwrites = {
  267.             ctx.guild.default_role: discord.PermissionOverwrite(view_channel=False),
  268.             ctx.author: discord.PermissionOverwrite(view_channel=True, send_messages=True, read_messages=True,
  269.                                                     attach_files=True),
  270.             moderator: discord.PermissionOverwrite(view_channel=True, send_messages=True, read_messages=True,
  271.                                                    attach_files=True, manage_channels=True),
  272.         }
  273.         if member is not None:
  274.             overwrites[member] = discord.PermissionOverwrite(view_channel=True, send_messages=True, read_messages=True,
  275.                                                              attach_files=True)
  276.         channel = await ctx.guild.create_text_channel(
  277.             name=f"Репорт №{created_report.id}",
  278.             topic=description,
  279.             category=ctx.guild.get_channel_or_thread(self.cache.get_server(ctx.guild.id).channels_category_id),
  280.             reason=f"Report №{created_report.id}",
  281.             overwrites=overwrites
  282.         )
  283.         created_report.change_data(channel_id=channel.id)
  284.         message = await channel.send(
  285.             f"Назначенные люди: {member.mention if member is not None else ''} {ctx.author.mention} {moderator.mention}",
  286.             embed=embed, view=self.report_buttons())
  287.         embed_success = discord.Embed(title="Репорт создан ✅",
  288.                                       description="Ваш репорт создан и ждет рассмотрения модераторами. Вы можете перейти к нему по ссылкам ниже")
  289.         embed_success.add_field(name="Канал", value=channel.mention)
  290.         embed_success.add_field(name="Сообщение", value=f"[Ссылка на сообщение]({message.jump_url})")
  291.         embed_success.set_footer(text="Powered by Shandy")
  292.         embed_success.set_author(name=f"Номер обращения: {created_report.id}", url=message.jump_url)
  293.         await ctx.send(embed=embed_success, ephemeral=True)
  294.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement