Переглянути джерело

Moved global vars to corresponding file

Added db insertion for AniList feed
Lucas Villeneuve 5 роки тому
батько
коміт
c4c737f7d7
4 змінених файлів з 309 додано та 236 видалено
  1. 53 6
      src/anilist.py
  2. 150 0
      src/globals.py
  3. 106 230
      src/myanimebot.py
  4. 0 0
      src/utils.py

+ 53 - 6
include/anilist.py → src/anilist.py

@@ -1,7 +1,10 @@
 import requests
 import time
+import datetime
 from enum import Enum
 
+import globals
+
 ANILIST_GRAPHQL_URL = 'https://graphql.anilist.co'
 
 DEBUG_USERS = [
@@ -82,20 +85,26 @@ def get_latest_users_activities(users_id, page, perPage = 5):
                 __typename
                 ... on ListActivity {
                     id
-                    userId
                     type
                     status
                     progress
                     isLocked
                     createdAt
+                    
+                    user {
+                        id
+                        name
+                    }
+
                     media {
                         id
+                        siteUrl
                         title {
                             romaji
                             english
                         }
                     }
-                }
+                } 
             } 
         }
     }'''
@@ -153,6 +162,19 @@ def get_latest_activity(users_id):
     return None
 
 
+def insert_feed_db(activity):
+    cursor = globals.conn.cursor(buffered=True)
+
+    cursor.execute("INSERT INTO t_feeds (published, title, url, user, found, type, service) VALUES (%s, %s, %s, %s, NOW(), %s, %s)",
+                    (datetime.datetime.fromtimestamp(activity["createdAt"]).isoformat(),
+                     activity["media"]["title"]["english"], # TODO When getting title if no english take romaji
+                     activity["media"]["siteUrl"], # TODO Get siteurl from MAL I guess
+                     activity["user"]["name"], # TODO Same user than mal one
+                     activity["status"], # TODO Create enum to make it generic
+                     globals.SERVICE_ANILIST))
+    globals.conn.commit()
+
+
 def process_new_activities(last_activity_date):
     """ Fetch and process all newest activities """
     
@@ -164,13 +186,23 @@ def process_new_activities(last_activity_date):
 
         # Processing them
         for activity in activities:
+            # Check if activity is a ListActivity
+            if activity["__typename"] != 'ListActivity':
+                continue
+
             print(activity) # TODO Remove, DEBUG
+
+            # Get time difference between now and activity creation date
+            diffTime = datetime.datetime.now(globals.timezone) - datetime.datetime.fromtimestamp(activity["createdAt"], globals.timezone)
             # If the activity is older than the last_activity_date, we processed all the newest activities
-            if activity["createdAt"] < last_activity_date:
+            # Also, if the time difference is bigger than the config's "secondMax", we can stop processing them
+            if activity["createdAt"] < last_activity_date or diffTime.total_seconds() > globals.secondMax:
                 continue_fetching = False
                 break
             # Process activity
-            # TODO Insert in DB
+            # TODO Add logger infos
+            insert_feed_db(activity)
+            # TODO Create embed and send to channels
 
         # Load next activities page
         # TODO How can I avoid duplicate if insertion in between? With storing ids?
@@ -180,10 +212,24 @@ def process_new_activities(last_activity_date):
             time.sleep(1)
 
 
+def get_last_activity_date_db():
+    cursor = globals.conn.cursor(buffered=True)
+    cursor.execute("SELECT published FROM t_feeds WHERE service=%s ORDER BY published DESC LIMIT 1", [globals.SERVICE_ANILIST])
+    data = cursor.fetchone()
+
+    print(data)
+    if data is None:
+        return 0
+    else:
+        return int(data)
+
+
 def check_new_activities():
     """ Check if there is new activities and process them """
     
-    last_activity_date = 1608340203 # TODO SELECT DATE IN DB
+    # last_activity_date = 1608340203 # TODO SELECT DATE IN DB
+    last_activity_date = get_last_activity_date_db()
+    print(last_activity_date)
 
     # Get latest activity on AniList
     latest_activity = get_latest_activity(DEBUG_USERS)
@@ -198,6 +244,7 @@ def check_new_activities():
 # [x] Convertir AniList ID en MAL ID
 # [ ] Recuperer utilisateurs qui nous interessent
 # [X] Recuperer activites de ces users
-# [ ] Traiter les donnees et les mettre en DB
+# [X] Traiter les donnees et les mettre en DB
+# [ ] Creer embed et envoyer messages
 # [ ] Faire task pour fetch automatiquement
 # [ ] Rajouter requests dans la liste de dependances pip (Site de Penta)

+ 150 - 0
src/globals.py

@@ -0,0 +1,150 @@
+import os
+import pytz
+import logging
+import discord
+import mariadb
+import feedparser
+import socket
+
+from configparser import ConfigParser
+
+class ImproperlyConfigured(Exception): pass
+
+BASE_DIR = os.path.dirname(os.path.abspath(__file__))
+HOME_DIR = os.path.expanduser("~")
+
+DEFAULT_CONFIG_PATHS = [
+	os.path.join("myanimebot.conf"),
+	os.path.join(BASE_DIR, "myanimebot.conf"),
+	os.path.join("/etc/malbot/myanimebot.conf"),
+	os.path.join(HOME_DIR, "myanimebot.conf")
+]
+
+def get_config():
+	config = ConfigParser()
+	config_paths = []
+
+	for path in DEFAULT_CONFIG_PATHS:
+		if os.path.isfile(path):
+			config_paths.append(path)
+			break
+	else: raise ImproperlyConfigured("No configuration file found")
+		
+	config.read(config_paths)
+
+	return config
+
+# Loading configuration
+try:
+	config=get_config()
+except Exception as e:
+	print ("Cannot read configuration: " + str(e))
+	exit (1)
+
+CONFIG=config["MYANIMEBOT"]
+logLevel=CONFIG.get("logLevel", "INFO")
+dbHost=CONFIG.get("dbHost", "127.0.0.1")
+dbUser=CONFIG.get("dbUser", "myanimebot")
+dbPassword=CONFIG.get("dbPassword")
+dbName=CONFIG.get("dbName", "myanimebot")
+logPath=CONFIG.get("logPath", "myanimebot.log")
+timezone=pytz.timezone(CONFIG.get("timezone", "utc"))
+secondMax=CONFIG.getint("secondMax", 7200)
+token=CONFIG.get("token")
+prefix=CONFIG.get("prefix", "!malbot")
+iconMAL=CONFIG.get("iconMAL", "https://cdn.myanimelist.net/img/sp/icon/apple-touch-icon-256.png")
+iconBot=CONFIG.get("iconBot", "http://myanimebot.pentou.eu/rsc/bot_avatar.jpg")
+SERVICE_ANILIST="AniList"
+SERVICE_MAL="mal"
+
+# class that send logs to DB
+class LogDBHandler(logging.Handler):
+	def __init__(self, sql_conn, sql_cursor):
+		logging.Handler.__init__(self)
+		self.sql_cursor = sql_cursor
+		self.sql_conn   = sql_conn
+
+	def emit(self, record):	
+		# Clear the log message so it can be put to db via sql (escape quotes)
+		self.log_msg = str(record.msg.strip().replace('\'', '\'\''))
+		
+		# Make the SQL insert
+		try:
+			self.sql_cursor.execute("INSERT INTO t_logs (host, level, type, log, date, source) VALUES (%s, %s, %s, %s, NOW(), %s)", (str(socket.gethostname()), str(record.levelno), str(record.levelname), self.log_msg, str(record.name)))
+			self.sql_conn.commit()
+		except Exception as e:
+			print ('Error while logging into DB: ' + str(e))
+
+# Log configuration
+log_format='%(asctime)-13s : %(name)-15s : %(levelname)-8s : %(message)s'
+logging.basicConfig(handlers=[logging.FileHandler(logPath, 'a', 'utf-8')], format=log_format, level=logLevel)
+
+console = logging.StreamHandler()
+console.setLevel(logging.INFO)
+console.setFormatter(logging.Formatter(log_format))
+
+logger = logging.getLogger("myanimebot")
+logger.setLevel(logLevel)
+
+logging.getLogger('').addHandler(console)
+
+# Script version
+VERSION = "0.9.6.2"
+
+# 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: !malbot add MyUser
+
+- delete :
+Followed by a username, remove a user from the database.
+ex: !malbot 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")
+
+feedparser.PREFERRED_XML_PARSERS.remove("drv_libxml2")
+
+# Initialization of the database
+try:
+	# Main database connection
+	conn = mariadb.connect(host=dbHost, user=dbUser, password=dbPassword, database=dbName)
+	
+	# We initialize the logs into the DB.
+	log_conn   = mariadb.connect(host=dbHost, user=dbUser, password=dbPassword, database=dbName)
+	log_cursor = log_conn.cursor()
+	logdb = LogDBHandler(log_conn, log_cursor)
+	logging.getLogger('').addHandler(logdb)
+	
+	logger.info("The database logger is running.")
+except Exception as e:
+	logger.critical("Can't connect to the database: " + str(e))
+	quit()
+
+
+# Initialization of the Discord client
+client = discord.Client()
+
+task_feed       = None
+task_gameplayed = None
+task_thumbnail  = None
+
+print("DONE GLOBALS") # TODO REMOVE, DEBUG

+ 106 - 230
myanimebot.py → src/myanimebot.py

@@ -23,9 +23,11 @@ import mariadb
 import string
 import time
 import socket
+import requests
 
 # Custom libraries
-sys.path.append('include/')
+import globals
+import anilist
 import utils
 
 from configparser import ConfigParser
@@ -38,155 +40,17 @@ if not sys.version_info[:2] >= (3, 7):
 	print("ERROR: Requires python 3.7 or newer.")
 	exit(1)
 
-class ImproperlyConfigured(Exception): pass
-
-BASE_DIR = os.path.dirname(os.path.abspath(__file__))
-HOME_DIR = os.path.expanduser("~")
-
-DEFAULT_CONFIG_PATHS = [
-	os.path.join("myanimebot.conf"),
-	os.path.join(BASE_DIR, "myanimebot.conf"),
-	os.path.join("/etc/malbot/myanimebot.conf"),
-	os.path.join(HOME_DIR, "myanimebot.conf")
-]
-
-def get_config():
-	config = ConfigParser()
-	config_paths = []
-
-	for path in DEFAULT_CONFIG_PATHS:
-		if os.path.isfile(path):
-			config_paths.append(path)
-			break
-	else: raise ImproperlyConfigured("No configuration file found")
-		
-	config.read(config_paths)
-
-	return config
-
-
-# Loading configuration
-try:
-	config=get_config()
-except Exception as e:
-	print ("Cannot read configuration: " + str(e))
-	exit (1)
-
-CONFIG=config["MYANIMEBOT"]
-logLevel=CONFIG.get("logLevel", "INFO")
-dbHost=CONFIG.get("dbHost", "127.0.0.1")
-dbUser=CONFIG.get("dbUser", "myanimebot")
-dbPassword=CONFIG.get("dbPassword")
-dbName=CONFIG.get("dbName", "myanimebot")
-logPath=CONFIG.get("logPath", "myanimebot.log")
-timezone=pytz.timezone(CONFIG.get("timezone", "utc"))
-secondMax=CONFIG.getint("secondMax", 7200)
-token=CONFIG.get("token")
-prefix=CONFIG.get("prefix", "!malbot")
-iconMAL=CONFIG.get("iconMAL", "https://cdn.myanimelist.net/img/sp/icon/apple-touch-icon-256.png")
-iconBot=CONFIG.get("iconBot", "http://myanimebot.pentou.eu/rsc/bot_avatar.jpg")
-
-# class that send logs to DB
-class LogDBHandler(logging.Handler):
-	def __init__(self, sql_conn, sql_cursor):
-		logging.Handler.__init__(self)
-		self.sql_cursor = sql_cursor
-		self.sql_conn   = sql_conn
-
-	def emit(self, record):	
-		# Clear the log message so it can be put to db via sql (escape quotes)
-		self.log_msg = str(record.msg.strip().replace('\'', '\'\''))
-		
-		# Make the SQL insert
-		try:
-			self.sql_cursor.execute("INSERT INTO t_logs (host, level, type, log, date, source) VALUES (%s, %s, %s, %s, NOW(), %s)", (str(socket.gethostname()), str(record.levelno), str(record.levelname), self.log_msg, str(record.name)))
-			self.sql_conn.commit()
-		except Exception as e:
-			print ('Error while logging into DB: ' + str(e))
-
-# Log configuration
-log_format='%(asctime)-13s : %(name)-15s : %(levelname)-8s : %(message)s'
-logging.basicConfig(handlers=[logging.FileHandler(logPath, 'a', 'utf-8')], format=log_format, level=logLevel)
-
-console = logging.StreamHandler()
-console.setLevel(logging.INFO)
-console.setFormatter(logging.Formatter(log_format))
-
-logger = logging.getLogger("myanimebot")
-logger.setLevel(logLevel)
-
-logging.getLogger('').addHandler(console)
-
-# Script version
-VERSION = "0.9.6.2"
-
-# 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: !malbot add MyUser
-
-- delete :
-Followed by a username, remove a user from the database.
-ex: !malbot 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")
-
-feedparser.PREFERRED_XML_PARSERS.remove("drv_libxml2")
-
-# Initialization of the database
-try:
-	# Main database connection
-	conn = mariadb.connect(host=dbHost, user=dbUser, password=dbPassword, database=dbName)
-	
-	# We initialize the logs into the DB.
-	log_conn   = mariadb.connect(host=dbHost, user=dbUser, password=dbPassword, database=dbName)
-	log_cursor = log_conn.cursor()
-	logdb = LogDBHandler(log_conn, log_cursor)
-	logging.getLogger('').addHandler(logdb)
-	
-	logger.info("The database logger is running.")
-except Exception as e:
-	logger.critical("Can't connect to the database: " + str(e))
-	quit()
-
-
-# Initialization of the Discord client
-client = discord.Client()
-
-task_feed       = None
-task_gameplayed = None
-task_thumbnail  = None
-
 # Function used to make the embed message related to the animes status
 def build_embed(user, item, channel, pubDate, image):
 	try:	
 		embed = discord.Embed(colour=0xEED000, url=item.link, description="[" + utils.filter_name(item.title) + "](" + item.link + ")\n```" + item.description + "```", timestamp=pubDate.astimezone(pytz.timezone("utc")))
 		embed.set_thumbnail(url=image)
-		embed.set_author(name=user + "'s MyAnimeList", url="https://myanimelist.net/profile/" + user, icon_url=iconMAL)
-		embed.set_footer(text="MyAnimeBot", icon_url=iconBot)
+		embed.set_author(name=user + "'s MyAnimeList", url="https://myanimelist.net/profile/" + user, icon_url=globals.iconMAL)
+		embed.set_footer(text="MyAnimeBot", icon_url=globals.iconBot)
 		
 		return embed
 	except Exception as e:
-		logger.error("Error when generating the message: " + str(e))
+		globals.logger.error("Error when generating the message: " + str(e))
 		return
 
 # Function used to send the embed
@@ -195,29 +59,29 @@ async def send_embed_wrapper(asyncioloop, channelid, client, embed):
 	
 	try:
 		await channel.send(embed=embed)
-		logger.info("Message sent in channel: " + channelid)
+		globals.logger.info("Message sent in channel: " + channelid)
 	except Exception as e:
-		logger.debug("Impossible to send a message on '" + channelid + "': " + str(e)) 
+		globals.logger.debug("Impossible to send a message on '" + channelid + "': " + str(e)) 
 		return
 	
 # Main function that check the RSS feeds from MyAnimeList
 async def background_check_feed(asyncioloop):
-	logger.info("Starting up background_check_feed")
+	globals.logger.info("Starting up background_check_feed")
 	
 	# We configure the http header
-	http_headers = { "User-Agent": "MyAnimeBot Discord Bot v" + VERSION, }
+	http_headers = { "User-Agent": "MyAnimeBot Discord Bot v" + globals.VERSION, }
 	
-	await client.wait_until_ready()
+	await globals.client.wait_until_ready()
 	
-	logger.debug("Discord client connected, unlocking background_check_feed...")
+	globals.logger.debug("Discord client connected, unlocking background_check_feed...")
 	
-	while not client.is_closed():
+	while not globals.client.is_closed():
 		try:
-			db_user = conn.cursor(buffered=True)
+			db_user = globals.conn.cursor(buffered=True)
 			db_user.execute("SELECT mal_user, servers FROM t_users")
 			data_user = db_user.fetchone()
 		except Exception as e:
-			logger.critical("Database unavailable! (" + str(e) + ")")
+			globals.logger.critical("Database unavailable! (" + str(e) + ")")
 			quit()
 
 		while data_user is not None:
@@ -225,7 +89,7 @@ async def background_check_feed(asyncioloop):
 			stop_boucle = 0
 			feed_type = 1
 			
-			logger.debug("checking user: " + user)
+			globals.logger.debug("checking user: " + user)
 			
 			try:
 				while stop_boucle == 0 :
@@ -238,28 +102,28 @@ async def background_check_feed(asyncioloop):
 								http_response = await httpclient.request("GET", "https://myanimelist.net/rss.php?type=rw&u=" + user, headers=http_headers)
 								media = "anime"
 					except Exception as e:
-						logger.error("Error while loading RSS (" + str(feed_type) + ") of '" + user + "': " + str(e))
+						globals.logger.error("Error while loading RSS (" + str(feed_type) + ") of '" + user + "': " + str(e))
 						break
 
 					http_data = await http_response.read()
 					feed_data = feedparser.parse(http_data)
 					
 					for item in feed_data.entries:
-						pubDateRaw = datetime.strptime(item.published, '%a, %d %b %Y %H:%M:%S %z').astimezone(timezone)
+						pubDateRaw = datetime.strptime(item.published, '%a, %d %b %Y %H:%M:%S %z').astimezone(globals.timezone)
 						DateTimezone = pubDateRaw.strftime("%z")[:3] + ':' + pubDateRaw.strftime("%z")[3:]
 						pubDate = pubDateRaw.strftime("%Y-%m-%d %H:%M:%S")
 						
-						cursor = conn.cursor(buffered=True)
+						cursor = globals.conn.cursor(buffered=True)
 						cursor.execute("SELECT published, title, url FROM t_feeds WHERE published=%s AND title=%s AND user=%s", [pubDate, item.title, user])
 						data = cursor.fetchone()
 
 						if data is None:
-							var = datetime.now(timezone) - pubDateRaw
+							var = datetime.now(globals.timezone) - pubDateRaw
 							
-							logger.debug(" - " + item.title + ": " + str(var.total_seconds()))
+							globals.logger.debug(" - " + item.title + ": " + str(var.total_seconds()))
 						
-							if var.total_seconds() < secondMax:
-								logger.info(user + ": Item '" + item.title + "' not seen, processing...")
+							if var.total_seconds() < globals.secondMax:
+								globals.logger.info(user + ": Item '" + item.title + "' not seen, processing...")
 								
 								if item.description.startswith('-') :
 									if feed_type == 1 :	item.description = "Re-Reading " + item.description
@@ -270,29 +134,29 @@ async def background_check_feed(asyncioloop):
 								
 								if data_img is None:
 									try:
-										image = utils.getThumbnail(item.link)
+										image = globals.utils.getThumbnail(item.link)
 										
-										logger.info("First time seeing this " + media + ", adding thumbnail into database: " + image)
+										globals.logger.info("First time seeing this " + media + ", adding thumbnail into database: " + image)
 									except Exception as e:
-										logger.warning("Error while getting the thumbnail: " + str(e))
+										globals.logger.warning("Error while getting the thumbnail: " + str(e))
 										image = ""
 										
 									cursor.execute("INSERT INTO t_animes (guid, title, thumbnail, found, discoverer, media) VALUES (%s, %s, %s, NOW(), %s, %s)", [item.guid, item.title, image, user, media])
-									conn.commit()
+									globals.conn.commit()
 								else: image = data_img[0]
 
 								type = item.description.partition(" - ")[0]
 								
 								cursor.execute("INSERT INTO t_feeds (published, title, url, user, found, type) VALUES (%s, %s, %s, %s, NOW(), %s)", (pubDate, item.title, item.guid, user, type))
-								conn.commit()
+								globals.conn.commit()
 								
 								for server in data_user[1].split(","):
-									db_srv = conn.cursor(buffered=True)
+									db_srv = globals.conn.cursor(buffered=True)
 									db_srv.execute("SELECT channel FROM t_servers WHERE server = %s", [server])
 									data_channel = db_srv.fetchone()
 									
 									while data_channel is not None:
-										for channel in data_channel: await send_embed_wrapper(asyncioloop, channel, client, build_embed(user, item, channel, pubDateRaw, image))
+										for channel in data_channel: await send_embed_wrapper(asyncioloop, channel, globals.client, build_embed(user, item, channel, pubDateRaw, image))
 										
 										data_channel = db_srv.fetchone()
 					if feed_type == 1:
@@ -302,55 +166,64 @@ async def background_check_feed(asyncioloop):
 						stop_boucle = 1
 					
 			except Exception as e:
-				logger.error("Error when parsing RSS for '" + user + "': " + str(e))
+				globals.logger.error("Error when parsing RSS for '" + user + "': " + str(e))
 			
 			await asyncio.sleep(1)
 
 			data_user = db_user.fetchone()
 
-@client.event
+
+def fetch_activities_anilist():
+	print("Fetching activities")
+
+	feed = {'__typename': 'ListActivity', 'id': 150515141, 'type': 'ANIME_LIST', 'status': 'rewatched episode', 'progress': '10 - 12', 'isLocked': False, 'createdAt': 1608738377, 'user': {'id': 102213, 'name': 'lululekiddo'}, 'media': {'id': 5081, 'siteUrl': 'https://anilist.co/anime/5081', 'title': {'romaji': 'Bakemonogatari', 'english': 'Bakemonogatari'}}}
+
+	anilist.check_new_activities()
+
+
+@globals.client.event
 async def on_ready():
-	logger.info("Logged in as " + client.user.name + " (" + str(client.user.id) + ")")
+	globals.logger.info("Logged in as " + globals.client.user.name + " (" + str(globals.client.user.id) + ")")
 
-	logger.info("Starting all tasks...")
+	globals.logger.info("Starting all tasks...")
 
-	task_feed = client.loop.create_task(background_check_feed(client.loop))
-	task_thumbnail = client.loop.create_task(update_thumbnail_catalog(client.loop))
-	task_gameplayed = client.loop.create_task(change_gameplayed(client.loop))
+	task_feed = globals.client.loop.create_task(background_check_feed(globals.client.loop))
+	task_thumbnail = globals.client.loop.create_task(update_thumbnail_catalog(globals.client.loop))
+	task_gameplayed = globals.client.loop.create_task(change_gameplayed(globals.client.loop))
 
 
-@client.event
+@globals.client.event
 async def on_error(event, *args, **kwargs):
-    logger.exception("Crap! An unknown Discord error occured...")
+    globals.logger.exception("Crap! An unknown Discord error occured...")
 
-@client.event
+@globals.client.event
 async def on_message(message):
-	if message.author == client.user: return
+	if message.author == globals.client.user: return
 
 	words = message.content.split(" ")
 	author = str('{0.author.mention}'.format(message))
 
 	# A user is trying to get help
-	if words[0] == prefix:
+	if words[0] == globals.prefix:
 		if len(words) > 1:
 			if words[1] == "ping": await message.channel.send("pong")
 			
 			elif words[1] == "here":
 				if message.author.guild_permissions.administrator:
-					cursor = conn.cursor(buffered=True)
+					cursor = globals.conn.cursor(buffered=True)
 					cursor.execute("SELECT server, channel FROM t_servers WHERE server=%s", [str(message.guild.id)])
 					data = cursor.fetchone()
 					
 					if data is None:
 						cursor.execute("INSERT INTO t_servers (server, channel) VALUES (%s,%s)", [str(message.guild.id), str(message.channel.id)])
-						conn.commit()
+						globals.conn.commit()
 						
 						await message.channel.send("Channel **" + str(message.channel) + "** configured for **" + str(message.guild) + "**.")
 					else:
 						if(data[1] == str(message.channel.id)): await message.channel.send("Channel **" + str(message.channel) + "** already in use for this server.")
 						else:
 							cursor.execute("UPDATE t_servers SET channel = %s WHERE server = %s", [str(message.channel.id), str(message.guild.id)])
-							conn.commit()
+							globals.conn.commit()
 							
 							await message.channel.send("Channel updated to: **" + str(message.channel) + "**.")
 							
@@ -366,13 +239,13 @@ async def on_message(message):
 							try:
 								urllib.request.urlopen('https://myanimelist.net/profile/' + user)
 								
-								cursor = conn.cursor(buffered=True)
+								cursor = globals.conn.cursor(buffered=True)
 								cursor.execute("SELECT servers FROM t_users WHERE LOWER(mal_user)=%s", [user.lower()])
 								data = cursor.fetchone()
 
 								if data is None:
 									cursor.execute("INSERT INTO t_users (mal_user, servers) VALUES (%s, %s)", [user, str(message.guild.id)])
-									conn.commit()
+									globals.conn.commit()
 									
 									await message.channel.send("**" + user + "** added to the database for the server **" + str(message.guild) + "**.")
 								else:
@@ -385,7 +258,7 @@ async def on_message(message):
 										await message.channel.send("User **" + user + "** already in our database for this server!")
 									else:
 										cursor.execute("UPDATE t_users SET servers = %s WHERE LOWER(mal_user) = %s", [data[0] + "," + str(message.guild.id), user.lower()])
-										conn.commit()
+										globals.conn.commit()
 										
 										await message.channel.send("**" + user + "** added to the database for the server **" + str(message.guild) + "**.")
 										
@@ -394,10 +267,10 @@ async def on_message(message):
 								if (e.code == 404): await message.channel.send("User **" + user + "** doesn't exist on MyAnimeList!")
 								else:
 									await message.channel.send("An error occured when we checked this username on MyAnimeList, maybe the website is down?")
-									logger.warning("HTTP Code " + str(e.code) + " while checking to add for the new user '" + user + "'")
+									globals.logger.warning("HTTP Code " + str(e.code) + " while checking to add for the new user '" + user + "'")
 							except Exception as e:
 								await message.channel.send("An unknown error occured while addind this user, the error has been logged.")
-								logger.warning("Error while adding user '" + user + "' on server '" + message.guild + "': " + str(e))
+								globals.logger.warning("Error while adding user '" + user + "' on server '" + message.guild + "': " + str(e))
 						else: await message.channel.send("Username too long!")
 					else: await message.channel.send("Too many arguments! You have to specify only one username.")
 				else: await message.channel.send("You have to specify a **MyAnimeList** username!")
@@ -407,7 +280,7 @@ async def on_message(message):
 					if (len(words) == 3):
 						user = words[2]
 						
-						cursor = conn.cursor(buffered=True)
+						cursor = globals.conn.cursor(buffered=True)
 						cursor.execute("SELECT servers FROM t_users WHERE LOWER(mal_user)=%s", [user.lower()])
 						data = cursor.fetchone()
 						
@@ -424,7 +297,7 @@ async def on_message(message):
 							if present == 1:
 								if srv_string == "": cursor.execute("DELETE FROM t_users WHERE LOWER(mal_user) = %s", [user.lower()])
 								else: cursor.execute("UPDATE t_users SET servers = %s WHERE LOWER(mal_user) = %s", [srv_string, user.lower()])
-								conn.commit()
+								globals.conn.commit()
 								
 								await message.channel.send("**" + user + "** deleted from the database for this server.")
 							else: await message.channel.send("The user **" + user + "** is not in our database for this server!")
@@ -437,14 +310,14 @@ async def on_message(message):
 			elif words[1] == "stop":
 				if message.author.guild_permissions.administrator:
 					if (len(words) == 2):
-						cursor = conn.cursor(buffered=True)
+						cursor = globals.conn.cursor(buffered=True)
 						cursor.execute("SELECT server FROM t_servers WHERE server=%s", [str(message.guild.id)])
 						data = cursor.fetchone()
 					
-						if data is None: await client.send_message(message.channel, "The server **" + str(message.guild) + "** is not in our database.")
+						if data is None: await globals.client.send_message(message.channel, "The server **" + str(message.guild) + "** is not in our database.")
 						else:
 							cursor.execute("DELETE FROM t_servers WHERE server = %s", [message.guild.id])
-							conn.commit()
+							globals.conn.commit()
 							await message.channel.send("Server **" + str(message.guild) + "** deleted from our database.")
 						
 						cursor.close()
@@ -452,18 +325,18 @@ async def on_message(message):
 				else: await message.channel.send("Only server's admins can use this command!")
 				
 			elif words[1] == "info":
-				cursor = conn.cursor(buffered=True)
+				cursor = globals.conn.cursor(buffered=True)
 				cursor.execute("SELECT server FROM t_servers WHERE server=%s", [str(message.guild.id)])
 				data = cursor.fetchone()
 				
 				if data is None: await message.channel.send("The server **" + str(message.guild) + "** is not in our database.")
 				else:
 					user = ""
-					cursor = conn.cursor(buffered=True)
+					cursor = globals.conn.cursor(buffered=True)
 					cursor.execute("SELECT mal_user, servers FROM t_users")
 					data = cursor.fetchone()
 					
-					cursor_channel = conn.cursor(buffered=True)
+					cursor_channel = globals.conn.cursor(buffered=True)
 					cursor_channel.execute("SELECT channel FROM t_servers WHERE server=%s", [str(message.guild.id)])
 					data_channel = cursor_channel.fetchone()
 					
@@ -477,18 +350,18 @@ async def on_message(message):
 							data = cursor.fetchone()
 						
 						if (user == ""): await message.channel.send("No user in this server.")
-						else: await message.channel.send("Here's the user(s) in the **" + str(message.guild) + "**'s server:\n```" + user + "```\nAssigned channel: **" + str(client.get_channel(int(data_channel[0]))) + "**")
+						else: await message.channel.send("Here's the user(s) in the **" + str(message.guild) + "**'s server:\n```" + user + "```\nAssigned channel: **" + str(globals.client.get_channel(int(data_channel[0]))) + "**")
 
 					cursor.close()
 					cursor_channel.close()
-			elif words[1] == "about": await message.channel.send(embed=discord.Embed(colour=0x777777, title="MyAnimeBot version " + VERSION + " by Penta", description="This bot check the MyAnimeList's RSS for each user specified, and send a message if there is something new.\nMore help with the **!malbot help** command.\n\nAdd me on steam: http://steamcommunity.com/id/Penta_Pingouin").set_thumbnail(url="https://cdn.discordapp.com/avatars/415474467033317376/2d847944aab2104923c18863a41647da.jpg?size=64"))
+			elif words[1] == "about": await message.channel.send(embed=discord.Embed(colour=0x777777, title="MyAnimeBot version " + globals.VERSION + " by Penta", description="This bot check the MyAnimeList's RSS for each user specified, and send a message if there is something new.\nMore help with the **!malbot help** command.\n\nAdd me on steam: http://steamcommunity.com/id/Penta_Pingouin").set_thumbnail(url="https://cdn.discordapp.com/avatars/415474467033317376/2d847944aab2104923c18863a41647da.jpg?size=64"))
 			
-			elif words[1] == "help": await message.channel.send(HELP)
+			elif words[1] == "help": await message.channel.send(globals.HELP)
 			
 			elif words[1] == "top":
 				if len(words) == 2:
 					try:
-						cursor = conn.cursor(buffered=True)
+						cursor = globals.conn.cursor(buffered=True)
 						cursor.execute("SELECT * FROM v_Top")
 						data = cursor.fetchone()
 						
@@ -501,13 +374,13 @@ async def on_message(message):
 									
 								data = cursor.fetchone()
 								
-							cursor = conn.cursor(buffered=True)
+							cursor = globals.conn.cursor(buffered=True)
 							cursor.execute("SELECT * FROM v_TotalFeeds")
 							data = cursor.fetchone()
 							
 							topText += "\n***Total user entry***: " + str(data[0])
 							
-							cursor = conn.cursor(buffered=True)
+							cursor = globals.conn.cursor(buffered=True)
 							cursor.execute("SELECT * FROM v_TotalAnimes")
 							data = cursor.fetchone()
 							
@@ -517,14 +390,14 @@ async def on_message(message):
 						
 						cursor.close()
 					except Exception as e:
-						logger.warning("An error occured while displaying the global top: " + str(e))
+						globals.logger.warning("An error occured while displaying the global top: " + str(e))
 						await message.channel.send("Unable to reply to your request at the moment...")
 				elif len(words) > 2:
 					keyword = str(' '.join(words[2:]))
-					logger.info("Displaying the global top for the keyword: " + keyword)
+					globals.logger.info("Displaying the global top for the keyword: " + keyword)
 					
 					try:
-						cursor = conn.cursor(buffered=True)
+						cursor = globals.conn.cursor(buffered=True)
 						cursor.callproc('sp_UsersPerKeyword', [str(keyword), '20'])
 						for result in cursor.stored_results():
 							data = result.fetchone()
@@ -542,7 +415,7 @@ async def on_message(message):
 							
 						cursor.close()
 					except Exception as e:
-						logger.warning("An error occured while displaying the global top for keyword '" + keyword + "': " + str(e))
+						globals.logger.warning("An error occured while displaying the global top for keyword '" + keyword + "': " + str(e))
 						await message.channel.send("Unable to reply to your request at the moment...")
 			
 			elif words[1] == "group":
@@ -553,45 +426,48 @@ async def on_message(message):
 					else: await message.channel.send("Only server's admins can use this command!")
 				else:
 					await message.channel.send("You have to specify a group!")
-		
+
+			elif words[1] == "fetch-debug":
+				fetch_activities_anilist()
+
 	# If mentioned
-	elif client.user in message.mentions:
+	elif globals.client.user in message.mentions:
 		await message.channel.send(":heart:")
 
 # Get a random anime name and change the bot's activity
 async def change_gameplayed(asyncioloop):
-	logger.info("Starting up change_gameplayed")
+	globals.logger.info("Starting up change_gameplayed")
 	
-	await client.wait_until_ready()
+	await globals.client.wait_until_ready()
 	await asyncio.sleep(1)
 
-	while not client.is_closed():
+	while not globals.client.is_closed():
 		# Get a random anime name from the users' list
-		cursor = conn.cursor(buffered=True)
+		cursor = globals.conn.cursor(buffered=True)
 		cursor.execute("SELECT title FROM t_animes ORDER BY RAND() LIMIT 1")
 		data = cursor.fetchone()
 		anime = utils.truncate_end_show(data[0])
 		
 		# Try to change the bot's activity
 		try:
-			if data is not None: await client.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name=anime))
+			if data is not None: await globals.client.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name=anime))
 		except Exception as e:
-			logger.warning("An error occured while changing the displayed anime title: " + str(e))
+			globals.logger.warning("An error occured while changing the displayed anime title: " + str(e))
 			
 		cursor.close()
 		# Do it every minute
 		await asyncio.sleep(60)
 
 async def update_thumbnail_catalog(asyncioloop):
-	logger.info("Starting up update_thumbnail_catalog")
+	globals.logger.info("Starting up update_thumbnail_catalog")
 	
-	while not client.is_closed():
+	while not globals.client.is_closed():
 		await asyncio.sleep(43200)
 		
-		logger.info("Automatic check of the thumbnail database on going...")
+		globals.logger.info("Automatic check of the thumbnail database on going...")
 		reload = 0
 		
-		cursor = conn.cursor(buffered=True)
+		cursor = globals.conn.cursor(buffered=True)
 		cursor.execute("SELECT guid, title, thumbnail FROM t_animes")
 		data = cursor.fetchone()
 
@@ -600,42 +476,42 @@ async def update_thumbnail_catalog(asyncioloop):
 				if (data[2] != "") : urllib.request.urlopen(data[2])
 				else: reload = 1
 			except urllib.error.HTTPError as e:
-				logger.warning("HTTP Error while getting the current thumbnail of '" + str(data[1]) + "': " + str(e))
+				globals.logger.warning("HTTP Error while getting the current thumbnail of '" + str(data[1]) + "': " + str(e))
 				reload = 1
 			except Exception as e:
-				logger.debug("Error while getting the current thumbnail of '" + str(data[1]) + "': " + str(e))
+				globals.logger.debug("Error while getting the current thumbnail of '" + str(data[1]) + "': " + str(e))
 			
 			if (reload == 1) :
 				try:
 					image = utils.getThumbnail(data[0])
 						
 					cursor.execute("UPDATE t_animes SET thumbnail = %s WHERE guid = %s", [image, data[0]])
-					conn.commit()
+					globals.conn.commit()
 						
-					logger.info("Updated thumbnail found for \"" + str(data[1]) + "\": %s", image)
+					globals.logger.info("Updated thumbnail found for \"" + str(data[1]) + "\": %s", image)
 				except Exception as e:
-					logger.warning("Error while downloading updated thumbnail for '" + str(data[1]) + "': " + str(e))
+					globals.logger.warning("Error while downloading updated thumbnail for '" + str(data[1]) + "': " + str(e))
 
 			await asyncio.sleep(3)
 			data = cursor.fetchone()
 
 		cursor.close()
 
-		logger.info("Thumbnail database checked.")
+		globals.logger.info("Thumbnail database checked.")
 	
 # Starting main function	
 if __name__ == "__main__":
     try:
-        client.run(token)
+        globals.client.run(globals.token)
     except:
         logging.info("Closing all tasks...")
-        task_feed.cancel()
-        task_thumbnail.cancel()
-        task_gameplayed.cancel()
+        globals.task_feed.cancel()
+        globals.task_thumbnail.cancel()
+        globals.task_gameplayed.cancel()
 
-    logger.critical("Script halted.")
+    globals.logger.critical("Script halted.")
 
 	# We close all the ressources
-    conn.close()
-    log_cursor.close()
-    log_conn.close()
+    globals.conn.close()
+    globals.log_cursor.close()
+    globals.log_conn.close()

+ 0 - 0
include/utils.py → src/utils.py