async def auto_unmute(client): """Corutina incluida como tarea en el loop que se ejecuta una vez por segundo y se encarga de desilenciar automáticamente a los usuarios que estén silenciados en cada servidor. Les quita el rol y los borra de la BD. *No lleva parámetros*. """ await client.wait_until_ready() #Espera a que esté listo while not client.is_closed: #Mientras esté abierto el bot servidor = discord.utils.get(client.servers, id="337854421876736003") if servidor != None: #Para cada servidor en el que esté #Conecta con la base de datos o la crea si no existe BD_URL = os.getenv('DATABASE_URL') base_de_datos = psycopg2.connect(BD_URL, sslmode='require') bd = base_de_datos.cursor() bd.execute(tabla_mute.format( '"' + servidor.id + '_silenciados"')) #Crea la tabla de silenciados si no existe #Seleciona la id de usuario y la fecha en que debe levantarse cada silencio (tupla) bd.execute( f'SELECT discord_id, termina FROM "{servidor.id}_silenciados"') tiempos_muteo = bd.fetchall() for usuario in tiempos_muteo: #Por cada pareja usuario-fecha tiempo_unmute = usuario[1] #Le da formato de fecha if datetime.now( ) >= tiempo_unmute: #Lo compara con la hora actual (UTC) miembro = discord.utils.get( servidor.members, id=usuario[0]) #Selecciona el miembro con esa id razon = "Ha transcurrido el tiempo de silencio especificado." #Establece la razón #Define los parámetros para el tiempo del footer pie_embed = pie_texto.format("desilenciado", client.user.name, client.user.name, client.user.discriminator) unmute_embed = crear_embed( client, unmute_titulo, en_descripcion, mute_color, miembro, client.user, servidor, razon, un_usuario, miniatura="avatar", pie=pie_embed, ed=("desilenciado", "en", " y ya puedes hablar de nuevo")) silenciado = get_mute_role( servidor.roles ) #Selecciona el rol de silenciados para el servidor bd.execute( quita_mute.format('"' + servidor.id + '_silenciados"'), (usuario[0], )) #Quita al usuario de la lista en la bd base_de_datos.commit() await client.remove_roles(miembro, silenciado ) #Le quita el rol en el server await client.send_typing( servidor) #Mensaje de "*BOT* está escribiendo" await client.send_message(servidor, embed=unmute_embed[0] ) #Envía el mensaje informativo if len(unmute_embed) == 2: #Si hay un segundo mensaje try: await client.send_message(miembro, embed=unmute_embed[1] ) #Lo manda al usuario except discord.errors.Forbidden: pass bd.close() base_de_datos.close() await asyncio.sleep(1 ) #Encargado de que se ejecute una vez por segundo
async def unmute(client, message, nick_autor, avatar_autor, mensaje_separado, prefijo): """Comando "unmute". Quita el silencio a uno o más usuarios pudiendo especificar una razón (individual para cada uno). Envía un mensaje al servidor por cada usuario desilenciado y uno al propio usuario, incluyendo el motivo (si fue especificado). Parámetros: -Usuario (mención): miembro del servidor que se encuentra silenciado y quieres desilenciar. -Razón: motivo por el cual quieres terminar su silencio. Sintaxis: usuario (razón usuario razón usuario razón usuario razón usuario razón)* * = opcionales.""" if message.mention_everyone == False: if not (message.author.server_permissions.kick_members or message.author.server_permissions.manage_roles): return silenciado = get_mute_role(message.server.roles) for miembro in message.mentions: razon = "" mencion = re.search("<@!?{}>".format(miembro.id), message.content) i = mensaje_separado.index(mencion.group()) + 1 while i < len(mensaje_separado): if not re.search("<@!?[0-9]+>", mensaje_separado[i]): razon += " " + mensaje_separado[i] i += 1 else: i = len(mensaje_separado) razon = borrar_repetidos(razon, " ") if razon == "": razon = "No se ha especificado una razón." pie_embed = pie_texto.format("desilenciado", nick_autor, message.author.name, message.author.discriminator) unmute_embed = crear_embed(client, unmute_titulo, en_descripcion, mute_color, miembro, message.author, message.server, razon, un_usuario, miniatura="avatar", pie=pie_embed, ed=("desilenciado", "en", " y ya puedes hablar de nuevo")) BD_URL = os.getenv("DATABASE_URL") base_de_datos = psycopg2.connect(BD_URL, sslmode='require') bd = base_de_datos.cursor() bd.execute( quita_mute.format('"' + message.server.id + '_silenciados"'), (miembro.id, )) base_de_datos.commit() bd.close() base_de_datos.close() await client.remove_roles(miembro, silenciado) await client.send_typing(message.channel) await client.send_message(message.channel, embed=unmute_embed[0]) if len(unmute_embed) == 2: try: await client.send_message(miembro, embed=unmute_embed[1]) except Forbidden: pass
async def unban(client, message, nick_autor, avatar_autor, mensaje_separado, prefijo): """Comando "unban". Desbanea a un usuario del servidor pudiendo especificar una razón para ello. Envía un mensaje en el servidor y puede, opcionalmente, enviar uno al usuario (si éste los permite) donde figura quién lo desbaneó y la razón (si fue especificada). Parámetros: -Usuario: Nombre de usuario de quien se pretende desbanear. -Razón: (Opcional) Motivo por el que se lo quiere desbanear. -Mensaje SI o NO: (Opcional) Si existe tercer parámetro, se envía un mensaje al usuario. Sintaxis: 1) usuario | razón | Extra 2) usuario; razón; extra Notas: 1) En contraste con el comando "ban", no se puede desbanear a múltiples usuarios de una vez. 2) El tercer parámetro puede ser uno o más carácteres cualquiera. 3) Puede o no haber espacio entre los parámetros y los separadores. 4) Los separadores pueden ser "|" o ";".""" if not message.author.server_permissions.ban_members: return lista = await client.get_bans(message.server) if ";" in message.content: mensaje_separado = message.content.split(";") else: mensaje_separado = message.content.split("|") empieza = 5 + len(prefijo) while mensaje_separado[0][empieza] == " ": mensaje_separado[0] = mensaje_separado[0][ 0:empieza:] + mensaje_separado[0][empieza + 1::] while mensaje_separado[0].endswith(" "): mensaje_separado[0] = mensaje_separado[0][0:len(mensaje_separado[0]) - 1:] if len(mensaje_separado) >= 2: while mensaje_separado[1].startswith(" "): mensaje_separado[1] = mensaje_separado[1][1::] while mensaje_separado[1].endswith(" "): mensaje_separado[1] = mensaje_separado[1][0:len(mensaje_separado[1] ) - 1:] razon = mensaje_separado[1] else: razon = "No se ha especificado ninguna razón" miembro = None for user in lista: if user.name.lower().startswith(mensaje_separado[0][empieza::]): miembro = user if miembro != None: pie_embed = pie_texto.format("desbaneado", nick_autor, message.author.name, message.author.discriminator) unban_embed = crear_embed(client, unban_titulo, del_descripcion, unban_color, miembro, message.author, message.server, razon, un_usuario, miniatura="avatar", pie=pie_embed, ed=("desbaneado", "de", "")) await client.unban(message.server, miembro) await client.send_typing(message.channel) await client.send_message(message.channel, embed=unban_embed[0]) if len(mensaje_separado) >= 3 and len(unban_embed) == 2: try: await client.send_typing(message.channel) await client.send_message(miembro, embed=unban_embed[1]) except Forbidden: pass
async def mute(client, message, nick_autor, avatar_autor, mensaje_separado, prefijo): """Comando "mute". Silencia a uno o más usuarios, impidiéndoles hablar en el servidor por un tiempo determinado. Puede especificarse el motivo por el que se los silencia y el tiempo (10min por defecto). Envía un mensaje al servidor por cada usuario silenciado y otro al propio usuario que incluye el tiempo y el motivo (si fue especificado). Parámetros: -Usuario (mención): miembro del servidor a quien se quiere silenciar. -Tiempo: tiempo durante el que se lo quiere silenciar (si no se especifica, serán 10 minutos). -Razón: motivo por el que se lo quiere silenciar. Sintaxis: 1) usuario (razón tiempo uzuario razón tiempo usuario razón tiempo usuario razón tiempo)* 2) usuario (tiempo razón usuario tiempo razón usuario tiempo razón usuario tiempo razón)* * = opcionales Notas: 1) La razón y el tiempo pueden ser intercambiados en orden. Sin embargo, el primer número que aparezca será usado como parámetro "tiempo". 2) El parámetro tiempo puede ir acompañado por los siguientes sufijos, inmediatamente luego del número y sin espacios: a) a: Años b) w: Semanas c) d: Días d) h: Horas e) m: minutos f) s: segundos De no estar acompañado por ningún sufijo, se asume que el tiempo está en segundos. 3) Una vez transcurrido el tiempo, el silencio es terminado automáticamente (por la corutina auto_unmute). Sin embargo, si deseas desilenciar antes al usuario, puedes usar el comando "unmute". 4) Este sistema funciona con roles, debes crear en tu servidor un rol llamado "CALLATE BOLUDO" o "Muted" y configurar sus permisos para que no pueda hablar. Este comando les dará dicho rol. """ if message.mention_everyone == False: #Evita mutear a todos los usuarios if not (message.author.server_permissions.kick_members or message.author.server_permissions.manage_roles): return silenciado = get_mute_role(message.server.roles) for miembro in message.mentions: mencion = re.search("<@!?{}>".format(miembro.id), message.content) i = mensaje_separado.index(mencion.group()) + 1 razon = "" tiempo = None while i < len(mensaje_separado): if not re.search("<@!?[0-9]+>", mensaje_separado[i]): if tiempo == None: if re.search("[0-9]+[hms]?$", mensaje_separado[i]): try: tiempo = int(mensaje_separado[i]) except ValueError: tiempo = int(mensaje_separado[i] [0:len(mensaje_separado[i]) - 1:]) if mensaje_separado[i].endswith("h"): multiplicador = 60 * 60 tiempo_texto = str(tiempo) + " horas." elif mensaje_separado[i].endswith("m"): multiplicador = 60 tiempo_texto = str(tiempo) + " minutos." else: multiplicador = 1 tiempo_texto = str(tiempo) + " segundos" tiempo *= multiplicador termina_muteo = message.timestamp + timedelta( seconds=tiempo) elif re.search("[0-9]+[awd]?$", mensaje_separado[i]): try: tiempo = int(mensaje_separado[i]) except ValueError: tiempo = int(mensaje_separado[i] [0:len(mensaje_separado[i]) - 1:]) if mensaje_separado[i].endswith("a"): multiplicador = 365 tiempo_texto = str(tiempo) + " años." elif mensaje_separado[i].endswith("w"): multiplicador = 7 tiempo_texto = str(tiempo) + " semanas." else: multiplicador = 1 tiempo_texto = str(tiempo) + " días." tiempo *= multiplicador termina_muteo = message.timestamp + timedelta( days=tiempo) else: razon += " " + mensaje_separado[i] else: razon += " " + mensaje_separado[i] i += 1 else: i = len(mensaje_separado) if razon == "": razon = "No se ha especificado una razón." if tiempo == None: tiempo = 10 * 60 tiempo_texto = "10 minutos." termina_muteo = message.timestamp + timedelta(seconds=tiempo) pie_embed = pie_texto.format("silenciado", nick_autor, message.author.name, message.author.discriminator) mute_embed = crear_embed(client, mute_titulo, en_descripcion, mute_color, miembro, message.author, message.server, razon, frown_usuario, tiempo=tiempo_texto, miniatura="avatar", pie=pie_embed, ed=("silenciado", "en", "")) BD_URL = os.getenv("DATABASE_URL") base_de_datos = psycopg2.connect(BD_URL, sslmode='require') bd = base_de_datos.cursor() bd.execute( tabla_mute.format('"' + message.server.id + '_silenciados"')) bd.execute( quita_mute.format('"' + message.server.id + '_silenciados"'), (miembro.id, )) bd.execute( nuevo_mute.format('"' + message.server.id + '_silenciados"'), (miembro.id, termina_muteo)) base_de_datos.commit() bd.close() base_de_datos.close() await client.add_roles(miembro, silenciado) await client.send_typing(message.channel) await client.send_message(message.channel, embed=mute_embed[0]) if len(mute_embed) == 2: try: await client.send_message(miembro, embed=mute_embed[1]) except Forbidden: pass
async def ban(client, message, nick_autor, avatar_autor, mensaje_separado, prefijo): """Comando "ban" y "kick". Bannea o expulsa a uno o más usuarios especificando una razón (individual para cada uno). Envía un mensaje al servidor por cada usuario baneado o kickeado y, también, uno a cada usuario avisándole e incluyendo el motivo (si fue especificado). Parámetros: -Usuario (mención): miembro del servidor que se quiere bannear/kickear. -Razón: razón por la cual se lo excluye del servidor. Sintaxis: usuario (razón usuario razón usuario razón usuario razón usuario razón)* * = opcionales.""" if message.mention_everyone == False: #Evita banear a todos los usuarios if not message.author.server_permissions.ban_members: return for miembro in message.mentions: if message.author.top_role.position > miembro.top_role.position: razon = "" mencion = re.search("<@!?{}>".format(miembro.id), message.content) i = mensaje_separado.index(mencion.group()) + 1 while i < len(mensaje_separado): if discord.utils.get( message.mentions, id=mensaje_separado[i][2:len(mensaje_separado[i]) - 1:]) == None: razon += " " + mensaje_separado[i] i += 1 else: i = len(mensaje_separado) razon = borrar_repetidos(razon, " ") if razon == "": razon = "No se ha especificado ninguna razón." if message.content.startswith( "ban", len(prefijo), len(prefijo) + 4) or message.content.startswith( "banear", len(prefijo), len(prefijo) + 7): ban_kick = "baneado" emoji = u"\U0000274E" puede = message.author.server_permissions.ban_members else: ban_kick = "expulsado" emoji = u"\U0001F462" puede = message.author.server_permissions.kick_members if puede == False: await client.send_typing(message.channel) await client.send_message( message.channel, "No tienes los permisos necesarios.") return pie_embed = pie_texto.format(ban_kick, nick_autor, message.author.name, message.author.discriminator) ban_embed = crear_embed(client, (emoji, ban_kick), del_descripcion, ban_kick_color, miembro, message.author, message.server, razon, frown_usuario, miniatura="avatar", pie=pie_embed, ed=(ban_kick, "de", "")) if len(ban_embed) == 2: try: await client.send_typing(miembro) await client.send_message(miembro, embed=ban_embed[1]) except Forbidden: pass if ban_kick == "baneado": await client.ban(miembro, delete_message_days=0) else: await client.kick(miembro) await client.send_typing(message.channel) await client.send_message(message.channel, embed=ban_embed[0]) else: await client.send_typing(message.channel) await client.send_message( message.channel, "{} es más profesional que tú, {}".format( miembro.display_name, message.author.display_name))