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
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)
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
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))
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('✅')
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('✅')
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))
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) ]
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)
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)
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)
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('✅')
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}")
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)
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}")
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)
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)