From 3a463e3af99f1723058f4ba2ab5e96732c1d1f6b Mon Sep 17 00:00:00 2001 From: flifloo Date: Tue, 3 Nov 2020 15:47:51 +0100 Subject: [PATCH] Add tomuss extension --- db/Tomuss.py | 16 ++++++ db/__init__.py | 1 + extensions/__init__.py | 1 + extensions/tomuss.py | 124 +++++++++++++++++++++++++++++++++++++++++ requirements.txt | 2 + 5 files changed, 144 insertions(+) create mode 100644 db/Tomuss.py create mode 100644 extensions/tomuss.py diff --git a/db/Tomuss.py b/db/Tomuss.py new file mode 100644 index 0000000..3892645 --- /dev/null +++ b/db/Tomuss.py @@ -0,0 +1,16 @@ +from datetime import datetime + +from db import Base +from sqlalchemy import Column, BigInteger, String, DateTime + + +class Tomuss(Base): + __tablename__ = "tomuss" + user_id = Column(BigInteger, primary_key=True) + url = Column(String, nullable=False) + last = Column(DateTime, nullable=False) + + def __init__(self, user_id: int, url: str, last: datetime): + self.user_id = user_id + self.url = url + self.last = last diff --git a/db/__init__.py b/db/__init__.py index 620746a..a983286 100644 --- a/db/__init__.py +++ b/db/__init__.py @@ -13,4 +13,5 @@ from db.Polls import Polls from db.Warn import Warn from db.WarnAction import WarnAction from db.InviteRole import InviteRole +from db.Tomuss import Tomuss Base.metadata.create_all(engine) diff --git a/extensions/__init__.py b/extensions/__init__.py index b679308..2c84dbe 100644 --- a/extensions/__init__.py +++ b/extensions/__init__.py @@ -14,3 +14,4 @@ bot.load_extension("extensions.tex") bot.load_extension("extensions.invite") bot.load_extension("extensions.speak") bot.load_extension("extensions.utils") +bot.load_extension("extensions.tomuss") diff --git a/extensions/tomuss.py b/extensions/tomuss.py new file mode 100644 index 0000000..704dff8 --- /dev/null +++ b/extensions/tomuss.py @@ -0,0 +1,124 @@ +import re +from datetime import datetime +from time import mktime, struct_time + +from discord import Embed, Forbidden +from discord.ext import commands, tasks +from discord.ext.commands import BadArgument +from feedparser import parse + +import db +from administrator.logger import logger + + +extension_name = "tomuss" +logger = logger.getChild(extension_name) +url_re = re.compile(r"https://tomuss\.univ-lyon1\.fr/S/[0-9]{4}/[a-zA-Z]+/rss/.+") + + +class Tomuss(commands.Cog): + def __init__(self, bot: commands.Bot): + self.bot = bot + self.tomuss_loop.start() + + def description(self): + return "PCP Univ Lyon 1" + + @commands.group("tomuss", pass_context=True) + async def tomuss(self, ctx: commands.Context): + if ctx.invoked_subcommand is None: + await ctx.invoke(self.tomuss_help) + + @tomuss.group("help", pass_context=True) + async def tomuss_help(self, ctx: commands.Context): + embed = Embed(title="Tomuss help") + embed.add_field(name="tomuss set ", value="Set your tomuss RSS feed", inline=False) + embed.add_field(name="tomuss unset", value="Unset your tomuss RSS feed", inline=False) + await ctx.send(embed=embed) + + @tomuss.group("set", pass_context=True) + async def tomuss_set(self, ctx: commands.Context, url: str): + if not url_re.fullmatch(url): + raise BadArgument() + entries = parse(url).entries + + if not entries: + raise BadArgument() + last = datetime.fromtimestamp(mktime(sorted(entries, key=lambda e: e.published_parsed)[0].published_parsed)) + + s = db.Session() + t = s.query(db.Tomuss).get(ctx.author.id) + if t: + t.url = url + t.last = last + else: + t = db.Tomuss(ctx.author.id, url, last) + s.add(t) + s.commit() + s.close() + + await ctx.message.add_reaction("\U0001f44d") + + @tomuss.group("unset", pass_context=True) + async def tomuss_unset(self, ctx: commands.Context): + s = db.Session() + t = s.query(db.Tomuss).get(ctx.author.id) + if not t: + raise BadArgument() + s.delete(t) + s.commit() + s.close() + await ctx.message.add_reaction("\U0001f44d") + + @tasks.loop(minutes=5) + async def tomuss_loop(self): + s = db.Session() + + for t in s.query(db.Tomuss).all(): + u = await self.bot.fetch_user(t.user_id) + if not u: + s.delete(t) + s.commit() + continue + + last = t.last.utctimetuple() + entries = list(filter(lambda e: e.published_parsed > last, + sorted(parse(t.url).entries, key=lambda e: e.published_parsed))) + if entries: + embed = Embed(title="Tomuss update !") + for e in entries: + embed.add_field(name=e.title, + value=e.summary.replace("
", "\n").replace("", "**").replace("", "**")) + try: + await u.send(embed=embed) + + t.last = datetime.fromtimestamp(mktime(entries[-1].published_parsed)) + s.add(t) + except Forbidden: + s.delete(t) + s.commit() + + s.close() + + def cog_unload(self): + self.tomuss_loop.stop() + + +def setup(bot): + logger.info(f"Loading...") + try: + bot.add_cog(Tomuss(bot)) + except Exception as e: + logger.error(f"Error loading: {e}") + else: + logger.info(f"Load successful") + + +def teardown(bot): + logger.info(f"Unloading...") + try: + bot.remove_cog("Tomuss") + except Exception as e: + logger.error(f"Error unloading: {e}") + else: + logger.info(f"Unload successful") diff --git a/requirements.txt b/requirements.txt index 4b9b3ea..56d1dbc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,9 @@ attrs==20.2.0 chardet==3.0.4 discord==1.0.1 discord.py==1.5.1 +feedparser==6.0.2 idna==2.10 multidict==4.7.6 +sgmllib3k==1.0.0 SQLAlchemy==1.3.20 yarl==1.5.1