mirror of https://github.com/stijndcl/didier
				
				
				
			
						commit
						2bc949de83
					
				| 
						 | 
					@ -8,6 +8,7 @@ files/stats.json
 | 
				
			||||||
files/lost.json
 | 
					files/lost.json
 | 
				
			||||||
files/locked.json
 | 
					files/locked.json
 | 
				
			||||||
files/database.json
 | 
					files/database.json
 | 
				
			||||||
 | 
					files/ufora_notifications.json
 | 
				
			||||||
.idea/
 | 
					.idea/
 | 
				
			||||||
__pycache__
 | 
					__pycache__
 | 
				
			||||||
.env
 | 
					.env
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@ import pytz
 | 
				
			||||||
import requests
 | 
					import requests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Temporarily disabled because of API (setup @ bottom)
 | 
				
			||||||
class Launch(commands.Cog):
 | 
					class Launch(commands.Cog):
 | 
				
			||||||
    def __init__(self, client):
 | 
					    def __init__(self, client):
 | 
				
			||||||
        self.client = client
 | 
					        self.client = client
 | 
				
			||||||
| 
						 | 
					@ -51,4 +52,5 @@ class Launch(commands.Cog):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def setup(client):
 | 
					def setup(client):
 | 
				
			||||||
    client.add_cog(Launch(client))
 | 
					    pass
 | 
				
			||||||
 | 
					    # client.add_cog(Launch(client))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@ from discord.ext import commands
 | 
				
			||||||
from enums.help_categories import Category
 | 
					from enums.help_categories import Category
 | 
				
			||||||
from functions import checks, clap, mock, sunrise, timeFormatters
 | 
					from functions import checks, clap, mock, sunrise, timeFormatters
 | 
				
			||||||
import pytz
 | 
					import pytz
 | 
				
			||||||
 | 
					from requests import get
 | 
				
			||||||
import time
 | 
					import time
 | 
				
			||||||
import urllib.parse
 | 
					import urllib.parse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,7 +102,7 @@ class Oneliners(commands.Cog):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @commands.command(name="Todo", aliases=["List", "Td"])
 | 
					    @commands.command(name="Todo", aliases=["List", "Td"])
 | 
				
			||||||
    @help.Category(category=Category.Didier)
 | 
					    @help.Category(category=Category.Didier)
 | 
				
			||||||
    async def todo(self, ctx, *args):
 | 
					    async def todo(self, ctx):
 | 
				
			||||||
        await ctx.send("https://trello.com/b/PdtsAJea/didier-to-do-list")
 | 
					        await ctx.send("https://trello.com/b/PdtsAJea/didier-to-do-list")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @commands.command(name="LMGTFY", aliases=["Dsfr"], usage="[Query]")
 | 
					    @commands.command(name="LMGTFY", aliases=["Dsfr"], usage="[Query]")
 | 
				
			||||||
| 
						 | 
					@ -130,7 +131,7 @@ class Oneliners(commands.Cog):
 | 
				
			||||||
        await ctx.send("Shut, it already is.")
 | 
					        await ctx.send("Shut, it already is.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @commands.command()
 | 
					    @commands.command()
 | 
				
			||||||
    async def sc(self, ctx, *args):
 | 
					    async def sc(self, ctx):
 | 
				
			||||||
        await ctx.send("http://take-a-screenshot.org/")
 | 
					        await ctx.send("http://take-a-screenshot.org/")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @commands.command(aliases=["os", "sauce", "src"])
 | 
					    @commands.command(aliases=["os", "sauce", "src"])
 | 
				
			||||||
| 
						 | 
					@ -144,9 +145,19 @@ class Oneliners(commands.Cog):
 | 
				
			||||||
        await ctx.send(":sunny:: **{}**\n:crescent_moon:: **{}**".format(s.sunrise(), s.sunset()))
 | 
					        await ctx.send(":sunny:: **{}**\n:crescent_moon:: **{}**".format(s.sunrise(), s.sunset()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @commands.command(name="Tias", aliases=["TryIt"])
 | 
					    @commands.command(name="Tias", aliases=["TryIt"])
 | 
				
			||||||
    async def tias(self, ctx, *args):
 | 
					    async def tias(self, ctx):
 | 
				
			||||||
        await ctx.send("***Try it and see***")
 | 
					        await ctx.send("***Try it and see***")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @commands.command(name="Inspire")
 | 
				
			||||||
 | 
					    @help.Category(Category.Other)
 | 
				
			||||||
 | 
					    async def inspire(self, ctx):
 | 
				
			||||||
 | 
					        image = get("http://inspirobot.me/api?generate=true")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if image.status_code == 200:
 | 
				
			||||||
 | 
					            await ctx.send(image.text)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            await ctx.send("Uh oh API down.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def setup(client):
 | 
					def setup(client):
 | 
				
			||||||
    client.add_cog(Oneliners(client))
 | 
					    client.add_cog(Oneliners(client))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@ from functions import timeFormatters
 | 
				
			||||||
from functions.config import config
 | 
					from functions.config import config
 | 
				
			||||||
from functions.database import currency, poke, prison, birthdays, stats
 | 
					from functions.database import currency, poke, prison, birthdays, stats
 | 
				
			||||||
from functions.scraping import getMatchweek
 | 
					from functions.scraping import getMatchweek
 | 
				
			||||||
 | 
					from functions import ufora_notifications
 | 
				
			||||||
import json
 | 
					import json
 | 
				
			||||||
import random
 | 
					import random
 | 
				
			||||||
import requests
 | 
					import requests
 | 
				
			||||||
| 
						 | 
					@ -24,6 +25,7 @@ class Tasks(commands.Cog):
 | 
				
			||||||
        self.updateMessageCounts.start()
 | 
					        self.updateMessageCounts.start()
 | 
				
			||||||
        self.sendReminders.start()
 | 
					        self.sendReminders.start()
 | 
				
			||||||
        self.updateMatchweek.start()
 | 
					        self.updateMatchweek.start()
 | 
				
			||||||
 | 
					        self.uforaAnnouncements.start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @tasks.loop(hours=1.0)
 | 
					    @tasks.loop(hours=1.0)
 | 
				
			||||||
    async def bankInterest(self):
 | 
					    async def bankInterest(self):
 | 
				
			||||||
| 
						 | 
					@ -238,6 +240,24 @@ class Tasks(commands.Cog):
 | 
				
			||||||
    async def beforeUpdateMatchweek(self):
 | 
					    async def beforeUpdateMatchweek(self):
 | 
				
			||||||
        await self.client.wait_until_ready()
 | 
					        await self.client.wait_until_ready()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @tasks.loop(minutes=30.0)
 | 
				
			||||||
 | 
					    async def uforaAnnouncements(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Task that checks for new Ufora announcements every few minutes
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        # Get new notifications
 | 
				
			||||||
 | 
					        announcements = ufora_notifications.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if announcements:
 | 
				
			||||||
 | 
					            announcements_channel = self.client.get_channel(816724500136591380)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for an in announcements:
 | 
				
			||||||
 | 
					                await announcements_channel.send(embed=an.to_embed())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @uforaAnnouncements.before_loop
 | 
				
			||||||
 | 
					    async def beforeUforaAnnouncements(self):
 | 
				
			||||||
 | 
					        await self.client.wait_until_ready()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def getCurrentHour(self):
 | 
					    def getCurrentHour(self):
 | 
				
			||||||
        return timeFormatters.dateTimeNow().hour
 | 
					        return timeFormatters.dateTimeNow().hour
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,11 +14,13 @@ botIDs = [
 | 
				
			||||||
    "728361496874057812"
 | 
					    "728361496874057812"
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
BugReports = "762668401960812554"
 | 
					BugReports = "762668401960812554"
 | 
				
			||||||
 | 
					BotTesting = "679701786189103106"
 | 
				
			||||||
CallOfCode = "626699611192688641"
 | 
					CallOfCode = "626699611192688641"
 | 
				
			||||||
CoCGeneral = "626699611813314561"
 | 
					CoCGeneral = "626699611813314561"
 | 
				
			||||||
DeZandbak = "728361030404538488"
 | 
					DeZandbak = "728361030404538488"
 | 
				
			||||||
ErrorLogs = "762668505455132722"
 | 
					ErrorLogs = "762668505455132722"
 | 
				
			||||||
FeatureRequests = "762668473313787964"
 | 
					FeatureRequests = "762668473313787964"
 | 
				
			||||||
 | 
					ZandbakSpeeltuin = "769248992957038612"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mods = {
 | 
					mods = {
 | 
				
			||||||
    626699611192688641: [384457911377854467, 171671190631481345],
 | 
					    626699611192688641: [384457911377854467, 171671190631481345],
 | 
				
			||||||
| 
						 | 
					@ -53,7 +55,12 @@ faq_channels = {
 | 
				
			||||||
    727876797458284584: "funcprog",
 | 
					    727876797458284584: "funcprog",
 | 
				
			||||||
    727876819264733244: "statprob",
 | 
					    727876819264733244: "statprob",
 | 
				
			||||||
    727876836587208714: "sysprog",
 | 
					    727876836587208714: "sysprog",
 | 
				
			||||||
    676713433567199232: "didier"
 | 
					    676713433567199232: "didier",
 | 
				
			||||||
 | 
					    807566495550013460: "comparch",
 | 
				
			||||||
 | 
					    807567007355895838: "multimedia",
 | 
				
			||||||
 | 
					    807567261216538644: "sel1",
 | 
				
			||||||
 | 
					    807567345484169237: "webdev",
 | 
				
			||||||
 | 
					    807567387775336499: "wetrek"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					from .ufora import UforaNotification
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,95 @@
 | 
				
			||||||
 | 
					from datetime import datetime, timedelta
 | 
				
			||||||
 | 
					from discord import Embed, Colour
 | 
				
			||||||
 | 
					from functions.stringFormatters import leadingZero as lz
 | 
				
			||||||
 | 
					from functions.timeFormatters import intToWeekday
 | 
				
			||||||
 | 
					import pytz
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UforaNotification:
 | 
				
			||||||
 | 
					    def __init__(self, content: dict, course, notif_id, course_id):
 | 
				
			||||||
 | 
					        self._content: dict = content
 | 
				
			||||||
 | 
					        self._course = course
 | 
				
			||||||
 | 
					        self._notif_id, self._course_id = notif_id, course_id
 | 
				
			||||||
 | 
					        self._view_url = self._create_url()
 | 
				
			||||||
 | 
					        self._title = self._clean_content(self._content["title"])
 | 
				
			||||||
 | 
					        self._description = self._get_description()
 | 
				
			||||||
 | 
					        self._published = self._get_published()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def to_embed(self):
 | 
				
			||||||
 | 
					        embed = Embed(colour=Colour.from_rgb(30, 100, 200))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        embed.set_author(name=self._course)
 | 
				
			||||||
 | 
					        embed.title = self._title
 | 
				
			||||||
 | 
					        embed.url = self._view_url
 | 
				
			||||||
 | 
					        embed.description = self._description
 | 
				
			||||||
 | 
					        embed.set_footer(text=self._published)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return embed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_id(self):
 | 
				
			||||||
 | 
					        return int(self._notif_id) if self._notif_id is not None else self._content["id"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _create_url(self):
 | 
				
			||||||
 | 
					        if self._notif_id is None or self._course_id is None:
 | 
				
			||||||
 | 
					            return self._content["link"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return "https://ufora.ugent.be/d2l/le/news/{0}/{1}/view?ou={0}".format(self._course_id, self._notif_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _get_description(self):
 | 
				
			||||||
 | 
					        desc = self._clean_content(self._content["summary"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if len(desc) > 500:
 | 
				
			||||||
 | 
					            return desc[:497] + "..."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return desc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _clean_content(self, text: str):
 | 
				
			||||||
 | 
					        # Dict with HTML & markdown tags to replace
 | 
				
			||||||
 | 
					        html_table = {
 | 
				
			||||||
 | 
					            # CHARACTERS:
 | 
				
			||||||
 | 
					            "&": '&',
 | 
				
			||||||
 | 
					            """: '"',
 | 
				
			||||||
 | 
					            "apos;": "'",
 | 
				
			||||||
 | 
					            ">": ">",
 | 
				
			||||||
 | 
					            "<": "<",
 | 
				
			||||||
 | 
					            # MARKDOWN SUPPORT:
 | 
				
			||||||
 | 
					            "<b>": "**",
 | 
				
			||||||
 | 
					            "</b>": "**",
 | 
				
			||||||
 | 
					            "<strong>": "**",
 | 
				
			||||||
 | 
					            "</strong>": "**",
 | 
				
			||||||
 | 
					            "<i>": "*",
 | 
				
			||||||
 | 
					            "</i>": "*",
 | 
				
			||||||
 | 
					            "<em>": "*",
 | 
				
			||||||
 | 
					            "</em>": "*",
 | 
				
			||||||
 | 
					            "<del>": "~~",
 | 
				
			||||||
 | 
					            "</del>": "~~",
 | 
				
			||||||
 | 
					            "<ins>": "__",
 | 
				
			||||||
 | 
					            "</ins>": "__",
 | 
				
			||||||
 | 
					            # Represent paragraphs with newlines
 | 
				
			||||||
 | 
					            "</p>": "\n",
 | 
				
			||||||
 | 
					            "<br>": "\n",
 | 
				
			||||||
 | 
					            "<br/>": "\n",
 | 
				
			||||||
 | 
					            "<br />": "\n"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Unescape HTML
 | 
				
			||||||
 | 
					        for key, value in html_table.items():
 | 
				
			||||||
 | 
					            text = text.replace(key, value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Remove HTML tags
 | 
				
			||||||
 | 
					        return re.sub(r"<[^>]*>", "", text)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _get_published(self):
 | 
				
			||||||
 | 
					        time_string = "%a, %d %b %Y %H:%M:%S %Z"
 | 
				
			||||||
 | 
					        dt = datetime.strptime(self._content["published"], time_string)\
 | 
				
			||||||
 | 
					            .astimezone(pytz.timezone("Europe/Brussels"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Apply timezone offset
 | 
				
			||||||
 | 
					        dt = dt + timedelta(hours=dt.utcoffset().seconds//3600)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return "{} {}/{}/{} om {}:{}:{}".format(
 | 
				
			||||||
 | 
					            intToWeekday(dt.weekday()),
 | 
				
			||||||
 | 
					            lz(dt.day), lz(dt.month), lz(dt.year),
 | 
				
			||||||
 | 
					            lz(dt.hour), lz(dt.minute), lz(dt.second)
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -46,12 +46,12 @@
 | 
				
			||||||
  "hangman start": "Start een nieuwe Hangman game indien er nog geen bezig is. Indien je geen woord opgeeft, wordt er een willekeurig woord gekozen.\n**Indien je wel een woord opgeeft, werkt dit enkel in DM.**",
 | 
					  "hangman start": "Start een nieuwe Hangman game indien er nog geen bezig is. Indien je geen woord opgeeft, wordt er een willekeurig woord gekozen.\n**Indien je wel een woord opgeeft, werkt dit enkel in DM.**",
 | 
				
			||||||
  "hangman guess": "Probeer het woord te raden.",
 | 
					  "hangman guess": "Probeer het woord te raden.",
 | 
				
			||||||
  "claim": "Claim [Aantal] Didier Dinks uit je profit.\nIndien je geen aantal opgeeft (of \"all\"), claim je alles, inclusief je investering.",
 | 
					  "claim": "Claim [Aantal] Didier Dinks uit je profit.\nIndien je geen aantal opgeeft (of \"all\"), claim je alles, inclusief je investering.",
 | 
				
			||||||
 | 
					  "inspire": "Generate quotes via [InspiroBot](https://inspirobot.me/).",
 | 
				
			||||||
  "inventory": "Bekijk de items in jouw inventory.",
 | 
					  "inventory": "Bekijk de items in jouw inventory.",
 | 
				
			||||||
  "invest": "Investeer [Aantal] Didier Dinks in jouw Didier Bank om rente te vergaren.",
 | 
					  "invest": "Investeer [Aantal] Didier Dinks in jouw Didier Bank om rente te vergaren.",
 | 
				
			||||||
  "jpl": "Informatie over de Jupiler Pro League.",
 | 
					  "jpl": "Informatie over de Jupiler Pro League.",
 | 
				
			||||||
  "jpl matches": "Bekijk de wedstrijden die gespeeld worden op [Week]. Default naar de huidige speeldag.",
 | 
					  "jpl matches": "Bekijk de wedstrijden die gespeeld worden op [Week]. Default naar de huidige speeldag.",
 | 
				
			||||||
  "jpl table": "De huidige stand van het klassement.",
 | 
					  "jpl table": "De huidige stand van het klassement.",
 | 
				
			||||||
  "launch": "Tijdstip van de volgende SpaceX lancering.",
 | 
					 | 
				
			||||||
  "leaderboard": "Bekijk de Top 10 van [Categorie].\nIndien je geen categorie opgeeft krijg je een lijst van categorieën.",
 | 
					  "leaderboard": "Bekijk de Top 10 van [Categorie].\nIndien je geen categorie opgeeft krijg je een lijst van categorieën.",
 | 
				
			||||||
  "les": "Bekijk het lessenrooster voor [Dag] in het [Jaargang]-de jaar.\nIndien je geen dag opgeeft, is dit standaard vandaag. De jaargang is standaard 2.\nLes Morgen/Overmorgen werkt ook.",
 | 
					  "les": "Bekijk het lessenrooster voor [Dag] in het [Jaargang]-de jaar.\nIndien je geen dag opgeeft, is dit standaard vandaag. De jaargang is standaard 2.\nLes Morgen/Overmorgen werkt ook.",
 | 
				
			||||||
  "lmgtfy": "Stuur iemand een LMGTFY link wanneer ze je een domme vraag stellen in plaats van het zelf op te zoeken.\nQueries met spaties moeten **niet** tussen aanhalingstekens staan.",
 | 
					  "lmgtfy": "Stuur iemand een LMGTFY link wanneer ze je een domme vraag stellen in plaats van het zelf op te zoeken.\nQueries met spaties moeten **niet** tussen aanhalingstekens staan.",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,7 @@
 | 
				
			||||||
import datetime
 | 
					import datetime
 | 
				
			||||||
import time
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import dateutil.relativedelta
 | 
					import dateutil.relativedelta
 | 
				
			||||||
import pytz
 | 
					import pytz
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def epochToDate(epochTimeStamp, strFormat="%d/%m/%Y om %H:%M:%S"):
 | 
					def epochToDate(epochTimeStamp, strFormat="%d/%m/%Y om %H:%M:%S"):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,67 @@
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import feedparser
 | 
				
			||||||
 | 
					from data.embeds import UforaNotification
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					course_urls = {
 | 
				
			||||||
 | 
					    "Algoritmen en Datastructuren 2": "https://ufora.ugent.be/d2l/le/news/rss/222018/course?token=aehhv6utkf46t8cc102e0&ou=222018",
 | 
				
			||||||
 | 
					    "Communicatienetwerken": "https://ufora.ugent.be/d2l/le/news/rss/221184/course?token=aehhv6utkf46t8cc102e0&ou=221184",
 | 
				
			||||||
 | 
					    "Computerarchitectuur": "https://ufora.ugent.be/d2l/le/news/rss/228912/course?token=aehhv6utkf46t8cc102e0&ou=228912",
 | 
				
			||||||
 | 
					    "Functioneel Programmeren": "https://ufora.ugent.be/d2l/le/news/rss/236396/course?token=aehhv6utkf46t8cc102e0&ou=236396",
 | 
				
			||||||
 | 
					    "Multimedia": "https://ufora.ugent.be/d2l/le/news/rss/236949/course?token=aehhv6utkf46t8cc102e0&ou=236949",
 | 
				
			||||||
 | 
					    "Software Engineering Lab 1": "https://ufora.ugent.be/d2l/le/news/rss/235800/course?token=aehhv6utkf46t8cc102e0&ou=235800",
 | 
				
			||||||
 | 
					    "Statistiek en Probabiliteit": "https://ufora.ugent.be/d2l/le/news/rss/236398/course?token=aehhv6utkf46t8cc102e0&ou=236398",
 | 
				
			||||||
 | 
					    "Systeemprogrammeren": "https://ufora.ugent.be/d2l/le/news/rss/222035/course?token=aehhv6utkf46t8cc102e0&ou=222035",
 | 
				
			||||||
 | 
					    "Webdevelopment": "https://ufora.ugent.be/d2l/le/news/rss/223449/course?token=aehhv6utkf46t8cc102e0&ou=223449",
 | 
				
			||||||
 | 
					    "Wetenschappelijk Rekenen": "https://ufora.ugent.be/d2l/le/news/rss/236404/course?token=aehhv6utkf46t8cc102e0&ou=236404"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def run():
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Check for new notifications
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    # List of new notifications
 | 
				
			||||||
 | 
					    new_notifications = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # List of old notifications
 | 
				
			||||||
 | 
					    with open("files/ufora_notifications.json", "r") as fp:
 | 
				
			||||||
 | 
					        notifications = json.load(fp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for course, url in course_urls.items():
 | 
				
			||||||
 | 
					        # Automatically append new/missing courses
 | 
				
			||||||
 | 
					        if course not in notifications:
 | 
				
			||||||
 | 
					            notifications[course] = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Get the updated feed
 | 
				
			||||||
 | 
					        feed = feedparser.parse(url)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Filter out old notifications
 | 
				
			||||||
 | 
					        feed = list(filter(lambda f: _parse_ids(f["id"])[0] not in notifications[course], feed.entries))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if feed:
 | 
				
			||||||
 | 
					            for item in feed:
 | 
				
			||||||
 | 
					                notif_id, course_id = _parse_ids(item["id"])
 | 
				
			||||||
 | 
					                new_notifications.append(UforaNotification(item, course, notif_id, course_id))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                notifications[course].append(notif_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Update list of notifications
 | 
				
			||||||
 | 
					    if new_notifications:
 | 
				
			||||||
 | 
					        with open("files/ufora_notifications.json", "w") as fp:
 | 
				
			||||||
 | 
					            json.dump(notifications, fp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return new_notifications
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _parse_ids(url: str):
 | 
				
			||||||
 | 
					    match = re.search(r"[0-9]+-[0-9]+$", url)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if not match:
 | 
				
			||||||
 | 
					        return None, None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    spl = match[0].split("-")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return spl[0], spl[1]
 | 
				
			||||||
							
								
								
									
										19
									
								
								ignored.md
								
								
								
								
							
							
						
						
									
										19
									
								
								ignored.md
								
								
								
								
							| 
						 | 
					@ -103,3 +103,22 @@ Contains the stats to track for gambling games. Weren't made as a PSQL table bec
 | 
				
			||||||
Contains Didier's status message for when he logs in. Keep in mind that his activity is set to `Playing `. This was first used in Didier V1 to show whether or not he was in sandbox mode.
 | 
					Contains Didier's status message for when he logs in. Keep in mind that his activity is set to `Playing `. This was first used in Didier V1 to show whether or not he was in sandbox mode.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    with your Didier Dinks.
 | 
					    with your Didier Dinks.
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					### files/ufora_notifications.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Stores ID's of all received Ufora notifications.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```json
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "Algoritmen en Datastructuren 2": [],
 | 
				
			||||||
 | 
					  "Communicatienetwerken": [],
 | 
				
			||||||
 | 
					  "Computerarchitectuur": [],
 | 
				
			||||||
 | 
					  "Functioneel Programmeren": [],
 | 
				
			||||||
 | 
					  "Multimedia": [],
 | 
				
			||||||
 | 
					  "Software Engineering Lab 1": [],
 | 
				
			||||||
 | 
					  "Statistiek en Probabiliteit": [],
 | 
				
			||||||
 | 
					  "Systeemprogrammeren": [],
 | 
				
			||||||
 | 
					  "Webdevelopment": [],
 | 
				
			||||||
 | 
					  "Wetenschappelijk Rekenen": []
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
		Loading…
	
		Reference in New Issue