Mempron

Untitled

May 18th, 2022
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.58 KB | None | 0 0
  1. import traceback
  2.  
  3. import discord
  4. from discord import app_commands
  5. from discord.ext import commands
  6. import psycopg2
  7. import vkbottle
  8. from vkbottle import VKAPIError
  9.  
  10. import typing
  11. from random import randint
  12. from dataclasses import dataclass
  13.  
  14. from config import config
  15. from text import text
  16. from Utils.get_targets import get_targets
  17.  
  18.  
  19. @dataclass
  20. class User:
  21.     ds_id: int
  22.     vk_id: int
  23.  
  24.  
  25. class Confirm(discord.ui.View):
  26.     def __init__(self):
  27.         super().__init__()
  28.         self.value = None
  29.  
  30.     @discord.ui.button(label='Подтвердить', style=discord.ButtonStyle.green)
  31.     async def confirm(self, interaction: discord.Interaction, button: discord.ui.Button):
  32.         self.value = True
  33.         self.stop()
  34.  
  35.     @discord.ui.button(label='Отменить', style=discord.ButtonStyle.red)
  36.     async def cancel(self, interaction: discord.Interaction, button: discord.ui.Button):
  37.         self.value = False
  38.         self.stop()
  39.  
  40.  
  41. class PingCog(commands.Cog):
  42.     def __init__(self, bot):
  43.         self.bot = bot
  44.  
  45.     @app_commands.command(name='ping', description=text['ping_description'])
  46.     @app_commands.guilds(config.dbot.privileged_guild)
  47.     @app_commands.checks.has_any_role(*config.dbot.privileged_roles)
  48.     @app_commands.describe(
  49.         target=text['ping_describe_target'],
  50.         note=text['ping_describe_note']
  51.     )
  52.     @app_commands.choices(choice=[
  53.         app_commands.Choice(name='в беседу и в лс', value=0),
  54.         app_commands.Choice(name='только в беседу', value=1),
  55.         app_commands.Choice(name='только в лс', value=2)
  56.     ])
  57.     async def ping(
  58.             self,
  59.             interaction: discord.Interaction,
  60.             target: typing.Union[discord.Role, discord.Member],
  61.             choice: app_commands.Choice[int],
  62.             note: str = None
  63.     ):
  64.         await interaction.response.defer()
  65.  
  66.         targets = await get_targets(interaction, target)
  67.  
  68.         if targets:
  69.             data_base_connection = psycopg2.connect(
  70.                 host=config.db.host,
  71.                 port=config.db.port,
  72.                 database=config.db.name,
  73.                 user=config.db.user,
  74.                 password=config.db.password
  75.             )
  76.             data_base_cursor = data_base_connection.cursor()
  77.  
  78.             data_base_cursor.execute(
  79.                 f'SELECT ds_id, vk_id '
  80.                 f'FROM "Users" '
  81.                 f'WHERE ds_id IN ({", ".join(str(target.id) for target in targets)}); ')
  82.             users = [User(*user) for user in data_base_cursor.fetchall()]
  83.  
  84.             data_base_cursor.close()
  85.             data_base_connection.close()
  86.  
  87.             vk = vkbottle.API(config.vbot.token)
  88.             vk_users = await vk.users.get(user_ids=[user.vk_id for user in users])
  89.  
  90.             users.sort(key=lambda user: user.vk_id)
  91.             vk_users.sort(key=lambda vk_user: vk_user.id)
  92.  
  93.             targets = [[target, None] for target in targets]
  94.  
  95.             for target in targets:
  96.                 for i in range(len(users)):
  97.                     if target[0].id == users[i].ds_id:
  98.                         target[1] = vk_users[i]
  99.                         break
  100.                 target = (target[0], target[1])
  101.  
  102.             where = ''
  103.             if choice.value == 0:
  104.                 where = 'в беседу и в личные сообщения'
  105.             elif choice.value == 1:
  106.                 where = 'в беседу'
  107.             elif choice.value == 2:
  108.                 where = 'в личные сообщения'
  109.  
  110.             list_users = ''
  111.             for target in targets:
  112.                 list_users += f'\n\u2022 {target[0].mention}'
  113.                 if target[1]:
  114.                     list_users += f' \u2192 ' \
  115.                                   f'[{target[1].first_name} {target[1].last_name}](https://vk.com/id{target[1].id})'
  116.  
  117.             embed = discord.Embed(
  118.                 title=text['ping_embed_confirm_form_title'],
  119.                 description=text['ping_embed_confirm_form_description'].format(
  120.                     total=str(len(targets)),
  121.                     where=where,
  122.                     list_users=list_users
  123.                 ),
  124.                 colour=discord.Colour.dark_gold()
  125.             )
  126.             embed.set_image(url=text['ping_embed_confirm_form_image'])
  127.             view = Confirm()
  128.  
  129.             if len(targets) != 1:
  130.                 await interaction.followup.send(embed=embed, view=view)
  131.                 await view.wait()
  132.                 await interaction.edit_original_message(embed=embed, view=None)
  133.             else:
  134.                 view.value = True
  135.  
  136.             if view.value:
  137.                 await interaction.edit_original_message(view=None)
  138.                 channel_name = interaction.channel.name
  139.                 try:
  140.                     if interaction.channel.parent:
  141.                         channel_name = interaction.channel.parent.name + ' \u2192 ' + channel_name
  142.                 except AttributeError:
  143.                     pass
  144.  
  145.                 if note:
  146.                     note = f'\nЗаметка:\n{note}'
  147.                 else:
  148.                     note = ''
  149.  
  150.                 not_success_ping = []
  151.  
  152.                 if choice.value == 0 or choice.value == 1:
  153.  
  154.                     list_users_to_ping = ''
  155.                     for target in targets:
  156.                         if target[1]:
  157.                             list_users_to_ping += f'\n[id{target[1].id}|{target[0].name}]'
  158.                         else:
  159.                             list_users_to_ping += f'\n{target[0].name}'
  160.                             if target not in not_success_ping:
  161.                                 not_success_ping.append(target)
  162.  
  163.                     await vk.messages.send(
  164.                         peer_id=2000000002,
  165.                         random_id=randint(0, 100000),
  166.                         message=text['ping_vk_group_chat_message'].format(
  167.                             ds_users_names=list_users_to_ping,
  168.                             channel=channel_name,
  169.                             note=note
  170.                         )
  171.                     )
  172.  
  173.                 if choice.value == 0 or choice.value == 2:
  174.                     for target in targets:
  175.                         if target[1]:
  176.                             try:
  177.                                 await vk.messages.send(
  178.                                     peer_id=target[1].id,
  179.                                     random_id=randint(0, 100000),
  180.                                     message=text['ping_vk_direct_message'].format(
  181.                                         vk_user_name=target[1].first_name,
  182.                                         channel=channel_name,
  183.                                         note=note
  184.                                     )
  185.                                 )
  186.                             except VKAPIError[901]:
  187.                                 if target not in not_success_ping:
  188.                                     not_success_ping.append(target)
  189.                         else:
  190.                             if target not in not_success_ping:
  191.                                 not_success_ping.append(target)
  192.  
  193.                 success_ping = []
  194.                 if len(targets) > len(not_success_ping):
  195.                     check = [user[0].id for user in not_success_ping]
  196.                     for target in targets:
  197.                         if target[0].id not in check:
  198.                             success_ping.append(target)
  199.  
  200.                 if not_success_ping:
  201.                     linked_accounts_names = ''
  202.  
  203.                     for target in not_success_ping:
  204.                         linked_accounts_names += f'\n\u2022 {target[0].mention}'
  205.                         if target[1]:
  206.                             linked_accounts_names += f' \u2192 [{target[1].first_name} {target[1].last_name}]' \
  207.                                                      f'(https://vk.com/id{target[1].id})'
  208.  
  209.                     embed = discord.Embed(
  210.                         title=text['ping_embed_error_VKAPIError_901_title'],
  211.                         description=text['ping_embed_error_VKAPIError_901_description'].format(
  212.                             linked_accounts_names=linked_accounts_names
  213.                         ),
  214.                         colour=discord.Colour.brand_red()
  215.                     )
  216.                     embed.set_image(url=text['ping_embed_error_VKAPIError_901_image'])
  217.  
  218.                     await interaction.edit_original_message(embed=embed, view=None)
  219.                     interaction.extras['message_edited'] = True
  220.  
  221.                     format_text = ''
  222.                     for user in not_success_ping:
  223.                         if user[1]:
  224.                             format_text += f'\n[id{user[1].id}|{user[0].name}]'
  225.                         else:
  226.                             format_text += f'\n{user[0].name}'
  227.  
  228.                     await vk.messages.send(
  229.                         peer_id=2000000005,
  230.                         random_id=randint(0, 100000),
  231.                         message=f'Не смог пингануть или упомянуть {where} следующих:'
  232.                                 f'{format_text}\n'
  233.                                 f'Откуда: {channel_name}\n'
  234.                                 f'{note}'
  235.                     )
  236.                     if len(not_success_ping) == 1:
  237.                         return
  238.  
  239.                 if success_ping:
  240.                     format_list = ''
  241.                     for target in success_ping:
  242.                         format_list += f'\n\u2022 {target[0].mention} \u2192 [{target[1].first_name} ' \
  243.                                        f'{target[1].last_name}]' \
  244.                                        f'(https://vk.com/id{target[1].id})'
  245.  
  246.                     embed = discord.Embed(
  247.                         title=text['ping_embed_error_not_full_title'],
  248.                         description=text['ping_embed_error_not_full_description'].format(
  249.                             ds_users_names=format_list
  250.                         ),
  251.                         colour=discord.Colour.dark_magenta()
  252.                     )
  253.                     embed.set_image(url=text['ping_embed_error_not_full_image'])
  254.  
  255.                     if interaction.extras.get('message_edited', True):
  256.                         await interaction.followup.send(embed=embed)
  257.                     else:
  258.                         await interaction.edit_original_message(embed=embed, view=None)
  259.  
  260.                     format_text = ''
  261.                     for user in success_ping:
  262.                         format_text += f'\n[id{user[1].id}|{user[0].name}]'
  263.                     await vk.messages.send(
  264.                         peer_id=2000000005,
  265.                         random_id=randint(0, 100000),
  266.                         message=f'Пинганул или упомянул {where} следующих:'
  267.                                 f'{format_text}\n'
  268.                                 f'Откуда: {channel_name}\n'
  269.                                 f'{note}'
  270.                     )
  271.             else:
  272.                 await interaction.delete_original_message()
  273.         else:
  274.             embed = discord.Embed(
  275.                 title=text['ping_embed_error_no_targets_title'],
  276.                 description=text['ping_embed_error_no_targets_description'],
  277.                 colour=discord.Colour.random()
  278.             )
  279.             embed.set_image(url=text['ping_embed_error_no_targets_image'])
  280.             await interaction.followup.send(embed=embed)
  281.  
  282.  
  283. async def setup(bot):
  284.     await bot.add_cog(PingCog(bot), guilds=[discord.Object(id=config.dbot.privileged_guild)])
  285.  
Add Comment
Please, Sign In to add comment