import json import logging import os import random import re import shutil from datetime import datetime import discord import numpy as np from discord.ext import commands, tasks from ai_functions import get_random_cyclic_message from constants import ( ENCODING, LAST_SPONTANEOUS_CALL, LOGFILE, LOGSTORE, MEMORY_FIVE_MUZYKA, MEMORY_FIVE_SIARA, TIME_BETWEEN_CALLS, ) class AdministrationModule(commands.Cog): def __init__(self, bot, logger_name): self.bot = bot self.logger = logging.getLogger(logger_name) @commands.hybrid_command( name="galeria_slaw", description="Jeśli nie wiesz jak użyć tej komendy to nawet nie próbuj", guild=discord.Object(id=664789470779932693), ) async def galeria_slaw(self, ctx): for guild in self.bot.guilds: async for entry in guild.bans(limit=1500): fnord = discord.File( "/home/pi/Conjurer/niech_spierdala.png", spoiler=False, description="Niech spierdala", ) await ctx.reply( f"User: {entry.user} wyjebany z serwera {guild.name} za {entry.reason} ", file=fnord, ) @commands.hybrid_command( name="update_banlist", description="Jeśli nie wiesz jak użyć tej komendy to nawet nie próbuj", guild=discord.Object(id=664789470779932693), ) async def update_banlist(self, ctx): """ Update a banlist in a Discord guild from preprovided list in channel. :param ctx: ctx stands for "context" and is a parameter commonly used in Discord.py commands. It contains information about the context in which the command was invoked, such as the message, the channel, the server, and the user who invoked the command. This information can be used to perform various actions, such """ async with ctx.channel.typing(): allowed = False for role in ctx.author.roles: if role.name == "Jarl": allowed = True if ctx.channel.id != 1102190666827702342: # trunk-ignore(codespell/misspelled) await ctx.send("Nie wydaje mnie sie") elif not allowed: await ctx.send("Idź bo Cię zdziele") else: tobancunter = 0 async with ctx.typing(): # 1. get list of users posted on channel for banning channel = ctx.channel messages = [ message async for message in channel.history(limit=None) ] ids_to_ban = [] for message in messages: lines = message.content.split("\n") for line in lines: match = re.search( "\\d{18}", line, # trunk-ignore(codespell/misspelled) ) # poprawilem backslash na podwojny bo linter sie czepial if match: ids_to_ban.append(match.group()) tobancunter += 1 # 2. get list of already banned users for all servers Conjurer # has rights to for guild in self.bot.guilds: bancunter = 0 # trunk-ignore(codespell/misspelled) self.logger.info("Serwer: %s", guild) current_banlist = [] permission = True try: async for entry in guild.bans(limit=None): current_banlist.append(entry.user.id) bancunter += 1 except BaseException: # pylint: disable=broad-exception-caught permission = False if permission: # 3. compare lists ban only users on list 2 and not on # list 1 cunter_counter = 0 bad_id_cunter_counter = 0 ban_list = np.setdiff1d(ids_to_ban, current_banlist) for ident in ban_list: try: tmp_user = await self.bot.fetch_user(int(ident)) await guild.ban( tmp_user, reason="Automatyczna lista banów", delete_message_seconds=0, ) # TODO: Maybe use guild.bulk_ban ? cunter_counter += 1 except discord.NotFound: self.logger.info( "Znaleziono uzyszkodnika ktory juz nie ma konta" ) bad_id_cunter_counter += 1 # 4. return message success/failure - how many banned await ctx.send( "Obecnie na serwerze {guild} jest {bancunter} zbanowanych użytkowników. Znaleziono na tym kanale {tobancunter} id użytkowników do zbanowania. Zbanowano {cunter_counter} użytkowników. Na liście jest {bad_id_cunter_counter} użytkowników którzy skasowali już konto" ) else: await ctx.send( f"Nie mam na serwerze {guild} uprawnień do banowania. :()" ) await ctx.send("Zrobione tak czy inaczej") async def archive_channel(self, channel_no): """ The function `archive_channel` retrieves messages from a specified channel, processes them, and saves the data in a JSON file with a timestamp in the filename. :param channel_no: The `archive_channel` function you provided seems to be incomplete. It looks like you are trying to archive messages from a Discord channel into a JSON file """ channel = self.bot.get_channel(channel_no) messages = [message async for message in channel.history(limit=None)] path_newfile = f"{LOGSTORE}channeldump_{channel_no}_{datetime.now()}.json" new_data = [] for message in messages: new_data.append(message) with open(path_newfile, "x", encoding=ENCODING) as new_file: new_file.seek(0) json.dump(new_data, new_file, indent=4) @tasks.loop(seconds=120) async def check_self(self): """ The function `check_data` periodically checks for conditions to send messages and manage log files in a Discord channel. """ # logger.info("Heartbeat of cleanup proc") channel = self.bot.get_channel(1062047367337095268) messages = [message async for message in channel.history(limit=1)] for mess in messages: channel = mess.channel if os.path.getsize(LOGFILE) > 60000000: await channel.send( "*Conjurer porządkuje bar, wypala szklanki do czysta miotaczem płomieni ze swojej zbroi i ogólnie wygląda na zajętego....*" ) async with channel.typing(): shutil.copyfile(LOGFILE, f"{LOGSTORE}discord{datetime.now()}") self.logger.info("Log rollover") handlers = self.logger.handlers for handler in handlers: if isinstance(handler, logging.handlers.RotatingFileHandler): handler.doRollover() await channel.send( "*Przeciąga się za barem* No dobra - porobione to można dalej pi... *Zauważa spojrzenie Hammera* ...sać powieści o naszym wspaniałym barze SZEFIE!" ) if os.path.getsize(MEMORY_FIVE_MUZYKA) > 3000000: await channel.send( "*Conjurer porządkuje bar, wypala szklanki do czysta miotaczem płomieni ze swojej zbroi i ogólnie wygląda na zajętego....*" ) async with channel.typing(): path_newfile = f"{LOGSTORE}pamiec_muzyki{datetime.now()}.json" self.logger.info(path_newfile) with open( MEMORY_FIVE_MUZYKA, "r+", encoding=ENCODING ) as file_music_memory: with open(path_newfile, "x", encoding=ENCODING) as new_file: # First we load existing data into a dict. file_data = json.load(file_music_memory) new_data = [] new_data.append(file_data[0]) new_data.extend(file_data[:-20]) file_music_memory.truncate(0) file_music_memory.seek(0) # convert back to json. new_file.seek(0) json.dump(new_data, file_music_memory, indent=4) json.dump(file_data, new_file, indent=4) await channel.send( "*Przeciąga się za barem* No dobra - porobione to można dalej pi... *Zauważa spojrzenie Hammera* ...sać powieści o naszym wspaniałym barze SZEFIE!" ) if os.path.getsize(MEMORY_FIVE_SIARA) > 3000000: path_newfile = f"{LOGSTORE}pamiec_rozmow{datetime.now()}.json" self.logger.info(path_newfile) await channel.send( "*Conjurer porządkuje bar, ścina lekkim laserem pulsacyjnym powierzchnie baru o grubości kilku mikronów i ogólnie wygląda na zajętego....*" ) with open(MEMORY_FIVE_SIARA, "r+", encoding=ENCODING) as file: with open(path_newfile, "x", encoding=ENCODING) as new_file: # First we load existing data into a dict. file_data = json.load(file) new_data = [] new_data.append(file_data[0]) new_data.extend(file_data[-20]) file.truncate(0) file.seek(0) new_file.seek(0) # convert back to json. json.dump(new_data, file, indent=4) json.dump(file_data, new_file, indent=4) await channel.send( "*Przeciąga się za barem* No dobra - porobione to można dalej pi... *Zauważa spojrzenie Hammera* eprzyć o głupotach z klientami... Szefie... *Bierze 'ukradkowy' łyk z piersiówki*" ) global LAST_SPONTANEOUS_CALL global TIME_BETWEEN_CALLS tdelta = datetime.now() - LAST_SPONTANEOUS_CALL tdelta = tdelta.total_seconds() if tdelta > TIME_BETWEEN_CALLS: self.logger.info("Spontaneous call") # trunk-ignore(bandit/B311) TIME_BETWEEN_CALLS = random.randint( 10200, 272800 ) # temp random, set after each call self.logger.debug(TIME_BETWEEN_CALLS) LAST_SPONTANEOUS_CALL = datetime.now() async with channel.typing(): message = await get_random_cyclic_message() self.logger.info("Odpowiedz") self.logger.info(message) await channel.send(message) async def setup(bot): logger = logging.getLogger("discord") am = AdministrationModule(bot, "discord") await bot.add_cog(am) am.check_self.start() logger.info("Loading administration commands module done")