mirror of https://github.com/stijndcl/didier
				
				
				
			
						commit
						2bc949de83
					
				|  | @ -8,6 +8,7 @@ files/stats.json | |||
| files/lost.json | ||||
| files/locked.json | ||||
| files/database.json | ||||
| files/ufora_notifications.json | ||||
| .idea/ | ||||
| __pycache__ | ||||
| .env | ||||
|  | @ -8,6 +8,7 @@ import pytz | |||
| import requests | ||||
| 
 | ||||
| 
 | ||||
| # Temporarily disabled because of API (setup @ bottom) | ||||
| class Launch(commands.Cog): | ||||
|     def __init__(self, client): | ||||
|         self.client = client | ||||
|  | @ -51,4 +52,5 @@ class Launch(commands.Cog): | |||
| 
 | ||||
| 
 | ||||
| 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 functions import checks, clap, mock, sunrise, timeFormatters | ||||
| import pytz | ||||
| from requests import get | ||||
| import time | ||||
| import urllib.parse | ||||
| 
 | ||||
|  | @ -101,7 +102,7 @@ class Oneliners(commands.Cog): | |||
| 
 | ||||
|     @commands.command(name="Todo", aliases=["List", "Td"]) | ||||
|     @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") | ||||
| 
 | ||||
|     @commands.command(name="LMGTFY", aliases=["Dsfr"], usage="[Query]") | ||||
|  | @ -130,7 +131,7 @@ class Oneliners(commands.Cog): | |||
|         await ctx.send("Shut, it already is.") | ||||
| 
 | ||||
|     @commands.command() | ||||
|     async def sc(self, ctx, *args): | ||||
|     async def sc(self, ctx): | ||||
|         await ctx.send("http://take-a-screenshot.org/") | ||||
| 
 | ||||
|     @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())) | ||||
| 
 | ||||
|     @commands.command(name="Tias", aliases=["TryIt"]) | ||||
|     async def tias(self, ctx, *args): | ||||
|     async def tias(self, ctx): | ||||
|         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): | ||||
|     client.add_cog(Oneliners(client)) | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ from functions import timeFormatters | |||
| from functions.config import config | ||||
| from functions.database import currency, poke, prison, birthdays, stats | ||||
| from functions.scraping import getMatchweek | ||||
| from functions import ufora_notifications | ||||
| import json | ||||
| import random | ||||
| import requests | ||||
|  | @ -24,6 +25,7 @@ class Tasks(commands.Cog): | |||
|         self.updateMessageCounts.start() | ||||
|         self.sendReminders.start() | ||||
|         self.updateMatchweek.start() | ||||
|         self.uforaAnnouncements.start() | ||||
| 
 | ||||
|     @tasks.loop(hours=1.0) | ||||
|     async def bankInterest(self): | ||||
|  | @ -238,6 +240,24 @@ class Tasks(commands.Cog): | |||
|     async def beforeUpdateMatchweek(self): | ||||
|         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): | ||||
|         return timeFormatters.dateTimeNow().hour | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,11 +14,13 @@ botIDs = [ | |||
|     "728361496874057812" | ||||
| ] | ||||
| BugReports = "762668401960812554" | ||||
| BotTesting = "679701786189103106" | ||||
| CallOfCode = "626699611192688641" | ||||
| CoCGeneral = "626699611813314561" | ||||
| DeZandbak = "728361030404538488" | ||||
| ErrorLogs = "762668505455132722" | ||||
| FeatureRequests = "762668473313787964" | ||||
| ZandbakSpeeltuin = "769248992957038612" | ||||
| 
 | ||||
| mods = { | ||||
|     626699611192688641: [384457911377854467, 171671190631481345], | ||||
|  | @ -53,7 +55,12 @@ faq_channels = { | |||
|     727876797458284584: "funcprog", | ||||
|     727876819264733244: "statprob", | ||||
|     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 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.", | ||||
|   "inspire": "Generate quotes via [InspiroBot](https://inspirobot.me/).", | ||||
|   "inventory": "Bekijk de items in jouw inventory.", | ||||
|   "invest": "Investeer [Aantal] Didier Dinks in jouw Didier Bank om rente te vergaren.", | ||||
|   "jpl": "Informatie over de Jupiler Pro League.", | ||||
|   "jpl matches": "Bekijk de wedstrijden die gespeeld worden op [Week]. Default naar de huidige speeldag.", | ||||
|   "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.", | ||||
|   "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.", | ||||
|  |  | |||
|  | @ -1,8 +1,7 @@ | |||
| import datetime | ||||
| import time | ||||
| 
 | ||||
| import dateutil.relativedelta | ||||
| import pytz | ||||
| import time | ||||
| 
 | ||||
| 
 | ||||
| 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] | ||||
							
								
								
									
										21
									
								
								ignored.md
								
								
								
								
							
							
						
						
									
										21
									
								
								ignored.md
								
								
								
								
							|  | @ -102,4 +102,23 @@ 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. | ||||
| 
 | ||||
|     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