Beispiel #1
0
 async def garden_dm(self, message):
     # message = dm ?
     if message.channel.type != discord.ChannelType.private:
         return
     # don't read a bot yourself included
     if message.author.bot:
         return
     # log for dm
     sql = f"select channel_id,guild_id from spy_log ;"
     fetched_log_channel = database.fetch_all_line(sql)
     # logger ("logs::garden_dm", f"fetched_log_channel: {fetched_log_channel}")
     if fetched_log_channel:
         for db_log_channel in fetched_log_channel:
             log_channel = await self.bot.fetch_channel(
                 int(db_log_channel[0]))
             guild = log_channel.guild
             if (not message.author in guild.members):
                 continue
             member = message.author
             colour = discord.Colour(0)
             colour = colour.from_rgb(225, 199, 255)
             embed = discord.Embed(colour=colour)
             embed.set_author(icon_url=member.avatar_url,
                              name="DM by " + str(member) + " [" +
                              str(member.id) + "]")
             embed.description = message.content
             embed.timestamp = datetime.utcnow()
             embed.set_footer(text=f"ID: {message.id}")
             try:
                 await log_channel.send(content=None, embed=embed)
             except Exception as e:
                 logger("logs::garden_dm", f" {type(e).__name__} - {e}")
     return
Beispiel #2
0
 async def on_member_update(self, before, after):
     # guild id
     guild_id = before.guild.id
     if not Utils.is_loaded("roledm", guild_id):
         return
     # all roles to listen
     select = f"select role_id from roledm_role where guild_id='{guild_id}'"
     fetched = database.fetch_all_line(select)
     for line in fetched:
         role_id = line[0]
         if (not Utils.has_role(before, role_id)
                 and Utils.has_role(after, role_id)):
             # The member obtained the role
             logger("roledm::on_member_update",
                    'The member obtained the role')
             select = f"select message from roledm_message where guild_id='{guild_id}'and role_id='{role_id}' ;"
             fetched = database.fetch_one_line(select)
             if fetched:
                 message = (fetched[0]).replace("$member",
                                                before.mention).replace(
                                                    "$role",
                                                    f"<@&{role_id}>")
             else:
                 message = Utils.get_text(
                     guild_id, 'welcome_no_message').format(before.mention)
             # send
             await before.send(message)
Beispiel #3
0
 def embed_get_no_result(self, message_id, guild_id, embed):
   # valid message saved ?
   sql = f"select channel_id,closed,month,year from vote_message where message_id='{message_id}' and guild_id='{guild_id}'"
   fetched = database.fetch_one_line(sql)
   if not fetched:
     logger ("vote::embed_get_no_result", "impossibru")
     return
   # vote closure status
   channel_id = int(fetched[0])
   end_proposition = (fetched[1] == 1)
   end_edit = (fetched[1] == 2)
   vote_closed = (fetched[1] == 3)
   month = fetched[2]
   year = fetched[3]
   field = embed.fields[0]
   select = f"select proposition_id,emoji,proposition,ballot from vote_propositions where message_id='{message_id}' order by proposition_id asc ;"
   fetched = database.fetch_all_line(select)
   if not fetched:
     new_value = "\uFEFF"
   else:
     for line in fetched:
       proposition_id = line[0]
       emoji = line[1]
       proposition = line[2]
       ballot = line[3]
       if proposition_id == 1:
         new_value = "- " + emoji + " " + proposition
       else:
         new_value = new_value + "\n - " + emoji + " " + proposition
   field = embed.fields[0]
   embed.clear_fields()
   embed.add_field(name=field.name, value=new_value, inline=False)
   return embed
Beispiel #4
0
 async def blacklist_domain(self,
                            ctx: commands.Context,
                            domain: str = None):
     if not domain:
         await ctx.send(
             Utils.get_text(ctx.guild.id,
                            "error_no_parameter").format("domain"))
         return
     if "." in domain:
         await ctx.send(Utils.get_text(ctx.guild.id, "source_wrong_format"))
         return
     sql = f"SELECT domain FROM source_domain WHERE guild_id='{ctx.guild.id}' ;"
     if domain in [domain[0] for domain in database.fetch_all_line(sql)]:
         await ctx.send(
             Utils.get_text(
                 ctx.guild.id,
                 "source_domain_already_blacklisted").format(domain))
         await ctx.message.add_reaction('❌')
         return
     sql = f"INSERT INTO source_domain VALUES ('{domain}', '{ctx.guild.id}') ;"
     try:
         database.execute_order(sql, [])
         await ctx.message.add_reaction('✅')
     except Exception as e:
         logger("source::blacklist_domain", f"{type(e).__name__} - {e}")
         await ctx.message.add_reaction('❌')
         return
     await ctx.send(
         Utils.get_text(ctx.guild.id,
                        "source_domain_blacklisted").format(domain))
Beispiel #5
0
  async def close_all_vote(self, ctx, message_id: str = None):
    """
    Close all vote
    """
    author = ctx.author
    guild_id = ctx.guild.id
    author = ctx.author
    guild_id = ctx.guild.id
    select = f"select message_id, month, year from vote_message where guild_id='{guild_id}' and closed <> 3 ;"
    fetched = database.fetch_all_line(select)
    if fetched:
      for message in fetched:
        message_id = message[0]
        update = f"update vote_message set closed=3 where message_id='{message_id}' ;"
        try:
          vote_msg = await ctx.channel.fetch_message(message_id)
        except Exception as e:
          if type(e).__name__ == "NotFound":
            await ctx.send(Utils.get_text(ctx.guild.id, "vote_error_message_not_found"))
          elif type(e).__name__ == "Forbidden":
            await ctx.send(Utils.get_text(ctx.guild.id, "error_permission_denied"))
          else:
            await ctx.send(Utils.get_text(ctx.guild.id, "error_unknown_error").format(type(e).__name__, e))
          await self.logger.log('vote_log', author, ctx.message, True)
          await ctx.message.add_reaction('❌')
          return
        embed = vote_msg.embeds[0]
        database.execute_order(update)
        colour = discord.Colour(0)
        colour = colour.from_rgb(255, 71, 71)
        embed.colour = colour
        embed.set_footer(text=f"{message[1]}/{message[2]} Phase de vote terminée")
        await vote_msg.edit(embed=embed)

      await ctx.message.add_reaction('✅')
Beispiel #6
0
 async def update_welcomeuser(self, ctx):
     guild_id = ctx.message.guild.id
     member = ctx.author
     select = f"select role_id from welcome_role where guild_id='{guild_id}'"
     fetched_all = database.fetch_all_line(select)
     if not fetched_all:
         await ctx.send(
             Utils.get_text(ctx.guild.id, "error_no_role_defined"))
         return
     for fetched in fetched_all:
         role_id = int(fetched[0])
         # get the role
         role = ctx.guild.get_role(role_id)
         # write every member
         for member in role.members:
             # sql
             insert = (
                 "insert into welcome_user (`user_id`, `role_id`, `welcomed_at`, `guild_id`)"
                 +
                 f"values ('{member.id}', {role_id},{math.floor(time.time())}, '{guild_id}') ;"
             )
             try:
                 database.execute_order(insert)
             except Exception as e:
                 logger("welcome::update_welcomeuser",
                        f'{type(e).__name__} - {e}')
     await ctx.message.add_reaction('✅')
Beispiel #7
0
 async def remove_domain(self, ctx: commands.Context, domain: str = None):
     if not domain:
         await ctx.send(
             Utils.get_text(ctx.guild.id,
                            "error_no_parameter").format("domain"))
         return
     sql = f"SELECT domain FROM source_domain WHERE guild_id='{ctx.guild.id}' ;"
     if domain not in [
             domain[0] for domain in database.fetch_all_line(sql)
     ]:
         await ctx.send(
             Utils.get_text(ctx.guild.id,
                            "source_domain_not_found").format(domain))
         await ctx.message.add_reaction('❌')
         return
     sql = f"DELETE FROM source_domain WHERE domain='{domain}' and guild_id='{ctx.guild.id}' ;"
     try:
         database.execute_order(sql, [])
         await ctx.message.add_reaction('✅')
     except Exception as e:
         logger("source::remove_domain", f"{type(e).__name__} - {e}")
         await ctx.message.add_reaction('❌')
         return
     await ctx.send(
         Utils.get_text(ctx.guild.id,
                        "source_domain_removed").format(domain))
Beispiel #8
0
 def is_url_in_blacklist(self, url: str, guild_id: str):
     if not Utils.is_valid_url(url):
         return False
     sql = f"SELECT domain FROM source_domain WHERE guild_id='{guild_id}' ;"
     ext = tldextract.extract(url)
     return ext.domain in [
         domain[0] for domain in database.fetch_all_line(sql)
     ]
Beispiel #9
0
 async def list_domains(self, ctx):
     message = ""
     sql = f"SELECT domain FROM source_domain WHERE guild_id='{ctx.guild.id}'"
     domains = [domain[0] for domain in database.fetch_all_line(sql)
                ]  # get the list of the domain
     if len(domains) == 0:
         await ctx.send(Utils.get_text(ctx.guild.id, "source_no_blacklist"))
     for domain in domains:
         message += f"- **{domain}**\n"
     await ctx.send(message)
Beispiel #10
0
 async def list_source_channels(self, ctx):
     message = ""
     sql = f"SELECT channel_id FROM source_channel WHERE guild_id='{ctx.guild.id}'"
     channels = [channel[0] for channel in database.fetch_all_line(sql)
                 ]  # get the list of the channels' id
     if len(channels) == 0:
         await ctx.send(
             Utils.get_text(ctx.guild.id, "source_channel_list_empty"))
     for channel in channels:
         message += f"- **<#{channel}>**\n"
     await ctx.send(message)
Beispiel #11
0
 async def list_rules(self, ctx: commands.Context):
     guild_id = ctx.guild.id
     sql = f"SELECT rule, emoji_text, emoji_id FROM rules_table WHERE guild_id= ? ;"
     rules = database.fetch_all_line(sql, [guild_id])
     colour = discord.Colour(0)
     colour = colour.from_rgb(176, 255, 176)
     embed = discord.Embed(colour=colour,
                           title=Utils.get_text(guild_id, 'rules_list'))
     array_rule = []
     line_rule = ""
     for rule in rules:
         rule_text = rule[0]
         emoji = None
         if rule[1]:
             emoji = rule[1]
         else:
             for guild in self.bot.guilds:
                 try:
                     emoji = str(await guild.fetch_emoji(int(rule[2])))
                 except Exception as e:
                     logger("rules::list_rules",
                            f"{type(e).__name__} - {e}")
                 else:
                     break
         if not emoji:
             raise Exception('Emoji not found', f'id = {rule[2]}')
         if (len(rule_text) > 500):
             rule_text = rule_text[:500] + "[...]"
         current_line = f"[{emoji}] {rule_text}\n"
         if len(line_rule + current_line) > 1024:
             array_rule.append(line_rule)
             line_rule = ""
         line_rule += current_line
     if len(line_rule) == 0:
         await ctx.send(content=None, embed=embed)
         return
     array_rule.append(line_rule)
     total_field = len(array_rule)
     current_field = 1
     for field in array_rule:
         embed.add_field(name=Utils.get_text(guild_id,
                                             'rules_list_title').format(
                                                 current_field,
                                                 total_field),
                         value=field,
                         inline=False)
         current_field += 1
     await ctx.send(content=None, embed=embed)
Beispiel #12
0
 async def do_unload_all(self, ctx):
     """
 Unload cogs for this guild
 """
     author = ctx.author
     guild_id = ctx.guild.id
     try:
         select = ("select   status "
                   "from     config_cog " + "where " + "guild_id=? ;" + "")
         fetched = database.fetch_all_line(select, [guild_id])
         if fetched:
             for line in fetched:
                 if line[0] == 1:
                     update = "update config_cog set status=0 where guild_id=? ;"
                     database.execute_order(update, [guild_id])
     except Exception as e:
         await ctx.message.add_reaction('❌')
         logger("loader::do_unload_all", f"{type(e).__name__} - {e}")
     else:
         await ctx.message.add_reaction('✅')
Beispiel #13
0
    async def is_ban_role(self, ctx, role: discord.Member = None):
        guild_id = ctx.message.guild.id
        author = ctx.author
        if not role:
            await ctx.send(
                Utils.get_text(ctx.guild.id,
                               "error_no_parameter").format('Rôle'))
        select = ("select command, until, role_id from ban_command_role " +
                  f"where guild_id='{guild_id}' " +
                  f"and role_id='{role.id}'" + "order by command ASC" + " ;")
        fetched = database.fetch_all_line(select)
        if not fetched:
            await ctx.send(
                Utils.get_text(ctx.guild.id,
                               "bancommand_no_command_banned_user"))
            return
        to_ret = []
        role_name = role.name
        to_ret_string = f"**{role_name}**\n"
        for line in fetched:
            command = line[0]
            until = line[1]
            temp = ""
            # parse until
            if until:
                # date = Utils.format_time (until)
                date = datetime.utcfromtimestamp(until).strftime(
                    Utils.get_text(ctx.guild.id, 'bancommand_date_format'))
            else:
                date = Utils.get_text(ctx.guild.id, 'bancommand_permanent')
            temp = (f"{command} [" + f"{date}]")
            if len(to_ret_string) + len(temp) >= 2000:
                to_ret.append(to_ret_string)
                to_ret_string = f"**{role_name}**\n"
            to_ret_string = to_ret_string + temp + "\n"
        if len(to_ret_string):
            to_ret.append(to_ret_string)

        for message_to_ret in to_ret:
            await ctx.send(message_to_ret)
        logger("bancommand::is_ban_role", f"to_ret: {to_ret}")
Beispiel #14
0
 async def ask_for_source(self, message: discord.Message):
     if not message.guild:
         return
     guild_id = message.guild.id
     if not Utils.is_loaded("source", guild_id):
         return
     url = re.search("(?P<url>https?://[^\s]+)", message.content)
     url = url.group("url") if url else None
     if "source" in message.content.lower():
         return
     if len(message.attachments) == 0 and (
             not url or not (self.is_url_in_blacklist(
                 url, guild_id or Utils.is_url_image(url)))):
         return
     sql = f"SELECT channel_id FROM source_channel WHERE guild_id=? ;"
     if not str(message.channel.id) in [
             channel[0]
             for channel in database.fetch_all_line(sql, [guild_id])
     ]:
         return
     response = self.get_source_message(message.author.id, message.guild.id)
     await message.channel.send(response)
Beispiel #15
0
    async def list_ban_role(self, ctx, command: str = None):
        guild_id = ctx.message.guild.id
        author = ctx.author
        if command:
            # Check if command exists
            all_commands = self.bot.commands
            cont_after = False
            for garden_command in all_commands:
                if command == garden_command.name or command in garden_command.aliases:
                    command = garden_command.name
                    cont_after = True
                if cont_after:
                    break
            if not cont_after:
                await ctx.send(
                    Utils.get_text(ctx.guild.id,
                                   "error_unknown_command").format(command))
                return
        select = ("select command, until, role_id from ban_command_role " +
                  f"where guild_id='{guild_id}' " +
                  (f" and command = '{command}' " if command else "") +
                  "order by command ASC" + " ;")
        fetched = database.fetch_all_line(select)
        if not fetched:
            if not command:
                await ctx.send(
                    Utils.get_text(ctx.guild.id,
                                   "bancommand_no_command_banned_user"))
            else:
                await ctx.send(
                    Utils.get_text(ctx.guild.id,
                                   "bancommand_no_user_banned_command").format(
                                       f'**{command}**'))
            return
        to_ret = []
        to_ret_string = ""
        current_command = ""
        for line in fetched:
            command = line[0]
            until = line[1]
            role_id = int(line[2])
            if not current_command == command:
                current_command = command
                to_ret_string = to_ret_string + f"\n**{current_command}**\n"
            temp = ""
            role = ctx.guild.get_role(role_id)
            role_name = role.name
            # parse until
            if until:
                # date = Utils.format_time (until)
                date = datetime.utcfromtimestamp(until).strftime(
                    Utils.get_text(ctx.guild.id, 'bancommand_date_format'))
            else:
                date = Utils.get_text(ctx.guild.id, 'bancommand_permanent')
            temp = (f"{role_name} [" + f"{date}]")
            if len(to_ret_string) + len(temp) >= 2000:
                to_ret.append(to_ret_string)
                to_ret_string = f"**{current_command}**\n"
            to_ret_string = to_ret_string + temp + "\n"
        if len(to_ret_string):
            to_ret.append(to_ret_string)

        for message_to_ret in to_ret:
            await ctx.send(message_to_ret)
        logger("bancommand::list_ban_role", f"to_ret: {to_ret}")
Beispiel #16
0
  async def handle_result(self, ctx, message_id, handle, permission_needed):
    author = ctx.author
    guild_id = ctx.guild.id
    error = False
    if not message_id:
      # search for the lastest vote in that channel
      select = f"select message_id from vote_message where channel_id={ctx.channel.id} and closed=0 ;"
      fetched = database.fetch_one_line(select)
      if not fetched:
        await ctx.send(Utils.get_text(ctx.guild.id, "vote_error_message_not_found"))
        await self.logger.log('vote_log', author, ctx.message, True)
        await ctx.message.add_reaction('❌')
        return  # Send 'Hi what is your proposition'
      message_id = fetched[0]
    if not message_id:
      await ctx.send(Utils.get_text('fr', 'error_no_parameter').format('<messageID>'))
      await ctx.message.add_reaction('❌')
      await self.logger.log('vote_log', author, ctx.message, True)
      return
    try:
      message_id = int(message_id)
    except Exception as e:
      await ctx.send(Utils.get_text('fr', 'error_message_id_invalid'))
      await ctx.message.add_reaction('❌')
      await self.logger.log('vote_log', author, ctx.message, True)
      return
    # valid message saved ?
    sql = f"select channel_id,closed,month,year from vote_message where message_id='{message_id}' and guild_id='{guild_id}'"
    fetched = database.fetch_one_line(sql)
    if not fetched:
      await ctx.send(Utils.get_text(ctx.guild.id, "error_message_id_not_found").format(message_id))
      await self.logger.log('vote_log', author, ctx.message, True)
      await ctx.message.add_reaction('❌')
      return
    # vote closure status
    channel_id = int(fetched[0])
    closure_status = fetched[1]
    end_proposition = (fetched[1] == 1)
    end_edit = (fetched[1] == 2)
    vote_closed = (fetched[1] == 3)
    month = fetched[2]
    year = fetched[3]
    # get the message
    try:
      channel = ctx.guild.get_channel(channel_id)
      vote_msg = await channel.fetch_message(message_id)
    except Exception as e:
      if type(e).__name__ == "NotFound":
        await ctx.send(Utils.get_text(ctx.guild.id, "error_message_id_not_found").format(message_id))
      elif type(e).__name__ == "Forbidden":
        await ctx.send(Utils.get_text(ctx.guild.id, "error_permission_denied"))
      else:
        await ctx.send(Utils.get_text(ctx.guild.id, "error_unknown_error").format(type(e).__name__, e))
      await self.logger.log('vote_log', author, ctx.message, True)
      await ctx.message.add_reaction('❌')
      return
    embed = vote_msg.embeds[0]

    if handle == "description":
      ask = await ctx.send(Utils.get_text(ctx.guild.id, "vote_choose_vote_description"))
    elif handle == "title":
      ask = await ctx.send(Utils.get_text(ctx.guild.id, "vote_ask_vote_title"))
    elif handle == "proposition_line":
      logger ("vote::add_proposition", "handle proposition_line")
      if end_proposition or end_edit or vote_closed:
        await ctx.send(Utils.get_text(ctx.guild.id, "vote_proposition_phase_end"))
        return
      ask = await ctx.send(Utils.get_text(ctx.guild.id, "vote_ask_proposition"))
    elif handle == "end_proposition":
      if closure_status > 0:
        await ctx.message.add_reaction('❌')
        feedback = await ctx.send(Utils.get_text(ctx.guild.id, "vote_cannot_close_proposition_phase"))
        await ctx.message.delete(delay=0.5)
        await feedback.delete(delay=1.5)
        return
      update = f"update vote_message set closed=1 where message_id='{message_id}'"
      database.execute_order(update, [])
      proposition_ended_at = math.floor(time.time())
      update = f"update vote_time set proposition_ended_at='{proposition_ended_at}' where message_id='{message_id}'"
      database.execute_order(update, [])
      colour = discord.Colour(0)
      colour = colour.from_rgb(20, 20, 255)
      embed.colour = colour
      embed.set_footer(text=f"{month}/{year} Phase de proposition terminée")
      await vote_msg.edit(embed=embed)
      await ctx.message.add_reaction('✅')
      await ctx.message.delete(delay=0.5)
      return
    elif handle == "end_edit":
      if closure_status > 1:
        await ctx.message.add_reaction('❌')
        feedback = await ctx.send(Utils.get_text(ctx.guild.id, "vote_cannot_close_edition_phase"))
        await ctx.message.delete(delay=0.5)
        await feedback.delete(delay=1.5)
        return
      update = f"update vote_message set closed=2 where message_id='{message_id}'"
      database.execute_order(update, [])
      edit_ended_at = math.floor(time.time())
      update = f"update vote_time set edit_ended_at='{edit_ended_at}' where message_id='{message_id}'"
      database.execute_order(update, [])
      colour = discord.Colour(0)
      colour = colour.from_rgb(56, 255, 56)
      embed.colour = colour
      embed.set_footer(text=f"{month}/{year} Phase de vote")
      await vote_msg.edit(embed=embed)
      await ctx.message.add_reaction('✅')
      await ctx.message.delete(delay=0.5)
      return
    elif handle == "close_vote":
      if closure_status > 2:
        await ctx.message.add_reaction('❌')
        feedback = await ctx.send(Utils.get_text(ctx.guild.id, "vote_cannot_close_vote_phase"))
        await ctx.message.delete(delay=0.5)
        await feedback.delete(delay=1.5)
        return
      update = f"update vote_message set closed=3 where message_id='{message_id}'"
      database.execute_order(update, [])
      vote_ended_at = math.floor(time.time())
      update = f"update vote_time set vote_ended_at='{vote_ended_at}' where message_id='{message_id}'"
      database.execute_order(update, [])
      colour = discord.Colour(0)
      colour = colour.from_rgb(255, 71, 71)
      embed.colour = colour
      embed.set_footer(text=f"{month}/{year} Phase de vote terminée")
      embed = self.embed_get_result(message_id, guild_id, embed)
      await vote_msg.edit(embed=embed)
      await ctx.message.add_reaction('✅')
      await ctx.message.delete(delay=0.5)
      return
    elif handle == "end_proposition_at":
      ask = await ctx.send(Utils.get_text(ctx.guild.id, "vote_new_proposition_closing"))
    elif handle == "end_vote_at":
      ask = await ctx.send(Utils.get_text(ctx.guild.id, "vote_new_closing"))
    elif handle == "remove_proposition":
      if end_edit or vote_closed:
        await ctx.send(Utils.get_text(ctx.guild.id, "cannot_close_proposition_phase_2"))
        return
      ask = await ctx.send(Utils.get_text(ctx.guild.id, "vote_choose_proposition_delete"))
    elif handle == "edit_proposition":
      if end_edit or vote_closed:
        await ctx.send(Utils.get_text(ctx.guild.id, "cannot_close_proposition_phase_3"))
        return
      ask = await ctx.send(Utils.get_text(ctx.guild.id, "vote_choose_proposition_edit"))
    elif handle == "reset_vote":
      if closure_status < 2:
        await ctx.message.add_reaction('❌')
        feedback = await ctx.send(Utils.get_text(ctx.guild.id, "vote_cannot_reset_vote"))
        await ctx.message.delete(delay=0.5)
        await feedback.delete(delay=1.5)
        return
      # reset all ballots
      self.reset_all_ballots(message_id)
      # reset all reactions
      for reaction in vote_msg.reactions:
        async for user in reaction.users():
          if user.id != self.bot.user.id:
            await reaction.remove(user)
      # repoen vote
      update = f"update vote_message set closed=2 where message_id='{message_id}'"
      database.execute_order(update)
      edit_ended_at = math.floor(time.time())
      update = f"update vote_time set edit_ended_at='{edit_ended_at}', vote_ended_at=NULL where message_id='{message_id}'"
      database.execute_order(update)
      colour = discord.Colour(0)
      colour = colour.from_rgb(56, 255, 56)
      embed.colour = colour
      embed.set_footer(text=f"{month}/{year} Phase de vote")
      embed = self.embed_get_no_result(message_id, guild_id, embed)
      await vote_msg.edit(embed=embed)
      await ctx.message.add_reaction('✅')
      await ctx.message.delete(delay=0.5)
      return
    check = lambda m: m.channel == ctx.channel and m.author == ctx.author
    msg = await self.bot.wait_for('message', check=check)
    if handle == "proposition_line":
      logger ("vote::add_proposition", "get infos")
      proposition = msg.content
      ask_emoji = await ctx.send(Utils.get_text(ctx.guild.id, "vote_ask_emoji"))
      msg_emoji = await self.bot.wait_for('message', check=check)
      emoji = msg_emoji.content
      logger ("vote::add_proposition", "test if emoji already exists")
      # test if emoji already exists
      select = f"select emoji from vote_propositions where message_id='{message_id}' and emoji='{emoji}' ;"
      logger ("vote::add_proposition", "select {}".format (select))
      fetched = database.fetch_one_line(select)
      if fetched:
        err_feedback = await ctx.send(Utils.get_text(ctx.guild.id, "vote_emoji_already_used_add"))
        await err_feedback.delete(delay=1)
        error = True
      else:
        # test emoji by using it in reaction
        try:
          await vote_msg.add_reaction(emoji)
        except Exception as e:
          feedback = await ctx.send(Utils.get_text(ctx.guild.id, "vote_emoji_invalid"))
          error = True
          logger ("vote::handle_result", f"vote_emoji_invalid {type(e).__name__} - {e}")
          await feedback.delete(delay=2)
        else:
          field = embed.fields[0]
          # get last id
          select = f"select proposition_id from vote_propositions where message_id='{message_id}' order by proposition_id desc limit 1 ;"
          fetched = database.fetch_one_line(select)
          if not fetched:
            last_id = 0
          else:
            last_id = int(fetched[0])
          # insert proposition : `proposition`,`emoji` , `proposition_id` ,`author_id` , `message_id`
          sql = f"insert into vote_propositions values (?, ?, {last_id + 1}, '{ctx.author.id}', '{message_id}', 0) ;"
          try:
            database.execute_order(sql, [proposition, emoji])
          except Exception as e:
            logger ("vote::handle_result", f"insert vote_propositions {type(e).__name__} - {e}")
          else:
            # create line
            if last_id == 0:
              new_value = "[" + str(last_id + 1) + "] - " + emoji + " " + proposition
            else:
              new_value = field.value + "\n[" + str(last_id + 1) + "] - " + emoji + " " + proposition
            embed.clear_fields()
            embed.add_field(name=field.name, value=new_value, inline=False)
            await vote_msg.edit(embed=embed)
      await msg_emoji.delete(delay=0.5)
      await ask_emoji.delete(delay=0.5)
      logger ("proposition_line", "END")
    elif handle == "description":
      embed.description = msg.content
    elif handle == "title":
      embed.title = msg.content
    elif handle == "end_proposition_at" or handle == "end_vote_at":
      try:
        date_time = parser.parse(msg.content, dayfirst=True)
        timestamp = datetime.timestamp(date_time)
        if timestamp < math.floor(time.time()):
          error_message = await ctx.send(Utils.get_text(ctx.guild.id, "error_date_invalid"))
          await error_message.delete(delay=1)
          error = True
        else:
          update = f"update vote_time set "
          if handle == "end_proposition_at":
            update = update + "proposition_ended_at "
          else:
            update = update + "vote_ended_at "
          update = update + f"= '{timestamp}' where message_id='{message_id}'"
          database.execute_order(update)
      except Exception as e:
        logger ("vote::handle_result", f"set end_prop_at and end_vote_at {type(e).__name__} - {e}")
        error_message = await ctx.send(Utils.get_text(ctx.guild.id, "error_date_format"))
        await error_message.delete(delay=1)
        error = True
    elif handle == "remove_proposition":
      try:
        proposition_id = int(msg.content)
      except Exception as e:
        logger ("vote::handle_result", f"remove_proposition {type(e).__name__} - {e}")
        await ctx.send(Utils.get_text(ctx.guild.id, "error_not_integer"))
        error = True
      else:
        if end_proposition:
          # modo
          select = f"select emoji from vote_propositions where message_id='{message_id}' and proposition_id={proposition_id} ;"
        else:
          # user
          select = f"select emoji from vote_propositions where message_id='{message_id}' and author_id='{ctx.author.id}' and proposition_id={proposition_id} ;"
        fetched_proposition = database.fetch_one_line(select);
        if fetched_proposition:
          delete = f"delete from vote_propositions where message_id='{message_id}' and proposition_id={proposition_id} ;"
          update = f"update vote_propositions set proposition_id=proposition_id-1 where message_id='{message_id}' and proposition_id>{proposition_id} ;"
          try:
            database.execute_order(delete)
            database.execute_order(update)
            new_value = ""
            select = f"select proposition_id,emoji,proposition from vote_propositions where message_id='{message_id}' ;"
            fetched = database.fetch_all_line(select)
            await vote_msg.remove_reaction(fetched_proposition[0], self.bot.user)  # remove emoji
            if not fetched:
              new_value = "\uFEFF"
            else:
              for line in fetched:
                proposition_id = line[0]
                emoji = line[1]
                proposition = line[2]
                if proposition_id == 1:
                  new_value = "[" + str(proposition_id) + "] - " + emoji + " " + proposition
                else:
                  new_value = new_value + "\n[" + str(proposition_id) + "] - " + emoji + " " + proposition
            field = embed.fields[0]
            embed.clear_fields()
            embed.add_field(name=field.name, value=new_value, inline=False)
          except Exception as e:
            await ctx.message.add_reaction('❌')
            logger ("vote::handle_result", f"remove_proposition{type(e).__name__} - {e}")
            await ctx.send(Utils.get_text(ctx.guild.id, "error_occured"))
            error = True
        else:
          error = True
          await ctx.send(Utils.get_text(ctx.guild.id, "vote_proposition_not_found").format(f'#{proposition_id}'))
    elif handle == "edit_proposition":
      try:
        proposition_id = int(msg.content)
      except Exception as e:
        logger ("vote::handle_result", f"edit_proposition {type(e).__name__} - {e}")
        await ctx.send(Utils.get_text(ctx.guild.id, "error_not_integer"))
        error = True
      else:
        if end_proposition or Utils.is_authorized(ctx.author, guild_id):
          # modo
          select = f"select emoji from vote_propositions where message_id='{message_id}' and proposition_id={proposition_id} ;"
        else:
          # user
          select = f"select emoji from vote_propositions where message_id='{message_id}' and author_id='{ctx.author.id}' and proposition_id={proposition_id} ;"
        fetched_proposition = database.fetch_one_line(select);
        if fetched_proposition:
          ask_line = await ctx.send(Utils.get_text(ctx.guild.id, "vote_new_proposition"))
          msg_line = await self.bot.wait_for('message', check=check)
          ask_emoji = await ctx.send(Utils.get_text(ctx.guild.id, "vote_new_emoji"))
          msg_emoji = await self.bot.wait_for('message', check=check)
          proposition = msg_line.content
          emoji = msg_emoji.content
          # test if emoji already exists
          select = f"select emoji from vote_propositions where message_id='{message_id}' and emoji='{emoji}' and proposition_id <> {proposition_id} ;"
          fetched = database.fetch_one_line(select)
          if fetched:
            err_feedback = await ctx.send(Utils.get_text(ctx.guild.id, "vote_emoji_already_used_edit"))
            await err_feedback.delete(delay=1)
            error = True
          else:
            # test emoji by using it in reaction
            try:
              await vote_msg.remove_reaction(fetched_proposition[0], self.bot.user)  # remove emoji
              await vote_msg.add_reaction(emoji)
            except Exception as e:
              feedback = await ctx.send(Utils.get_text(ctx.guild.id, "vote_emoji_invalid"))
              error = True
              await vote_msg.add_reaction(fetched_proposition[0])
              logger ("vote::handle_result", f"edit_proposition {type(e).__name__} - {e}")
              await feedback.delete(delay=2)
            else:
              field = embed.fields[0]
              # get last id
              select = f"select proposition_id from vote_propositions where message_id='{message_id}' order by proposition_id desc limit 1 ;"
              fetched = database.fetch_one_line(select)
              if not fetched:
                last_id = 0
              else:
                last_id = int(fetched[0])
              update = f"update vote_propositions set proposition=?, emoji=? where message_id='{message_id}' and proposition_id={proposition_id} ;"
              try:
                database.execute_order(update, [proposition, emoji])
                new_value = ""
                select = f"select proposition_id,emoji,proposition from vote_propositions where message_id='{message_id}' order by proposition_id asc ;"
                fetched = database.fetch_all_line(select)
                if not fetched:
                  new_value = "\uFEFF"
                else:
                  for line in fetched:
                    proposition_id = line[0]
                    emoji = line[1]
                    proposition = line[2]
                    if proposition_id == 1:
                      new_value = "[" + str(proposition_id) + "] - " + emoji + " " + proposition
                    else:
                      new_value = new_value + "\n[" + str(proposition_id) + "] - " + emoji + " " + proposition
                field = embed.fields[0]
                embed.clear_fields()
                embed.add_field(name=field.name, value=new_value, inline=False)
              except Exception as e:
                await ctx.message.add_reaction('❌')
                logger ("vote::handle_result", f"edit_proposition {type(e).__name__} - {e}")
                await ctx.send(Utils.get_text(ctx.guild.id, "error_occured"))
                error = True
          await msg_line.delete(delay=0.5)
          await ask_line.delete(delay=0.5)
          await msg_emoji.delete(delay=0.5)
          await ask_emoji.delete(delay=0.5)
        else:
          error = True
          await ctx.send(Utils.get_text(ctx.guild.id, "vote_proposition_not_found").format(f'#{proposition_id}'))

    await vote_msg.edit(embed=embed)
    if error:
      await ctx.message.add_reaction('❌')
    else:
      await ctx.message.add_reaction('✅')
    await self.logger.log('vote_log', author, ctx.message, error)
    await self.logger.log('vote_log', author, msg, error)
    await ask.delete(delay=0.5)
    await msg.delete(delay=0.5)
    await ctx.message.delete(delay=0.5)
Beispiel #17
0
 async def on_member_update(self, before, after):
     # guild id
     guild_id = before.guild.id
     # logger ("welcome::on_member_update", f'guild_id: {guild_id}')
     if not Utils.is_loaded("welcome", guild_id):
         return
     unique_welcome = True  # to put on config later
     # all roles to listen
     select = f"select role_id from welcome_role where guild_id='{guild_id}'"
     fetched = database.fetch_all_line(select)
     #logger ("welcome::on_member_update", f'fetched: {fetched}')
     for line in fetched:
         role_id = int(line[0])
         if (not Utils.has_role(before, role_id)
                 and Utils.has_role(after, role_id)):
             # The member obtained the role
             logger("welcome::on_member_update",
                    'The member obtained the role')
             # already welcomed ?
             if unique_welcome:
                 select = f"select * from welcome_user where user_id='{before.id}' and guild_id='{guild_id}' and role_id={role_id} ;"
                 fetched = database.fetch_one_line(select)
                 if fetched:
                     # already welcomed !
                     logger("welcome::on_member_update", 'already welcomed')
                     return
             # get the channel
             channel = None
             select = f"select channel_id from welcome_channel where guild_id='{guild_id}' ;"
             fetched = database.fetch_one_line(select)
             if fetched:
                 channel_id = fetched[0]
                 channel = before.guild.get_channel(int(channel_id))
             if not channel:
                 logger("welcome::on_member_update", 'Not channel')
                 channel = before.guild.system_channel
             # get the message
             select = f"select message from welcome_message where guild_id='{guild_id}' and role_id={role_id} ; "
             fetched = database.fetch_one_line(select)
             if fetched:
                 text = ""
                 # split around '{'
                 text_rand = (fetched[0]).split('{')
                 logger("welcome::on_member_update",
                        f"text_rand: {text_rand}")
                 for current in text_rand:
                     parts = current.split('}')
                     logger("welcome::on_member_update", f"parts: {parts}")
                     for part in parts:
                         all_rand = part.split("|")
                         logger("welcome::on_member_update",
                                f"all_rand: {all_rand}")
                         current_part = all_rand[random.randint(
                             0,
                             len(all_rand) - 1)]
                         logger("welcome::on_member_update",
                                f"current_part: {current_part}")
                         text = text + current_part
                 """
       if text.startswith('{') and text.endswith('}'):
         # random
         text = text [1:len(text)-1]
         all_rand = text.split ("|")
         index = random.randint(0,len(all_rand)-1)
         text = all_rand [index]
       """
                 message = text.replace("$member", before.mention).replace(
                     "$role", f"<@&{role_id}>")
             else:
                 message = Utils.get_text(
                     guild_id, 'welcome_user_1').format(before.mention)
             # send
             await channel.send(message)
             # save welcome
             if unique_welcome:
                 sql = (
                     "insert into welcome_user " +
                     " (`user_id`, `role_id`, `welcomed_at` ,`guild_id`) " +
                     " values " +
                     f"('{before.id}', {role_id}, {math.floor(time.time())}, '{guild_id}') ;"
                 )
                 database.execute_order(sql)