Testing/CI #21

Merged
jp merged 40 commits from testing into master 2022-12-11 16:27:22 +01:00
16 changed files with 883 additions and 527 deletions
+15
View File
@@ -0,0 +1,15 @@
__pycache__/
discord.py-rewrite/
tijd/
.vs/
test.png
UpgradeLog\.htm
markov_dict.npy
*.ini
Stroopwafel.sln
Stroopwafel.pyproj
*.txt
!requirements.txt
*.sh
*.npy
#.env
+36
View File
@@ -0,0 +1,36 @@
kind: pipeline
name: default
steps:
- name: test
image: python:3.10
environment:
STROOP_DISCORD_TOKEN:
from_secret: STROOP_DISCORD_TOKEN
STROOP_TWITTER_KEY:
from_secret: STROOP_TWITTER_KEY
STROOP_TWITTER_SECRET:
from_secret: STROOP_TWITTER_SECRET
STROOP_REDDIT_ID:
from_secret: STROOP_REDDIT_ID
STROOP_REDDIT_SECRET:
from_secret: STROOP_REDDIT_SECRET
STROOP_WEERLIVE:
from_secret: STROOP_WEERLIVE
STROOP_CALDAV_HOST:
from_secret: STROOP_CALDAV_HOST
STROOP_CALDAV_CAL:
from_secret: STROOP_CALDAV_CAL
STROOP_IMGFLIP_PASSWORD:
from_secret: STROOP_IMGFLIP_PASSWORD
STROOP_RESET_PASSWORD:
from_secret: STROOP_RESET_PASSWORD
STROOP_CHANNEL_SHITPOST:
from_secret: STROOP_CHANNEL_SHITPOST
commands:
- pip install -r requirements.txt
- python -m unittest tests
trigger:
event:
exclude:
- pull_request
+4 -2
View File
@@ -5,9 +5,11 @@ tijd/
test.png test.png
UpgradeLog\.htm UpgradeLog\.htm
markov_dict.npy markov_dict.npy
stroopwafel.ini *.ini
Stroopwafel.sln Stroopwafel.sln
Stroopwafel.pyproj Stroopwafel.pyproj
*.txt *.txt
!requirements.txt
*.sh *.sh
*.npy *.npy
.env
+12
View File
@@ -0,0 +1,12 @@
FROM python:3.10
WORKDIR /opt/stroopwafel
# Do the requirements first for better caching
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . ./
CMD python -m unittest tests
+44 -81
View File
@@ -1,30 +1,33 @@
import asyncio import asyncio
import discord import discord
import sys, os import os
import praw import praw
import random import random
import re import re
import json, requests import json, requests
import warnings
from discord.ext import commands from discord.ext import commands
from sympy import latex, symbols, preview, Symbol #for LaTeX images
import youtube_dl
import ffmpeg
class General(commands.Cog): class General(commands.Cog):
"""Overal toegestaan.""" """Overal toegestaan."""
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
self.voice_states = {} self.muzak_url = 'https://hdcon-muzak.herokuapp.com'
self.r = praw.Reddit( self.r = praw.Reddit(
user_agent='StroopwafelBot', user_agent='StroopwafelBot',
client_secret=self.bot.tokens["redditSecret"], client_secret=os.getenv("STROOP_REDDIT_SECRET"),
client_id=self.bot.tokens["redditId"] client_id=os.getenv("STROOP_REDDIT_ID")
) )
self.r.read_only = True self.r.read_only = True
warnings.simplefilter("ignore")
def __check(self, ctx): #Todo: Is dit het porno kanaal? def get_emoji_embed(self, tag: str):
return True emoji = re.search(".*\<\:([A-z]*)\:(\d*)\>.*", tag)
embed = discord.Embed(title=emoji.group(1), type='photo')
hugemoji = 'https://cdn.discordapp.com/emojis/' + emoji.group(2) + '.png'
embed.set_image(url=hugemoji)
return embed
@commands.command() @commands.command()
@asyncio.coroutine @asyncio.coroutine
@@ -33,110 +36,70 @@ class General(commands.Cog):
Bijvoorbeeld: Bijvoorbeeld:
!huge :ancilla: !huge :ancilla:
""" """
id = re.search("\<\:([A-z]*)\:(\d*)\>", arg) em = self.get_emoji_embed(arg)
hugemoji = 'https://cdn.discordapp.com/emojis/' + id.group(2) + '.png'
em = discord.Embed(title=id.group(1), type='photo')
em.set_image(url=hugemoji)
try: try:
yield from ctx.message.delete() yield from ctx.message.delete()
except: except:
print("No permission to delete message") print("No permission to delete message")
yield from ctx.channel.send(ctx.author.mention, embed=em) yield from ctx.channel.send(ctx.author.mention, embed=em)
@commands.command() def get_aww_post(self):
@asyncio.coroutine raww = self.r.subreddit('aww+catloaf+tuckedinkitties+babyelephantgifs+babybigcatgifs+blep+holdmynip+gingerkitty+cathighfive+catsstandingup+catsareassholes+eyebleach')
def tex(self, ctx, *, arg): listing = list(raww.top(time_filter='month'))
"""Geeft een mooi LaTeX plaatje terug. return random.choice(listing)
Bijvoorbeeld:
!tex Je moeder is lelijk! $a^b b^c \\rightarrow d$
"""
preamble = "\\documentclass[10pt]{article}\\pagestyle{empty}\\usepackage[margin=1in]{geometry}\\usepackage{amsmath, amsfonts}\\begin{document}" #\\usepackage{CJKutf8}\\usepackage[T1]{fontenc}\\usepackage[english]{babel}
options = ["-T", "tight", "-z", "9", "--truecolor", "-D", "512"]
preview(r''+arg+'', viewer='file', filename='test.png', dvioptions=options, preamble=preamble)
#file = open('test.png', 'rb')
#yield from ctx.channel.send(file, filename ='test.png', content='')
try:
yield from ctx.message.delete()
except:
print("No permission to delete message")
yield from ctx.channel.send(ctx.author.mention, file=discord.File('test.png', 'tex.png'))
@commands.command(pass_context=True) @commands.command(pass_context=True)
@asyncio.coroutine @asyncio.coroutine
def aww(self, ctx): def aww(self, ctx):
""" iets schattigs... """ """ iets schattigs... """
print(type(ctx.message.channel)) post = self.get_aww_post()
raww = self.r.subreddit('aww+catloaf+tuckedinkitties+babyelephantgifs+babybigcatgifs+blep+holdmynip+gingerkitty+cathighfive+catsstandingup+catsareassholes+eyebleach')
post = raww.top('month', limit=250)
listing = list(post)
random.shuffle(listing)
post = listing[0]
try: try:
yield from ctx.message.delete() yield from ctx.message.delete()
except: except:
print("No permission to delete message") print("No permission to delete message")
yield from ctx.channel.send(ctx.author.mention + ' ' + post.url) yield from ctx.channel.send(ctx.author.mention + ' ' + post.url)
def get_kopieerpasta(self):
rkopieerpasta = self.r.subreddit('kopieerpasta')
post = rkopieerpasta.random()
# Subreddits kunnen de random functie uitzetten, dus dit is de fallback:
if post == None:
listing = list(rkopieerpasta.top('month', limit=250))
post = random.choice(listing)
return post
@commands.command(pass_context=True) @commands.command(pass_context=True)
@asyncio.coroutine @asyncio.coroutine
def kopieerpasta(self, ctx): def kopieerpasta(self, ctx):
"""Een willekeurige shitpost""" """Een willekeurige shitpost"""
rkopieerpasta = self.r.subreddit('kopieerpasta') post = self.get_kopieerpasta()
post = rkopieerpasta.random() print(post.url)
ATTEMPTS = 10
# Subreddits kunnen de random functie uitzetten, dus dit is de fallback: a = 0
if post == None: while len(post.selftext + post.title) >= 1990 and a < ATTEMPTS:
post = rkopieerpasta.top('month', limit=250) post = self.get_kopieerpasta()
listing = list(post) print(post.url)
random.shuffle(listing) a += 1
post = listing[0]
try: try:
yield from ctx.message.delete() yield from ctx.message.delete()
except: except:
print("No permission to delete message") print("No permission to delete message")
# Er is een 2000 karakter limiet wat met sommige pastas overschreden kan worden. if len(post.selftext + post.title) < 1990:
# eigenlijk willen we het dan opnieuw proberen maar dat is lastiger, dus maar gewoon berichtje.
if (len(post.selftext)+len(post.title)) >= 1990:
yield from ctx.channel.send('Sorry, kopieerpasta te lang. Probeer het maar opnieuw .')
else:
yield from ctx.channel.send('**'+post.title+'**```'+post.selftext+'```') yield from ctx.channel.send('**'+post.title+'**```'+post.selftext+'```')
else:
yield from ctx.channel.send("Geen kopieerpasta voor jou vandaag.")
@commands.command(pass_context=True) def get_playlist_json(self):
@asyncio.coroutine return requests.get(self.muzak_url + '/stroopwafel')
def gif(self, ctx, yt: str, start: str="0", duration: str="5", res: str="320", fps: int=10):
""" Giffify. Tijdelijk uitgeschakeld.
"""
try:
yield from ctx.message.delete()
except:
print("No permission to delete message")
yield from ctx.channel.send(
ctx.author.mention +
"""
Welkom bij de stroopwafel GIF hotline!
Deze functionaliteit is momenteel helaas offline voor onderhoud. Gelukkig is vergelijkbare functionaliteit ook elders beschikbaar:
Op <https://gifrun.com/> kunt u bijvoorbeeld via een web-interface gifjes maken van youtube-filmpjes. Geavanceerde gebruikers kunnen u ook <https://youtube-dl.org/> proberen, waarna u gifjes kan genereren via bijvoorbeeld <https://ezgif.com/>.
Namens de directie van Stroopwafel B.V. onze excuses voor dit ongemak.""")
@commands.command(pass_context=True) @commands.command(pass_context=True)
@asyncio.coroutine @asyncio.coroutine
def playlist(self, ctx): def playlist(self, ctx):
"""HDcon2021 playlist""" """HDcon2021 playlist"""
muzak_url = 'https://hdcon-muzak.herokuapp.com' data = json.loads(self.get_playlist_json().content)
data = json.loads(requests.get(muzak_url + '/stroopwafel').content) # als dit faalt yolo no catch msg = 'Stemmen en nomineren kan hier: {}\n'.format(self.muzak_url)
msg = 'Stemmen en nomineren kan hier: {}\n'.format(muzak_url)
msg += '*Er zijn al {} nummers genomineerd*\n'.format(data['stemCount']) msg += '*Er zijn al {} nummers genomineerd*\n'.format(data['stemCount'])
yield from ctx.channel.send(msg) yield from ctx.channel.send(msg)
@commands.command(pass_context=True, hidden=True)
@asyncio.coroutine
def reboot(self, ctx, password=""):
""" Reboot.. """
if password == self.bot.passwords["resetpassword"]:
yield from ctx.channel.send("Rebooting.. brb!")
os.execv(sys.executable, ['python3'] + sys.argv)
else:
yield from ctx.channel.send(ctx.author.mention + " What's the magic word?")
+58 -42
View File
@@ -5,6 +5,7 @@ from pprint import pprint
import time import time
import numpy as np import numpy as np
import random import random
import os
from datetime import datetime from datetime import datetime
class Points(commands.Cog): class Points(commands.Cog):
@@ -17,6 +18,9 @@ class Points(commands.Cog):
self.BANK_ID = 42 self.BANK_ID = 42
self.init() self.init()
self.pointsCount = {}
self.reloadPointsCount()
def __check(self, ctx): def __check(self, ctx):
return True return True
@@ -30,6 +34,8 @@ class Points(commands.Cog):
De eerste 10 punten zijn on the house. (Als er genoeg in de bank zit.) De eerste 10 punten zijn on the house. (Als er genoeg in de bank zit.)
""" """
self.reloadPointsCount()
if points == 0: if points == 0:
yield from ctx.channel.send("0 punten? Gul hoor.") yield from ctx.channel.send("0 punten? Gul hoor.")
return return
@@ -57,21 +63,26 @@ class Points(commands.Cog):
return return
# Execute the transaction: # Execute the transaction:
# First, try to give a away (at most 10) bankpoints self.execute_geefpunten(ctx.author.id, userObj.id, points)
areBeingGivenFromBank = min(points, self.getUsersRemainingBankPointsToGiveAwayToday(ctx.author.id))
areBeingGivenFromBank = min(areBeingGivenFromBank, self.getBankBalance()) self.savePointsCount()
if areBeingGivenFromBank > 0:
self.transferPoints(self.BANK_ID, userObj.id, areBeingGivenFromBank)
self.increaseUsersBankPointGivenAwayToday(ctx.author.id, areBeingGivenFromBank)
remainingPointsToGive = points - areBeingGivenFromBank
else:
remainingPointsToGive = points
# The remaining points come out of your own pocket
if remainingPointsToGive > 0:
self.transferPoints(ctx.author.id, userObj.id, remainingPointsToGive)
message = self.getMessageForAwardingPoints(ctx.author.name, userObj.name, points) message = self.getMessageForAwardingPoints(ctx.author.name, userObj.name, points)
yield from ctx.channel.send(message) yield from ctx.channel.send(message)
def execute_geefpunten(self, giverId, recieverId, points):
# First, try to give away (at most 10) bankpoints
areBeingGivenFromBank = min(points, self.getUsersRemainingBankPointsToGiveAwayToday(giverId))
areBeingGivenFromBank = min(areBeingGivenFromBank, self.getBankBalance())
if areBeingGivenFromBank > 0:
self.transferPoints(self.BANK_ID, recieverId, areBeingGivenFromBank)
self.increaseUsersBankPointGivenAwayToday(giverId, areBeingGivenFromBank)
remainingPointsToGive = points - areBeingGivenFromBank
else:
remainingPointsToGive = points
# The remaining points come out of your own pocket
if remainingPointsToGive > 0:
self.transferPoints(giverId, recieverId, remainingPointsToGive)
@commands.command(pass_context=True, hidden=False) @commands.command(pass_context=True, hidden=False)
@@ -84,6 +95,8 @@ class Points(commands.Cog):
Let op: je moet iemand taggen om punten weg te nemen. Let op: je moet iemand taggen om punten weg te nemen.
""" """
self.reloadPointsCount()
if points < 1: if points < 1:
yield from ctx.channel.send("Volgens mij snap je het niet.") yield from ctx.channel.send("Volgens mij snap je het niet.")
return return
@@ -109,11 +122,16 @@ class Points(commands.Cog):
return return
# Execute the transaction: # Execute the transaction:
self.increaseUsersPointTakenOnDate(ctx.author.id, points) self.execute_neempunten(ctx.author.id, userObj.id, points);
self.transferPoints(userObj.id, self.BANK_ID, points)
self.savePointsCount()
message = self.getMessageForTakingPoints(userObj.name, ctx.author.name, points) message = self.getMessageForTakingPoints(userObj.name, ctx.author.name, points)
yield from ctx.channel.send(message) yield from ctx.channel.send(message)
def execute_neempunten(self, takerId, victimId, points):
self.increaseUsersPointTakenOnDate(takerId, points)
self.transferPoints(victimId, self.BANK_ID, points)
@commands.command(pass_context=True, hidden=False) @commands.command(pass_context=True, hidden=False)
@@ -122,14 +140,14 @@ class Points(commands.Cog):
"""Hoeveel punten heeft iedereen? """Hoeveel punten heeft iedereen?
""" """
self.reloadPointsCount()
message = "**De puntentelling:** \n```" message = "**De puntentelling:** \n```"
pointsCount = np.load('pointscount.npy', allow_pickle=True).item() pointsCountSorted = sorted(self.pointsCount.items(), key=lambda i: i[1]['points'], reverse=True)
pointsCountSorted = sorted(pointsCount.items(), key=lambda i: i[1]['points'], reverse=True)
for user in pointsCountSorted: for user in pointsCountSorted:
if user[0] != self.BANK_ID: if user[0] != self.BANK_ID:
message += str(user[1]["points"]).rjust(4) + " " + user[1]["name"] + "\n" message += str(user[1]["points"]).rjust(4) + " " + user[1]["name"] + "\n"
message += str(pointsCount[self.BANK_ID]["points"]).rjust(4) + " " + pointsCount[self.BANK_ID]["name"] + "```" message += str(self.pointsCount[self.BANK_ID]["points"]).rjust(4) + " " + self.pointsCount[self.BANK_ID]["name"] + "```"
#message += "```"
yield from ctx.channel.send(message) yield from ctx.channel.send(message)
@@ -145,40 +163,42 @@ class Points(commands.Cog):
except: except:
print("No permission to send DM") print("No permission to send DM")
# Get the points count object from the file
def reloadPointsCount(self):
self.pointsCount = np.load('pointscount.npy', allow_pickle=True).item()
# Save the points count to the file
def savePointsCount(self):
np.save("pointscount.npy", self.pointsCount)
# Transfer points form one user to another # Transfer points form one user to another
def transferPoints(self, fromUserId, toUserId, points): def transferPoints(self, fromUserId, toUserId, points):
pointsCount = np.load('pointscount.npy', allow_pickle=True).item() self.pointsCount[fromUserId]["points"] -= points
pointsCount[fromUserId]["points"] -= points self.pointsCount[toUserId]["points"] += points
pointsCount[toUserId]["points"] += points
np.save("pointscount.npy", pointsCount)
# Do we know this user? # Do we know this user?
def isUserOnList(self, user): def isUserOnList(self, user):
pointsCount = np.load('pointscount.npy', allow_pickle=True).item() return user.id in self.pointsCount.keys()
return user.id in pointsCount.keys()
# Get a user's point balance # Get a user's point balance
def getUserBalance(self, user): def getUserBalance(self, user):
pointsCount = np.load('pointscount.npy', allow_pickle=True).item() return self.pointsCount[user.id]["points"]
return pointsCount[user.id]["points"]
# Get the balance of the bank # Get the balance of the bank
def getBankBalance(self): def getBankBalance(self):
pointsCount = np.load('pointscount.npy', allow_pickle=True).item() return self.pointsCount[self.BANK_ID]["points"]
return pointsCount[self.BANK_ID]["points"]
# To keep track if a user used some points today, we look at when the last time was he/she used them # To keep track if a user used some points today, we look at when the last time was he/she used them
# If this was in the past: reset # If this was in the past: reset
# Also, return the updated object. Why not. # Also, return the updated object. Why not.
def refreshDateVarsAndReturnUserVars(self, userId): def refreshDateVarsAndReturnUserVars(self, userId):
pointsCount = np.load('pointscount.npy', allow_pickle=True).item()
currentDateStr = datetime.now().strftime("%Y%m%d") currentDateStr = datetime.now().strftime("%Y%m%d")
if pointsCount[userId]["theDate"] != currentDateStr: if self.pointsCount[userId]["theDate"] != currentDateStr:
pointsCount[userId]["theDate"] = currentDateStr self.pointsCount[userId]["theDate"] = currentDateStr
pointsCount[userId]["pointTakenOnDate"] = 0 self.pointsCount[userId]["pointTakenOnDate"] = 0
pointsCount[userId]["bankPointsGivenOnDate"] = 0 self.pointsCount[userId]["bankPointsGivenOnDate"] = 0
np.save("pointscount.npy", pointsCount) return self.pointsCount[userId]
return pointsCount[userId]
# How many points can this user still take away today? # How many points can this user still take away today?
def getUsersRemainingPointsToTakeToday(self, userId): def getUsersRemainingPointsToTakeToday(self, userId):
@@ -193,16 +213,12 @@ class Points(commands.Cog):
# Increase the number of points this user has taken away today. # Increase the number of points this user has taken away today.
# Warning: assumes you executed refreshDateVarsAndReturnUserVars() # Warning: assumes you executed refreshDateVarsAndReturnUserVars()
def increaseUsersPointTakenOnDate(self, userId, points): def increaseUsersPointTakenOnDate(self, userId, points):
pointsCount = np.load('pointscount.npy', allow_pickle=True).item() self.pointsCount[userId]["pointTakenOnDate"] += points
pointsCount[userId]["pointTakenOnDate"] += points
np.save("pointscount.npy", pointsCount)
# Increase the number of bank points this user has given today # Increase the number of bank points this user has given today
# Warning: assumes you executed refreshDateVarsAndReturnUserVars() # Warning: assumes you executed refreshDateVarsAndReturnUserVars()
def increaseUsersBankPointGivenAwayToday(self, userId, points): def increaseUsersBankPointGivenAwayToday(self, userId, points):
pointsCount = np.load('pointscount.npy', allow_pickle=True).item() self.pointsCount[userId]["bankPointsGivenOnDate"] += points
pointsCount[userId]["bankPointsGivenOnDate"] += points
np.save("pointscount.npy", pointsCount)
# Generate a semi-random text to tell somebody they got some shiny new points # Generate a semi-random text to tell somebody they got some shiny new points
@@ -264,7 +280,7 @@ class Points(commands.Cog):
np.save("pointscount.npy", pointsCount) np.save("pointscount.npy", pointsCount)
# Add new/unknown members: # Add new/unknown members:
list_channel = self.bot.get_channel(self.bot.hdChannels["shitpost"]) list_channel = self.bot.get_channel(int(os.getenv('STROOP_CHANNEL_SHITPOST')))
memberList = list_channel.members if list_channel else [] memberList = list_channel.members if list_channel else []
for member in memberList: for member in memberList:
# Give new members 100 points # Give new members 100 points
+1 -13
View File
@@ -13,18 +13,6 @@ Vragen en/of opmerkingen kunnen in onderstaande suggestiebox:\
## Zelf deze bot runnen? ## Zelf deze bot runnen?
Deze link legt uit hoe je een bot token maakt: Maak een bot token aan, vul wat dingen in in de `.env`, installeer requirements.txt en gaan met de banaan.
[https://github.com/reactiflux/discord-irc/wiki/Creating-a-discord-bot-&-getting-a-token](https://github.com/reactiflux/discord-irc/wiki/Creating-a-discord-bot-&-getting-a-token)
Requirements:
* `discord.py`
* `praw`
* `sympy`
* `asyncio`
* `numpy`
* `youtube_dl`
* `ffmpeg-python`
* `caldav`
Verder zoek je het zelf maar uit. Verder zoek je het zelf maar uit.
+270 -368
View File
@@ -2,24 +2,29 @@ import asyncio
import discord import discord
from discord.ext import commands from discord.ext import commands
from urllib import request from urllib import request
import requests
import json, requests import json, requests
import math import math
from datetime import datetime, timedelta from datetime import datetime, timedelta
import sys
import os import os
import random import random
import caldav import caldav
import warnings
import re
class Shitpost(commands.Cog): class Shitpost(commands.Cog):
"""Schijtpaal commando's. Alleen bruikbaar in de daarvoor toegewezen schijtpaal kanalen.""" """Schijtpaal commando's. Alleen bruikbaar in de daarvoor toegewezen schijtpaal kanalen."""
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
self.voice_states = {}
self.hdConImpatientEvents = [] self.hdConImpatientEvents = []
self.zwarte_lijst = [line.rstrip('\n') for line in open('black.txt')] try:
self.witte_lijst = [line.rstrip('\n') for line in open('white.txt')] # nihao with open('black.txt') as zwart:
self.zwarte_lijst = [line.rstrip('\n') for line in zwart]
with open('white.txt') as wit:
self.witte_lijst = [line.rstrip('\n') for line in wit]
except:
self.zwarte_lijst = ["___", "___, ___", "___, ___, ___"]
self.witte_lijst = ["A", "B", "C"]
self.insult = ['koekenbakker','stumperd','knurft','oelewapper','klungel','stoethaspel', self.insult = ['koekenbakker','stumperd','knurft','oelewapper','klungel','stoethaspel',
'onnozelaar','beunhaas','uilskuiken','bamibal','zwakzinnige','oenemeloen', 'onnozelaar','beunhaas','uilskuiken','bamibal','zwakzinnige','oenemeloen',
'klaphark','rompeknonker','bal gehakt','ongewassen vlerk','droeftoeter','omgedraaid pak hagelslag', 'klaphark','rompeknonker','bal gehakt','ongewassen vlerk','droeftoeter','omgedraaid pak hagelslag',
@@ -27,15 +32,20 @@ class Shitpost(commands.Cog):
'knoeier','sufferd','slaapkop','onbenul','enorme nerf herder','geinponem', 'knoeier','sufferd','slaapkop','onbenul','enorme nerf herder','geinponem',
'clownsfiguur','krotenkoker','hansworst','grappenmaker','flapdrol','oen', 'clownsfiguur','krotenkoker','hansworst','grappenmaker','flapdrol','oen',
'achterlijk gebakje','demente dibbes','geitenbreier','koekwous','sufkop'] 'achterlijk gebakje','demente dibbes','geitenbreier','koekwous','sufkop']
self.caldav_client = caldav.DAVClient(url=self.bot.tokens['caldav_url']) self.caldav_client = caldav.DAVClient(url=os.getenv('STROOP_CALDAV_HOST'))
self.imgflips = {
def __check(self, ctx): #Todo: Is dit het shitpost kanaal? 'tering': '78416340',
return True 'mark': '112898841',
'eriku': '93296473',
'tegeltje': '121572521',
'zout': '116231806'
}
warnings.simplefilter("ignore")
@commands.command(pass_context=True, hidden=False) @commands.command(pass_context=True, hidden=False)
@asyncio.coroutine @asyncio.coroutine
def ishetalhdcon(self, ctx): def ishetalhdcon(self, ctx):
"""Hoe lang nog tot Hoestende Dranken Con 2022? """Hoe lang nog tot Hoestende Draken Con 2022?
Gebruik: !ishetalhdcon Gebruik: !ishetalhdcon
""" """
@@ -98,6 +108,16 @@ class Shitpost(commands.Cog):
yield from ctx.channel.send(ctx.author.mention + ' ' + str(Message)) yield from ctx.channel.send(ctx.author.mention + ' ' + str(Message))
def zalgofy(self, sentence, factor = 4):
random.seed(datetime.now().timestamp())
message = ''
#from https://github.com/Aethylia/zalgo-cli:
for letter in sentence:
for i in range(factor):
letter += random.randint(0x300, 0x36f).to_bytes(2, byteorder='big').decode('utf-16be')
message += letter
return message
@commands.command(pass_context=True, hidden=False) @commands.command(pass_context=True, hidden=False)
@asyncio.coroutine @asyncio.coroutine
def zalgo(self, ctx, *, arg): def zalgo(self, ctx, *, arg):
@@ -108,39 +128,27 @@ class Shitpost(commands.Cog):
Gebruik: !zalgo [text] Gebruik: !zalgo [text]
Bijv: !zalgo "Je moeder" Bijv: !zalgo "Je moeder"
""" """
factor = 4 message = self.zalgofy(arg)
message = ''
#from https://github.com/Aethylia/zalgo-cli:
for letter in arg:
for i in range(factor):
letter += random.randint(0x300, 0x36f).to_bytes(2, byteorder='big').decode('utf-16be')
message += letter
try: try:
yield from ctx.message.delete() yield from ctx.message.delete()
except: except:
print("No permission to delete message") print("No permission to delete message")
yield from ctx.channel.send(ctx.author.mention + ' ' + str(message)) yield from ctx.channel.send(str(message))
@commands.command(pass_context=True, hidden=False) def get_corona_message(self):
@asyncio.coroutine response = requests.get('https://covid.ourworldindata.org/data/latest/owid-covid-latest.json')
def coronaold(self, ctx): if response:
try: answer = json.loads(response.content.decode('utf-8'))
yield from ctx.message.delete() d = answer["NLD"]
except: message = f"Dit is mijn informatie van **{d['last_updated_date']}**: \n\n"
print("No permission to delete message") message += f"Er zijn in Nederland {d['total_cases']:.0f} bevestigde gevallen 😷"
params = ( message += f" dat is 🔺{d['new_cases']:.0f}🔺 meer dan de dag er voor! \n"
('minimal/', 'true'), message += f"Er zijn ondertussen {d['total_deaths']:.0f} mensen dood 💀"
('format/', 'json') message += f" waarvan {d['new_deaths']:.0f} ☠️ in de meest recente 24 uur. \n"
) message += f"En het r-getal is {d['reproduction_rate']}!\n\n"
response = requests.get('https://corona-stats.online/NL/?format=json&source=2') message += "*Data van https://ourworldindata.org/coronavirus*"
answer = json.loads(response.content.decode('utf-8')) return message
answer = answer["data"] return None
message = "Er zijn in Nederland " + str(answer[0]["cases"]) + " bevestigde gevallen 😷"
message += " dat is 🔺" + str(answer[0]["todayCases"]) + "🔺 meer dan gisteren! "
message += "Er zijn ondertussen " + str(answer[0]["deaths"]) + " mensen dood 💀"
message += " waarvan " + str(answer[0]["todayDeaths"]) + " ☠️ in de afgelopen 24 uur. "
message += "Ook liggen er " + str(answer[0]["critical"]) + " mensen op de IC 🏥"
yield from ctx.channel.send(ctx.author.mention + ' ' + str(message))
@commands.command(pass_context=True, hidden=False) @commands.command(pass_context=True, hidden=False)
@asyncio.coroutine @asyncio.coroutine
@@ -149,21 +157,7 @@ class Shitpost(commands.Cog):
yield from ctx.message.delete() yield from ctx.message.delete()
except: except:
print("No permission to delete message") print("No permission to delete message")
params = ( message = self.get_corona_message()
('minimal/', 'true'),
('format/', 'json')
)
response = requests.get('https://covid.ourworldindata.org/data/latest/owid-covid-latest.json')
answer = json.loads(response.content.decode('utf-8'))
d = answer["NLD"]
message = f"Dit is mijn informatie van **{d['last_updated_date']}**: \n\n"
message += f"Er zijn in Nederland {d['total_cases']:.0f} bevestigde gevallen 😷"
message += f" dat is 🔺{d['new_cases']:.0f}🔺 meer dan de dag er voor! \n"
message += f"Er zijn ondertussen {d['total_deaths']:.0f} mensen dood 💀"
message += f" waarvan {d['new_deaths']:.0f} ☠️ in de meest recente 24 uur. \n"
message += f"Er zijn ondertussen {d['people_vaccinated']:.0f} mensen gevaccineerd! 💉 "
message += f"En het r-getal is {d['reproduction_rate']}!\n\n"
message += "*Data van https://ourworldindata.org/coronavirus*"
yield from ctx.channel.send(ctx.author.mention + ' ' + str(message)) yield from ctx.channel.send(ctx.author.mention + ' ' + str(message))
@commands.command(pass_context=True, hidden=False) @commands.command(pass_context=True, hidden=False)
@@ -210,6 +204,10 @@ class Shitpost(commands.Cog):
Message = "Nee. :frowning2: Nog even geduld..." Message = "Nee. :frowning2: Nog even geduld..."
yield from ctx.channel.send(ctx.author.mention + ' ' + str(Message)) yield from ctx.channel.send(ctx.author.mention + ' ' + str(Message))
def get_giet_het_oan(self):
# Alsof we ooit nog een elfstedentocht gaan krijgen.
return "nee"
@commands.command(pass_context=True, hidden=False) @commands.command(pass_context=True, hidden=False)
@asyncio.coroutine @asyncio.coroutine
@@ -217,14 +215,7 @@ class Shitpost(commands.Cog):
"""Giet het al oan? """Giet het al oan?
Ja of Nee.. kom op nou. Ja of Nee.. kom op nou.
""" """
#We halen dit op van de twitter account @gietitaloan die vertrouwen wij als de ultieme waarheid answer = self.get_giet_het_oan()
consumer = oauth.Consumer(key=self.bot.tokens["twitterKey"], secret=self.bot.tokens["twitterSecret"])
client = oauth.Client(consumer)
resp, content = client.request("https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=gietitaloan&count=1", "GET")
#TODO kijken of resp iets zinnigs teruggeeft.. of iets doen met een try of catch ofzow
content_str = content.decode('utf-8') #converteren naar str voor welke stomme reden dan ook
answer = json.loads(content_str)[0]["text"] #inhoud van de tweet
answer = answer.lower()
reactie = "" reactie = ""
if 'ja' in answer: if 'ja' in answer:
if 'nee' in answer: if 'nee' in answer:
@@ -235,6 +226,13 @@ class Shitpost(commands.Cog):
if 'nee' in answer: if 'nee' in answer:
reactie += 'Nee helaas..' reactie += 'Nee helaas..'
yield from ctx.channel.send(ctx.author.mention + ' ' + reactie) yield from ctx.channel.send(ctx.author.mention + ' ' + reactie)
def get_inspiration(self):
inspiration = requests.get(url='http://inspirobot.me/api?generate=true')
if inspiration:
return inspiration.text
return None
@commands.command(pass_context=True, hidden=False) @commands.command(pass_context=True, hidden=False)
@asyncio.coroutine @asyncio.coroutine
@@ -243,11 +241,10 @@ class Shitpost(commands.Cog):
Bijvoorbeeld: Bijvoorbeeld:
!inspire !inspire
""" """
r = requests.get(url='http://inspirobot.me/api?generate=true') inspo = self.get_inspiration()
if r.status_code is 200: if inspo:
url = r.text
em = discord.Embed(title='Uw wijze woorden:', type='photo') em = discord.Embed(title='Uw wijze woorden:', type='photo')
em.set_image(url=url) em.set_image(url=inspo)
try: try:
yield from ctx.message.delete() yield from ctx.message.delete()
except: except:
@@ -256,6 +253,25 @@ class Shitpost(commands.Cog):
else: else:
yield from ctx.channel.send(ctx.author.mention + ' helaas, geen quote gevonden.') yield from ctx.channel.send(ctx.author.mention + ' helaas, geen quote gevonden.')
def get_imgflip_embed(self, template: str, boven: str, onder: str, extra_options: dict = None):
params = dict(
template_id = template,
username = 'Stroopwafel',
password = os.getenv("STROOP_IMGFLIP_PASSWORD"),
text0 = boven,
text1 = onder
)
if extra_options:
params.update(extra_options)
resp = requests.get(url='https://api.imgflip.com/caption_image', params=params)
if resp:
photourl = resp.json()['data']['url']
em = discord.Embed(type='photo')
em.set_image(url=photourl)
return em
return None
@commands.command(pass_context=True, hidden=True) @commands.command(pass_context=True, hidden=True)
@asyncio.coroutine @asyncio.coroutine
def tering(self, ctx, boven: str, onder: str): def tering(self, ctx, boven: str, onder: str):
@@ -263,23 +279,13 @@ class Shitpost(commands.Cog):
Bijvoorbeeld: Bijvoorbeeld:
!tering \"Vanavond\" \"gaan we helemaal naar de tering\" !tering \"Vanavond\" \"gaan we helemaal naar de tering\"
""" """
params = dict( em = self.get_imgflip_embed(self.imgflips['tering'], boven, onder)
template_id = '78416340', #party hard
username = 'Stroopwafel',
password = self.bot.passwords["imgflip"],
text0 = boven,
text1 = onder
)
resp = requests.get(url='https://api.imgflip.com/caption_image', params=params)
#todo check for success
photourl = resp.json()['data']['url']
em = discord.Embed(type='photo')
em.set_image(url=photourl)
try: try:
yield from ctx.message.delete() yield from ctx.message.delete()
except: except:
print("No permission to delete message") print("No permission to delete message")
yield from ctx.channel.send(ctx.author.mention, embed=em) if em:
yield from ctx.channel.send(ctx.author.mention, embed=em)
@commands.command(pass_context=True, hidden=True) @commands.command(pass_context=True, hidden=True)
@asyncio.coroutine @asyncio.coroutine
@@ -288,24 +294,13 @@ class Shitpost(commands.Cog):
Bijvoorbeeld: Bijvoorbeeld:
!mark \"je moeder\" \"is een hoer\" !mark \"je moeder\" \"is een hoer\"
""" """
params = dict( em = self.get_imgflip_embed(self.imgflips['mark'], boven, onder)
template_id = '112898841', #de marku
username = 'Stroopwafel',
password = self.bot.passwords["imgflip"],
text0 = boven,
text1 = onder
)
#self.bot.say("deed ik het ding?")
resp = requests.get(url='https://api.imgflip.com/caption_image', params=params)
#todo check for success
photourl = resp.json()['data']['url']
em = discord.Embed(title='De Mark heeft gesproken.', type='photo')
em.set_image(url=photourl)
try: try:
yield from ctx.message.delete() yield from ctx.message.delete()
except: except:
print("No permission to delete message") print("No permission to delete message")
yield from ctx.channel.send(ctx.author.mention, embed=em) if em:
yield from ctx.channel.send(ctx.author.mention, embed=em)
@commands.command(pass_context=True, hidden=True) @commands.command(pass_context=True, hidden=True)
@asyncio.coroutine @asyncio.coroutine
@@ -314,37 +309,16 @@ class Shitpost(commands.Cog):
Bijvoorbeeld: Bijvoorbeeld:
!eriku \"je moeder\" \"is een hoer\" !eriku \"je moeder\" \"is een hoer\"
""" """
params = dict( em = self.get_imgflip_embed(self.imgflips['eriku'], boven, onder)
template_id = '93296473', #de eriku
username = 'Stroopwafel',
password = self.bot.passwords["imgflip"],
text0 = boven,
text1 = onder
)
#self.bot.say("deed ik het ding?")
resp = requests.get(url='https://api.imgflip.com/caption_image', params=params)
#todo check for success
photourl = resp.json()['data']['url']
em = discord.Embed(title='De Eriku heeft gesproken. Prijs hem!', type='photo')
em.set_image(url=photourl)
try: try:
yield from ctx.message.delete() yield from ctx.message.delete()
except: except:
print("No permission to delete message") print("No permission to delete message")
yield from ctx.channel.send(ctx.author.mention, embed=em) if em:
yield from ctx.channel.send(ctx.author.mention, embed=em)
@commands.command(pass_context=True, hidden=True)
@asyncio.coroutine
def tegeltje(self, ctx, tekst: str, auteur: str=" "):
"""Maak een mooi tegeltje met volkswijsheid
Bijvoorbeeld:
!tegeltje \"Oost west, 420 best\" \"Lourens\"
"""
def get_tegeltje(self, tekst, auteur):
params = { params = {
'template_id': '121572521', #delfts blauw
'username': 'Stroopwafel',
'password': self.bot.passwords["imgflip"],
'text0': 'dummy0', 'text0': 'dummy0',
'text1': 'dummy1', 'text1': 'dummy1',
'font': 'arial', 'font': 'arial',
@@ -364,48 +338,22 @@ class Shitpost(commands.Cog):
'boxes[1][color]': '#0044cc', 'boxes[1][color]': '#0044cc',
'boxes[1][outline_color]': '#ffffff' 'boxes[1][outline_color]': '#ffffff'
} }
return self.get_imgflip_embed(self.imgflips['tegeltje'], "", "", params)
resp = requests.get(url='https://api.imgflip.com/caption_image', params=params)
#todo check for success
photourl = resp.json()['data']['url']
em = discord.Embed(title='Tegeltjeswijsheid:', type='photo')
em.set_image(url=photourl)
try:
yield from ctx.message.delete()
except:
print("No permission to delete message")
yield from ctx.channel.send(ctx.author.mention, embed=em)
@commands.command(pass_context=True) @commands.command(pass_context=True, hidden=True)
@asyncio.coroutine @asyncio.coroutine
def relevantxkcd(self, ctx, query: str): def tegeltje(self, ctx, tekst: str, auteur: str=" "):
"""There is always a relevant XKCD """Maak een mooi tegeltje met volkswijsheid
Bijvoorbeeld: Bijvoorbeeld:
!relevantxkcd python !tegeltje \"Oost west, 420 best\" \"Lourens\"
""" """
em = get_tegeltje(tekst, auteur)
#self.bot.say("deed ik het ding?")
response = requests.get("https://relevantxkcd.appspot.com/process?action=xkcd&query=" + query)
splitResponse = response.text.split(" ")
if (float(splitResponse[0]) == 0.0):
yield from ctx.channel.send('Ik kan helaas geen XKCD vinden met als onderwerp "' + query + '".')
return
photoUrl = "http://www.explainxkcd.com" + splitResponse[3]
print(photoUrl)
em = discord.Embed(title='', type='photo')
em.set_image(url=photoUrl)
try: try:
yield from ctx.message.delete() yield from ctx.message.delete()
except: except:
print("No permission to delete message") print("No permission to delete message")
yield from ctx.channel.send(ctx.author.mention + if em:
' een XKCD over "' + query + '"', embed=em) yield from ctx.channel.send(ctx.author.mention, embed=em)
@commands.command(pass_context=True, hidden=True) @commands.command(pass_context=True, hidden=True)
@asyncio.coroutine @asyncio.coroutine
@@ -414,29 +362,17 @@ class Shitpost(commands.Cog):
Bijvoorbeeld: Bijvoorbeeld:
!zout \"je moeder\" \"is een hoer\" !zout \"je moeder\" \"is een hoer\"
""" """
params = dict( em = self.get_imgflip_embed(self.imgflips['zout'], boven, onder)
template_id = '116231806', #de martijn
username = 'Stroopwafel',
password = self.bot.passwords["imgflip"],
text0 = boven,
text1 = onder
)
#self.bot.say("deed ik het ding?")
resp = requests.get(url='https://api.imgflip.com/caption_image', params=params)
#todo check for success
photourl = resp.json()['data']['url']
em = discord.Embed(title='De Martijn heeft gesproken.', type='photo')
em.set_image(url=photourl)
try: try:
yield from ctx.message.delete() yield from ctx.message.delete()
except: except:
print("No permission to delete message") print("No permission to delete message")
yield from ctx.channel.send(ctx.author.mention, embed=em) if em:
yield from ctx.channel.send(ctx.author.mention, embed=em)
@commands.command(pass_context=True, hidden=True) @commands.command(pass_context=True, hidden=True)
@asyncio.coroutine @asyncio.coroutine
def nihao(self,ctx): def nihao(self,ctx):
#yield from self.bot.say("Kankerlauw")
yield from ctx.channel.send("kankerlauw") yield from ctx.channel.send("kankerlauw")
@commands.command(pass_context=True) @commands.command(pass_context=True)
@@ -452,8 +388,6 @@ class Shitpost(commands.Cog):
for argument in args: for argument in args:
time = argument time = argument
filepath = '' filepath = ''
#filejpg = './tijd/' + time + '.jpg'
#filepng = './tijd/' + time + '.png'
filejpg = os.path.join('tijd', time) + '.jpg' filejpg = os.path.join('tijd', time) + '.jpg'
filepng = os.path.join('tijd', time) + '.png' filepng = os.path.join('tijd', time) + '.png'
filegif = os.path.join('tijd', time) + '.gif' filegif = os.path.join('tijd', time) + '.gif'
@@ -467,138 +401,136 @@ class Shitpost(commands.Cog):
yield from ctx.message.delete() yield from ctx.message.delete()
except: except:
print("No permission to delete message") print("No permission to delete message")
if filepath is not '': if filepath != '':
#file = open(filepath, 'rb')
#yield from self.bot.upload(file, filename = filepath)
yield from ctx.channel.send(ctx.author.mention + ' Het is nu ' + datetime.now().strftime('%H:%M'), file=discord.File(filepath, 'tijd.png')) yield from ctx.channel.send(ctx.author.mention + ' Het is nu ' + datetime.now().strftime('%H:%M'), file=discord.File(filepath, 'tijd.png'))
else: else:
yield from ctx.channel.send(ctx.author.mention + ' Het is nu ' + datetime.now().strftime('%H:%M')) yield from ctx.channel.send(ctx.author.mention + ' Het is nu ' + datetime.now().strftime('%H:%M'))
def get_dice_roll(self, nrOfDice, dieType, modifier=None):
if nrOfDice > 99 or dieType > 9999 or dieType < 2 or (modifier and abs(modifier) > 9999):
return None
# Do the rolling
random.seed(datetime.now())
total = 0
rolls = []
for x in range(0, nrOfDice):
roll = random.randint(1, dieType)
total += roll
rolls.append(roll)
total += modifier if modifier else 0
#Tally results
modifierText = "%+d" % modifier if modifier else "" # print modifier with sign
returnText = f"Rolling {nrOfDice}d{dieType}{modifierText}...\n"
rolls = [f"[**{roll}**]" if dieType >= 10 and (roll == 1 or roll == dieType) else f"[{roll}]" for roll in rolls]
returnText += "+".join(rolls)
returnText += modifierText
if nrOfDice > 1 or modifier: # only show calculation if it makes sense:
returnText += " = **" + str(total) + "**"
return returnText
def get_dice_parameters(self, dice):
match = re.match(r"(\d+)d(\d+)(\s*([+-])\s*(\d+))?\s*", dice.lower())
if not match:
return None
numDice = int(match.group(1))
die = int(match.group(2))
modifier = None
modified = match.group(3)
if modified:
modifierType = match.group(4)
modifier = int(match.group(5))
if "-" in modifierType:
modifier = -modifier
return (numDice, die, modifier)
@commands.command(pass_context=True) @commands.command(pass_context=True)
@asyncio.coroutine @asyncio.coroutine
def roll(self, ctx, dice="1d20", modifier1="", modifier2=""): def roll(self, ctx, *, dice):
"""Roll een dobbelsteen. Of een paar. Bijvoorbeeld: """Roll een dobbelsteen. Of een paar. Bijvoorbeeld:
!roll 4d20 !roll 4d20
!roll 1d6 + 5 !roll 1d6 + 5
""" """
diceSplit = dice.lower().split('d') (nrOfDice, dieType, modifier) = self.get_dice_parameters(dice)
if len(diceSplit) != 2: message = self.get_dice_roll(nrOfDice, dieType, modifier)
return if message:
modifier1 = modifier1.replace("+", "") #this is both possible: "1d20 + 1" and "1d20 +1" yield from ctx.channel.send(message)
modifier2 = modifier2.replace("+", "") else:
if modifier1 == "-": yield from ctx.channel.send("Die roll vind ik echt een beetje te mal..")
modifier1 = ""; #this is also possible: "1d20 - 1"
modifier2 = "-" + modifier2 def get_weerbericht(self, wData, verbose=None):
try: #check if they are numbers: if not wData:
nrOfDice = 1 if (diceSplit[0]=="") else int(diceSplit[0]) #allow input like: "!roll d20" return None
dieType = int(diceSplit[1]) message = ""
mod1 = 0 if (modifier1=="") else int(modifier1) # Weather alert:
mod2 = 0 if (modifier2=="") else int(modifier2) alertCode, alertMessage = self.getWeerAlarm(wData)
except ValueError: if (verbose and alertCode):
return message += alertMessage + "\n\n"
#validate values: elif (not verbose and alertCode):
if nrOfDice < 1 or nrOfDice > 99 or dieType < 2 or dieType > 100: if (alertCode == "rood"):
return message += alertMessage + "\n\n"
if mod1 < -999 or mod1 > 999 or mod2 < -999 or mod2 > 999:
return
#roll:
random.seed(datetime.now())
total = 0
returnText = "Rolling " + str(nrOfDice) + "d" + str(dieType) + "...\n"
for x in range(0, nrOfDice):
if x != 0:
returnText += "+ "
roll = random.randint(1, dieType)
total += roll
if dieType >= 10 and (roll == 1 or roll == dieType):
returnText += "[**" + str(roll) + "**] " #make significant numbers bold
else: else:
returnText += "[" + str(roll) + "] " message += ":warning: Er is een weeralarm van kracht. Code " + alertCode + ".\n\n"
total += mod1 + mod2
if mod1 != 0:
if mod1 > 0:
returnText += "+"
returnText += str(mod1) + " "
if mod2 != 0:
if mod2 > 0:
returnText += "+"
returnText += str(mod2) + " "
if nrOfDice > 1 or mod1 != 0 or mod2 != 0: #only show calculation if it makes sense:
returnText += " = __**" + str(total) + "**__"
yield from ctx.channel.send(returnText)
# Today:
message += self.getWeatherIconTranslation( wData["image"] )
message += " Het is " + wData["temp"] + " graden "
message += "en het weer is: " + wData["samenv"] + ". "
message += "De verwachting: " + wData["verw"]
if (verbose):
# Only print tomorrow, the day after and the BBQ grade if verbose is on:
message += "\n\nMorgen: " + self.getWeatherIconTranslation( wData["d1weer"] )
message += " " + wData["d1tmin"] + " tot "
message += wData["d1tmax"] + " graden. "
if (wData["d1neerslag"] == "0"):
message += "Geen neerslag. "
else:
message += "Kans op neerslag: " + wData["d1neerslag"] + "%. "
if (int(wData["d1windk"]) > 5):
message += "Windkracht " + wData["d1windk"] + ". Blow it."
message += "\n\nOvermorgen: "+ self.getWeatherIconTranslation( wData["d2weer"] )
message += " " + wData["d2tmin"] + " tot "
message += wData["d2tmax"] + " graden. "
if (wData["d2neerslag"] == "0"):
message += "Geen neerslag. "
else:
message += "Kans op neerslag: " + wData["d2neerslag"] + "%. "
if (int(wData["d2windk"]) > 5):
message += "Windkracht " + wData["d2windk"] + ". "
bbqGrade = self.getBbqGrade(wData)
message += "\n\nHet BBQ cijfer voor vandaag is: " + '{0:g}'.format(round(bbqGrade, 1))
message += "\n\nOant Moarn!"
return message
def get_weer_json(self, location=None):
if not location:
location = "Leiden"
url = f"http://weerlive.nl/api/json-data-10min.php?key={os.getenv('STROOP_WEERLIVE')}&locatie={location}"
response = requests.get(url)
if response:
return json.loads(response.content.decode('utf-8'))["liveweer"][0]
return None
@commands.command(pass_context=True) @commands.command(pass_context=True)
@asyncio.coroutine @asyncio.coroutine
def weer(self, ctx, location="Leiden", verbose="False"): def weer(self, ctx, location="Leiden", verbose=None):
"""Vertelt je het weer. """Vertelt je het weer.
Omdat je te lui bent om naar buiten te kijken. Omdat je te lui bent om naar buiten te kijken.
Oant Moarn! Oant Moarn!
""" """
if(location == ""): wData = self.get_weer_json(location)
location = "Leiden" if wData:
if(str(verbose).lower() == "false"): message = self.get_weerbericht(wData, verbose)
v = False if not wData or not message:
else: message = "Weer ophalen niet gelukt. Probeer het later nogmaals.."
v = True yield from ctx.channel.send(message)
url = f"http://weerlive.nl/api/json-data-10min.php?key={self.bot.tokens['weerLive']}&locatie={location}"
response = requests.get(url)
#Oant Moarn
if (response.ok):
wData = json.loads(response.content.decode('utf-8'))
message = ""
# Weather alert:
alertCode, alertMessage = self.getWeerAlarm(wData["liveweer"][0])
if (v and alertCode != None):
message += alertMessage + "\n\n"
elif (not v and alertCode != None):
if (alertCode == "rood"):
message += alertMessage + "\n\n"
else:
message += ":warning: Er is een weeralarm van kracht. Code " + alertCode + ".\n\n"
# Today:
message += self.getWeatherIconTranslation( wData["liveweer"][0]["image"] )
message += " Het is " + wData["liveweer"][0]["temp"] + " graden "
message += "en het weer is: " + wData["liveweer"][0]["samenv"] + ". "
message += "De verwachting: " + wData["liveweer"][0]["verw"]
if (v):
# Only print tomorrow, the day after and the BBQ grade if verbose is on:
message += "\n\nMorgen: " + self.getWeatherIconTranslation( wData["liveweer"][0]["d1weer"] )
message += " " + wData["liveweer"][0]["d1tmin"] + " tot "
message += wData["liveweer"][0]["d1tmax"] + " graden. "
if (wData["liveweer"][0]["d1neerslag"] == "0"):
message += "Geen neerslag. "
else:
message += "Kans op neerslag: " + wData["liveweer"][0]["d1neerslag"] + "%. "
if (int(wData["liveweer"][0]["d1windk"]) > 5):
message += "Windkracht " + wData["liveweer"][0]["d1windk"] + ". Blow it."
message += "\n\nOvermorgen: "+ self.getWeatherIconTranslation( wData["liveweer"][0]["d2weer"] )
message += " " + wData["liveweer"][0]["d2tmin"] + " tot "
message += wData["liveweer"][0]["d2tmax"] + " graden. "
if (wData["liveweer"][0]["d2neerslag"] == "0"):
message += "Geen neerslag. "
else:
message += "Kans op neerslag: " + wData["liveweer"][0]["d2neerslag"] + "%. "
if (int(wData["liveweer"][0]["d2windk"]) > 5):
message += "Windkracht " + wData["liveweer"][0]["d2windk"] + ". "
bbqGrade = self.getBbqGrade(wData["liveweer"][0])
message += "\n\nHet BBQ cijfer voor vandaag is: " + '{0:g}'.format(round(bbqGrade, 1))
message += "\n\nOant Moarn!"
yield from ctx.channel.send(message)
else:
print("API ERROR. :robot:")
#returns a nice weather icon. Sometimes the API uses non-documented icons, so we return something else #returns a nice weather icon. Sometimes the API uses non-documented icons, so we return something else
def getWeatherIconTranslation(self, iconKey): def getWeatherIconTranslation(self, iconKey):
@@ -621,10 +553,8 @@ class Shitpost(commands.Cog):
try: try:
return WEATHER_ICONS[iconKey] return WEATHER_ICONS[iconKey]
except KeyError: except KeyError:
print("WARN Unknown iconKey:", str(iconKey))
return ":park:" return ":park:"
#returns which the current weatheralert code and returns a message
def getWeerAlarm(self, weatherObj): def getWeerAlarm(self, weatherObj):
if (weatherObj["alarm"] != "1"): if (weatherObj["alarm"] != "1"):
return None, "" return None, ""
@@ -656,49 +586,43 @@ class Shitpost(commands.Cog):
return -1.0 return -1.0
return max(1.0, min(10.0, grade)) return max(1.0, min(10.0, grade))
def get_ktdm(self, wit = []):
if not wit:
zwarte_kaart = random.choice(self.zwarte_lijst)
aantal_wit = zwarte_kaart.count("___")
if aantal_wit == 0: # Soms staat er geen ___ in de kaart
zwarte_kaart = zwarte_kaart + " ___"
aantal_wit = 1
wit = random.sample(self.witte_lijst, k=aantal_wit)
else:
if len(wit) > 3:
return None
zwarte_kaart = None
random.shuffle(self.zwarte_lijst)
for zwart in self.zwarte_lijst:
if zwart.count("___") == len(wit):
zwarte_kaart = zwart
break
if not zwarte_kaart:
return None
return zwarte_kaart.replace("___", "**{}**").format(*wit)
@commands.command(pass_context=True) @commands.command(pass_context=True)
@asyncio.coroutine @asyncio.coroutine
def ktdm(self, ctx, *args): def ktdm(self, ctx, *args):
'''Speel Kaarten Tegen De Mensheid! Genereer een kaart of geef zelf opties. '''Speel Kaarten Tegen De Mensheid! Genereer een kaart of geef zelf opties.
Bijvoorbeeld: !ktdm <"1"><"2"><"3"> (aanbevolen 1 of 2, max 3)''' Bijvoorbeeld: !ktdm <"1"><"2"><"3"> (aanbevolen 1 of 2, max 3)'''
random.shuffle(self.witte_lijst) # schudden voor gebruik try:
zwarte_kaart = random.choice(self.zwarte_lijst).replace("___", "**{}**") # kies en maak het juiste format yield from ctx.message.delete()
aantal_wit = zwarte_kaart.count("{}") # tel hoeveel witte kaarten er nodig zijn except:
if aantal_wit == 0: # Soms staat er geen ___ in de kaart print("No permission to delete message")
zwarte_kaart = zwarte_kaart + " **{}**" resultaat = self.get_ktdm(args)
aantal_wit = 1 if resultaat:
arg_count = len(args) yield from ctx.channel.send(f"{ctx.author.mention}\n{resultaat}")
if arg_count > 3:
yield from ctx.channel.send(ctx.author.mention + ", " + random.choice(insult) + ", 3 is het maximum.")
elif arg_count > 0:
for elem in args:
self.witte_lijst.append(elem)
if arg_count != 0: # Indien extra args gegeven
while arg_count != aantal_wit: # Match het aantal args aan het aantal dat nodig is
zwarte_kaart = random.choice(self.zwarte_lijst).replace("___", "**{}**")
aantal_wit = zwarte_kaart.count("{}")
wit={} # maak dynamisch dict aan met de witte kaarten die ingevuld worden
for x in range(aantal_wit, 0, -1):
key = "wit" + str(x)
wit[key] = self.witte_lijst.pop()
# Dit gedeelte print de zwarte kaart mooi af
if aantal_wit == 1:
print(zwarte_kaart.format(wit['wit1']))
yield from ctx.channel.send(ctx.author.mention + "\n" + zwarte_kaart.format(wit['wit1']))
elif aantal_wit == 2:
print(zwarte_kaart.format(wit['wit1'],wit['wit2']))
yield from ctx.channel.send(ctx.author.mention + "\n" + zwarte_kaart.format(wit['wit1'],wit['wit2']))
elif aantal_wit == 3:
print(zwarte_kaart.format(wit['wit1'],wit['wit2'],wit['wit3']))
yield from ctx.channel.send(ctx.author.mention + "\n" + zwarte_kaart.format(wit['wit1'],wit['wit2'],wit['wit3']))
else: else:
print("Dit is een vreemd aantal witte kaarten: " + str(aantal_wit) + "\nDe boosdoener: " + zwarte_kaart) yield from ctx.channel.send(f"{ctx.author.mention}\nIets ging niet helemaal lekker")
yield from ctx.channel.send("Arme " + random.choice(insult) + ", er is iets foutgegaan!")
yield from ctx.message.delete()
@commands.command(pass_context=True) @commands.command(pass_context=True)
@asyncio.coroutine @asyncio.coroutine
@@ -708,9 +632,9 @@ class Shitpost(commands.Cog):
yield from ctx.channel.send(member.mention+ ", " + ctx.author.mention + " vindt jou een " + random.choice(self.insult) + "! :angry:") yield from ctx.channel.send(member.mention+ ", " + ctx.author.mention + " vindt jou een " + random.choice(self.insult) + "! :angry:")
yield from ctx.message.delete() yield from ctx.message.delete()
def watspelenweecht(self): def get_watspelenwe_cal(self):
"""Geeft een paar terug, met de titel en omschrijving van het eerstvolgende event uit de kalender""" """Geeft een paar terug, met de titel en omschrijving van het eerstvolgende event uit de kalender"""
calendar = self.caldav_client.calendar(url=self.bot.tokens["calendar"]) # refresh kalender calendar = self.caldav_client.calendar(url=os.getenv('STROOP_CALDAV_CAL')) # refresh kalender
# geen errorchecking hier, de caller doet dat maar gewoon ofzo, yolo # geen errorchecking hier, de caller doet dat maar gewoon ofzo, yolo
events = calendar.date_search( events = calendar.date_search(
@@ -720,14 +644,7 @@ class Shitpost(commands.Cog):
) )
return (events[0].vobject_instance.vevent.summary.value, events[0].vobject_instance.vevent.description.value) return (events[0].vobject_instance.vevent.summary.value, events[0].vobject_instance.vevent.description.value)
def get_watspelenwe_sass(self):
@commands.command(pass_context=True)
@asyncio.coroutine
def watspelenwe(self, ctx):
"""Stroop weet wat we spelen op vrijdag.
Geeft elke week een pseudo-random antwoord.
Geseed op weeknummer + jaar.
"""
SASS = [ SASS = [
"Pathfinder. Nee lmao wie speelt er nu nog pathfinder?", "Pathfinder. Nee lmao wie speelt er nu nog pathfinder?",
"Midfloat. Oh wacht dat is? Oh in Apeldoorn zeg je? Jeetje.", "Midfloat. Oh wacht dat is? Oh in Apeldoorn zeg je? Jeetje.",
@@ -743,26 +660,17 @@ class Shitpost(commands.Cog):
] ]
SPELLEN = [ SPELLEN = [
"DND", "Ars Magica", "DND", "Ars Magica",
#"5e", "4e",
#"Pathfinder", "Pathfinder 2",
#"CoC", "Delta Green",
"een one-shot", "Kaarten tegen de Mensheid", "een one-shot", "Kaarten tegen de Mensheid",
#"Midfloat", "Isle of Arden",
"Cyberpunk 2020", "Star Wars", "Cyberpunk 2020", "Star Wars",
"Blades in the Dark", #"Vampire the Masquerade", "Blades in the Dark",
"Expeditie Acquisitie", "Starfinder" "Expeditie Acquisitie", "Starfinder"
#"MAGE the Ascension"
] ]
PLAATSEN = [ PLAATSEN = [
# het is de na-lockdown-voor-de-volgende-lockdown-patch
"bij Mark thuis", "bij Freek thuis", "bij Mark thuis", "bij Freek thuis",
"bij JP thuis", "bij Erik thuis", "bij JP thuis", "bij Erik thuis",
"bij Lourens thuis", "in de Vrouwensteeg", "bij Lourens thuis", "in de Vrouwensteeg",
"bij Martijn thuis", "bij je moeder thuis", "bij Martijn thuis", "bij je moeder thuis",
"bij de Privé2000", "Vakantiepark Landal Kasteeldomein de Cauberg" "bij de Privé2000", "Vakantiepark Landal Kasteeldomein de Cauberg"
#"op Roll-20", "op Roll-20, bij jezelf thuis, het is lockdown immers",
#"op de digitale vrouwensteeg, te weten Roll-20", "op tabletop simulator? Oh maar dit is bizar kut, toch maar weer Roll-20",
#"bij Freek thuis. Echt. Heus"
] ]
AANVANG = [ AANVANG = [
"17:00.", "17:30.", "17:00.", "17:30.",
@@ -772,10 +680,7 @@ class Shitpost(commands.Cog):
"nadat iedereen tot 20:30 het uitgebreid over databases \"bij ons op het werk\" heeft gehad en de DM er een sarcastische opmerking over maakt.", "nadat iedereen tot 20:30 het uitgebreid over databases \"bij ons op het werk\" heeft gehad en de DM er een sarcastische opmerking over maakt.",
"na een flinke portie slap gelul.", "nadat Mark tenminste 20 plaatjes in #tiger-girls heeft gepost.", "na een flinke portie slap gelul.", "nadat Mark tenminste 20 plaatjes in #tiger-girls heeft gepost.",
"wanneer iedereen thuis is van zijn werk.", "nadat JP met de klantenservice heeft gebeld.", "wanneer iedereen thuis is van zijn werk.", "nadat JP met de klantenservice heeft gebeld.",
#"als Martijn aanbelt.", "als iedereen heeft gekookt.",
"ongeveer een uur voordat JP's trein gaat." "ongeveer een uur voordat JP's trein gaat."
#"als Guus zijn GPU werkend heeft gekregen.",
#"wanneer Martijn klaar is met nakijken.", "als Mark klaar is met zijn dailies."
] ]
PERSONEN = [ PERSONEN = [
"Mark", "Lourens", "JP", "Mark", "Lourens", "JP",
@@ -791,21 +696,14 @@ class Shitpost(commands.Cog):
"Minecraft met een of andere kutmodpack die Martijn gevonden heeft waardoor je de meeste troep niet zo maar kunt craften.", "Minecraft met een of andere kutmodpack die Martijn gevonden heeft waardoor je de meeste troep niet zo maar kunt craften.",
"Golf with y- oh het werkt niet op Linux? Oh jeetje oh nee, ja wat moeten we? Misschien kunnen we een ander spelletje - ja echt sorry ik weet het ook niet.", "Golf with y- oh het werkt niet op Linux? Oh jeetje oh nee, ja wat moeten we? Misschien kunnen we een ander spelletje - ja echt sorry ik weet het ook niet.",
"Warcraft 3 met een hamachi-server.", #Martijn poogt onironisch dit idee te pushen "Warcraft 3 met een hamachi-server.", #Martijn poogt onironisch dit idee te pushen
#"dat ene flavour-of-the-week lockdown spel leuk jongens.",
"allemaal afzonderlijk Dark Souls omdat we het JP hebben zien spelen en nu begint het toch weer te kriebelen heh? Toch weer een spelletje wat over het algemeen als moeilijk wordt ervaren even opnieuw doen zodat je je goed voelt over jezelf. Oh je doet het voor de achievements? Uhuh ja die heb ik ook. Alsjeblieft JP mag ik je invaden? JP stop niet zo goed zijn in het spel toe.", "allemaal afzonderlijk Dark Souls omdat we het JP hebben zien spelen en nu begint het toch weer te kriebelen heh? Toch weer een spelletje wat over het algemeen als moeilijk wordt ervaren even opnieuw doen zodat je je goed voelt over jezelf. Oh je doet het voor de achievements? Uhuh ja die heb ik ook. Alsjeblieft JP mag ik je invaden? JP stop niet zo goed zijn in het spel toe.",
"Subnautica. Te weten: we kijken hoe Martijn zijn broek volpoept op stream.", "Subnautica. Te weten: we kijken hoe Martijn zijn broek volpoept op stream.",
"SOMA. Lmao knul niemand speelt SOMA. We gaan Minecraft doen en je gaat het maar naar je zin hebben.", "SOMA. Lmao knul niemand speelt SOMA. We gaan Minecraft doen en je gaat het maar naar je zin hebben.",
"een best wel okee spel wat net uit is. Misschien hebben we het nog eens naar ons zin." "een best wel okee spel wat net uit is. Misschien hebben we het nog eens naar ons zin."
#"Barotrauma.", "Among Us.", #alsjeblieft zeg
#"Elder Scrolls Online."
#"Monster Hunter.", "Grim Dawn.",
#"Diablo.", "PoE.",
#"dat ene spel dat net uit is gekomen in de Humble Bundle waar we na 2 dagen klaar mee zijn precies wanneer Martijn wel tijd heeft mee te spelen."
] ]
GEBEURTENIS = [ GEBEURTENIS = [
"is ziek. We spelen", "is ziek. We spelen",
"moet overwerken want ze hebben het weer verneukt. Iets met IT. De rest speelt", "moet overwerken want ze hebben het weer verneukt. Iets met IT. De rest speelt",
#"moet overwerken want ze hebben het weer verneukt. Iets met IT. Of parkieten op Teams. De rest speelt",
"heeft mogelijk corona en we zijn toch een risicogroep. We spelen", "heeft mogelijk corona en we zijn toch een risicogroep. We spelen",
"zijn kat is van de trap gekankerd. De rest speelt", "zijn kat is van de trap gekankerd. De rest speelt",
"heeft best wel hard zijn teen gestoten. De rest doet", "heeft best wel hard zijn teen gestoten. De rest doet",
@@ -845,13 +743,22 @@ class Shitpost(commands.Cog):
message = "We spelen " + DAG + random.choice(SPELLEN) + " " + random.choice(PLAATSEN) + ", aanvang " + random.choice(AANVANG) + random.choice(EXTRA) message = "We spelen " + DAG + random.choice(SPELLEN) + " " + random.choice(PLAATSEN) + ", aanvang " + random.choice(AANVANG) + random.choice(EXTRA)
elif KEUZEMOGELIJKHEDEN == 6: elif KEUZEMOGELIJKHEDEN == 6:
message = "We spelen " + DAG + random.choice(VIDYA) + " Ja, ik weet het, eigenlijk \"D&D\"-avond maar ja. Wees nou eerlijk heh. Aanvang " + random.choice(AANVANG) message = "We spelen " + DAG + random.choice(VIDYA) + " Ja, ik weet het, eigenlijk \"D&D\"-avond maar ja. Wees nou eerlijk heh. Aanvang " + random.choice(AANVANG)
#elif KEUZEMOGELIJKHEDEN > 2:
# message = "We spelen " + DAG + "omwille van de lockdown " + random.choice(VIDYA) + " Aanvang op discord " + random.choice(AANVANG)
else: else:
message = "We spelen " + DAG + random.choice(SPELLEN) + " " + random.choice(PLAATSEN) + ", aanvang " + random.choice(AANVANG) message = "We spelen " + DAG + random.choice(SPELLEN) + " " + random.choice(PLAATSEN) + ", aanvang " + random.choice(AANVANG)
return message
@commands.command(pass_context=True)
@asyncio.coroutine
def watspelenwe(self, ctx):
"""Stroop weet wat we spelen op vrijdag.
Geeft elke week een pseudo-random antwoord.
Geseed op weeknummer + jaar.
"""
message = self.get_watspelenwe_sass()
try: try:
(activiteit, reden) = self.watspelenweecht() (activiteit, reden) = self.get_watspelenwe_cal()
message += f"\nNee, we doen eigenlijk {activiteit} want {reden}" message += f"\nNee, we doen eigenlijk {activiteit} want {reden}"
except: except:
message += ". En wilt iemand even aan Mark vragen of hij de kalender bijhoudt?" message += ". En wilt iemand even aan Mark vragen of hij de kalender bijhoudt?"
@@ -861,17 +768,10 @@ class Shitpost(commands.Cog):
except: except:
print("No permission to delete message") print("No permission to delete message")
yield from ctx.channel.send(message) yield from ctx.channel.send(message)
@commands.command(pass_context=True)
@asyncio.coroutine
def review(self, ctx, *args):
"""Stroop heeft (bijna) overal een mening over. Vraag het hem!
"""
topic = " ".join(args)
def get_review_string(self, topic = ""):
if topic == "": if topic == "":
random.seed(datetime.now()) random.seed(datetime.now().timestamp())
else: else:
random.seed(topic.lower().replace(" ", "")) random.seed(topic.lower().replace(" ", ""))
@@ -916,11 +816,13 @@ class Shitpost(commands.Cog):
emoj = random.choice(EMOJI) emoj = random.choice(EMOJI)
message += str(rating) + " " + emoj*rating + " out of " + str(maxRating) + "." message += str(rating) + " " + emoj*rating + " out of " + str(maxRating) + "."
yield from ctx.channel.send(message) return message
@commands.command(pass_context=True)
@asyncio.coroutine
def review(self, ctx, *args):
def setup(bot): """Stroop heeft (bijna) overal een mening over. Vraag het hem!
bot.add_cog(Shitpost(bot)) """
topic = " ".join(args)
message = self.get_review_string(topic)
yield from ctx.channel.send(message)
+5 -21
View File
@@ -7,14 +7,15 @@ import Cryptocoin
import Chatbot import Chatbot
import Points import Points
import logging import logging
import importlib import dotenv
import configparser import os
import base64
from discord.ext import commands from discord.ext import commands
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
dotenv.load_dotenv()
async def add_cogs(bot): async def add_cogs(bot):
await bot.add_cog(Shitpost.Shitpost(bot)) await bot.add_cog(Shitpost.Shitpost(bot))
await bot.add_cog(General.General(bot)) await bot.add_cog(General.General(bot))
@@ -28,26 +29,9 @@ intents.members = True
bot = commands.Bot(command_prefix=commands.when_mentioned_or('!'), description='Stroopwafel. Shitpost bot extraordinaire.', pm_help=True, intents=intents) bot = commands.Bot(command_prefix=commands.when_mentioned_or('!'), description='Stroopwafel. Shitpost bot extraordinaire.', pm_help=True, intents=intents)
#Read configuration file:
config = configparser.ConfigParser()
config.read('stroopwafel.ini')
bot.tokens = config["tokens"]
bot.hdChannels = {}
for channel in config["channels"]: #channelIDs must be integers
bot.hdChannels[channel] = int(config["channels"][channel])
#passwords are base64 encoded, which makes it like 1% safer
bot.passwords = {}
for pw in config["passwords"]:
try:
bot.passwords[pw] = (base64.standard_b64decode(config["passwords"][pw])).decode()
except:
print("Problem with decoding password!")
bot.passwords[pw] = config["passwords"][pw]
@bot.event @bot.event
async def on_ready(): async def on_ready():
await add_cogs(bot) await add_cogs(bot)
print('Logged in as:\n{0} (ID: {0.id})'.format(bot.user)) print('Logged in as:\n{0} (ID: {0.id})'.format(bot.user))
bot.run(bot.tokens["discordbot"]) bot.run(os.getenv("STROOP_DISCORD_TOKEN"))
+16
View File
@@ -0,0 +1,16 @@
STROOP_DISCORD_TOKEN=
STROOP_TWITTER_KEY=
STROOP_TWITTER_SECRET=
STROOP_REDDIT_ID=
STROOP_REDDIT_SECRET=
STROOP_SPOTIFY_ID=
STROOP_SPOTIFY_SECRET=
STROOP_SPOTIFY_USER=
STROOP_SPOTIFY_PLAYLIST=
STROOP_WEERLIVE=
STROOP_CALDAV_HOST=
STROOP_CALDAV_CAL=
STROOP_IMGFLIP_PASSWORD=
STROOP_RESET_PASSWORD=
STROOP_CHANNEL_SHITPOST=
STROOP_CHANNEL_BELANGRIJK=
+5
View File
@@ -0,0 +1,5 @@
caldav
discord.py
praw
numpy
python-dotenv
+4
View File
@@ -0,0 +1,4 @@
from .shitpost import TestShitpost
from .general import TestGeneral
from .chatbot import TestChatbot
from .points import TestPoints
+36
View File
@@ -0,0 +1,36 @@
import unittest
import praw
import dotenv
import re
import discord
from discord.ext import commands
import Chatbot
class TestChatbot(unittest.TestCase):
def setUp(self):
dotenv.load_dotenv()
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
bot = commands.Bot(command_prefix=commands.when_mentioned_or('!'), description='Stroopwafel. Shitpost bot extraordinaire.', pm_help=True, intents=intents)
self.cog = Chatbot.Chatbot(bot)
def test_countsyllables(self):
with self.subTest("1 syllable word"):
self.assertEqual(1, self.cog.countSyllables("big"))
with self.subTest("1 syllable word (longer)"):
self.assertEqual(1, self.cog.countSyllables("Paard"))
with self.subTest("2 syllable word"):
self.assertEqual(2, self.cog.countSyllables("Bakfiets"))
with self.subTest("2 syllable word (more complex)"):
self.assertEqual(2, self.cog.countSyllables("Skiën"))
with self.subTest("3 syllable word"):
self.assertEqual(3, self.cog.countSyllables("Spookpoeper"))
with self.subTest("4 syllable word"):
self.assertEqual(4, self.cog.countSyllables("Papzakprobleem"))
with self.subTest("8 syllable word"):
self.assertEqual(8, self.cog.countSyllables("zuremattenvampirisme"))
with self.subTest("OMG"):
self.assertEqual(3, self.cog.countSyllables("OMG"))
+49
View File
@@ -0,0 +1,49 @@
import unittest
import praw
import random
import requests
import json
import dotenv
import re
import discord
from discord.ext import commands
import General
class TestGeneral(unittest.TestCase):
def setUp(self):
dotenv.load_dotenv()
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
bot = commands.Bot(command_prefix=commands.when_mentioned_or('!'), description='Stroopwafel. Shitpost bot extraordinaire.', pm_help=True, intents=intents)
self.cog = General.General(bot)
def test_playlist(self):
data = self.cog.get_playlist_json()
if data.status_code >= 500:
self.skipTest(f"Server at {self.cog.muzak_url} has an error")
with self.subTest(msg=f"{self.cog.muzak_url} doesn't return 200"):
self.assertEqual(data.status_code, 200)
with self.subTest(msg="Not a good response"):
self.assertIsInstance(data, requests.Response)
with self.subTest(msg="Does not convert to json"):
self.assertIsInstance(json.loads(data.content), dict)
def test_aww(self):
if not isinstance(self.cog.r, praw.Reddit):
self.skipTest("PRAW Reddit instance failed to create")
post = self.cog.get_aww_post()
self.assertIsInstance(post.url, str)
def test_kopieerpasta(self):
if not isinstance(self.cog.r, praw.Reddit):
self.skipTest("PRAW Reddit instance failed to create")
post = self.cog.get_kopieerpasta()
self.assertIsInstance(post.url, str)
def test_huge(self):
embed = self.cog.get_emoji_embed("<:test:123456789>")
self.assertIsInstance(embed, discord.Embed)
+157
View File
@@ -0,0 +1,157 @@
import unittest
import praw
import dotenv
from datetime import datetime
import discord
from discord.ext import commands
import Points
class User:
def __init__(self, id, name):
self.id = id
self.name = name
class TestPoints(unittest.TestCase):
def setUp(self):
dotenv.load_dotenv()
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
bot = commands.Bot(command_prefix=commands.when_mentioned_or('!'), description='Stroopwafel. Shitpost bot extraordinaire.', pm_help=True, intents=intents)
self.cog = Points.Points(bot)
self.user1 = User(10001, "Alice")
self.user2 = User(10002, "Bob")
def test_getUserBalance(self):
self.cog.pointsCount = {}
self.cog.pointsCount[self.user1.id] = {"name": self.user1.name, "points": 69}
self.assertEqual(69, self.cog.getUserBalance(self.user1))
def test_getBankBalance(self):
self.cog.pointsCount = {}
self.cog.pointsCount[self.user1.id] = {"name": self.user1.name, "points": 1}
self.cog.pointsCount[self.cog.BANK_ID] = {"name": "DE BANK", "points": 999}
self.assertEqual(999, self.cog.getBankBalance())
def test_isUserOnList(self):
self.cog.pointsCount = {}
self.cog.pointsCount[self.user1.id] = {"name": self.user1.name, "points": 1}
self.cog.pointsCount[self.cog.BANK_ID] = {"name": "DE BANK", "points": 999}
self.assertTrue(self.cog.isUserOnList(self.user1))
self.assertFalse(self.cog.isUserOnList(self.user2))
def test_transferPoints(self):
self.cog.pointsCount = {}
self.cog.pointsCount[self.user1.id] = {"name": self.user1.name, "points": 50}
self.cog.pointsCount[self.user2.id] = {"name": self.user2.name, "points": 30}
self.cog.transferPoints(self.user1.id, self.user2.id, 4)
self.assertEqual(46, self.cog.getUserBalance(self.user1))
self.assertEqual(34, self.cog.getUserBalance(self.user2))
def test_given_bankHasBalanceAndUserHasNotGivenPointsYetToday_when_givingPoints_then_tenPointComeFromBank(self):
self.cog.pointsCount = {}
self.cog.pointsCount[self.cog.BANK_ID] = {"name": "DE BANK", "points": 1000}
self.cog.pointsCount[self.user1.id] = {"name": self.user1.name, "points": 200, "pointTakenOnDate":0, "bankPointsGivenOnDate":0, "theDate":"20220101"}
self.cog.pointsCount[self.user2.id] = {"name": self.user2.name, "points": 100, "pointTakenOnDate":0, "bankPointsGivenOnDate":0, "theDate":"20220101"}
self.cog.execute_geefpunten(self.user1.id, self.user2.id, 12)
self.assertEqual(990, self.cog.getBankBalance())
self.assertEqual(198, self.cog.getUserBalance(self.user1))
self.assertEqual(112, self.cog.getUserBalance(self.user2))
def test_given_bankHasBalanceButUserHasNoBalanceAndUserHasNotGivenPointsYetToday_when_givingPoints_then_pointComeFromBank(self):
currentDateStr = datetime.now().strftime("%Y%m%d")
self.cog.pointsCount = {}
self.cog.pointsCount[self.cog.BANK_ID] = {"name": "DE BANK", "points": 1000}
self.cog.pointsCount[self.user1.id] = {"name": self.user1.name, "points": 0, "pointTakenOnDate":10, "bankPointsGivenOnDate":0, "theDate":currentDateStr}
self.cog.pointsCount[self.user2.id] = {"name": self.user2.name, "points": 100, "pointTakenOnDate":10, "bankPointsGivenOnDate":10, "theDate":currentDateStr}
self.cog.execute_geefpunten(self.user1.id, self.user2.id, 5)
self.assertEqual(995, self.cog.getBankBalance())
self.assertEqual(0, self.cog.getUserBalance(self.user1))
self.assertEqual(105, self.cog.getUserBalance(self.user2))
def test_given_bankIsEmpty_when_givingPoints_then_AllPointsComeFromUser(self):
self.cog.pointsCount = {}
self.cog.pointsCount[self.cog.BANK_ID] = {"name": "DE BANK", "points": 0}
self.cog.pointsCount[self.user1.id] = {"name": self.user1.name, "points": 200, "pointTakenOnDate":0, "bankPointsGivenOnDate":0, "theDate":"20220101"}
self.cog.pointsCount[self.user2.id] = {"name": self.user2.name, "points": 100, "pointTakenOnDate":0, "bankPointsGivenOnDate":0, "theDate":"20220101"}
self.cog.execute_geefpunten(self.user1.id, self.user2.id, 15)
self.assertEqual(0, self.cog.getBankBalance())
self.assertEqual(185, self.cog.getUserBalance(self.user1))
self.assertEqual(115, self.cog.getUserBalance(self.user2))
def test_given_userHasAlreadyGivenSomeBankPointsToday_when_givingPoints_then_NotAllPointsComeFromBank(self):
currentDateStr = datetime.now().strftime("%Y%m%d")
self.cog.pointsCount = {}
self.cog.pointsCount[self.cog.BANK_ID] = {"name": "DE BANK", "points": 1000}
self.cog.pointsCount[self.user1.id] = {"name": self.user1.name, "points": 200, "pointTakenOnDate":0, "bankPointsGivenOnDate":0, "theDate":currentDateStr}
self.cog.pointsCount[self.user2.id] = {"name": self.user2.name, "points": 100, "pointTakenOnDate":0, "bankPointsGivenOnDate":0, "theDate":"20220101"}
# First a normal transaction:
self.cog.execute_geefpunten(self.user1.id, self.user2.id, 5)
self.assertEqual(995, self.cog.getBankBalance())
self.assertEqual(200, self.cog.getUserBalance(self.user1))
self.assertEqual(105, self.cog.getUserBalance(self.user2))
# Then another one:
self.cog.execute_geefpunten(self.user1.id, self.user2.id, 8)
self.assertEqual(990, self.cog.getBankBalance()) # Only the first 5 come from the bank
self.assertEqual(197, self.cog.getUserBalance(self.user1))
self.assertEqual(113, self.cog.getUserBalance(self.user2))
# One more:
self.cog.execute_geefpunten(self.user1.id, self.user2.id, 3)
self.assertEqual(990, self.cog.getBankBalance()) # All points come out of the user's pocket now
self.assertEqual(194, self.cog.getUserBalance(self.user1))
self.assertEqual(116, self.cog.getUserBalance(self.user2))
def test_given_usersWithPoints_when_takingPoints_then_pointsGoToTheBank(self):
self.cog.pointsCount = {}
self.cog.pointsCount[self.cog.BANK_ID] = {"name": "DE BANK", "points": 1000}
self.cog.pointsCount[self.user1.id] = {"name": self.user1.name, "points": 200, "pointTakenOnDate":0, "bankPointsGivenOnDate":0, "theDate":"20220101"}
self.cog.pointsCount[self.user2.id] = {"name": self.user2.name, "points": 100, "pointTakenOnDate":0, "bankPointsGivenOnDate":0, "theDate":"20220101"}
self.cog.refreshDateVarsAndReturnUserVars(self.user1.id) #usually happens in !neempunten, so this unittest is a bit poor
self.cog.execute_neempunten(self.user1.id, self.user2.id, 2)
self.assertEqual(1002, self.cog.getBankBalance())
self.assertEqual(200, self.cog.getUserBalance(self.user1))
self.assertEqual(98, self.cog.getUserBalance(self.user2))
# The user should only have 8 points left to give away today:
self.assertEqual(8, self.cog.getUsersRemainingPointsToTakeToday(self.user1.id))
def test_given_user_when_takingPoints_then_pointsToTakeAreLimited(self):
self.cog.pointsCount = {}
self.cog.pointsCount[self.cog.BANK_ID] = {"name": "DE BANK", "points": 1000}
self.cog.pointsCount[self.user1.id] = {"name": self.user1.name, "points": 200, "pointTakenOnDate":0, "bankPointsGivenOnDate":0, "theDate":"20220101"}
self.cog.pointsCount[self.user2.id] = {"name": self.user2.name, "points": 100, "pointTakenOnDate":0, "bankPointsGivenOnDate":0, "theDate":"20220101"}
self.cog.refreshDateVarsAndReturnUserVars(self.user1.id) #usually happens in !neempunten, so this unittest is a bit poor
self.cog.execute_neempunten(self.user1.id, self.user2.id, 6)
self.assertEqual(94, self.cog.getUserBalance(self.user2))
# The user should only have 4 points left to give away today:
self.assertEqual(4, self.cog.getUsersRemainingPointsToTakeToday(self.user1.id))
self.cog.execute_neempunten(self.user1.id, self.user2.id, 3)
self.assertEqual(91, self.cog.getUserBalance(self.user2))
# The user should only have 1 point left to give away today:
self.assertEqual(1, self.cog.getUsersRemainingPointsToTakeToday(self.user1.id))
self.cog.execute_neempunten(self.user1.id, self.user2.id, 1)
self.assertEqual(90, self.cog.getUserBalance(self.user2))
# The user should have 0 points left to take away:
self.assertEqual(0, self.cog.getUsersRemainingPointsToTakeToday(self.user1.id))
# The actual check whether or not a user can keep on taking points away happens in !neempunten and is not tested here
def test_refreshDateVarsAndReturnUserVars(self):
with self.subTest("Should not be updated yet. Update was just today."):
currentDateStr = datetime.now().strftime("%Y%m%d")
self.cog.pointsCount = {}
self.cog.pointsCount[self.user1.id] = {"name": self.user1.name, "points": 100, "pointTakenOnDate":2, "bankPointsGivenOnDate":1, "theDate":currentDateStr}
self.cog.refreshDateVarsAndReturnUserVars(self.user1.id)
# Still today. Values should stay the same:
self.assertEqual(2, self.cog.pointsCount[self.user1.id]["pointTakenOnDate"])
self.assertEqual(1, self.cog.pointsCount[self.user1.id]["bankPointsGivenOnDate"])
with self.subTest("Should be reset. Update was in the past."):
currentDateStr = datetime.now().strftime("%Y%m%d")
self.cog.pointsCount = {}
self.cog.pointsCount[self.user1.id] = {"name": self.user1.name, "points": 100, "pointTakenOnDate":2, "bankPointsGivenOnDate":1, "theDate":"20150101"}
self.cog.refreshDateVarsAndReturnUserVars(self.user1.id)
# A new day. Values should be set to 0 again:
self.assertEqual(0, self.cog.pointsCount[self.user1.id]["pointTakenOnDate"])
self.assertEqual(0, self.cog.pointsCount[self.user1.id]["bankPointsGivenOnDate"])
self.assertNotEqual("20150101", self.cog.pointsCount[self.user1.id]["theDate"])
+171
View File
@@ -0,0 +1,171 @@
import unittest
import dotenv
import os
import discord
import requests
from discord.ext import commands
import Shitpost
class TestShitpost(unittest.TestCase):
def setUp(self):
dotenv.load_dotenv()
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
bot = commands.Bot(command_prefix=commands.when_mentioned_or('!'), description='Stroopwafel. Shitpost bot extraordinaire.', pm_help=True, intents=intents)
self.cog = Shitpost.Shitpost(bot)
def test_review(self):
TOPIC = "qpwoeirut12"
topic_review = self.cog.get_review_string(TOPIC)
with self.subTest(msg=f"Topic review does not return a string"):
self.assertIsInstance(topic_review, str)
with self.subTest(msg=f"Topic review does not contain the topic"):
self.assertIn(TOPIC, topic_review)
basic_review = self.cog.get_review_string()
with self.subTest(msg=f"Review does not return a string"):
self.assertIsInstance(basic_review, str)
def test_watspelenwe_sass(self):
once = self.cog.get_watspelenwe_sass()
twice = self.cog.get_watspelenwe_sass()
with self.subTest(msg="Watspelenwe does not seed correctly"):
self.assertEqual(once, twice)
with self.subTest(msg="Watspelenwe does not return a string"):
self.assertIsInstance(once, str)
def test_watspelenwe_cal(self):
data = requests.get(os.getenv('STROOP_CALDAV_CAL'))
if not data:
self.skipTest(f"Server at {self.cog.muzak_url} has an error, or is unavailable")
(activiteit, reden) = self.cog.get_watspelenwe_cal()
with self.subTest(msg="Watspelenwe activiteit does not return a string"):
self.assertIsInstance(activiteit, str)
with self.subTest(msg="Watspelenwe reden does not return a string"):
self.assertIsInstance(reden, str)
def test_ktdm(self):
with self.subTest():
wit = ["qwerty", "yuiop"]
kaart = self.cog.get_ktdm(wit)
self.assertIn(wit[0], kaart)
self.assertIn(wit[1], kaart)
with self.subTest():
wit = ["a", "b", "c", "d"]
kaart = self.cog.get_ktdm(wit)
self.assertEqual(kaart, None)
with self.subTest():
wit = ["a", "b", "c"]
self.cog.zwarte_lijst = ["___"]
kaart = self.cog.get_ktdm(wit)
self.assertEqual(kaart, None)
def test_weer(self):
data = requests.get("http://weerlive.nl/api/json-data-10min.php")
if not data:
self.skipTest(f"Weerlive has an error, or is unavailable")
weerJson = self.cog.get_weer_json()
with self.subTest("Weer does not correctly convert from json"):
self.assertIsInstance(weerJson, dict)
icon = self.cog.getWeatherIconTranslation(weerJson["d2weer"])
with self.subTest("Weericon not available"):
self.assertNotEqual(icon, ":park:")
with self.subTest("Weericon incorrect"):
self.assertRegex(icon, ":[A-z]+:")
with self.subTest("No weericon for unknown weather"):
icon = self.cog.getWeatherIconTranslation("sniezelig") # Bestaat niet natuurlijk
self.assertRegex(icon, ":[A-z]+:")
bbq = self.cog.getBbqGrade(weerJson)
with self.subTest("BBQ cijfer incorrect"):
self.assertIsInstance(bbq, float)
self.assertGreaterEqual(bbq, 1.0)
self.assertLessEqual(bbq, 10.0)
with self.subTest("False positive alarm"):
weerMock = { "alarm": 0}
alertCode, alertMessage = self.cog.getWeerAlarm(weerMock)
self.assertEqual(alertCode, None)
self.assertEqual(alertMessage, "")
with self.subTest("False negative rood alarm"):
weerMock = { "alarm": "1", "alarmtxt": "qwerty code rood yuiop"}
alertCode, alertMessage = self.cog.getWeerAlarm(weerMock)
self.assertEqual(alertCode, "rood")
self.assertIsInstance(alertMessage, str)
with self.subTest("False negative oranje alarm"):
weerMock = { "alarm": "1", "alarmtxt": "qwerty code oranje yuiop"}
alertCode, alertMessage = self.cog.getWeerAlarm(weerMock)
self.assertEqual(alertCode, "oranje")
self.assertIsInstance(alertMessage, str)
with self.subTest("False negative geel alarm"):
weerMock = { "alarm": "1", "alarmtxt": "lorem ipsum dolor sit amet"}
alertCode, alertMessage = self.cog.getWeerAlarm(weerMock)
self.assertEqual(alertCode, "geel")
self.assertIsInstance(alertMessage, str)
wb = self.cog.get_weerbericht(weerJson)
wb_v = self.cog.get_weerbericht(weerJson, "verbose pls")
with self.subTest("Can't render message from json"):
self.assertIsInstance(wb, str)
self.assertIsInstance(wb_v, str)
with self.subTest("Verbose isn't actually verbose"):
self.assertTrue(len(wb_v) > len(wb))
def test_roll(self):
with self.subTest("Incorrect acceptance of malformed string"):
self.assertIsNone(self.cog.get_dice_parameters("1 d 20 "))
with self.subTest("Incorrect parsing of capital D"):
self.assertEqual((1, 20, None), self.cog.get_dice_parameters("1D20"))
with self.subTest("Incorrect parsing of die-string"):
self.assertEqual((1, 20, None), self.cog.get_dice_parameters("1d20"))
with self.subTest("Incorrect parsing of die modifier"):
self.assertEqual((2, 20, 3), self.cog.get_dice_parameters("2d20+3"))
with self.subTest("Incorrect parsing of spacing in die-string"):
self.assertEqual((1, 20, 5), self.cog.get_dice_parameters("1d20 + 5"))
with self.subTest("Incorrect parsing of negative modifier"):
self.assertEqual((1, 12, -3), self.cog.get_dice_parameters("1d12 - 3"))
with self.subTest("Incorrect parsing of unbalanced spacing"):
self.assertEqual((1, 12, -3), self.cog.get_dice_parameters("1d12 -3"))
with self.subTest("Incorrect parsing of largest values"):
self.assertEqual((99, 9999, 9999), self.cog.get_dice_parameters("99d9999 + 9999"))
with self.subTest("Incorrect acceptance of too many dice"):
self.assertIsNone(self.cog.get_dice_roll(100, 20, None))
with self.subTest("Incorrect acceptance of too big die"):
self.assertIsNone(self.cog.get_dice_roll(4, 10000, None))
with self.subTest("Incorrect acceptance of too large modifier"):
self.assertIsNone(self.cog.get_dice_roll(1, 20, 999999))
with self.subTest("Incorrect acceptance of too large negative modifier"):
self.assertIsNone(self.cog.get_dice_roll(1, 20, -999999))
with self.subTest("Critical fail/success not marked"):
self.assertIn("**10**", self.cog.get_dice_roll(99, 10, None))
self.assertIn("**1**", self.cog.get_dice_roll(99, 10, None))
self.assertTrue(True)
def test_imgflips(self):
eriku = self.cog.get_imgflip_embed(self.cog.imgflips['eriku'], "a", "b")
tegeltje = self.cog.get_tegeltje("Man who put penis in peanut butter is fucking nuts", "Confucius")
self.assertIsInstance(eriku, discord.Embed)
self.assertIsInstance(tegeltje, discord.Embed)
def test_inspire(self):
inspo = self.cog.get_inspiration()
self.assertIn("https://", inspo)
self.assertIn(".jpg", inspo)
def test_giethetaloan(self):
self.assertIn("nee", self.cog.get_giet_het_oan().lower())
def test_corona(self):
message = self.cog.get_corona_message()
self.assertIsInstance(message, str)
def test_zalgo(self):
inmsg = "lorem ipsum"
message = self.cog.zalgofy(inmsg)
self.assertIsInstance(message, str)
self.assertEqual(len(message), len(inmsg)*5)