Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#17 Primera implementación del BAN-HAMMER #22

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
138afad
Implementación moderador
Santixs Aug 17, 2020
672fb8b
Implementación moderador
Santixs Aug 17, 2020
4bbd53b
new functionalities
Santixs Aug 17, 2020
451f787
minor bug fixed
Santixs Aug 17, 2020
d19ac0b
minor bug (command without message) fixed
Santixs Aug 18, 2020
b2bbbde
Actualización de estructura y cambios menores
jonsalchichonnn Aug 21, 2020
ac11a5e
Actualización de estructura y cambios menores
jonsalchichonnn Aug 21, 2020
a04dc8d
Añadida funcionalidad para que el bot no te haga ban a ti mismo cuand…
Daniel-Tomas Aug 27, 2020
f1fda21
Añadido un comentario explicativo y especificada una excepción
Daniel-Tomas Aug 28, 2020
7622fbd
UTF-8 adaptation
Santixs Sep 1, 2020
ddca0d0
Modificación de estructura
Santixs Sep 2, 2020
0db637a
Aumento cobertura test y codigo refactorizado para adecuarlo a la nue…
Santixs Sep 11, 2020
ce7e87f
Incremento cobertura test, implementación SequenceMatcher y filtrado …
Santixs Sep 11, 2020
614cdaf
Improved coverage
Santixs Sep 12, 2020
8f9e94b
String format and interaction with the bot (outside channel)
Santixs Sep 12, 2020
8eb6a93
Nueva estructura
Santixs Sep 12, 2020
30a5bf0
Añadidas instancias de la clase Command para cada comando y cambios m…
Santixs Sep 14, 2020
cde9f6b
Creadas instancias para optimizar espacio en memoria
Santixs Sep 14, 2020
41997b8
refactor the code
Santixs Sep 19, 2020
a4a8a9b
pep8 y poner metodos estaticos cuando no se utiliza self
Daniel-Tomas Sep 22, 2020
2ac4b06
commit por si acaso se pierde
Daniel-Tomas Sep 22, 2020
3f12975
falla el path al abrir un archivo en ban_hammer.py. Incluido en lib/ …
Daniel-Tomas Sep 22, 2020
a2c6272
arreglado el problema del path
Daniel-Tomas Sep 22, 2020
7d57e6b
Documentation added,blacklist utf8 adaptation
Santixs Sep 23, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
src/token.txt
src/token.txt
pytest_cache/
vs/
vscode/
src/__pycache__/
src/funcionalidades/__pycache__
test/__pycache__/
*.pyc_
.vscode/
.vs/
.idea/
Empty file added src/__init__.py
Empty file.
24 changes: 7 additions & 17 deletions src/bot.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
import discord
from discord.ext import commands
import os

client = discord.Client()
TOKEN = open('src/token.txt', 'r').read()
bot = commands.Bot(command_prefix='!')

with open('src/token.txt', 'r') as token_file:
TOKEN = token_file.read()

@client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
bot.load_extension(f'extensions.view.ban_hammer_view')


@client.event
async def on_message(message):
if message.author == client.user:
return

if message.content.startswith('$hello'):
await message.channel.send('Hello!')


client.run(TOKEN)
bot.run(TOKEN)
Empty file.
90 changes: 90 additions & 0 deletions src/extensions/logic/ban_hammer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
from difflib import SequenceMatcher
from src.Extensions.logic.lib.roles_functions import have_permitted_rol, BAN_HAMMER_PERMITTED_ROLES_NAMES


def similar_word(message):
"""
check if the message has forbidden words (or a similar word)
Args:
message: the message object which contains the phrase to check

Returns:
String list: a list with the words that matches with a forbidden word
"""
words = message.split(" ")
forbidden = [insult for word in words for insult in BanHammer.BLACKLIST if
SequenceMatcher(None, insult, word).ratio() > 0.8]
return forbidden
# More than 80% similarity


class BanHammer:
PATH = r'C:\Users\Daniel\OneDrive - Universidad Politécnica de Madrid\Estudios\Python\discord-bot\src\static\blacklist_insultos.txt'
with open(PATH, 'r') as f:
BLACKLIST = [line.strip().casefold() for line in f if line.strip().casefold() != ""]

@staticmethod
def add_word_blacklist(message):

"""
Add a word to the blacklist file
Args:
message: the message object which contains the phrase or word to add

Returns:
String: A string which describes whether the operation was successful
"""

word = message.content.split(" ", 1)[1]
if word in BanHammer.BLACKLIST:
return "La palabra ya estaba baneada"
else:
with open(BanHammer.PATH, 'a') as file:
file.write("\n" + word)
BanHammer.BLACKLIST.append(word)
return 'Palabra censurada correctamente :)'

@staticmethod
def get_forbidden_words(message, commands_name):

"""
Get the text from the message, check if it is a normal message (and then call similar_word()
to check for forbidden words) or if the uncensor command is being used (and the user
has the correct role) so the message should not be removed.
Args:
message: the message object which contains the phrase or word to check
commands_name: The command that has been used (if it has been used)

Returns:
String list: A list with the words that matches with a forbidden word
"""

# Si comprobamos es comando de /censor o alias(1) y rol de autor es válido (2):
command_str = message.content.split()[0]
if have_permitted_rol(message.author.roles, BAN_HAMMER_PERMITTED_ROLES_NAMES) and command_str in commands_name:
return None
# Obtenemos lista con palabras invalidas
return similar_word(message.content)

@staticmethod
def uncensor_word(message):

"""
Get the text from the message, check if the word is in the blacklist and if it is then remove it.
Args:
message: the message object which contains the phrase or word to remove

Returns:
String: A string which describes whether the operation was successful
"""

word = message.content.split(" ", 1)[1]
if word in BanHammer.BLACKLIST:
with open(BanHammer.PATH, 'w') as file:
for line in BanHammer.BLACKLIST:
if line.strip("\n") != word and line != "":
file.write("\n" + line)
BanHammer.BLACKLIST.remove(word)
return 'Palabra descensurada correctamente :)'
else:
return "La palabra no está baneada, por lo que no se ha removido"
12 changes: 12 additions & 0 deletions src/extensions/logic/lib/command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Command:
prefix = "!" # Se puede sacar directamente de bot con _prefix = self.bot.command_prefix

def __init__(self, name, aliases, description, usage, brief):
self.name = name
self.aliases = aliases
self.description = description
self.usage = usage
self.brief = brief

def get_command_n_aliases(self):
return [self.prefix + command for command in ([self.name] + self.aliases)]
12 changes: 12 additions & 0 deletions src/extensions/logic/lib/roles_functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
VOICE_PERMITTED_ROLES_NAMES = ('Ponente', 'Admin')
BAN_HAMMER_PERMITTED_ROLES_NAMES = ('Junta', 'Admin')

def have_permitted_rol(autor_roles, permitted_roles):
for autor_rol in autor_roles:
if autor_rol.name in permitted_roles:
return True
return False


def str_permitted_roles_names(permitted_roles):
return ' o '.join(permitted_roles)
Empty file added src/extensions/view/__init__.py
Empty file.
Binary file not shown.
Binary file not shown.
64 changes: 64 additions & 0 deletions src/extensions/view/ban_hammer_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from discord.ext import commands
from discord import user

from src.Extensions.logic.ban_hammer import BanHammer
from src.Extensions.logic.lib.command import Command


def setup(bot):
bot.add_cog(BanHammerView(bot))


class BanHammerView(commands.Cog):
censor_command = Command(name="censor", aliases=["censura", "censurar", "ban"],
description="Añadir una palabra a la lista de palabras prohibidas",
usage="palabra_a_censurar", brief="Censurar una palabra")

uncensor_command = Command(name="uncensor", aliases=["descensurar", "descensura", "unban"],
description="Quitar una palabra de la lista de palabras censuradas ",
usage="palabra_a_descensurar", brief="desCensurar una palabra")

def __init__(self, bot):
self.bot = bot
self.hammer = BanHammer()

@commands.command(name=censor_command.name, aliases=censor_command.aliases, brief=censor_command.brief,
description=censor_command.description, usage=censor_command.usage)
@commands.has_role('Junta')
async def ban_word(self, ctx):
await ctx.send(self.hammer.add_word_blacklist(ctx.message))

@commands.Cog.listener()
async def on_ready(self):
print(f'We have logged in as {self.bot.user}')

@commands.Cog.listener()
async def on_message(self, message):
if message.author == self.bot.user:
return None

if type(message.author) is user.User: # Está interactuando con el bot, no en el canal general
return None

forbidden_words_used = self.hammer.get_forbidden_words(message=message,
commands_name=self.censor_command.get_command_n_aliases())
if forbidden_words_used:
# Delete the message
await message.delete()
# Send an alert through the channel
await message.channel.send(message.author.mention + ", debes cuidar tu vocabulario, jovencito")
# Send a private message to the user
await message.author.send("El mensaje {} no se ajusta a las normas, intenta no usar {} ni parecidos"
.format(str(f'```diff\n- "{message.content}"```'),
str(forbidden_words_used).strip('[]')))

@commands.command(name=uncensor_command.name, aliases=uncensor_command.aliases, brief=uncensor_command.brief,
description=uncensor_command.description, usage=uncensor_command.usage)
@commands.has_role('Junta')
async def unban_word(self, ctx):
await ctx.send(self.hammer.uncensor_word(ctx.message))

@commands.Cog.listener()
async def on_command_error(self, ctx, error):
if isinstance(error, commands.errors.MissingRole):
await ctx.send('Lo siento, no es nada personal, pero no tienes permiso para hacer eso :)')
Empty file added src/static/__init__.py
Empty file.
Loading