Răsfoiți Sursa

Fixed hierarchy
Added new tests
Added mariadb addon to travis

Lucas Villeneuve 5 ani în urmă
părinte
comite
d98e14f725
7 a modificat fișierele cu 111 adăugiri și 62 ștergeri
  1. 2 0
      .travis.yml
  2. 4 42
      myanimebot.py
  3. 1 1
      myanimebot/__init__.py
  4. 2 3
      myanimebot/anilist.py
  5. 18 0
      myanimebot/myanimelist.py
  6. 45 16
      myanimebot/utils.py
  7. 39 0
      tests/test_myanimelist.py

+ 2 - 0
.travis.yml

@@ -1,6 +1,8 @@
 language: python
 python:
   - 3.7
+addons:
+  mariadb: 10.5.6
 before_install:
   - python --version
   - pip install -U pip

+ 4 - 42
myanimebot/myanimebot.py → myanimebot.py

@@ -30,50 +30,12 @@ from html2text import HTML2Text
 import myanimebot.anilist as anilist
 import myanimebot.globals as globals
 import myanimebot.utils as utils
+import myanimebot.myanimelist as myanimelist
 
 if not sys.version_info[:2] >= (3, 7):
 	print("ERROR: Requires python 3.7 or newer.")
 	exit(1)
 
-# TODO Create a Feed class instead of sending a lot of parameters
-def build_embed(user, item_title, item_link, item_description, pub_date, image, service: utils.Service):
-	''' Build the embed message related to the anime's status '''
-
-	# Get service
-	if service == utils.Service.MAL:
-		service_name = 'MyAnimeList'
-		profile_url = "{}{}".format(globals.MAL_PROFILE_URL, user)
-		icon_url = globals.MAL_ICON_URL
-	elif service == utils.Service.ANILIST:
-		service_name = 'AniList'
-		profile_url = "{}{}".format(globals.ANILIST_PROFILE_URL, user)
-		icon_url = globals.ANILIST_ICON_URL
-	else:
-		raise NotImplementedError('Unknown service {}'.format(service))
-	description = "[{}]({})\n```{}```".format(utils.filter_name(item_title), item_link, item_description)
-	profile_url_label = "{}'s {}".format(user, service_name)
-
-	try:	
-		embed = discord.Embed(colour=0xEED000, url=item_link, description=description, timestamp=pub_date.astimezone(pytz.timezone("utc")))
-		embed.set_thumbnail(url=image)
-		embed.set_author(name=profile_url_label, url=profile_url, icon_url=icon_url)
-		embed.set_footer(text="MyAnimeBot", icon_url=globals.iconBot)
-		
-		return embed
-	except Exception as e:
-		globals.logger.error("Error when generating the message: " + str(e))
-		return
-
-# Function used to send the embed
-async def send_embed_wrapper(asyncioloop, channelid, client, embed):
-	channel = client.get_channel(int(channelid))
-	
-	try:
-		await channel.send(embed=embed)
-		globals.logger.info("Message sent in channel: " + channelid)
-	except Exception as 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):
@@ -145,7 +107,7 @@ async def background_check_feed(asyncioloop):
 								
 								if data_img is None:
 									try:
-										image = utils.getThumbnail(item.link)
+										image = myanimelist.get_thumbnail(item.link)
 										
 										globals.logger.info("First time seeing this " + media + ", adding thumbnail into database: " + image)
 									except Exception as e:
@@ -167,7 +129,7 @@ async def background_check_feed(asyncioloop):
 									data_channel = db_srv.fetchone()
 									
 									while data_channel is not None:
-										for channel in data_channel: await send_embed_wrapper(asyncioloop, channel, globals.client, build_embed(user, item.title, item.link, item.description, pubDateRaw, image, utils.Service.MAL))
+										for channel in data_channel: await utils.send_embed_wrapper(asyncioloop, channel, globals.client, utils.build_embed(user, item.title, item.link, item.description, pubDateRaw, image, utils.Service.MAL))
 										
 										data_channel = db_srv.fetchone()
 					if feed_type == 1:
@@ -576,7 +538,7 @@ async def update_thumbnail_catalog(asyncioloop):
 			
 			if (reload == 1) :
 				try:
-					image = utils.getThumbnail(data[0])
+					image = myanimelist.get_thumbnail(data[0])
 						
 					cursor.execute("UPDATE t_animes SET thumbnail = %s WHERE guid = %s", [image, data[0]])
 					globals.conn.commit()

+ 1 - 1
myanimebot/__init__.py

@@ -1,4 +1,4 @@
 from .utils import * 
 from .anilist import *
 from .globals import *
-from .myanimebot import*
+from .myanimelist import *

+ 2 - 3
myanimebot/anilist.py

@@ -7,7 +7,6 @@ from typing import Dict, List
 import requests
 
 import myanimebot.globals as globals
-import myanimebot.myanimebot as mab
 import myanimebot.utils as utils
 
 ANILIST_GRAPHQL_URL = 'https://graphql.anilist.co'
@@ -317,10 +316,10 @@ async def send_embed_to_channels(activity : utils.Feed):
     
         if data_channels is not None:
             for channel in data_channels:
-                await mab.send_embed_wrapper(None,
+                await utils.send_embed_wrapper(None,
                                                     channel["channel"],
                                                     globals.client,
-                                                    mab.build_embed(activity.user.name,
+                                                    utils.build_embed(activity.user.name,
                                                                             activity.media.name,
                                                                             activity.media.url,
                                                                             activity.status,

+ 18 - 0
myanimebot/myanimelist.py

@@ -0,0 +1,18 @@
+import re
+import urllib
+
+from bs4 import BeautifulSoup
+
+
+def get_thumbnail(urlParam):
+    ''' Returns the MAL media thumnail from a link '''
+
+    url = "/".join((urlParam).split("/")[:5])
+	
+    websource = urllib.request.urlopen(url)
+    soup = BeautifulSoup(websource.read(), "html.parser")
+    image = re.search("(?P<url>https?://[^\s]+)", str(soup.find("img", {"itemprop": "image"}))).group("url")
+    thumbnail = "".join(image.split('"')[:1]).replace('"','')
+	
+    print(thumbnail)
+    return thumbnail

+ 45 - 16
myanimebot/utils.py

@@ -1,13 +1,12 @@
 import datetime
-import re
-import urllib.request
+import discord
+import pytz
 from enum import Enum
 from typing import List
 
-from bs4 import BeautifulSoup
-
 import myanimebot.globals as globals
 
+
 class Service(Enum):
 	MAL=globals.SERVICE_MAL
 	ANILIST=globals.SERVICE_ANILIST
@@ -94,18 +93,6 @@ class Feed():
 		self.description = description
 
 
-# Get thumbnail from an URL
-def getThumbnail(urlParam):
-	url = "/".join((urlParam).split("/")[:5])
-	
-	websource = urllib.request.urlopen(url)
-	soup = BeautifulSoup(websource.read(), "html.parser")
-	image = re.search("(?P<url>https?://[^\s]+)", str(soup.find("img", {"itemprop": "image"}))).group("url")
-	thumbnail = "".join(image.split('"')[:1]).replace('"','')
-	
-	return thumbnail
-
-
 def replace_all(text : str, replace_dic : dict) -> str:
 	''' Replace multiple substrings from a string '''
 	
@@ -265,3 +252,45 @@ def insert_user_into_db(user_name : str, service : Service, servers : str) -> bo
 	globals.conn.commit()
 	cursor.close()
 	return True
+
+# TODO Move those functions somewhere else (E.g. discord.py)
+
+# TODO Create a Feed class instead of sending a lot of parameters
+def build_embed(user, item_title, item_link, item_description, pub_date, image, service: Service):
+	''' Build the embed message related to the anime's status '''
+
+	# Get service
+	if service == Service.MAL:
+		service_name = 'MyAnimeList'
+		profile_url = "{}{}".format(globals.MAL_PROFILE_URL, user)
+		icon_url = globals.MAL_ICON_URL
+	elif service == Service.ANILIST:
+		service_name = 'AniList'
+		profile_url = "{}{}".format(globals.ANILIST_PROFILE_URL, user)
+		icon_url = globals.ANILIST_ICON_URL
+	else:
+		raise NotImplementedError('Unknown service {}'.format(service))
+	description = "[{}]({})\n```{}```".format(filter_name(item_title), item_link, item_description)
+	profile_url_label = "{}'s {}".format(user, service_name)
+
+	try:	
+		embed = discord.Embed(colour=0xEED000, url=item_link, description=description, timestamp=pub_date.astimezone(pytz.timezone("utc")))
+		embed.set_thumbnail(url=image)
+		embed.set_author(name=profile_url_label, url=profile_url, icon_url=icon_url)
+		embed.set_footer(text="MyAnimeBot", icon_url=globals.iconBot)
+		
+		return embed
+	except Exception as e:
+		globals.logger.error("Error when generating the message: " + str(e))
+		return
+
+# Function used to send the embed
+async def send_embed_wrapper(asyncioloop, channelid, client, embed):
+	channel = client.get_channel(int(channelid))
+	
+	try:
+		await channel.send(embed=embed)
+		globals.logger.info("Message sent in channel: " + channelid)
+	except Exception as e:
+		globals.logger.debug("Impossible to send a message on '" + channelid + "': " + str(e)) 
+		return

+ 39 - 0
tests/test_myanimelist.py

@@ -0,0 +1,39 @@
+import pytest
+
+from myanimebot.myanimelist import get_thumbnail
+
+def test_get_thumbnail():
+    # Test manga
+    try:
+        link = "https://myanimelist.net/manga/103890/Bokutachi_wa_Benkyou_ga_Dekinai"
+        expected_thumbnail = "https://cdn.myanimelist.net/images/manga/3/197080.jpg"
+        assert get_thumbnail(link) == expected_thumbnail
+    except Exception:
+        pytest.fail("Should not raise Exception")
+
+    # Test anime
+    try:
+        link = "https://myanimelist.net/anime/40028/Shingeki_no_Kyojin__The_Final_Season"
+        expected_thumbnail = "https://cdn.myanimelist.net/images/anime/1000/110531.jpg"
+        assert get_thumbnail(link) == expected_thumbnail
+    except Exception:
+        pytest.fail("Should not raise Exception")
+
+    # Test anime 2
+    try:
+        link = "https://myanimelist.net/anime/40028"
+        expected_thumbnail = "https://cdn.myanimelist.net/images/anime/1000/110531.jpg"
+        assert get_thumbnail(link) == expected_thumbnail
+    except Exception:
+        pytest.fail("Should not raise Exception")
+
+    # Test fail
+    with pytest.raises(Exception):
+        get_thumbnail('')
+
+    with pytest.raises(Exception):
+        get_thumbnail('https://myanimelist.net/anime/test/')
+        
+    with pytest.raises(Exception):
+        get_thumbnail('https://anilist.co/anime/110277/Attack-on-Titan-Final-Season/')
+