Merge branch 'main' of github.com:pvanarkel/discord-jeeves into main

This commit is contained in:
2025-03-30 20:51:19 +02:00
19 changed files with 221 additions and 287 deletions

6
.gitignore vendored
View File

@@ -1,9 +1,9 @@
jeevesbot/env.py jeevesbot/env.py
jeevesbot/secret.json jeevesbot/databases/*
jeevesbot/__pycache__/*
logs/ logs/
__init__.py __init__.py
*.pyc *.pyc
__pycache__/* __pycache__/*
cogs/__pycache__/* cogs/__pycache__/*
jeevesbot/__pycache__/* .vscode/
.vscode/

View File

@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2022 - Peter van Arkel Copyright (c) 2024 - Peter van Arkel
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.

View File

@@ -4,7 +4,6 @@
- Clone this repository to a directory you want the bot to run from - Clone this repository to a directory you want the bot to run from
- `pip3 install -r requirements.txt` - `pip3 install -r requirements.txt`
- Copy `jeevesbot/env.py.dist` to `jeevesbot/env.py` and change the variables. - Copy `jeevesbot/env.py.dist` to `jeevesbot/env.py` and change the variables.
- Copy `jeevesbot/secret.json.dist` to `jeevesbot/secret.json` and add your Google Drive API secret.json
- `cp scripts/jeeves.service /etc/systemd/system/jeeves.service` and change the variables to suit your environment. - `cp scripts/jeeves.service /etc/systemd/system/jeeves.service` and change the variables to suit your environment.
- `systemctl daemon-reload` - `systemctl daemon-reload`
- `systemctl start jeeves.service` - `systemctl start jeeves.service`

View File

@@ -1,4 +1,3 @@
import discord
from discord.ext import commands from discord.ext import commands
from logging import getLogger from logging import getLogger
import typing import typing

View File

@@ -1,6 +1,6 @@
import discord import discord
from discord.ext import commands from discord.ext import commands
from jeevesbot import functions, babbelbingo from jeevesbot import functions
from logging import getLogger from logging import getLogger
@@ -17,15 +17,6 @@ class Games(commands.Cog):
self.bot = bot self.bot = bot
@commands.command()
@commands.guild_only()
async def bingo(self, ctx):
""" Maak een babbelbingo kaart (staat niet altijd aan) """
name = ctx.message.author.name
bingocard = babbelbingo.bingo(name)
await ctx.author.send(file=discord.File(bingocard))
@commands.command() @commands.command()
async def roll(self, ctx): async def roll(self, ctx):
""" Roll the dice! """ Roll the dice!
@@ -68,4 +59,4 @@ class Games(commands.Cog):
async def setup(bot): async def setup(bot):
await bot.add_cog(Games(bot)) await bot.add_cog(Games(bot))

View File

@@ -2,11 +2,9 @@ import discord
from discord.ext import commands from discord.ext import commands
from logging import getLogger from logging import getLogger
# setup logging # setup logging
log = getLogger(__name__) log = getLogger(__name__)
e = discord.Embed() e = discord.Embed()
@@ -17,12 +15,6 @@ class Misc(commands.Cog):
self.bot = bot self.bot = bot
@commands.command()
async def hug(self, ctx):
msg = f'Jeeves geeft {ctx.message.author.mention} een grote knuffel'
await ctx.send(msg)
@commands.command() @commands.command()
async def eirik(self, ctx): async def eirik(self, ctx):
await ctx.send('Deze vraag heeft Eirik Fatland al beantwoord in 1997.') await ctx.send('Deze vraag heeft Eirik Fatland al beantwoord in 1997.')
@@ -34,4 +26,4 @@ class Misc(commands.Cog):
async def setup(bot): async def setup(bot):
await bot.add_cog(Misc(bot)) await bot.add_cog(Misc(bot))

View File

@@ -1,69 +1,74 @@
import discord import discord
from discord.ext import commands from discord.ext import commands
from jeevesbot import functions from jeevesbot import functions, env
from logging import getLogger from logging import getLogger
import re import re
import pytube import pytube
from pytube.exceptions import RegexMatchError from pytube.exceptions import RegexMatchError, VideoUnavailable, ExtractError
# setup logging # setup logging
log = getLogger(__name__) log = getLogger(__name__)
e = discord.Embed()
class Preview(commands.Cog): class Preview(commands.Cog):
""" Ensures that high-risk channels don't display embedded links, but only gifs and youtube previews.""" """ Ensures that high-risk channels don't display embedded links, but only gifs and youtube previews."""
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
self.video_id_regex = re.compile(r'(?:youtube\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/|m\.youtube\.com/(?:watch\?v=|embed/|v/))([^"&?/ ]{11})') self.video_id_regex = re.compile(r'(?:youtube\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/|m\.youtube\.com/(?:watch\?v=|embed/|v/))([^"&?/ ]{11})')
self.e = discord.Embed()
@commands.Cog.listener() @commands.Cog.listener()
async def on_message(self, message): async def on_message(self, message):
if message.author.bot:
return # Ignore messages from bots
if message.content.startswith('https://tenor.com/'): if message.content.startswith('https://tenor.com/'):
roles = functions.checkrole(message.author.roles) is_admin = message.author.guild_permissions.administrator
channel = functions.checkchannel(message.channel.id) is_high_risk_channel = self.check_channel(message.channel.id)
embed_url = message.content embed_url = message.content
follow_url = embed_url + '.gif' follow_url = embed_url + '.gif'
full_url = await functions.resolve(follow_url) full_url = await functions.resolve(follow_url)
gif_url = full_url.split('?')[0] gif_url = full_url.split('?')[0]
embed = e.set_image(url=gif_url) embed = self.e.set_image(url=gif_url)
if channel is True: if is_high_risk_channel and not is_admin:
if roles is not True: await message.channel.send(embed=embed)
await message.channel.send(embed=embed) logline = (str(message.author) + ' requested a gif: ' + str(gif_url))
logline = (str(message.author) + ' requested a gif: ' + str(gif_url)) log.info(logline)
log.info(logline)
if message.content.endswith('.gif'):
roles = functions.checkrole(message.author.roles)
channel = functions.checkchannel(message.channel.id)
embed_url = message.content
embed = e.set_image(url=embed_url)
if channel is True:
if roles is not True:
await message.channel.send(embed=embed)
logline = (str(message.author) + ' requested a gif: ' + str(embed_url))
log.info(logline)
if message.content.startswith('https://giphy.com/'): if message.content.startswith('https://giphy.com/'):
roles = functions.checkrole(message.author.roles) is_admin = message.author.guild_permissions.administrator
channel = functions.checkchannel(message.channel.id) is_high_risk_channel = self.check_channel(message.channel.id)
embed_url = message.content embed_url = message.content
image_code = embed_url.split('-')[-1] image_code = embed_url.split('-')[-1]
gif_url = 'https://media.giphy.com/media/' + image_code + '/giphy.gif' gif_url = 'https://media.giphy.com/media/' + image_code + '/giphy.gif'
embed = e.set_image(url=gif_url) embed = self.e.set_image(url=gif_url)
if channel is True: if is_high_risk_channel and not is_admin:
if roles is not True: await message.channel.send(embed=embed)
await message.channel.send(embed=embed) logline = (str(message.author) + ' requested a gif: ' + str(gif_url))
logline = (str(message.author) + ' requested a gif: ' + str(gif_url)) log.info(logline)
log.info(logline)
if 'https://youtu' or 'https://m.youtu' or 'https://www.youtu' in message.content():
roles = functions.checkrole(message.author.roles) if message.content.endswith('.gif'):
channel = functions.checkchannel(message.channel.id) is_admin = message.author.guild_permissions.administrator
if channel is True: is_high_risk_channel = self.check_channel(message.channel.id)
if roles is not True: embed_url = message.content
url = message.content embed = self.e.set_image(url=embed_url)
if is_high_risk_channel and not is_admin:
await message.channel.send(embed=embed)
logline = (str(message.author) + ' requested a gif: ' + str(embed_url))
log.info(logline)
if 'https://youtu' in message.content or 'https://m.youtu' in message.content or 'https://www.youtu' in message.content:
is_admin = message.author.guild_permissions.administrator
is_high_risk_channel = self.check_channel(message.channel.id)
if is_high_risk_channel and not is_admin:
url = message.content
try:
youtube = pytube.YouTube(url) youtube = pytube.YouTube(url)
video_title = youtube.title video_title = youtube.title
video_author = youtube.author video_author = youtube.author
@@ -71,12 +76,19 @@ class Preview(commands.Cog):
if video_id: if video_id:
embed = discord.Embed() embed = discord.Embed()
embed.set_image(url=f"https://img.youtube.com/vi/{video_id}/hqdefault.jpg") embed.set_image(url=f"https://img.youtube.com/vi/{video_id}/hqdefault.jpg")
embed.set_author(name=f"{video_author}") embed.set_author(name=video_author)
embed.add_field(name=f"", value=f"[{video_title}]({url})") embed.add_field(name="", value=f"[{video_title}]({url})")
await message.channel.send(embed=embed) await message.channel.send(embed=embed)
log.info(f'User {message.author} requested preview for {url}') log.info(f'User {message.author} requested preview for {url}')
except (VideoUnavailable, ExtractError, KeyError) as e:
log.error(f'Error extracting YouTube video details for {url}: {e}')
await message.channel.send('Sorry, there was an error retrieving the YouTube video details.')
def check_channel(self, channel_id):
high_risk_channels = env.PREVIEWCHANNELS
return channel_id in high_risk_channels
def extract_video_id(self, url): def extract_video_id(self, url):
try: try:
match = self.video_id_regex.search(url) match = self.video_id_regex.search(url)

41
cogs/reminders.py Normal file
View File

@@ -0,0 +1,41 @@
import discord
from discord.ext import commands
from jeevesbot import env
import datetime
from jeevesbot.database import add_reminder
from logging import getLogger
# setup logging
log = getLogger(__name__)
class Reminders(commands.Cog):
""" Reminder command"""
def __init__(self, bot):
self.bot = bot
@discord.app_commands.command(name='remindme', description='Set a reminder - Use YY-MM-DD HH:MM:SS notation')
@discord.app_commands.guilds(discord.Object(id=env.GUILD_ID))
async def remindme(self, interaction: discord.Interaction, time: str, message: str):
try:
reminder_time = datetime.datetime.strptime(time, '%Y-%m-%d %H:%M:%S')
add_reminder(interaction.user.id, message, reminder_time.isoformat())
await interaction.response.send_message(f'Reminder set for {reminder_time}')
log.info(f'Reminder set by {interaction.user} for {reminder_time}: {message}')
except ValueError:
await interaction.response.send_message('Invalid time format. Use YYYY-MM-DD HH:MM:SS', ephemeral=True)
log.warn(f'Reminder set by {interaction.user} went wrong.')
@commands.Cog.listener()
async def on_ready(self):
log.info(f'module active')
async def setup(bot):
await bot.add_cog(Reminders(bot))
log.info(f'Added Reminders.remindme as command')

View File

@@ -3,9 +3,6 @@
`!roll <xdx>` `!roll <xdx>`
Rolt dobbelstenen voor je! De standaard notatie is xdx, maar ook ingewikkelde rolls zijn mogelijk. Zie `!info` voor meer informatie. Rolt dobbelstenen voor je! De standaard notatie is xdx, maar ook ingewikkelde rolls zijn mogelijk. Zie `!info` voor meer informatie.
`!bingo`
Maakt een Babbelbingo kaart voor je aan. Deze optie wordt doorgaans alleen aangezet tijdens digitale evenementen.
** Links ** ** Links **
`!youtube` `!youtube`
`!donatie` `!donatie`
@@ -14,4 +11,4 @@
`!organisaties` `!organisaties`
** Misc ** ** Misc **
`!eirik` `!eirik`

View File

@@ -3,9 +3,6 @@
Om te voorkomen dat mensen een linkje posten die direct een confronterende preview kan geven, staan embeds uit in sommige kanalen waar daar meer kans op is. Om te voorkomen dat mensen een linkje posten die direct een confronterende preview kan geven, staan embeds uit in sommige kanalen waar daar meer kans op is.
Dit zorgt er helaas wel voor dat GIFjes in die kanalen niet werken. Door Jeeves is het toch mogelijk om het GIFje te laten zien, zonder dat confronterende previews van links er ook zijn. Dit zorgt er helaas wel voor dat GIFjes in die kanalen niet werken. Door Jeeves is het toch mogelijk om het GIFje te laten zien, zonder dat confronterende previews van links er ook zijn.
** Flair **
In het #rollen kanaal staat een bericht met daar onder emoji. Als je een voornaamwoord of andere flair rol in je account wil hebben, kun je op de emoji klikken en dan krijg je de rol automatisch.
** Extra informatie voor het !roll commando ** ** Extra informatie voor het !roll commando **
- Simpele rolls - Simpele rolls

112
jeeves.py
View File

@@ -1,66 +1,108 @@
#!/usr/bin/env python3.8 #!/usr/bin/env python3.8
import discord import discord
from discord.ext import commands from discord.ext import commands, tasks
from jeevesbot import env from jeevesbot import env
from jeevesbot.database import init_db, get_due_reminders
import os import os
import log import log
import logging.config import logging.config
from logging import getLogger from logging import getLogger
import datetime
import asyncio import asyncio
# setup root logger handlers # Initialize the database
logging.config.dictConfig(log.LOGGING) init_db()
# setup logging # setup logging
logging.config.dictConfig(log.LOGGING)
log = getLogger(__name__) log = getLogger(__name__)
# setup discord.py bot # setup discord.py bot
intents = discord.Intents().all() intents = discord.Intents().all()
bot = commands.Bot(command_prefix='!', intents=intents, help_command=None) intents.message_content = True
e = discord.Embed() e = discord.Embed()
class Jeeves(commands.Bot):
@bot.command(name='load', hidden=True) def __init__(self):
@commands.has_permissions(administrator=True) super().__init__(command_prefix='!', intents=intents, help_command=None)
async def load(ctx, extension): self.guild_ids = [env.GUILD_ID]
bot.load_extension(f'cogs.{extension}')
log.info(f'{ctx.message.author} loaded the {extension} module')
@bot.command(name='unload', hidden=True) @commands.command(name='load', hidden=True)
@commands.has_permissions(administrator=True) @commands.has_permissions(administrator=True)
async def unload(ctx, extension): async def load(self, ctx, extension):
bot.unload_extension(f'cogs.{extension}') self.load_extension(f'cogs.{extension}')
log.info(f'{ctx.message.author} unloaded the {extension} module') log.info(f'{ctx.message.author} loaded the {extension} module')
@bot.command(name='reload', hidden=True) @commands.command(name='unload', hidden=True)
@commands.has_permissions(administrator=True) @commands.has_permissions(administrator=True)
async def reload(ctx, extension): async def unload(self, ctx, extension):
bot.unload_extension(f'cogs.{extension}') self.unload_extension(f'cogs.{extension}')
bot.load_extension(f'cogs.{extension}') log.info(f'{ctx.message.author} unloaded the {extension} module')
log.info(f'{ctx.message.author} reloaded the {extension} module')
async def load_extensions(): @commands.command(name='reload', hidden=True)
for filename in os.listdir('./cogs'): @commands.has_permissions(administrator=True)
if filename.endswith('.py'): async def reload(self, ctx, extension):
await bot.load_extension(f'cogs.{filename[:-3]}') self.unload_extension(f'cogs.{extension}')
self.load_extension(f'cogs.{extension}')
log.info(f'{ctx.message.author} reloaded the {extension} module')
@bot.event async def load_extensions(self):
async def on_ready(): for filename in os.listdir('./cogs'):
log.info(f'Active with ID:{bot.user.id} as {bot.user.name}') if filename.endswith('.py'):
activity = discord.Activity(name='!help', type=discord.ActivityType.listening) await self.load_extension(f'cogs.{filename[:-3]}')
await bot.change_presence(activity=activity)
@tasks.loop(seconds=60)
async def check_reminders(self):
now = datetime.datetime.now().isoformat()
reminders = get_due_reminders(now)
for reminder in reminders:
user = self.get_user(reminder[1])
if user:
try:
await user.send(reminder[2])
except Exception as e:
log.error(f'Error sending reminder to user {reminder[1]}: {e}')
async def on_ready(self):
log.info(f'Active with ID:{self.user.id} as {self.user.name}')
activity = discord.Activity(name='!help', type=discord.ActivityType.listening)
await self.change_presence(activity=activity)
# Sync commands for all guilds
for guild_id in self.guild_ids:
guild = discord.Object(id=guild_id)
try:
await self.tree.sync(guild=guild)
log.info(f'Successfully synced commands for guild {guild_id}')
except discord.errors.Forbidden as e:
log.error(f'Failed to sync commands for guild {guild_id}: {e}')
# Start the reminder check loop
if not self.check_reminders.is_running():
self.check_reminders.start()
async def on_command_error(self, ctx, error):
if isinstance(error, commands.CommandNotFound):
await ctx.send('Command not found.')
log.warning(f'Command not found: {ctx.message.content}')
else:
await ctx.send('An error occurred.')
log.error(f'An error occurred: {error}')
async def main(): async def main():
async with bot: bot = Jeeves()
await load_extensions() await bot.load_extensions()
await bot.start(env.TOKEN) await bot.start(env.TOKEN)
if __name__ == "__main__":
asyncio.run(main()) asyncio.run(main())

View File

@@ -1,84 +0,0 @@
#!/usr/bin/env python3
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import random
from PIL import Image, ImageFont, ImageDraw
import textwrap
# setup gspread
scope = ['https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive']
creds = ServiceAccountCredentials.from_json_keyfile_name('jeevesbot/secret.json', scope)
gclient = gspread.authorize(creds)
# load babbelbingofile
def babbelbingo_file():
file = gclient.open_by_key("1zdWl17fhdT2P96ZgjSwB_2wsCHi_ZVA42JroX5d1ylc")
babbelbingo = file.get_worksheet(1)
values = babbelbingo.get_all_values()
list_values = [item for sublist in values for item in sublist]
questions = random.sample(list_values, k=24)
return questions
def make_bingocard(name, questions):
image = Image.open('jeevesbot/files/bingokaart.png')
font_name = ImageFont.truetype('jeevesbot/files/Overpass-Regular.ttf', 13)
draw = ImageDraw.Draw(image)
wrapper = textwrap.TextWrapper(width=20, break_on_hyphens=True)
box01 = '\n'.join(wrapper.wrap(questions[0]))
box02 = '\n'.join(wrapper.wrap(questions[1]))
box03 = '\n'.join(wrapper.wrap(questions[2]))
box04 = '\n'.join(wrapper.wrap(questions[3]))
box05 = '\n'.join(wrapper.wrap(questions[4]))
box06 = '\n'.join(wrapper.wrap(questions[5]))
box07 = '\n'.join(wrapper.wrap(questions[6]))
box08 = '\n'.join(wrapper.wrap(questions[7]))
box09 = '\n'.join(wrapper.wrap(questions[8]))
box10 = '\n'.join(wrapper.wrap(questions[9]))
box11 = '\n'.join(wrapper.wrap(questions[10]))
box12 = '\n'.join(wrapper.wrap(questions[11]))
box13 = '\n'.join(wrapper.wrap(questions[12]))
box14 = '\n'.join(wrapper.wrap(questions[13]))
box15 = '\n'.join(wrapper.wrap(questions[14]))
box16 = '\n'.join(wrapper.wrap(questions[15]))
box17 = '\n'.join(wrapper.wrap(questions[16]))
box18 = '\n'.join(wrapper.wrap(questions[17]))
box19 = '\n'.join(wrapper.wrap(questions[18]))
box20 = '\n'.join(wrapper.wrap(questions[19]))
box21 = '\n'.join(wrapper.wrap(questions[20]))
box22 = '\n'.join(wrapper.wrap(questions[21]))
box23 = '\n'.join(wrapper.wrap(questions[22]))
box24 = '\n'.join(wrapper.wrap(questions[23]))
draw.multiline_text((95, 280.5), box01, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((229, 280.5), box02, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((363, 280.5), box03, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((497, 280.5), box04, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((631, 280.5), box05, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((95, 399.5), box06, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((229, 399.5), box07, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((363, 399.5), box08, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((497, 399.5), box09, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((631, 399.5), box10, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((95, 518.5), box11, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((229, 518.5), box12, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((497, 518.5), box13, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((631, 518.5), box14, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((95, 637.5), box15, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((229, 637.5), box16, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((363, 637.5), box17, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((497, 637.5), box18, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((631, 637.5), box19, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((95, 756.5), box20, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((229, 756.5), box21, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((363, 756.5), box22, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((497, 756.5), box23, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
draw.multiline_text((631, 756.5), box24, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8)
table = str.maketrans({'(':None, ')':None, '/':None, ' ':'_'})
image.save('jeevesbot/files/generated_bingocards/' + str(name).translate(table) + '.png')
def bingo(name):
questions = babbelbingo_file()
make_bingocard(name, questions)
table = str.maketrans({'(':None, ')':None, '/':None, ' ':'_'})
bingoimage = ('jeevesbot/files/generated_bingocards/' + str(name).translate(table) + '.png')
return bingoimage

34
jeevesbot/database.py Normal file
View File

@@ -0,0 +1,34 @@
#!/usr/bin/env python3
import sqlite3
def init_db():
conn = sqlite3.connect(r"jeevesbot/databases/reminders.db")
c = conn.cursor()
c.execute('''
CREATE TABLE IF NOT EXISTS reminders (
id INTEGER PRIMARY KEY,
user_id INTEGER,
message TEXT,
reminder_time TIMESTAMP
)
''')
conn.commit()
conn.close()
def add_reminder(user_id, message, reminder_time):
conn = sqlite3.connect(r"jeevesbot/databases/reminders.db")
c = conn.cursor()
c.execute('INSERT INTO reminders (user_id, message, reminder_time) VALUES (?, ?, ?)', (user_id, message, reminder_time))
conn.commit()
conn.close()
def get_due_reminders(current_time):
conn = sqlite3.connect(r"jeevesbot/databases/reminders.db")
c = conn.cursor()
c.execute('SELECT id, user_id, message FROM reminders WHERE reminder_time <= ?', (current_time,))
reminders = c.fetchall()
c.execute('DELETE FROM reminders WHERE reminder_time <= ?', (current_time,))
conn.commit()
conn.close()
return reminders

View File

@@ -2,7 +2,5 @@
TOKEN = 'discord-bot-token-here' TOKEN = 'discord-bot-token-here'
ADMIN_ROLE = 'role-to-exclude-from-gifbot' ADMIN_ROLE = 'role-to-exclude-from-gifbot'
PREVIEWCHANNELS = [add-channel-ids-for-bot-to-work-in] GUILD_ID = 'id-of-guild'
BOTCHANNEL = [add id of bot channel] PREVIEWCHANNELS = ['add-channel-ids-for-bot-to-work-in']
FLAIRROLES = [add list of role ids to correspond to the emoji]
FLAIRROLE = [add id of flair separator role]

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

View File

@@ -17,6 +17,7 @@ def roll(notation):
result = int(roll) result = int(roll)
return roll,result return roll,result
<<<<<<< HEAD
# check if user has admin role and output True if it's the case. # check if user has admin role and output True if it's the case.
def checkrole(roles): def checkrole(roles):
for role in roles: for role in roles:
@@ -30,3 +31,5 @@ def checkchannel(channelid):
else: else:
return False return False
=======
>>>>>>> d194332843b93f36e724aeca0dcd41c96a10ae95

View File

@@ -2,16 +2,14 @@
aiohttp aiohttp
async-timeout async-timeout
dice dice
discord.py discord.py[voice]
docopt docopt
multidict multidict
pyparsing pyparsing
typing-extensions typing-extensions
pylint pylint
gspread
oauth2client
Pillow
pytube pytube
sqlite3
# needs this version, otherwise TypeErrors will break stuff # needs this version, otherwise TypeErrors will break stuff
yarl==1.4.2 yarl==1.4.2

View File

@@ -1,85 +0,0 @@
#!/usr/bin/env python3
import time
import discord
from discord.ext import commands
import sys
import ast
from ..jeevesbot import env
## Standalone script for emoji-vvdd
# setup discord.py bot
intents = discord.Intents().all()
client = commands.Bot(command_prefix='!', intents=intents)
if len(sys.argv) >= 2:
params = sys.argv[1:]
else:
print("Missing parameter input.")
async def score(question, score):
e = discord.Embed(title='Emoji-VVDD', color=discord.Color.green())
e.set_author(name='Jeeves', icon_url='https://cdn.hippogrief.nl/jeevesbot/jeeves.jpg')
e.add_field(name=question, value='\u200b', inline=False)
e.add_field(name='Hoogste score:', value=score, inline=False)
e.set_thumbnail(url='https://cdn.hippogrief.nl/jeevesbot/logo.jpg')
return score
async def run_script(params):
params = params
channel = client.get_channel(729667183126511617) # vvdd 729667183126511617 # tech 790908319005933598 # test 749399756752814105
emoji_numbers = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
question = params[0] # string
answers = ast.literal_eval(params[1]) # list
number_of_responses = len(answers) # int
e = discord.Embed(title='Emoji-VVDD', description='Klik de emoji beneden dit bericht om te stemmen op het antwoord wat bij de emoji hoort.', color=discord.Color.blue())
e.set_author(name='Jeeves', icon_url='https://cdn.hippogrief.nl/jeevesbot/jeeves.jpg')
e.add_field(name=question, value='\u200b', inline=False)
for emoji, answer in zip(emoji_numbers, answers):
e.add_field(name=emoji, value=answer, inline=False)
e.set_thumbnail(url='https://cdn.hippogrief.nl/jeevesbot/logo.jpg')
message = await channel.send(embed=e)
for i in range(number_of_responses):
await message.add_reaction(emoji_numbers[i])
for i in range(24, -1, -1):
time.sleep(60)
message = await channel.fetch_message(message.id)
values = {}
for i in message.reactions:
itervalues = {str(i): int(i.count)}
values.update(itervalues)
max_key = max(values, key=values.get)
all_values = values.values()
max_value = max(all_values)
highest_keys = [key for key in values if values[key] == max_value]
if len(highest_keys) == 1:
max_key = highest_keys[0]
hoogste_score = 'Hoogste score:'
elif len(highest_keys) != 1:
max_key = highest_keys
print(max_key)
hoogste_score = 'Gelijkspel tussen:'
score = (str(max_key) + ' met ' + str(max_value) + ' stemmen.')
f = discord.Embed(title='Emoji-VVDD', color=discord.Color.green())
f.set_author(name='Jeeves', icon_url='https://cdn.hippogrief.nl/jeevesbot/jeeves.jpg')
f.add_field(name=question, value='\u200b', inline=False)
f.add_field(name=hoogste_score, value=score, inline=False)
f.set_footer(text="Je mag blijven doorstemmen, deze tussenstand zal niet worden bijgewerkt meer verder.")
f.set_thumbnail(url='https://cdn.hippogrief.nl/jeevesbot/logo.jpg')
message = await channel.send(embed=f)
await client.close()
@client.event
async def on_ready():
print('### Active with id %s as %s ###' % (client.user.id,client.user.name) )
activity = discord.Activity(name='!help', type=discord.ActivityType.listening)
await client.change_presence(activity=activity)
await run_script(params)
if __name__ == '__main__':
client.run(env.TOKEN)