async def dsgvodelete(self,ctx): await ctx.send("Dieser Befehl löscht alle Daten, die wir von dir gespeichert haben (aber nicht die Daten, die Discord Inc. von dir gespeichert hat, vgl. `\\dsgvo`). Du wirst dadurch von unserem Server entfernt, weil wir zur Identitätsfeststellung deinen Account mit deinem RHRK-Login verknüpfen müssen. Du wirst nicht mehr in der Lage sein, Nachrichten auf dem fünften Stock zu sehen oder zu verschicken.\n\nUm fortzufahren, schreibe innerhalb der nächsten 60 Sekunden eine Nachricht, die nur das Wort```ja```enthält. Deine Daten werden dann mit sofortiger Wirkung gelöscht. (Wenn du stattdessen irgendeine andere Nachricht schreibst, gehe ich davon aus, dass du dich gegen die Löschung entschieden hast.)") def check(m): return m.author == ctx.author and m.channel == ctx.channel msg = None try: msg = await self.bot.wait_for('message',check=check,timeout=60) except: await ctx.send("Ich habe den Löschvorgang abgebrochen.") else: if msg.content in ["ja","Ja","JA"]: await ctx.send("Mach es gut!") u = b5("user").get(ctx.author.id).inGuild() await b5("log").log("removed a user") await b5('ext').guild().kick(u,reason="Du hast die Löschung deiner Daten beantragt. Mach es gut!") b5("user").remove(ctx.author.id) try: b5("ext").reloadExtension("user") except Exception as e: await b5('log').log("Error reloading user extension!\n"+str(e)) else: await b5('log').log("Reloaded extension user.") else: await ctx.send("Ich habe den Löschvorgang abgebrochen.")
async def b5reload(self, ctx, ext): try: b5('ext').reloadExtension(ext) except Exception as e: await b5('log').log("reload " + ext + ": exception\n" + str(e)) else: await b5('log').log("reload " + ext + ": success")
async def b5forceunload(self, ctx, ext): try: b5('ext').unloadExtension(ext, force=True) except Exception as e: await b5('log').log("unload " + ext + ": exception\n" + str(e)) else: await b5('log').log("unload " + ext + ": success")
async def coffee(self, ctx): def finish(exception): async def f(): await ctx.send("\N{HOT BEVERAGE}") await cli.disconnect() future = asyncio.run_coroutine_threadsafe(f(), self.bot.loop) vc = discord.utils.get(b5('ext').guild().voice_channels, name="an der Kaffeemaschine") if b5('user').get(ctx.author.id).inGuild() in vc.members: if not discord.opus.is_loaded(): discord.opus.load_opus("libopus.so.0") try: cli = await vc.connect() except Exception as e: cli = None print(e) audio_source = discord.FFmpegPCMAudio( b5path + '/extensiondata/komraum/coffee.mp3') if cli is not None and not cli.is_playing(): cli.play(audio_source, after=finish) else: await ctx.send( "Du musst warten, bis die Person vor dir ihren Kaffee hat." ) #await cli.disconnect() #time.sleep(20) return await ctx.send("Du musst an die Kaffeemaschine gehen.")
async def massverify(self,ctx): if not self.debugEnabled: await ctx.send("Du musst mich erst aufschrauben. Benutze den \\debug Befehl.") return for i in b5('user').list(): b5('user').get(i).forceVerify()
async def on_member_remove(self, member): u = b5('user').get(member.id) if u is None: await b5('log').debug("WARNING: " + str(member.display_name) + " left the guild, but was not in my memory") return b5('user').remove(member.id)
async def userlistunknown(self, ctx): known = [u.getID() for u in b5("user").list()] for m in b5('ext').guild().members: if m.id not in known: await ctx.send( str(m) + ", roles: " + str( discord.utils.get(b5('ext').guild().members, id=m.id).roles))
async def on_member_join(self, member): # TODO: what if ID already in USERS? existing_user = b5('user').get(member.id) if existing_user is not None: await b5('log' ).debug("WARNING: " + str(member.display_name) + " just joined, but already exists as follows\n" + existing_user.show()) u = b5('user').add(member.id) await self.welcomeMessage(u)
async def userlistslipped(self, ctx): if b5('auth') is None: await ctx.send(_("Authentication extension not loaded.")) return known = [u.getID() for u in b5("user").list()] for m in b5('ext').guild().members: if m.id not in known and len( discord.utils.get(b5('ext').guild().members, id=m.id).roles) > 1: await ctx.send(m)
def __init__(self, bot): self.bot = bot self.channel = discord.utils.get(b5('ext').guild().text_channels, name="whiteboard") # list of words indexed by YYYYMMDD. self.words = {} try: self.words = b5('persist').load('wortdestages.bot5') except FileNotFoundError as e: print(e) print("Keine gespeicherten Wörter des Tages!")
async def erstihilfe(self, ctx): if b5('user').get(ctx.author.id) is not None and b5('user').get( ctx.author.id).get('verified'): await ctx.send(_("Your account is already verified.")) return u = b5('user').get(ctx.author.id) subject = "LEOBOT: Ersti-Anfrage" mailcontent = "Jemand hat den Erstihilfe-Befehl verwendet. Folgendes weiß ich:\n" + u.show( ) b5('email').send("*****@*****.**", subject, mailcontent) await ctx.send( _("An administrator will contact you regarding your verification." ))
async def userverify(self, ctx, members: Greedy[discord.Member]): if b5('auth') is None: await ctx.send(_("Authentication extension not loaded.")) return for m in members: u = b5("user").get(m.id) if u is None: await ctx.send( _("User $displayname not found.", displayname=m.display_name)) else: await b5('auth').verify(u, 0, force=True) await ctx.send( _("User $displayname is now verified.", displayname=u.inGuild().display_name))
async def leoscriptvor(self, ctx, *args): helpcmd = "" if len(args) == 0: helpcmd = "0" else: helpcmd = " ".join(args) if helpcmd == "0": for h in lt.beispiele[helpcmd]: await b5("user").get(ctx.author.id).sendPM(h) await b5('user').get(ctx.author.id).notifyAboutPM(ctx) return if helpcmd in lt.beispiele: helptext = "".join(lt.beispiele[helpcmd]) # helptext is now one long string containing a valid leoscript interpreter = LeoInterpreter(helptext, ctx.channel, b5("user").get(ctx.author.id)) async with ctx.channel.typing(): try: ret = await asyncio.wait_for(interpreter.run(), timeout=TIMEOUT) except (asyncio.TimeoutError): await b5('user').get(ctx.author.id).sendPM( "Dein Leoscript wurde abgebrochen, weil das Zeitlimit von " + str(TIMEOUT) + " Sekunden überschritten wurde.") else: await ctx.send("Ergebnis: " + str(ret) + ".") await ctx.send("Ausführung beendet.") else: await ctx.send( "Dieses Beispiel kenne ich nicht. Rufe `\\leo beispiel` auf, um eine Liste aller verfügbaren Beispiele zu sehen." )
async def erstiVerify(self, user, wort: str) -> bool: if re_ersti.match(wort) is None: return False newrole = discord.utils.get(b5('ext').guild().roles, name="Ersti") await user.inGuild().add_roles(newrole) return await self.verify(user, 0, True, "ERSTI")
async def on_message(self, message): if message.author == self.bot.user: return if self.bot.user in message.mentions or message.guild is None: if not re_command.match(message.content): if len(message.attachments) > 0: await message.channel.send( "Ich versuche dein Skript auszuführen.") await message.attachments[0].save( os.gentenv('BOT_CONFIG') + '/scripts/' + str(message.author.id)) code = "" with open(b5path + '/scripts/' + str(message.author.id), 'r') as scr: code = scr.read() interpreter = LeoInterpreter( code, message.channel, b5("user").get(message.author.id)) try: ret = await asyncio.wait_for(interpreter.run(), timeout=TIMEOUT) except (asyncio.TimeoutError): await b5('user').get(message.author.id).sendPM( "Dein Leoscript wurde abgebrochen, weil das Zeitlimit von " + str(TIMEOUT) + " Sekunden überschritten wurde.") else: await message.channel.send("Ergebnis: " + str(ret) + ".") await message.channel.send("Ausführung beendet.")
async def b5check(self, ctx, check="admin", role=None): #return True #print("userb5check "+str(check)+" called.") if role is not None: rl = role if isinstance(role, str): rl = [role] for r in rl: if b5('user').get(ctx.author.id).isRole(r): return True #await ctx.send("Du musst eine der folgenden Rollen haben, um diesen Befehl zu verwenden:\n"+str(rl)) return False if check == "admin": if ext('user').get(ctx.author.id).isAdmin(): return True else: #await ctx.send("Du bist nicht mein Boss!") #await ctx.message.add_reaction('\N{ANGRY FACE}') return False if check == "verified": if ext('user').getField(ctx.author.id, 'verified'): return True else: #await ctx.send("Dieser Befehl ist nur für verifizierte Benutzer verfügbar.") return False return False
async def rhrk(self, ctx, *args): # we need an argument: if len(args) == 0: await ctx.send(_("Please provide a username.")) return # TODO: allow Erstis to set their RHRK account a posteriori if b5('user').get(ctx.author.id) is not None and b5('user').get( ctx.author.id).get('verified'): await ctx.send(_("Your account is already verified.")) return async with ctx.channel.typing(): # find the user in our database: print(f"DEBUG: rhrk message from {ctx.author.id}") try: u = b5('user').get(ctx.author.id) except KeyError: await ctx.send( "Database error. Please leave the server and rejoin via the invite link." ) raise Bot5Error("rhrk: user was None") return # assign necessary variables rhrk_mail = args[0] auth_int = self.generateAuthCode( u, timeout=AUTH_TIMEOUT) #randint(1,10000) # try sending an email with the generated code mailcontent = _( "You are getting this email because you requested a verification code from Bot5. Your code is $code.", code=auth_int) try: b5('email').send(rhrk_mail + '@rhrk.uni-kl.de', _("Bot5 Verification Email"), mailcontent) except Exception as e: print(e) await ctx.send(_("Could not send you an email.")) return u.set('rhrk', rhrk_mail) await ctx.send( _("I have sent your verification code to $email.", email=rhrk_mail + '@rhrk.uni-kl.de'))
async def userset(self, ctx, mem: discord.Member, attribute: str, value): m = b5('user').get(mem.id) if m is None: await ctx.send( _("User $displayname not found.", displayname=mem.display_name)) else: m.set(attribute, value) await ctx.send(_("Value has been set."))
async def changeChannelPerms(self, category, channel=None, role=None, **kwargs): if isinstance(category, discord.CategoryChannel): cat = category else: cat = discord.utils.get(bot5utils.b5('ext').guild().categories, name=category) if cat is None: raise Bot5Error("Kategorie " + str(category) + " finde ich nicht.") if role is None: rl = bot5utils.b5('ext').guild().roles[0] elif isinstance(role, discord.Role): rl = role else: rl = discord.utils.get(b5('ext').guild().roles, name="role") if rl is None: raise Bot5Error("Die Rolle " + str(role) + " kenne ich nicht.") toChange = cat if channel is not None: if isinstance(channel, discord.VoiceChannel): toChange = channel else: toChange = discord.utils.get(cat.voice_channels, name=channel) if toChange is None: raise Bot5Error("Den Channel " + str(channel) + " finde ich nicht.") # toChange is now either a CategoryChannel or a VoiceChannel. try: await toChange.set_permissions(rl, **kwargs) if isinstance(toChange, discord.CategoryChannel): for c in toChange.voice_channels: await self.changeChannelPerms(toChange, c, role, **kwargs) except Exception as e: raise Bot5Error("Editing category failed!\n" + str(e)) else: return True
async def userwelcome(self, ctx, members: Greedy[discord.Member]): for m in members: u = b5('user').get(m.id) if u is None: await ctx.send( _("User $displayname not found.", displayname=m.display_name)) else: await b5('auth').welcomeMessage(u) await ctx.send(_("Message sent."))
async def komnopush(self, ctx, *, arg=None): try: await self.changeChannelPerms("KOM-Raum", arg, b5('ext').guild().roles[0], use_voice_activation=True) except Bot5Error as e: await ctx.send("Konnte Berechtigungen nicht ändern!\n" + str(e)) else: wh = "überall" if arg is None else arg await ctx.send("Voice Activation ist jetzt " + wh + " erlaubt.")
async def ersti(self, ctx, *wort): if b5('user').get(ctx.author.id) is not None and b5('user').get( ctx.author.id).get('verified'): await ctx.send(_("Your account is already verified.")) return u = b5('user').get(ctx.author.id) if u is None: await ctx.send( _("Database error. Please leave the server and rejoin via the invite link." )) return if len(wort) == 0: await ctx.send(_("Instructions for Ersti verification go here.")) else: if await self.erstiVerify(u, wort[0]): await ctx.send(_("Code correct. You are now verified.")) else: await ctx.send( _("Text for failed Ersti verification goes here."))
async def verify(self, user, code: int, force: bool = False, accountType="TUK") -> bool: if force or (user.get('authCode') > 0 and user.get('authCode') == code and time.time() < user.get('authCodeValidUntil')): user.set('verified', True) newrole = discord.utils.get(b5('ext').guild().roles, name='Studi') await user.inGuild().add_roles(newrole) user.set('accountType', accountType) if user.get('rhrk') != '': await user.inGuild().edit(nick=user.get('rhrk') + "@rhrk") return user.get('verified')
async def code(self, ctx, *args): if len(args) == 0: await ctx.send(_("Missing mandatory argument: verification code.")) return if b5('user').get(ctx.author.id) is not None and b5('user').get( ctx.author.id).get('verified'): await ctx.send(_("Your account is already verified.")) return entered_code = args[0] try: u = b5('user').get(ctx.author.id) except KeyError: await ctx.send( _("Database error. Please leave the server and rejoin via the invite link." )) raise Bot5Error("code: user was None") return if await self.verify(u, int(entered_code)): await ctx.send(_("Code correct. You are now verified.")) else: await ctx.send(_("Code incorrect or expired. Please try again."))
def __init__(self): self.users = {} self.fields = {} # map name of field to UserField() instance if os.path.isfile(b5path + '/user.debug'): print("USER: DEBUG FILE FOUND") self.loadRawData() else: try: self.users = b5('persist').load('users.bot5') except FileNotFoundError as e: print(e) print("Keine gespeicherten Nutzer. Bin ich neu geboren?") # TODO: how to log this to Discord? self.registerField('user', 'id', int, 0)
async def leoscriptmsg(self, ctx): await ctx.send( "Ich werde deine nächste Nachricht als Skript interpretieren.") def check(m): return m.author == ctx.author and m.channel == ctx.channel msg = await self.bot.wait_for('message', check=check) interpreter = LeoInterpreter(msg.content, ctx.channel, b5("user").get(ctx.author.id)) async with ctx.channel.typing(): try: ret = await asyncio.wait_for(interpreter.run(), timeout=TIMEOUT) except (asyncio.TimeoutError): await b5('user').get(ctx.author.id).sendPM( "Dein Leoscript wurde abgebrochen, weil das Zeitlimit von " + str(TIMEOUT) + " Sekunden überschritten wurde.") else: await ctx.send("Ergebnis: " + str(ret) + ".") await ctx.send("Ausführung beendet.")
async def b5pm(self, ctx, user: str): username = user[0:-5] userdisc = user[-4:] u = discord.utils.get(b5('ext').guild().members, name=username, discriminator=userdisc) if u is None: await ctx.send("Dieser User ist nicht auf dem Server.") return await ctx.send("Deine nächste Nachricht wird an " + u.display_name + " gesendet.") def check(m): return m.author == ctx.author and m.channel == ctx.channel try: msg = await self.bot.wait_for('message', check=check, timeout=120) except: await ctx.send("Ich habe den Sendevorgang abgebrochen.") else: await u.create_dm() await u.dm_channel.send(msg.content) await ctx.send("Gesendet.")
def teardown(bot): b5('ext').unregister('persist')
def setup(bot): b5('ext').register('persist', Persist())
#---------------------------------------------------------------------------- #"THE COFFEEWARE LICENSE": #Adrian Rettich ([email protected]) wrote this file. As long as you retain this notice, you can do whatever you want with this stuff. If we should meet in person some day, and you think this stuff is worth it, you are welcome to buy me a coffee in return. #---------------------------------------------------------------------------- from bot5utils import * import bot5utils from bot5utils import ext as b5 import subprocess import re re_command = re.compile('^\\\\') _ = b5('ext')._('misc') class Misc(commands.Cog, name=_("Miscellaneous")): def __init__(self,bot): self.bot = bot # @commands.Cog.listener() # async def on_message(self,message): # if message.author == self.bot.user: # return # # reply if Bot5 was mentioned # # or if we are in a private chat <=> not on a server <=> message.guild is None # if self.bot.user in message.mentions or message.guild is None: # # of course, if this is a command, we don't need to react: # if not re_command.match(message.content):