This repository has been archived on 2023-07-12. You can view files and clone it, but cannot push or open issues or pull requests.
kaizen-bot-old/kaizenbot/commands.py

680 lines
36 KiB
Python
Raw Normal View History

2022-04-20 23:41:25 +02:00
import asyncio
from copy import copy
import datetime
import discord
from discord.ext import commands, menus
from pathlib import Path
import os
import random
import re
import requests
import signal
import tempfile
import time
from typing import List, Optional
from . import logger, glob
from . import flags
from .utils import Embeds, MenuListPageSource, role_names
class Chat(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.flag_parser = flags.Flag(raise_errors=False)
self.flag_parser.add_flag('--all',
store_type=flags.StoreType.store_bool,
allowed_roles=['Mod'],
not_allowed_role_message='Nur Mods können die `{flag}` flag benutzen',
wrong_store_type_message='Die `{flag}` flag darf keinen parameter haben',
show_help=False)
self.flag_parser.add_flag('--limit',
store_type=(flags.StoreType.store_value, 100),
parser=self._parse_history,
wrong_store_type_message='Die {flag} muss eine Zahl als parameter haben',
help='')
async def _parse_history(self, ctx: commands.Context, flag, value):
try:
return int(value)
except ValueError:
await ctx.send(f'Der parameter der `{flag}` muss eine Zahl sein')
return False
@commands.command(name='export', ignore_extra=False,
usage='export [flags]', help='Exportiert den Chat',
flags='flag_parser')
async def history(self, ctx: commands.Context, *, args):
parsed = await self.flag_parser.parse(args, ctx=ctx)
pass
# ADDED AFTERWARS: This never was really active in use
class Economy(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.cooldown = {}
self.cooldown_date = datetime.datetime.now()
self.shop_items = {
'color': [10000, self.bot.database.set_user_color_count, 'Nachrichten Farbe', True, 'Setzt die Farbe die rechts bei den Bot Nachrichten, die von <@!802659482693926943> kommen'],
'extra vote': [150, self.bot.database.set_user_extra_vote, 'Extra Vote', False, 'Kann eine Umfrage starten, selbst wenn man normalerweise noch Umfrage cooldown hätte']
}
@commands.command(name='buy', aliases=['b'], usage='buy <zu kaufendes item>', help='Kauft ein Shop Item. Tippe `$shop` um alle verfügbaren Items zu sehen')
async def buy(self, ctx: commands.Context, *item):
await ctx.send(embed=Embeds.error_embed(description='Der Befehl steht wegen bearbeitung temporär nicht zur Verfügung'))
return
to_buy = ' '.join(item)
if values := self.shop_items.get(to_buy, None):
if self.bot.database.has_remove_user_gold(ctx.author.id, values[0]):
embed = discord.Embed(title='Item kauf')
embed.add_field(name=values[2], value=f'*{values[4]}*\n\n'
f'<@!{ctx.author.id}> erhält:\n'
f'```diff\n'
f'+1 {values[2]}'
f'```\n'
f'<@!{ctx.author.id}> bezahlt:\n'
f'```diff\n'
f'- {values[0]} Gold\n'
f'```')
message = await ctx.send(embed=embed)
await message.add_reaction('')
await message.add_reaction('')
def check(reaction: discord.Reaction, user):
return user.id == ctx.author.id and reaction.message.id == message.id and str(reaction.emoji) in ['', '']
try:
reaction, user = await self.bot.wait_for('reaction_add', timeout=30, check=check)
if reaction.emoji == '':
embed.colour = 0xff0000
msg = 'Der Kauf wurde abgebrochen'
elif reaction.emoji == '':
values[1](ctx.author.id, 1)
embed.colour = 0x00ff00
msg = f'**{values[2]}** wurde gekauft{f". Tippe `$use {to_buy}` um das Item zu benutzen!" if values[3] else "!"}'
else:
msg = 'Hackerman hat den Bot überlistet, weshalb diese Nachricht erscheint, die eigentlich niemals hätte erscheinen dürfen'
embed.clear_fields()
embed.add_field(name=values[2], value=f'*{values[4]}*\n\n'
f'<@!{ctx.author.id}> erhält:\n'
f'```diff\n'
f'+1 {values[2]}'
f'```\n'
f'<@!{ctx.author.id}> bezahlt:\n'
f'```diff\n'
f'- {values[0]} Gold\n'
f'```\n'
f'{msg}')
await message.edit(embed=embed)
except asyncio.exceptions.TimeoutError:
pass
else:
await ctx.send(embed=Embeds.error_embed(description='Du hast nicht genügend Gold um dieses Item zu kaufen'))
else:
await ctx.send(embed=Embeds.error_embed(description=f'Es existiert kein Item mit dem Name `{to_buy}`'))
@commands.command(name='items', aliases=['i'], usage='items', help='Zeigt alle Items im besitzt an')
async def items(self, ctx: commands.Context, *, user_mention: str = None):
await ctx.send(embed=Embeds.error_embed(description='Der Befehl steht wegen bearbeitung temporär nicht zur Verfügung'))
return
id = ctx.author.id
if user_mention is not None:
regex_id = re.match(r'^<@(!)?(?P<id>\d{18})>', user_mention)
if regex_id:
id = regex_id.group('id')
else:
await Help(self.bot).show_help(ctx, ctx.command)
return
embeds = []
embed = discord.Embed(title='Items', description=f'Items von <@!{id}>')
embed.set_footer(text='Alle Items die mit 💫 beginnen können über `$use <item>` benutzt werden!')
for name, value in self.bot.database.get_user_items(id).items():
if len(embed.fields) >= 10:
embeds.append(embed)
embed = discord.Embed(title='Items', description=f'Items von <@!{id}>')
embed.set_footer(text='Alle Items die mit 💫 beginnen können über `$use <item>` benutzt werden!')
if name == 'gold':
embed.description += f'\n\n:moneybag: **{value}** *Gold*'
elif value > 0:
item = self.shop_items[name]
embed.description += f'\n{":dizzy:" if item[3] else ":sparkles:"} **{value}** · `{name}` · *{item[2]}*'
embeds.append(embed)
send_embeds = menus.MenuPages(source=MenuListPageSource(embeds), clear_reactions_after=True, timeout=30)
await send_embeds.start(ctx)
@commands.command(name='leaderboard', aliases=['l'], usage='leaderboard', help='Zeigt das Server Leaderboard an')
async def leaderboard(self, ctx: commands.Context):
await ctx.send(embed=Embeds.error_embed(description='Der Befehl steht wegen bearbeitung temporär nicht zur Verfügung'))
return
gold_leaderboard = discord.Embed(title='Gold Leaderboard', description='*Man kann alle 2 Minuten zwischen 5 und 15 Gold bekommen, wenn man in diesen Zeitabständen eine Nachricht schreibt. '
'Die gedroppte Gold Anzahl wird mit deinem Kaizen-Sub Level addiert (Server Booster gelten als Sub Level 2).\n'
'Also je aktiver, desto mehr Gold:moneybag:^^*')
gold_leaderboard.set_footer(text='Tippe `$shop` um dir anzusehen, was du alles kaufen kannst!')
gold_text = ''
for i, (id, gold) in enumerate(self.bot.database.get_leaderboard().items(), 1):
gold_text += f'\n{i}. - `{gold}` Gold · __**{(await self.bot.guild.fetch_member(id)).display_name}**__'
gold_leaderboard.add_field(name='Top 10', value=gold_text)
menu = menus.MenuPages(source=MenuListPageSource([gold_leaderboard]))
await menu.start(ctx)
@commands.command(name='shop', aliases=['s'], usage='shop', help='Zeigt alle Shop Elemente an')
async def shop(self, ctx: commands.Context):
await ctx.send(embed=Embeds.error_embed(description='Der Befehl steht wegen bearbeitung temporär nicht zur Verfügung'))
return
embeds = []
embed = discord.Embed(title='Show durchsuchen')
for name, item in self.shop_items.items():
if len(embed.fields) >= 10:
embeds.append(embed)
embed = discord.Embed(title='Show durchsuchen')
embed.add_field(name=item[2], value=f'*{item[4]}*\n'
f'```diff\n'
f'- {item[0]} Gold\n'
f'+ 1 {item[2]}\n'
f'> $buy {name}\n'
f'```', inline=False)
embeds.append(embed)
embeds = menus.MenuPages(source=MenuListPageSource(embeds), clear_reactions_after=True, timeout=30)
await embeds.start(ctx)
@commands.command(name='use', aliases=['u'], usage='use', help='Benutzt ein Item')
async def use(self, ctx: commands.Context, *args):
await ctx.send(embed=Embeds.error_embed(description='Der Befehl steht wegen bearbeitung temporär nicht zur Verfügung'))
return
pass
# --- #
@commands.Cog.listener()
@commands.guild_only()
async def on_message(self, message: discord.Message):
return
if not message.author.bot and message.channel.id not in [812436978809307156, # rank abfrage
822938804461502524, # offene daten
813135345725341736, # karuta
813886662841073684, # rin
813487848027193398]: # quiz erraten
now = time.time()
cooldown = self.cooldown.get(message.author.id, [0.0, 0])
if cooldown[1] < 120 and cooldown[0] + 120 < now:
cooldown[0] = now
cooldown[1] += 1
self.cooldown[message.author.id] = cooldown
gold = random.randint(5, 15)
roles = role_names(message.author)
if 'Kaizen-Sub: Level 3' in roles:
gold += 3
elif 'Kaizen-Sub: Level 2' in roles:
gold += 2
elif 'Kaizen-Sub: Level 1' in roles:
gold += 1
if 'Server Booster' in roles:
gold += 2
self.bot.database.add_user_gold(message.author.id, gold)
def reset(self):
for key in self.cooldown:
self.cooldown[key] = [0.0, 0]
# ADDED AFTERWARDS: I had the idea of implementing familiarly relationship and show it in a tree
# but this was never finished (not that I really started to try working on it)
class Family(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.command(name='tree', usage='tree', help='Zeigt den Familienstammbaum')
@commands.guild_only()
async def family_tree(self, ctx: commands.Context):
self.bot.database.get_user_parents(ctx.author.id)
def _family_tree(self, id: int) -> List[List[str]]:
parents = self.bot.database.get_user_parents()
if parents:
return [].extend()
else:
return [self.bot.guild.fetch_member(id).display_name]
class Mod(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.command(name='error', usage='error')
@commands.guild_only()
@commands.has_role('Mod')
async def error(self, ctx: commands.Context):
logger.info('NOTICE: Raising controlled exception...')
raise Exception('Exception raised by the error command')
@commands.command(name='restart', usage='restart')
@commands.guild_only()
@commands.has_role('Mod')
async def restart(self, ctx: commands.Context):
for thread in glob['timers']:
thread.cancel()
logger.info('Restarting...')
os.kill(os.getpid(), signal.SIGKILL)
@commands.command(name='transcript', usage='transcript', help='Schickt eine Datei mit dem gesamten Nachrichtenverlauf der letzten Stunde')
@commands.guild_only()
@commands.has_role('Mod')
async def transcript(self, ctx: commands.Context):
tmp = tempfile.mktemp('.txt')
with open(tmp, 'w+') as file:
for message in glob['transcript'].values():
file.write(message + '\n')
file.close()
await ctx.send(file=discord.File(tmp, 'transcript.txt'))
os.remove(tmp)
class Help(commands.Cog):
def __init__(self, bot):
self.bot = bot
async def show_help(self, ctx: commands.Context, command: commands.Command):
embed = discord.Embed(title=f'`{command.name}` command\n\n', color=discord.Color(0xff0000))
embed.set_footer(text='<...> - required; [...] - optional; <...|...> - or\nDo NOT include <>, [] or | when executing the command')
embed.add_field(name='Usage', value=f'`{self.bot.command_prefix}{command.usage}`', inline=False)
embed.add_field(name='Description', value=command.help, inline=False)
if command_flags := flags.get_flags(command):
all_flags = {}
for flag, info in command_flags.flags().items():
if info['show_help']:
hash_sum = hash(str(info))
if hash_sum not in all_flags:
all_flags[hash_sum] = copy(info)
all_flags[hash_sum]['names'] = [flag]
else:
all_flags[hash_sum]['names'].append(flag)
embed.add_field(name='Flags', value='\n'.join([f'• `{"`, `".join(flag["names"])}` - {flag["help"].format(flag=flag["names"][0])}' for flag in all_flags.values()]), inline=False)
await ctx.send(embed=embed)
@commands.command(name='commands', usage='commands', description='Liste alle verfügbaren Befehle auf')
async def cmds(self, ctx: commands.Context):
commands = {command.name: command for command in self.bot.commands}
groups = {'default': []}
for command in sorted(commands):
if hasattr(command, 'group'):
if command.group not in groups:
groups[command.group] = []
groups[command.group].append(commands[command])
new_line = '\n'
embed = discord.Embed(title='Commands', description=f'Um Hilfe zu einem bestimmten Befehl zu bekommen, tippe `{self.bot.command_prefix}help [command]`',
color=discord.Color(0xff0000))
for group_name, group in groups.items():
embed.add_field(name=group_name, value=f'```• {f"{new_line}".join([self.bot.command_prefix + command.usage for command in group])}```', inline=False)
await ctx.send(embed=embed)
@commands.command(name='help', usage='help [command]', description='Zeigt Hilfe an')
async def help(self, ctx: commands.Context, command: Optional[str]):
if command:
if cmd := self.bot.get_command(command):
await self.show_help(ctx, cmd)
else:
embed = discord.Embed(title=f'{self.bot.user.name} help', description=f'Der Befehl {command} existiert nicht!', color=discord.Color(0xff0000))
embed.add_field(name='Get help', value=f'Um Hilfe zu einem bestimmten Befehl zu bekommen, tippe `{self.bot.command_prefix}help [command]`', inline=False)
embed.add_field(name='Commands', value=f'Tippe `{self.bot.command_prefix}commands`, um eine Liste mit allen Befehlen zu bekommen', inline=False)
embed.set_footer(text='<...> - required; [...] - optional; <...|...> - or\nDo NOT include <>, [] or | when executing the command')
await ctx.send(embed=embed)
else:
embed = discord.Embed(title=f'{self.bot.user.name} help', color=discord.Color(0xff0000))
embed.add_field(name='Get help', value=f'Um Hilfe zu einem bestimmten Befehl zu bekommen, tippe `{self.bot.command_prefix}help [command]`', inline=False)
embed.add_field(name='Commands', value=f'Tippe `{self.bot.command_prefix}commands`, um eine Liste mit allen Befehlen zu bekommen', inline=False)
embed.set_footer(text='<...> - required; [...] - optional; <...|...> - or\nDo NOT include <>, [] or | when executing the command')
await ctx.send(embed=embed)
class Info(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.flag_parser = flags.Flag()
@commands.command(name='info', usage='info [@user]', help='Zeigt Infos über einen Nutzer an')
@commands.guild_only()
async def info(self, ctx: commands.Context, *, user_mention: str = None):
id = ctx.author.id
if user_mention is not None:
regex_id = re.match(r'^<@(!)?(?P<id>\d{18})>', user_mention)
if regex_id:
id = regex_id.group('id')
else:
await Help(self.bot).show_help(ctx, ctx.command)
return
if (infos := self.bot.database.get_user_infos(id)) is None:
await ctx.send(embed=Embeds.error_embed(description="Der Nutzer existiert nicht"))
return
else:
member = await self.bot.guild.fetch_member(int(id))
name = member.display_name if member.display_name.lower().endswith(('s', 'z')) else member.display_name + "'s"
embed = discord.Embed(title=name + " Infos", color=member.roles[-1].color)
embed.set_thumbnail(url=member.avatar_url)
embed.set_footer(text='Tippe `$help addinfo` um zu sehen, was für Infos noch hinzugefügt / geändert werden können')
for key, value in infos.items():
if value is not None:
embed.add_field(name=key, value=value, inline=False)
if len(embed.fields) == 0:
embed.description = "Es wurden noch keine Infos eingetragen"
await ctx.send(embed=embed)
@commands.command(name='addinfo', aliases=['infoadd'], usage='addinfo <name, age | list | fav | waifu | husbando> <name, alter, link zu einer anime liste, lieblings anime, waifu, husbando>',
help='Fügt den Namen / das Alter / eine Anime Liste / einen Lieblings Anime / eine Waifu / ein Husbando zu einem Nutzer hinzu.\n\n'
'Tippe `$help removeinfo` um Infos wieder zu entfernen')
@commands.guild_only()
async def infoadd(self, ctx: commands.Context, info_type: str, *info_value):
if info_type.lower() == 'name':
self.bot.database.set_user_name(ctx.author.id, ' '.join(info_value))
await ctx.send(embed=Embeds.success_embed(description=f'Name (__{" ".join(info_value)}__) wurde hinzugefügt'))
elif info_type.lower() == 'age':
try:
age = int(info_value[0])
except ValueError:
await ctx.send(embed=Embeds.error_embed(description='`age` sollte eine Zahl sein'))
return
if age < 0:
await ctx.send(embed=Embeds.error_embed(description='Hmmm noch nie von einer Person gehört die minus Jahre alt ist'))
return
elif age > 99:
await ctx.send(embed=Embeds.error_embed(description='Uff, bei so einem hohen Alter komm selbst ich in Bedrängnis und kann es nicht zu deinen Infos hinzufügen :/'))
return
self.bot.database.set_user_age(ctx.author.id, age)
# ADDED AFTERWARDS: hehe
if age == 69:
embed = Embeds.success_embed(title='Alter wurde hinzugefügt')
embed.description = 'Ah, I see you\'re a man of culture as well'
embed.set_thumbnail(url='attachment://man_of_culture.jpg')
await ctx.send(embed=embed, file=discord.File(Path.cwd().joinpath('assets', 'man_of_culture.jpg')))
else:
await ctx.send(embed=Embeds.success_embed(description=f'Alter __{age}__ wurde hinzugefügt'))
elif info_type.lower() == 'list':
try:
requests.get(info_value[0])
except Exception:
await ctx.send(embed=Embeds.error_embed(description='Ich konnte mich nicht mit der gegeben URL verbinden'))
return
self.bot.database.set_user_list(ctx.author.id, info_value[0])
await ctx.send(embed=Embeds.success_embed(description='Anime Liste wurde hinzugefügt'))
elif info_type.lower() == 'fav':
self.bot.database.set_user_fav(ctx.author.id, ' '.join(info_value))
await ctx.send(embed=Embeds.success_embed(description=f'Lieblings Anime (__{" ".join(info_value)}__) wurde hinzugefügt'))
elif info_type.lower() == 'waifu':
self.bot.database.set_user_waifu(ctx.author.id, ' '.join(info_value))
await ctx.send(embed=Embeds.success_embed(description=f'Waifu (__{" ".join(info_value)}__) wurde hinzugefügt'))
elif info_type.lower() == 'husbando':
self.bot.database.set_user_husbando(ctx.author.id, ' '.join(info_value))
await ctx.send(embed=Embeds.success_embed(description=f'Husbando (__{" ".join(info_value)}__) wurde hinzugefügt'))
else:
await Help(self.bot).show_help(ctx, ctx.command)
@commands.command(name='removeinfo', aliases=['inforemove'], usage='removeinfo <name, age | list | fav | waifu | husbando>',
help='Entfernt Name / Alter / Anime Liste / lieblings Anime / Waifu / Husbando von einem Nutzer.\n\n'
'Tippe `$help addinfo` um Infos hinzuzufügen')
@commands.guild_only()
async def inforemove(self, ctx: commands.Context, info_type: str):
if info_type.lower() == 'name':
self.bot.database.set_user_name(ctx.author.id, None)
await ctx.send(embed=Embeds.success_embed(description='Name wurde entfernt'))
elif info_type.lower() == 'age':
self.bot.database.set_user_age(ctx.author.id, None)
await ctx.send(embed=Embeds.success_embed(description='Alter wurde entfernt'))
elif info_type.lower() == "list":
self.bot.database.set_user_list(ctx.author.id, None)
await ctx.send(embed=Embeds.success_embed(description='Anime Liste wurde entfernt'))
elif info_type.lower() == "fav":
self.bot.database.set_user_fav(ctx.author.id, None)
await ctx.send(embed=Embeds.success_embed(description='Lieblings Anime wurde entfernt'))
elif info_type.lower() == "waifu":
self.bot.database.set_user_waifu(ctx.author.id, None)
await ctx.send(embed=Embeds.success_embed(description='Waifu wurde entfernt'))
elif info_type.lower() == "husbando":
self.bot.database.set_user_husbando(ctx.author.id, None)
await ctx.send(embed=Embeds.success_embed(description='Husbando wurde entfernt'))
else:
await Help(self.bot).show_help(ctx, ctx.command)
class Kaizen(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.command(name='kaizen', usage='kaizen', help='Alle Links zu den Social Media Kanälen von Kaizen')
async def links(self, ctx: commands.Context):
await Embeds.send_kaizen_infos(ctx)
class Vote(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.total_votes = []
self.next_normal_time = datetime.datetime.now()
self.sub_or_booster_time = {}
self.number_emojis = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '🔟']
self.flag_parser = flags.Flag(raise_errors=False,
double_flag_error='Die flag `{flag}` wurde schon gegeben',
flag_position_error='Flags müssen als letztes aufgerufen werden',
quotation_error='Es fehlen ein oder mehrere Anführungszeichen (`"` oder `\'`)')
self.flag_parser.add_flag('--duration',
store_type=(flags.StoreType.store_value, 60*5),
parser=self._duration_parser,
allowed_roles=['Mod', 'Server Booster', 'Kaizen-Sub'],
not_allowed_role_message='Nur Nutzer, die Server Booster oder Twich-Sub von Kaizen sind, können die `{flag}` flag benutzen!',
wrong_store_type_message='Die `{flag}` flag muss eine Zeitangabe haben (z.B. `{flag}=12m21s`)',
help='Zeit, bis das Ergebnis bekanntgegeben werden soll. Ist nur für Server Booster und Kaizen Twitch Subs verfügbar! (z.B. {flag}=12m21s)')
self.flag_parser.add_flag('--image',
store_type=flags.StoreType.store_value,
wrong_store_type_message='Die `{flag}` flag muss einen URL zu einem Bild haben (z.B. `{flag}="https://bytedream.org/darling.jpg"`)',
help='Fügt ein extra Bild zur Umfrage hinzu. Bild muss als URL angegeben sein (z.B. {flag}=https://bytedream.org/darling.jpg)')
super().__init__()
async def _duration_parser(self, ctx: commands.Context, flag, value):
regex_time = re.match(r'^((?P<hour>\d*?)h)?((?P<min>\d*?)m)?((?P<sec>\d*?)s)?', str(value))
time = 0
if regex_time['hour']:
time += int(regex_time['hour']) * 60 * 60
if regex_time['min']:
time += int(regex_time['min']) * 60
if regex_time['sec']:
time += int(regex_time['sec'])
if time == 0:
await ctx.send(embed=Embeds.warn_embed(description=f'Die Zeit der `{flag}` flag sollte in Form von __12m21s__ oder __21m__ sein'))
return False
elif time > 60 * 60:
roles = role_names(ctx.author)
if 'Mod' not in roles and 'A&M Redakteur' not in roles:
await ctx.send(embed=Embeds.warn_embed(description=f'Die Gesamtzeit der `{flag}` flag kann höchstens 60 Minuten betragen!'))
return False
return time
@commands.command(name='vote', ignore_extra=False,
usage='vote "<title>" <2 bis 10 "Antwortmöglichkeiten"> [flags]', help='Startet eine Umfrage mit maximal 10 Antwortmöglichkeiten',
flags='flag_parser')
@commands.guild_only()
async def vote(self, ctx: commands.Context, *, args):
parsed = await self.flag_parser.parse(args, ctx=ctx)
if not parsed:
return
args = list(parsed.normal_args)
if len(args) == 0:
async with ctx.typing():
await asyncio.sleep(.7)
await ctx.send(embed=Embeds.error_embed(description=f'Syntax für den \'{self.bot.command_prefix}vote\':\n'
f'`{self.bot.command_prefix}vote [titel] [antwortmöglichkeiten] (dauer)`\n\n'
f'Argumente:\n'
f'`titel`: Titel der Umfrage ("Wie findet ihr Anime xy?")\n'
f'`antwortmöglichkeiten`: Bis zu zehn mögliche Antwortmöglichkeiten ("super" "ok" "schlecht")\n'
f'`dauer`: Zeit, bis das Ergebnis bekanntgegeben werden soll.\n\n'
f'Beispiel:\n'
f'`{self.bot.command_prefix}vote "Wie findet Ihr Anime xy?" "sehr gut" super ok schlecht "sehr schlecht" time=12m`\n\n'
f'Um Leerzeichen im Titel oder in den Antwortmöglichkeiten zu benutzen, die entsprechenden Dinge einfach mit Anführungszeichen (`"`) vorne und hinten versehen'))
return
elif len(args) <= 2:
await ctx.send(embed=Embeds.error_embed('Es müssen mindestens zwei Antwortmöglichkeit angegeben sein!'))
return
elif len(args) > 10 + 1: # the +1 is the title
await ctx.send(embed=Embeds.error_embed('Es können nur maximal 10 Antwortmöglichkeiten angegeben werden!'))
return
roles = role_names(ctx.author)
privileges = 'Mod' in roles or 'A&M Redakteur' in roles
booster = 'Server Booster' in roles
sub = 'Kaizen-Sub' in roles
now = datetime.datetime.now()
if len(self.total_votes) >= 3 and not privileges:
difference = divmod(min(self.total_votes) - now.timestamp(), 60)
await ctx.send(embed=Embeds.error_embed(description=f'Es können maximal 3 Umfragen gleichzeitig laufen. In {round(difference[0])} Minuten und {round(difference[1])} Sekunden kann wieder eine neue Umfrage gestartet werden.'))
return
# check for cooldown
if privileges:
pass
elif booster or sub:
if self.sub_or_booster_time.get(ctx.author.id, now - datetime.timedelta(hours=1)) < now:
self.sub_or_booster_time[ctx.author.id] = now + datetime.timedelta(minutes=15)
elif self.next_normal_time < now:
self.next_normal_time = now + datetime.timedelta(minutes=40)
elif self.bot.database.set_user_extra_vote(ctx.author.id, -1):
pass
else:
if (t := self.sub_or_booster_time[ctx.author.id]) < self.next_normal_time:
difference = divmod((t - now).total_seconds(), 60)
else:
difference = divmod((self.next_normal_time - now).total_seconds(), 60)
await ctx.send(embed=Embeds.error_embed(description=f'Du musst leider noch {round(difference[0])} Minuten und {round(difference[1])} Sekunden warten, bis du den Befehl erneut benutzen kannst.'))
return
elif self.next_normal_time < now:
self.next_normal_time = now + datetime.timedelta(minutes=40)
else:
difference = divmod((self.next_normal_time - now).total_seconds(), 60)
await ctx.send(embed=Embeds.error_embed(description=f'Du musst leider noch {round(difference[0])} Minuten und {round(difference[1])} Sekunden warten, du den Befehl erneut benutzen kannst.\n'
f'Werde Server Booster oder Twich-Sub, um die Wartezeit zu verringern!'))
return
# send the message embed
args[0] = args[0] if args[0].endswith('?') else args[0] + '?'
embed = discord.Embed(title=f'**{args[0]}**',
description='\n'.join([f'{self.number_emojis[i]}: {answer}' for i, answer in enumerate(args[1:])]),
color=ctx.author.roles[-1].color)
if parsed.image:
embed.set_thumbnail(url=parsed.image)
end_time = datetime.datetime.now() + datetime.timedelta(seconds=parsed.duration)
embed.set_footer(text=f'Umfrage endet am {end_time.strftime("%d.%m.%Y")} um ca. {end_time.strftime("%H:%M")} Uhr')
async with ctx.typing():
await asyncio.sleep(.5)
message = await ctx.send(embed=embed)
for i in range(len(args[1:])):
await message.add_reaction(self.number_emojis[i])
if parsed.pin:
await message.pin()
await ctx.message.delete()
last_mention_id = message.id
self.total_votes.append(end_time.timestamp())
walked = 0
for _ in range(0, (parsed.duration - 5) // (60 * 10)):
await asyncio.sleep(60 * 10)
is_fresh = False
async for old_message in ctx.channel.history(limit=10):
if old_message.id == last_mention_id:
is_fresh = True
break
if not is_fresh:
last_mention_id = (await message.reply(embed=discord.Embed(description=f'Es läuft aktuell eine Umfrage, stimmt doch zur Frage `{args[0]}` ab!',
color=embed.color))).id
walked += 60 * 10
await asyncio.sleep(parsed.duration - walked)
self.total_votes.remove(end_time.timestamp())
if parsed.pin:
await message.unpin()
reactions = []
users = []
for reaction in (await ctx.channel.fetch_message(message.id)).reactions:
reactions.append(reaction)
async for user in reaction.users():
if not user.bot and user.id not in users:
users.append(user.id)
embed = discord.Embed(title=f'**{args[0]}**',
description='\n'.join([f'{self.number_emojis[i]}: {answer} - {reactions[i].count - 1} {"Stimme" if reactions[i].count - 1 == 1 else "Stimmen"}' for i, answer in enumerate(args[1:])]),
color=embed.color)
if parsed.image:
embed.set_thumbnail(url=parsed.image)
now = datetime.datetime.now()
embed.set_footer(text=f'Umfrage endete am {now.strftime("%d.%m.%Y")} um {now.strftime("%H:%M:%S")} Uhr')
await message.clear_reactions()
await message.edit(embed=embed)
reaction_dict = {arg: count for arg, count in sorted({arg: reactions[i].count for i, arg in enumerate(args[1:])}.items(), key=lambda item: item[1], reverse=True)}
result_embed = discord.Embed(title=f'Umfrageergebnisse zu `{args[0]}`\n\n',
description='\n'.join([f'{i + 1}. {arg} - {count - 1} {"Stimme" if count - 1 == 1 else "Stimmen"}' for i, (arg, count) in enumerate(reaction_dict.items())]),
color=embed.color)
result_embed.description += f'\n\nInsgesamt mitgemacht: {len(users)}'
await ctx.send(embed=result_embed)
# ADDED AFTERWARDS: hehe pt. 2
class NSFW(commands.Cog):
def __init__(self, bot):
self.id = 796873618026004481
self.bot = bot
@commands.command(name='color', usage='color', help='Shows a random colored hentai image')
@commands.guild_only()
@commands.cooldown(1, 60 * 5, type=commands.BucketType.channel)
async def color(self, ctx: commands.Context):
if ctx.channel.id != self.id:
await ctx.send(embed=Embeds.error_embed(description='Dieser Befehl kann nur in <#796873618026004481> genutzt werden'))
else:
await ctx.send(file=discord.File(os.path.join('/srv/media/hentai/image', random.choice(os.listdir('/srv/media/hentai/image')))))
@commands.command(name='lewd', usage='lewd', help='Shows a random lewd')
@commands.guild_only()
@commands.cooldown(1, 60 * 5, type=commands.BucketType.channel)
async def lewd(self, ctx: commands.Context):
if ctx.channel.id != self.id:
await ctx.send(embed=Embeds.error_embed(description='Dieser Befehl kann nur in <#796873618026004481> genutzt werden'))
else:
page = random.randint(0, glob['twitter'].get_user('lewdxsthetic').statuses_count // 20)
await ctx.send(random.choice(glob['twitter'].user_timeline('lewdxsthetic', page=page, count=20))._json['entities']['media'][0]['media_url_https'])