Пример #1
0
    async def removecog(self, ctx: commands.Context, *args: str):
        """Rimuove una o più cog dal bot e dal file extensions.json se presente così da
        non caricarla più a ogni futuro riavvio del bot. Occorre passare il nome esatto della cog da
        aggiungere, che deve trovarsi nella cartella cogs del bot.

        Sintassi:
        <removecog nome_cog              # rimuove nome_cog dal bot e dal file extensions.json
        <removecog nome_cog altra_cog    # più cogs separate da spazio
        """
        if not args:
            await ctx.send('Devi specificare il nome della cog da rimuovere.',
                           delete_after=5)
            await ctx.message.delete(delay=5)
        else:
            with open('extensions.json', 'r') as file:
                extensions = json.load(file)
            removed: str = ''
            for ext in args:
                ext = 'cogs.' + ext
                if ext in extensions:
                    extensions.remove(ext)
                try:
                    self.bot.unload_extension(ext)
                except commands.ExtensionError as e:
                    await ctx.send('Impossibile rimuovere ' + ext)
                    print(e)
                else:
                    removed += '`' + ext + '` '
            if removed != '':
                await self.logger.log('estensioni ' + removed +
                                      'rimosse correttamente')
                await ctx.send('Estensioni ' + removed +
                               'rimosse correttamente.')
            shared_functions.update_json_file(extensions, 'extensions.json')
Пример #2
0
def adjust_vote_count(payload: discord.RawReactionActionEvent,
                      change: int) -> None:
    """Aggiusta il contatore dei voti in base al parametro passato. Stabilisce in autonomia
    se il voto è a favore o contrario guardando il tipo di emoji cambiata.

    :param payload: l'evento di rimozione dell'emoji
    :param change: variazione del voto (+1 o -1)
    """
    try:
        with open('proposals.json', 'r') as file:
            proposals: Dict[str, Dict[str, Any]] = json.load(file)
    except FileNotFoundError:
        print('errore nel file delle proposte')
        return
    try:
        proposal = proposals[str(payload.message_id)]
    except KeyError:
        print('impossibile trovare la proposta')
        return
    if str(payload.emoji.name).__eq__('\U0001F7E2'):  # sarebbe :green_circle:
        proposal['yes'] += change
        if proposal['yes'] < 0:
            proposal['yes'] = 0
        if proposal['yes'] >= proposal['threshold']:
            proposal['passed'] = True
        else:
            # è possibile cambiare idea, il controllo lo fa la task
            proposal['passed'] = False
    else:
        proposal['no'] += change
        if proposal['no'] < 0:
            proposal['no'] = 0
    shared_functions.update_json_file(proposals, 'proposals.json')
Пример #3
0
def add_proposal(message: discord.Message, guild: discord.Guild) -> None:
    """Aggiunge la proposta al file proposals.json salvando timestamp e numero di membri attivi
    in quel momento.

    :param message: messaggio mandato nel canale proposte da aggiungere
    :param guild: il server discord
    """
    proposals: Dict[str, Dict[str, Any]] = {}
    try:
        with open('proposals.json', 'r') as file:
            proposals = json.load(file)
    except FileNotFoundError:
        print('file non trovato, lo creo ora')
        with open('proposals.json', 'w+') as file:
            proposals = {}
    active_count = 2  # moderatori non hanno ruolo attivo
    members = guild.members
    active_role = guild.get_role(Config.get_config().active_role_id)
    for member in members:
        if not member.bot:
            if active_role in member.roles:
                active_count += 1
    proposal = {
        'timestamp': datetime.date(message.created_at).__str__(),
        'total_voters': active_count,
        'threshold': calculate_threshold(active_count),
        'passed': False,
        'yes': 0,
        'no': 0,
        'content': message.content
    }
    # save as string for coherency with the loading
    proposals[str(message.id)] = proposal
    shared_functions.update_json_file(proposals, 'proposals.json')
Пример #4
0
    async def setprefix(self, ctx: commands.Context, prefix: str):
        """Imposta prefix come nuovo prefisso del bot. Viene memorizzato
        anche nella configurazione del bot e mantenuto in caso di riavvio.

        Sintassi:
        <setprefix ?     # imposta '?' come nuovo prefisso
        """
        self.bot.command_prefix = prefix
        await self.logger.log((f'prefisso cambiato in ``{prefix}``'))
        await ctx.send(f'Prefisso cambiato in ``{prefix}``')
        self.config.current_prefix = prefix
        with open('config.json', 'r') as file:
            data: Dict[str, Any] = json.load(file)
        data['current_prefix'] = prefix
        shared_functions.update_json_file(data, 'config.json')
Пример #5
0
    async def blackremove(self, ctx: commands.Context, *, ban_word):
        """Elimina la parola passata dall'elenco delle parole bannate e aggiorna
        il file banned_words.json. Occorre rimuovere la parola scrivendola nello stesso modo
        con cui era stata inserita.

        Sintassi:
        <blackremove word     # rimuove 'word' dall'elenco
        """
        if ban_word in BannedWords.banned_words:
            BannedWords.remove(ban_word)
            shared_functions.update_json_file(BannedWords.banned_words,
                                              'banned_words.json')
            await self.logger.log(f'rimossa parola bannata `{ban_word}`')
            await ctx.send('la parola è stata rimossa', delete_after=5)
        else:
            await ctx.send('la parola non è presente nell\'elenco',
                           delete_after=5)
Пример #6
0
def remove_proposal(message: discord.Message) -> None:
    """Rimuove la proposta con id uguale al messaggio passato dal file. Se non trovata
    non fa nulla.

    :param message: messaggio della proposta
    """
    try:
        with open('proposals.json', 'r') as file:
            proposals: Dict[str, Dict[str, Any]] = json.load(file)
    except FileNotFoundError:
        print('errore nel file delle proposte')
        return
    try:
        del proposals[str(message.id)]
    except KeyError:
        print('proposta non trovata')
    else:
        shared_functions.update_json_file(proposals, 'proposals.json')
Пример #7
0
    async def blackadd(self, ctx: commands.Context, *, ban_word: str):
        """Aggiunge la stringa passata alla lista contenuta e aggiorna banned_words.json.
        Se si scrivono più parole queste vengono considerate come una unica entry.
        Per come sono controllate, non occorre mettere gli spazi tra le parole.
        Esempio:
        <blackadd seistupido   # aggiunge seistupido all'elenco
        il controllo delle parole è poi in grado di capire quali messaggi la contengono
        es. 'sei stupido'  's3i stupid0' vengono tutte rilevate.

        Sintassi:
        <blackadd word           # aggiunge 'word' all'elenco
        <blackadd aListOfWords   # aggiunge 'aListOfWord' come unica entry
        """
        if ban_word in BannedWords.banned_words:
            await ctx.send('la parola è già contenuta nell\'elenco')
            return
        BannedWords.add(ban_word)
        shared_functions.update_json_file(BannedWords.banned_words,
                                          'banned_words.json')
        await self.logger.log(f'aggiunta parola bannata `{ban_word}`')
        await ctx.send('parola aggiunta correttamente', delete_after=5)
Пример #8
0
    async def addcog(self, ctx: commands.Context, *args: str):
        """Aggiunge una o più cog al bot e al file extensions.json se non presente in modo
        da caricarla in automatico a ogni futuro riavvio. Occorre passare il nome esatto della
        cog da aggiungere, che deve trovarsi nella cartella cogs del bot.

        Sintassi:
        <addcog nome_cog                # aggiunge nome_cog al bot e al file extensions.json
        <addcog nome_cog altra_cog      # più cogs separate da spazio
        """
        if not args:
            await ctx.send('Devi specificare il nome della cog da caricare.',
                           delete_after=5)
            await ctx.message.delete(delay=5)
        else:
            with open('extensions.json', 'r') as file:
                extensions = json.load(file)
            added: str = ''
            for ext in args:
                ext = 'cogs.' + ext
                if ext not in extensions:
                    try:
                        self.bot.load_extension(ext)
                    except commands.ExtensionError as e:
                        await ctx.send('Impossibile caricare ' + ext)
                        print(e)
                    else:
                        extensions.append(ext)
                        added += '`' + ext + '` '
                else:
                    await ctx.send(ext + ' già presente.')
            if added != '':
                await self.logger.log('estensioni ' + added +
                                      'aggiunte correttamente')
                await ctx.send('Estensioni ' + added +
                               'aggiunte correttamente.')
            shared_functions.update_json_file(extensions, 'extensions.json')
Пример #9
0
    async def periodic_checks(self):
        """Task periodica per la gestione di:
            - rimozione delle proposte scadute
            - controllo sulle proposte passate con relativo avviso
            - consolidamento dei messaggi temporanei in counter se necessario
            - azzeramento dei messaggi conteggiati scaduti
            - assegnamento/rimozione ruolo attivo (i mod sono esclusi)
            - rimozione strike/violazioni

        Viene avviata tramite la on_ready quando il bot ha completato la fase di setup ed è
        programmata per essere eseguita ogni 24 ore da quel momento.
        """
        await self.logger.log('controllo proposte...')
        try:
            with open('proposals.json', 'r') as file:
                proposals = json.load(file)
        except FileNotFoundError:
            await self.logger.log('nessun file di proposte trovato')
        else:
            to_delete = []
            for key in proposals:
                proposal = proposals[key]
                if proposal['passed']:
                    to_delete.append(key)
                    channel = self.bot.get_channel(self.config.poll_channel_id)
                    await self.logger.log('proposta passata: ' +
                                          proposal['content'])
                    await channel.send(
                        'Raggiunta soglia per la proposta, in attesa di approvazione dai mod.\n'
                        + '`' + proposal['content'] + '`')
                elif datetime.date(datetime.now() - timedelta(
                        days=3)).__str__() == proposal['timestamp']:
                    await self.logger.log('proposta scaduta: ' +
                                          proposal['content'])
                    to_delete.append(key)
            for key in to_delete:
                try:
                    message = await self.bot.get_channel(
                        self.config.poll_channel_id).fetch_message(key)
                except discord.NotFound:
                    # capita se viene cancellata dopo un riavvio o mentre è offline
                    await self.logger.log('proposta già cancellata, ignoro')
                else:
                    await message.delete()
                del proposals[key]
            shared_functions.update_json_file(proposals, 'proposals.json')
        await self.logger.log('controllo proposte terminato')
        await self.logger.log('controllo conteggio messaggi...')
        for id in self.archive.keys():
            item = self.archive.get(id)
            item.clean()
            count = item.count_consolidated_messages()
            if count >= self.config.active_threshold and self.bot.get_guild(
                    self.config.guild_id).get_member(
                        id).top_role.id not in self.config.moderation_roles_id:
                item.set_active()
                guild = self.bot.get_guild(self.config.guild_id)
                await guild.get_member(id).add_roles(
                    guild.get_role(self.config.active_role_id))
                await self.logger.log('membro ' + item.nick + ' è attivo')
                channel = self.bot.get_channel(self.config.main_channel_id)
                await channel.send('membro <@!' + str(id) +
                                   '> è diventato attivo')

            # controllo sulla data dell'ultima violazione, ed eventuale reset
            item.reset_violations()

            # rimuovo i messaggi contati 7 giorni fa
            item.forget_last_week()

            if item.is_active_expired():
                channel = self.bot.get_channel(self.config.main_channel_id)
                guild = self.bot.get_guild(self.config.guild_id)
                await guild.get_member(id).remove_roles(
                    guild.get_role(self.config.active_role_id))
                await self.logger.log('membro ' + item.nick +
                                      ' non più è attivo')
                await channel.send('membro <@!' + str(id) +
                                   '> non più attivo :(')
                item.set_inactive()
        await self.logger.log('controllo conteggio messaggi terminato')
        self.archive.save()