Explorar o código

WIP: Moving commands to appropriate file

Lucas Villeneuve %!s(int64=5) %!d(string=hai) anos
pai
achega
f5b4b09097
Modificáronse 4 ficheiros con 229 adicións e 213 borrados
  1. 11 185
      myanimebot.py
  2. 2 1
      myanimebot/__init__.py
  3. 216 0
      myanimebot/commands.py
  4. 0 27
      myanimebot/globals.py

+ 11 - 185
myanimebot.py

@@ -25,6 +25,7 @@ import myanimebot.anilist as anilist
 import myanimebot.globals as globals
 import myanimebot.utils as utils
 import myanimebot.myanimelist as myanimelist
+import myanimebot.commands as commands
 from myanimebot.discord import send_embed_wrapper, build_embed, in_allowed_role
 
 
@@ -180,193 +181,19 @@ async def on_error(event, *args, **kwargs):
 	globals.logger.exception("Crap! An unknown Discord error occured...")
 
 
-def build_info_cmd_message(users, server, channels, filters : List[utils.Service]) -> str:
-	''' Build the corresponding message for the info command '''
-
-	registered_channel = globals.client.get_channel(int(channels[0]["channel"]))
-
-	# Store users
-	mal_users = []
-	anilist_users = []
-	for user in users:
-		# If user is part of the server, add it to the message
-		if str(server.id) in user['servers'].split(','):
-			try:
-				user_service = utils.Service.from_str(user["service"])
-				if user_service == utils.Service.MAL:
-					mal_users.append(user[globals.DB_USER_NAME])
-				elif user_service == utils.Service.ANILIST:
-					anilist_users.append(user[globals.DB_USER_NAME])
-			except NotImplementedError:
-				pass # Nothing to do here
-
-	if not mal_users and not anilist_users:
-		return "No users registered on this server. Try to add one."
-	else:
-		message =  'Registered user(s) on **{}**\n\n'.format(server)
-		if mal_users: # If not empty
-			# Don't print if there is filters and MAL is not in them
-			if not filters or (filters and utils.Service.MAL in filters): 
-				message += '**MyAnimeList** users:\n'
-				message += '```{}```\n'.format(', '.join(mal_users))
-		if anilist_users: # If not empty
-			# Don't print if there is filters and MAL is not in them
-			if not filters or (filters and utils.Service.ANILIST in filters):
-				message += '**AniList** users:\n'
-				message += '```{}```\n'.format(', '.join(anilist_users))
-		message += 'Assigned channel : **{}**'.format(registered_channel)
-	return message
-
-
-def get_service_filters_list(filters : str) -> List[utils.Service]:
-	''' Creates and returns a service filter list from a comma-separated string '''
-
-	filters_list = []
-	for filter in filters.split(','):
-		try:
-			filters_list.append(utils.Service.from_str(filter))
-		except NotImplementedError:
-			pass # Ignore incorrect filter
-	return filters_list
-
-
-async def info_cmd(message, words):
-	''' Processes the command "info" and sends a message '''
-
-	# Get filters if available
-	filters = []
-	if (len(words) >= 3): # If filters are specified
-		filters = get_service_filters_list(words[2])
-
-	server = message.guild
-	if utils.is_server_in_db(server.id) == False:
-		 await message.channel.send("The server **{}** is not in our database.".format(server))
-	else:
-		users = utils.get_users()
-		channels = utils.get_channels(server.id)
-		if channels is None:
-			await message.channel.send("No channel assigned for this bot on this server.")
-		else:
-			await message.channel.send(build_info_cmd_message(users, server, channels, filters))
-
-
-def check_user_name_validity(user_name: str, service : utils.Service) -> Tuple[bool, str]:
-	""" Check if user_name exists on a specific service.
-		
-		Returns:
-			- bool: 	True if user_name exists
-			- str:		Error string if the user does not exist
-	"""
-
-	if service == utils.Service.MAL:
-		try:
-			# Ping user profile to check validity
-			urllib.request.urlopen('{}{}'.format(globals.MAL_PROFILE_URL, user_name))
-		except urllib.error.HTTPError as e:
-			if (e.code == 404): # URL profile not found
-				return False, "User **{}** doesn't exist on MyAnimeList!".format(user_name)
-			else:
-				globals.logger.warning("HTTP Code {} while trying to add user '{}' and checking its validity.".format(e.code, user_name))
-				return False, "An error occured when we checked this username on MyAnimeList, maybe the website is down?"
-	elif service == utils.Service.ANILIST:
-		is_user_valid = anilist.check_username_validity(user_name)
-		if is_user_valid == False:
-			globals.logger.warning("No results returned while trying to add user '{}' and checking its validity.".format(user_name))
-			return False, "User **{}** doesn't exist on AniList!".format(user_name)
-	return True, None
-
-
-async def add_user_cmd(words, message):
-	''' Processes the command "add" and add a user to fetch the data for '''
-
-	# Check if command is valid
-	if len(words) != 4:
-		if (len(words) < 4):
-			return await message.channel.send("Usage: {} add **{}**/**{}** **username**".format(globals.prefix, globals.SERVICE_MAL, globals.SERVICE_ANILIST))
-		return await message.channel.send("Too many arguments! You have to specify only one username.")
-
-	try:
-		service = utils.Service.from_str(words[2])
-	except NotImplementedError:
-		return await message.channel.send('Incorrect service. Use **"{}"** or **"{}"** for example'.format(globals.SERVICE_MAL, globals.SERVICE_ANILIST))
-	user = words[3]
-	server_id = str(message.guild.id)
-
-	if(len(user) > 14):
-		return await message.channel.send("Username too long!")
-
-	try:
-		# Check user validity
-		is_valid, error_string = check_user_name_validity(user, service)
-		if is_valid == False:
-			return await message.channel.send(error_string)
-
-		# Get user's servers
-		user_servers = utils.get_user_servers(user, service)
-		# User not present in database
-		if user_servers is None: 
-			utils.insert_user_into_db(user, service, server_id)
-			return await message.channel.send("**{}** added to the database for the server **{}**.".format(user, str(message.guild)))
-		else: # User present in database
-
-			is_server_present = server_id in user_servers.split(',')
-			if is_server_present == True: # The user already has registered this server
-				return await message.channel.send("User **{}** is already registered in our database for this server!".format(user))
-			else:
-				new_servers = '{},{}'.format(user_servers, server_id)
-				utils.update_user_servers_db(user, service, new_servers)					
-				return await message.channel.send("**{}** added to the database for the server **{}**.".format(user, str(message.guild)))
-	except Exception as e:
-		globals.logger.warning("Error while adding user '{}' on server '{}': {}".format(user, message.guild, str(e)))
-		return await message.channel.send("An unknown error occured while addind this user, the error has been logged.")
-
-
-async def delete_user_cmd(words, message):
-	''' Processes the command "delete" and remove a registered user '''
-
-	# Check if command is valid
-	if len(words) != 4:
-		if (len(words) < 4):
-			return await message.channel.send("Usage: {} delete **{}**/**{}** **username**".format(globals.prefix, globals.SERVICE_MAL, globals.SERVICE_ANILIST))
-		return await message.channel.send("Too many arguments! You have to specify only one username.")
-	try:
-		service = utils.Service.from_str(words[2])
-	except NotImplementedError:
-		return await message.channel.send('Incorrect service. Use **"{}"** or **"{}"** for example'.format(globals.SERVICE_MAL, globals.SERVICE_ANILIST))
-	user = words[3]
-	server_id = str(message.guild.id)
-	
-	user_servers = utils.get_user_servers(user, service)
-	# If user is not present in the database
-	if user_servers is None:
-		return await message.channel.send("The user **" + user + "** is not in our database for this server!")
-
-	# Else if present, update the servers for this user
-	srv_string = utils.remove_server_from_servers(server_id, user_servers)
-	
-	if srv_string is None: # Server not present in the user's servers
-		return await message.channel.send("The user **" + user + "** is not in our database for this server!")
-
-	if srv_string == "":
-		utils.delete_user_from_db(user, service)
-	else:
-		utils.update_user_servers_db(user, service, srv_string)
-
-	return await message.channel.send("**" + user + "** deleted from the database for this server.")
-
-
 @globals.client.event
 async def on_message(message):
 	if message.author == globals.client.user: return
 
 	words = message.content.split(" ")
+	channel = message.channel
 	author = str('{0.author.mention}'.format(message))
 
 	# A user is trying to get help
 	if words[0] == globals.prefix:
 		if len(words) > 1:
 			if words[1] == "ping":
-				await message.channel.send("pong")
+				await commands.ping_cmd(channel)
 			
 			elif words[1] == "here":
 				if in_allowed_role(message.author, message.guild):
@@ -392,12 +219,12 @@ async def on_message(message):
 				
 			elif words[1] == "add":
 				if in_allowed_role(message.author, message.guild):
-					await add_user_cmd(words, message)
+					await commands.add_user_cmd(words, message)
 				else: await message.channel.send("Only allowed users can use this command!")
 				
 			elif words[1] == "delete":
 				if in_allowed_role(message.author, message.guild):
-					await delete_user_cmd(words, message)
+					await commands.delete_user_cmd(words, message)
 				else: await message.channel.send("Only allowed users can use this command!")
 				
 			elif words[1] == "stop":
@@ -418,11 +245,13 @@ async def on_message(message):
 				else: await message.channel.send("Only allowed users can use this command!")
 				
 			elif words[1] == "info":
-				await info_cmd(message, words)
+				await commands.info_cmd(message, words)
 
-			elif words[1] == "about": await message.channel.send(embed=discord.Embed(colour=0x777777, title="MyAnimeBot version " + globals.VERSION + " by Penta & lulu", description="This bot check the MyAnimeList and Anilist profiles for each user specified, and send a message if there is something new.\nMore help with the **" + globals.prefix + " help** command.\n\nCheck the GitHub page: https://github.com/Penta/MyAnimeBot").set_thumbnail(url=globals.iconBot))
+			elif words[1] == "about":
+				await commands.about_cmd(channel)
 			
-			elif words[1] == "help": await message.channel.send(globals.HELP)
+			elif words[1] == "help":
+				await commands.help_cmd(channel)
 			
 			elif words[1] == "top":
 				if len(words) == 2:
@@ -510,12 +339,9 @@ async def on_message(message):
 				else:
 					await message.channel.send("You have to specify a role!")
 
-			elif words[1] == "fetch-debug":
-				await fetch_activities_anilist()
-
 	# If mentioned
 	elif globals.client.user in message.mentions:
-		await message.channel.send(":heart:")
+		await channel.send(":heart:")
 
 # Get a random anime name and change the bot's activity
 async def change_gameplayed(asyncioloop):

+ 2 - 1
myanimebot/__init__.py

@@ -2,4 +2,5 @@ from .utils import *
 from .anilist import *
 from .globals import *
 from .myanimelist import *
-from .discord import *
+from .discord import *
+from .commands import *

+ 216 - 0
myanimebot/commands.py

@@ -0,0 +1,216 @@
+import discord
+import urllib
+
+from typing import List, Tuple
+
+import myanimebot.utils as utils
+import myanimebot.globals as globals
+
+
+def build_info_cmd_message(users, server, channels, filters : List[utils.Service]) -> str:
+	''' Build the corresponding message for the info command '''
+
+	registered_channel = globals.client.get_channel(int(channels[0]["channel"]))
+
+	# Store users
+	mal_users = []
+	anilist_users = []
+	for user in users:
+		# If user is part of the server, add it to the message
+		if str(server.id) in user['servers'].split(','):
+			try:
+				user_service = utils.Service.from_str(user["service"])
+				if user_service == utils.Service.MAL:
+					mal_users.append(user[globals.DB_USER_NAME])
+				elif user_service == utils.Service.ANILIST:
+					anilist_users.append(user[globals.DB_USER_NAME])
+			except NotImplementedError:
+				pass # Nothing to do here
+
+	if not mal_users and not anilist_users:
+		return "No users registered on this server. Try to add one."
+	else:
+		message =  'Registered user(s) on **{}**\n\n'.format(server)
+		if mal_users: # If not empty
+			# Don't print if there is filters and MAL is not in them
+			if not filters or (filters and utils.Service.MAL in filters): 
+				message += '**MyAnimeList** users:\n'
+				message += '```{}```\n'.format(', '.join(mal_users))
+		if anilist_users: # If not empty
+			# Don't print if there is filters and MAL is not in them
+			if not filters or (filters and utils.Service.ANILIST in filters):
+				message += '**AniList** users:\n'
+				message += '```{}```\n'.format(', '.join(anilist_users))
+		message += 'Assigned channel : **{}**'.format(registered_channel)
+	return message
+
+
+def get_service_filters_list(filters : str) -> List[utils.Service]:
+	''' Creates and returns a service filter list from a comma-separated string '''
+
+	filters_list = []
+	for filter in filters.split(','):
+		try:
+			filters_list.append(utils.Service.from_str(filter))
+		except NotImplementedError:
+			pass # Ignore incorrect filter
+	return filters_list
+
+
+def check_user_name_validity(user_name: str, service : utils.Service) -> Tuple[bool, str]:
+	""" Check if user_name exists on a specific service.
+		
+		Returns:
+			- bool: 	True if user_name exists
+			- str:		Error string if the user does not exist
+	"""
+
+	if service == utils.Service.MAL:
+		try:
+			# Ping user profile to check validity
+			urllib.request.urlopen('{}{}'.format(globals.MAL_PROFILE_URL, user_name))
+		except urllib.error.HTTPError as e:
+			if (e.code == 404): # URL profile not found
+				return False, "User **{}** doesn't exist on MyAnimeList!".format(user_name)
+			else:
+				globals.logger.warning("HTTP Code {} while trying to add user '{}' and checking its validity.".format(e.code, user_name))
+				return False, "An error occured when we checked this username on MyAnimeList, maybe the website is down?"
+	elif service == utils.Service.ANILIST:
+		is_user_valid = anilist.check_username_validity(user_name)
+		if is_user_valid == False:
+			globals.logger.warning("No results returned while trying to add user '{}' and checking its validity.".format(user_name))
+			return False, "User **{}** doesn't exist on AniList!".format(user_name)
+	return True, None
+
+
+async def add_user_cmd(words, message):
+	''' Processes the command "add" and add a user to fetch the data for '''
+
+	# Check if command is valid
+	if len(words) != 4:
+		if (len(words) < 4):
+			return await message.channel.send("Usage: {} add **{}**/**{}** **username**".format(globals.prefix, globals.SERVICE_MAL, globals.SERVICE_ANILIST))
+		return await message.channel.send("Too many arguments! You have to specify only one username.")
+
+	try:
+		service = utils.Service.from_str(words[2])
+	except NotImplementedError:
+		return await message.channel.send('Incorrect service. Use **"{}"** or **"{}"** for example'.format(globals.SERVICE_MAL, globals.SERVICE_ANILIST))
+	user = words[3]
+	server_id = str(message.guild.id)
+
+	if(len(user) > 14):
+		return await message.channel.send("Username too long!")
+
+	try:
+		# Check user validity
+		is_valid, error_string = check_user_name_validity(user, service)
+		if is_valid == False:
+			return await message.channel.send(error_string)
+
+		# Get user's servers
+		user_servers = utils.get_user_servers(user, service)
+		# User not present in database
+		if user_servers is None: 
+			utils.insert_user_into_db(user, service, server_id)
+			return await message.channel.send("**{}** added to the database for the server **{}**.".format(user, str(message.guild)))
+		else: # User present in database
+
+			is_server_present = server_id in user_servers.split(',')
+			if is_server_present == True: # The user already has registered this server
+				return await message.channel.send("User **{}** is already registered in our database for this server!".format(user))
+			else:
+				new_servers = '{},{}'.format(user_servers, server_id)
+				utils.update_user_servers_db(user, service, new_servers)					
+				return await message.channel.send("**{}** added to the database for the server **{}**.".format(user, str(message.guild)))
+	except Exception as e:
+		globals.logger.warning("Error while adding user '{}' on server '{}': {}".format(user, message.guild, str(e)))
+		return await message.channel.send("An unknown error occured while addind this user, the error has been logged.")
+
+
+async def delete_user_cmd(words, message):
+	''' Processes the command "delete" and remove a registered user '''
+
+	# Check if command is valid
+	if len(words) != 4:
+		if (len(words) < 4):
+			return await message.channel.send("Usage: {} delete **{}**/**{}** **username**".format(globals.prefix, globals.SERVICE_MAL, globals.SERVICE_ANILIST))
+		return await message.channel.send("Too many arguments! You have to specify only one username.")
+	try:
+		service = utils.Service.from_str(words[2])
+	except NotImplementedError:
+		return await message.channel.send('Incorrect service. Use **"{}"** or **"{}"** for example'.format(globals.SERVICE_MAL, globals.SERVICE_ANILIST))
+	user = words[3]
+	server_id = str(message.guild.id)
+	
+	user_servers = utils.get_user_servers(user, service)
+	# If user is not present in the database
+	if user_servers is None:
+		return await message.channel.send("The user **" + user + "** is not in our database for this server!")
+
+	# Else if present, update the servers for this user
+	srv_string = utils.remove_server_from_servers(server_id, user_servers)
+	
+	if srv_string is None: # Server not present in the user's servers
+		return await message.channel.send("The user **" + user + "** is not in our database for this server!")
+
+	if srv_string == "":
+		utils.delete_user_from_db(user, service)
+	else:
+		utils.update_user_servers_db(user, service, srv_string)
+
+	return await message.channel.send("**" + user + "** deleted from the database for this server.")
+
+
+async def info_cmd(message, words):
+	''' Processes the command "info" and sends a message '''
+
+	# Get filters if available
+	filters = []
+	if (len(words) >= 3): # If filters are specified
+		filters = get_service_filters_list(words[2])
+
+	server = message.guild
+	if utils.is_server_in_db(server.id) == False:
+		 await message.channel.send("The server **{}** is not in our database.".format(server))
+	else:
+		users = utils.get_users()
+		channels = utils.get_channels(server.id)
+		if channels is None:
+			await message.channel.send("No channel assigned for this bot on this server.")
+		else:
+			await message.channel.send(build_info_cmd_message(users, server, channels, filters))
+
+
+async def ping_cmd(channel):
+    ''' Responds to ping command '''
+    await channel.send("pong")
+
+
+async def about_cmd(channel):
+    ''' Responds to about command with a brief description of this bot '''
+
+    title = "MyAnimeBot version {} by Penta & lulu".format(globals.VERSION)
+    description = """MyAnimeBot checks MyAnimeList and Anilist profiles for specified users, and send a message for every new activities found.
+        More help with the **{} help** command.
+        
+        Check our GitHub page for more informations: https://github.com/Penta/MyAnimeBot
+        """.format(globals.prefix)
+
+    await channel.send(embed=discord.Embed(colour=0x777777, title=title, description=description).set_thumbnail(url=globals.iconBot))
+
+
+async def help_cmd(channel):
+    ''' Responds to help command '''
+
+    embed = discord.Embed(title="***MyAnimeBot Commands***", colour=0xEED000)
+    embed.add_field(name="`here`", value="Register this channel. The bot will send new activities on registered channels.")
+    embed.add_field(name="`stop`", value="Un-register this channel. The bot will now stop sending new activities for this channel.")
+    embed.add_field(name="`info [mal|ani]`", value="Get the registered users for this server. Users can be filtered by specifying a service.")
+    embed.add_field(name="`add {mal|ani} <user>`", value="Register a user for a specific service.\nEx: `add mal MyUser`")
+    embed.add_field(name="`delete {mal|ani} <user>`", value="Remove a user for a specific service.\nEx: `delete ani MyUser`")
+    embed.add_field(name="`role <@discord_role>`", value="Specify a role that is able to manage the bot.\nEx: `role @Moderator`, `role @everyone`")
+    embed.add_field(name="`top`", value="Show statistics for this server.")
+    embed.add_field(name="`ping`", value="Ping the bot.")
+    embed.add_field(name="`about`", value="Get some information about this bot")
+    await channel.send(embed=embed)

+ 0 - 27
myanimebot/globals.py

@@ -100,33 +100,6 @@ logging.getLogger('').addHandler(console)
 # Script version
 VERSION = "1.0.0a"
 
-# The help message
-HELP = 	"""**Here's some help for you:**
-```
-- here :
-Type this command on the channel where you want to see the activity of the MAL profiles.
-
-- stop :
-Cancel the here command, no message will be displayed.
-
-- add :
-Followed by a username, add a MAL user into the database to be displayed on this server.
-ex: add MyUser
-
-- delete :
-Followed by a username, remove a user from the database.
-ex: delete MyUser
-
-- group :
-Specify a group that can use the add and delete commands.
-
-- info :
-Get the users already in the database for this server.
-
-- about :
-Get some information about this bot.
-```"""
-
 logger.info("Booting MyAnimeBot " + VERSION + "...")
 logger.debug("DEBUG log: OK")