async def vote(self, ctx): message = ctx.message lines = message.content.split("\n") if len(lines) < 3: await ctx.send( ">>> " + text.fill("vote", "vote_help", prefix=config.prefix)) return now = datetime.now() try: timex = re.compile(r"[ ](\d*[h])*[ ]*(\d*[m])*[ ]*(\d*[s])*[ ]") if timex.search(str(lines[0])) is not None: now = datetime.now() t = dparser.parse(lines[0], dayfirst=True, fuzzy=True) diff = t - now.replace(hour=0, minute=0, second=0) date = now + diff else: date = dparser.parse(lines[0], dayfirst=True, fuzzy=True) if now > date: date += timedelta(days=1) except dateutil.parser._parser.ParserError: date = now + timedelta(hours=1) votes = [] for idx, line in enumerate(lines): if idx > 0: emote = re.match(r"<:\w*:\d*>", line) if emote is not None: for emoji in self.bot.emojis: if str(emoji) in line: votes.append({ "emote": emoji, "option": line.replace(str(emoji) + " ", ""), "num_votes": 0, }) break else: await ctx.send(text.get("vote", "emote_unknown")) return else: await ctx.send(text.get("vote", "emote_unknown")) return for option in votes: await ctx.message.add_reaction(option["emote"]) edit_msg = await ctx.send( text.fill("vote", "waiting", date=date.strftime("%Y-%m-%d %H:%M:%S"))) repository.add_vote( channel_id=message.channel.id, message_id=message.id, edit_id=edit_msg.id, date=date.strftime("%Y-%m-%d %H:%M:%S"), ) await self.loop(ctx.message, edit_msg, date) return
async def channelboard(self, ctx, offset: int = 1): await asyncio.sleep(0.5) user_channels = repository.get_user_channels() if not user_channels: return ctx.send(text.get("boards", "not found")) # convert to be zero-indexed offset -= 1 if offset < 0: return await ctx.send(text.get("boards", "invalid offset")) results = await self.sort_channels(user_channels, False) if offset > len(results): return await ctx.send(text.get("boards", "offset too big")) embed = discord.Embed( title=text.get("boards", "channel board title"), description=text.get("boards", "channel board desc"), color=config.color, ) # get data for "TOP X" list lines = [] for position, item in enumerate(results): if position < offset: continue if position - offset >= config.board_top: break channel = self.bot.get_channel(item["channel_id"]) if not hasattr(channel, "name"): # channel was not found continue # fmt: off if ctx.guild is not None and channel.guild.id == ctx.guild.id: lines.append(text.fill("boards", "channel template", index=f"{position + 1:>2}", count=f"{item['count']:>5}", name=discord.utils.escape_markdown(channel.name))) else: # channel is on some other guild lines.append(text.fill("boards", "channel template guild", index=f"{position + 1:>2}", count=f"{item['count']:>5}", name=discord.utils.escape_markdown(channel.name), guild=discord.utils.escape_markdown(channel.guild.name))) # fmt: on title = "top number" if offset == 0 else "top offset" # fmt: off embed.add_field( name=text.fill("boards", title, top=config.board_top, offset=offset + 1), value="\n".join(lines), inline=False, ) # fmt: on await ctx.send(embed=embed)
async def voice_rename(self, ctx: commands.Context, *args): """Rename current voice channel""" await ctx.send(text.fill("voice", "wip", mention=ctx.author.mention), delete_after=10) await utils.delete(ctx) return name = " ".join(args) if len(name) <= 0: await ctx.send( delete_after=config.delay_embed, content=text.fill("voice", "rename empty", user=ctx.author), ) return if len(name) > 25: await ctx.send( delete_after=config.delay_embed, content=text.fill("voice", "rename long", user=ctx.author), ) return v = self.getVoiceChannel(ctx) name = name.replace(" " + self.lock, "").replace(self.lock, "") if v.id in self.locked: name = name + " " + self.lock await v.edit(name=name) await utils.delete(ctx)
async def _role_remove(self, location: discord.abc.Messageable, member: discord.Member, role: discord.Role): if role < self.getLimitProgrammes( location) and role > self.getLimitInterests(location): # role is programme, check if user has permission for programme_role in config.get("faceshifter", "programme roles"): if programme_role in [r.id for r in member.roles]: break else: await location.send( text.fill("faceshifter", "deny role", mention=member.mention), delete_after=config.get("delay", "user error"), ) return elif role < self.getLimitInterests(location): # role is below interests limit, continue pass else: # role is limit itself or something above programmes await location.send( text.fill("faceshifter", "deny high role", mention=member.mention), delete_after=config.get("delay", "user error"), ) return await member.remove_roles(role)
async def power_on(self, ctx): """Restore""" jail = self.getGuild().get_channel(config.get("channels", "jail")) everyone = self.getGuild().default_role botspam = self.getGuild().get_channel(config.get( "channels", "botspam")) visited = [] if jail is not None: # remove the message messages = await jail.history(limit=10).flatten() for message in messages: if message.content.startswith( text.get("admin", "poweroff jail")): await message.delete() break # switch to read-write await jail.set_permissions(everyone, send_messages=True, reason="?power on") visited.append(jail.mention) if botspam is not None: # send message await botspam.send(text.get("admin", "poweron botspam")) visited.append(botspam.mention) # send confirmation message if len(visited) > 0: await ctx.send( text.fill("admin", "poweron ok", channels=", ".join(visited))) else: await ctx.send(text.fill("admin", "power fail")) await self.event.sudo(ctx.author, ctx.channel, "Power on")
def fill_subject_embed(self, embed: discord.Embed, review: object, average: float) -> discord.Embed: # reset any previous embed.clear_fields() # add content # fmt: off name = self.bot.get_user(int(review.discord_id)) or text.get( "judge", "embed_no_user") if review.anonym: name = text.get("judge", "embed_anonymous") embed.add_field( inline=False, name=text.fill("judge", "embed_no", num=str(review.id)), value=text.fill("judge", "embed_average", num=f"{average:.1f}"), ) embed.add_field(name=name, value=review.date) embed.add_field(name=text.get("judge", "embed_mark"), value=review.tier) embed.add_field( inline=False, name=text.get("judge", "embed_text"), value=review.text_review, ) # fmt: on embed.add_field(name="👍", value=f"{repo_r.get_votes_count(review.id, True)}") embed.add_field(name="👎", value=f"{repo_r.get_votes_count(review.id, False)}") return embed
async def on_command_error(self, ctx: commands.Context, error): # try to get original error if hasattr(ctx.command, "on_error") or hasattr(ctx.command, "on_command_error"): return error = getattr(error, "original", error) # non-rubbergoddess exceptions are handled globally if not isinstance(error, rubbercog.RubbercogException): return # fmt: off # exceptions with parameters if isinstance(error, InvalidReactionKey): await self.output.error( ctx, text.fill("actress", "InvalidReactionKey", key=error.key)) elif isinstance(error, ReactionParsingException): await self.output.error( ctx, text.fill("actress", "ReactionParsingException", key=error.key, value=error.value)) # exceptions without parameters elif isinstance(error, ActressException): await self.output.error(ctx, text.get("actress", type(error).__name__))
def fillBoard(self, embed, *, member, order: str, offset: int) -> discord.Embed: limit = config.get("karma", "leaderboard limit") # around = config.get("karma", "leaderboard around") template = "`{position:>2}` … `{karma:>5}` {username}" embed.clear_fields() # get repository parameters column = "karma" if order == "give": column = "positive" if order == "take": column == "negative" if order == "desc": attr = DB_Karma.karma.desc() elif order == "asc": attr = DB_Karma.karma elif order == "give": attr = DB_Karma.positive.desc() elif order == "take": attr = DB_Karma.negative.desc() # construct first field value = [] board = repo_k.getLeaderboard(attr, offset, limit) for i, db_user in enumerate(board, start=offset): # fmt: off user = self.bot.get_user(int(db_user.discord_id)) username = ( self.sanitise(user.display_name) if hasattr(user, "display_name") else "_unknown_" ) if int(db_user.discord_id) == member.id: username = f"**{username}**" value.append(template.format( position=i + 1, karma=getattr(db_user, column), username=username, )) # fmt: on if offset == 0: name = text.fill("karma", "board_1", num=limit) else: name = text.fill("karma", "board_x", num=limit, offset=offset + 1) embed.add_field(name=name, value="\n".join(value)) # construct second field # FIXME How to get user's position? # value = [] # board = repo_k.getLeaderboard(attr, offset=user_position - around, limit=around*2+1) return embed
async def _announceDuplicate(self, message: discord.Message, original: object, hamming: int): """Send message that a post is a original original: object hamming: Hamming distance between the image and closest database entry """ if hamming <= self.limit_full: t = "**♻️ To je repost!**" await message.add_reaction("♻️") elif hamming <= self.limit_hard: t = "**♻️ To je asi repost**" await message.add_reaction("🤔") else: t = "To je možná repost" await message.add_reaction("🤷🏻") prob = "{:.1f} %".format((1 - hamming / 128) * 100) timestamp = original.timestamp.strftime("%Y-%m-%d %H:%M:%S") src_chan = self.getGuild().get_channel(original.channel_id) try: src_post = await src_chan.fetch_message(original.message_id) link = src_post.jump_url author = discord.utils.escape_markdown( src_post.author.display_name) except: link = "404 " + emote.sad author = "_??? (404)_" d = text.fill( "warden", "repost description", name=discord.utils.escape_markdown(message.author.display_name), value=prob, ) embed = discord.Embed(title=t, color=config.color, description=d, url=message.jump_url) embed.add_field(name=f"**{author}**, {timestamp}", value=link, inline=False) embed.add_field( name=text.get("warden", "repost title"), value="_" + text.fill("warden", "repost content", limit=config.get("warden", "not duplicate limit")) + "_", ) embed.set_footer(text=f"{message.author.id} | {message.id}") m = await message.channel.send(embed=embed) await m.add_reaction("❎") await m.add_reaction("🆗")
async def remind(self, ctx, member: discord.Member): message = ctx.message lines = message.content.split("\n") arg = lines[0] arg = arg.replace("weekend", "saturday") date, date_str = await self.parse_datetime(arg) lines = "\n".join(lines) for prefix in config.prefixes: if lines[0] == prefix: lines = lines.replace(f"{prefix}remind ", "") lines = lines.replace(f"<@!{member.id}>", "") lines = lines.replace(date_str, "") lines = re.split(" ", lines) while "" in lines: lines.remove("") lines = " ".join(lines) if len(lines) == 0: await ctx.send( ">>> " + text.fill("remindme", "remind help", prefix=config.prefix)) return elif len(lines) > 1024: lines = lines[:1024] if date is None: await ctx.send(text.get("remindme", "datetime not found")) date = datetime.now() + timedelta(days=1) repository.add( user_id=member.id, reminder_user_id=ctx.author.id, permalink=ctx.message.jump_url, message=lines, origin_date=ctx.message.created_at, new_date=date, ) date = date.strftime("%d.%m.%Y %H:%M") await self.log(level="debug", message=f"Reminder created for {ctx.author.name}") await ctx.message.add_reaction("✅") await ctx.message.author.send( text.fill("remindme", "reminder confirmation", name=member.display_name, date=date)) return
async def loop(self, vote_msg, edit_msg, date): votes = await self.find_emotes(vote_msg) while True: if date < datetime.now(): break timeout = (date - datetime.now()).seconds pending_tasks = [ self.bot.wait_for("raw_reaction_add"), self.bot.wait_for("raw_reaction_remove"), ] done_tasks, pending_tasks = await asyncio.wait( pending_tasks, return_when=asyncio.FIRST_COMPLETED, timeout=timeout) for task in done_tasks: raw_reaction = await task await self.check_reactions(raw_reaction, vote_msg, votes, edit_msg, date) if vote_msg not in self.bot.cached_messages: vote_msg = await vote_msg.channel.fetch_message(vote_msg.id) for reaction in vote_msg.reactions: for option in votes: if reaction.emoji == option["emote"]: option["num_votes"] = reaction.count lines = vote_msg.content.split("\n") content = text.fill("vote", "ended", now=datetime.now().strftime("%Y-%m-%d %H:%M:%S")) content += lines[0] + "\n" votes = sorted(votes, key=lambda i: (i["num_votes"]), reverse=True) for option in votes: content += text.fill( "vote", "option", option=option["option"], num=option["num_votes"] - 1, ) content = escape_mentions(escape_markdown(content)) await edit_msg.channel.send(content=content) repository.del_vote(channel_id=vote_msg.channel.id, message_id=vote_msg.id) return
async def on_command_error(self, ctx: commands.Context, error): # try to get original error if hasattr(ctx.command, "on_error") or hasattr(ctx.command, "on_command_error"): return error = getattr(error, "original", error) # non-rubbergoddess exceptions are handled globally if not isinstance(error, rubbercog.RubbercogException): return # fmt: off # exceptions with parameters if isinstance(error, ProblematicVerification): await self.output.error( ctx, text.fill("gatekeeper", "ProblematicVerification", status=error.status)) await self.event.user( ctx.author, ctx.location, f"Problem with verification: {error.login}: {error.status}") elif isinstance(error, BadEmail): await self.output.error( ctx, text.fill("gatekeeper", "BadEmail", constraint=error.constraint)) elif isinstance(error, WrongVerificationCode): await self.output.error( ctx, text.fill("gatekeeper", "WrongVerificationCode", mention=ctx.author.mention)) await self.event.user( ctx.author, ctx.channel, f"User ({error.login}) code mismatch: `{error.their}` != `{error.database}`" ) # exceptions without parameters elif isinstance(error, VerificationException): await self.output.error( ctx, text.get("gatekeeper", type(error).__name__))
async def react_add(self, ctx, name: str = None, *, parameters=None): """Add new reaction ``` ?react add <reaction name> type <image | text> match <full | start | end | any> sensitive <true | false> triggers "a b c" "d e" f responses "abc def" users 0 1 2 channels 0 1 2 counter 10 ``` """ if name is None: return await utils.send_help(ctx) elif name in self.reactions.keys(): raise ReactionNameExists() reaction = await self.parse_react_message(ctx.message, strict=True) self.reactions[name] = reaction self._save_reactions() await self.output.info( ctx, text.fill("actress", "reaction added", name=name)) await self.event.sudo(ctx.author, ctx.channel, f"Reaction **{name}** added.")
async def hoarders(self, ctx: commands.Context, warn: str = None): """Check for users with multiple programme roles warn: Optional. Use "warn" string to send warnings, else just list the users """ warn = warn == "warn" hoarders = [] limit_top = discord.utils.get(self.getGuild().roles, name="---PROGRAMMES") limit_bottom = discord.utils.get(self.getGuild().roles, name="---INTERESTS") for member in self.getGuild().members: prog = [] for role in member.roles: if role < limit_top and role > limit_bottom: prog.append(role.name) if len(prog) > 1: hoarders.append([member, prog]) if len(hoarders) == 0: await ctx.send(text.get("janitor", "no hoarders")) else: all = len(hoarders) if warn: msg = await ctx.send( "Odesílání zprávy 1/{all}.".format(all=all)) embed = discord.Embed(title="Programme hoarders", color=config.color) for num, (hoarder, progs) in enumerate(hoarders, start=1): embed.add_field( name="User", value= f"**{discord.utils.escape_markdown(hoarder.name)}** ({hoarder.id})", ) embed.add_field(name="Status", value=hoarder.status) embed.add_field(name="Programmes", value=", ".join(progs), inline=False) if warn: if num % 5 == 0: # Do not stress the API too much await msg.edit(content="Odesílání zprávy {num}/{all}.". format(num=num, all=all)) await hoarder.send( text.fill("janitor", "hoarding warning", guild=self.getGuild().name)) if num % 8 == 0: # Can't have more than 25 fields in an embed await ctx.channel.send(embed=embed, delete_after=config.delay_embed) embed = discord.Embed(title="Programme hoarders", color=config.color) if warn and num % 5 != 0: await msg.edit(content="Odesílání zprávy {num}/{all}.".format( num=num, all=all)) await ctx.channel.send(embed=embed, delete_after=config.delay_embed) await utils.delete(ctx)
async def urban(self, ctx): await self.deleteCommand(ctx, now=True) message = ctx.message args = message.content.split(" ") if len(args) == 1: await ctx.send( ">>> " + text.fill("urban", "urban_help", prefix=config.prefix)) return args.pop(0) search = " ".join(args) term = url_parse.quote(search) async with ctx.typing(): try: response = requests.get( "http://api.urbandictionary.com/v0/define?term={term}". format(term=term)) dic = response.json() response.raise_for_status() except requests.HTTPError as http_err: await ctx.send(f"HTTP error occurred: {http_err}") except Exception as err: await ctx.send(f"Error occurred: {err}") else: # Request was successful embeds = self.urban_embeds(ctx, dic) await self.urban_pages(ctx, embeds) return
async def send_image(self, ctx, channel: discord.TextChannel, filename): """Send an image as a bot channel: Target text channel filename: A filename """ now = time.monotonic() try: async with ctx.typing(): message = await channel.send(file=discord.File(self.path + filename)) delta = time.monotonic() - now await self.output.info( ctx, text.fill("actress", "file sent", delta=delta)) mention = channel.mention if hasattr( channel, "mention") else type(channel).__name__ await self.event.sudo( ctx.author, ctx.channel, f"Media file sent to {mention}:\n" f"> _{filename}_\n> <{message.jump_url}>", ) except Exception as e: await self.output.error(ctx, text.get("actress", "FileSendError"), e)
async def verify(self, ctx, email: str): """Ask for verification code""" await utils.delete(ctx) if "@" not in email or len(email.split("@")) > 2: raise NotAnEmail() # check the database for member ID if repo_u.get(ctx.author.id) is not None: raise IDAlreadyInDatabase() # check the database for email if repo_u.getByLogin(email) is not None: raise EmailAlreadyInDatabase() # check e-mail format role = await self._email_to_role(ctx, email) # generate code code = await self._add_user(ctx.author, login=email, role=role) # send mail await self._send_verification_email(ctx.author, email, code) anonymised = "[redacted]@" + email.split("@")[1] await ctx.send( text.fill( "gatekeeper", "verify successful", mention=ctx.author.mention, email=anonymised, prefix=config.prefix, ), delete_after=config.get("delay", "verify"), )
async def reverify_prove(self, ctx): """Ask for verification code""" await utils.delete(ctx) db_user = repo_u.get(ctx.author.id) if db_user is None: await self.console.error( "User in `?reverify prove` is not in database.") raise NotInDatabase() if db_user.status != "quarantined": await self.console.error( "User in `?reverify prove` did not have `quarantined` status.") raise UnexpectedReverify() if db_user.group == "FEKT" and "@" not in db_user.login: email = db_user.login + "@stud.feec.vutbr.cz" elif db_user.group == "VUT" and "@" not in db_user.login: email = db_user.login + "@vutbr.cz" else: email = db_user.login # generate new code code = await self._update_user(ctx.author) # send mail await self._send_verification_email(ctx.author, email, code) await ctx.send( text.fill("gatekeeper", "reverify successful", mention=ctx.author.mention), delete_after=config.get("delay", "verify"), )
async def karma_stalk(self, ctx, member: discord.Member): """See someone's karma""" k = repo_k.get_karma(member.id) embed = self.embed( ctx=ctx, description=text.fill( "karma", "stalk_user", user=self.sanitise(member.display_name, limit=32) ), ) embed.add_field( name=text.get("karma", "stalk_karma"), value=f"**{k.karma.value}** ({k.karma.position}.)", inline=False, ) embed.add_field( name=text.get("karma", "stalk_positive"), value=f"**{k.positive.value}** ({k.positive.position}.)", ) embed.add_field( name=text.get("karma", "stalk_negative"), value=f"**{k.negative.value}** ({k.negative.position}.)", ) await ctx.send(embed=embed) await self.event.user(ctx.author, ctx.channel, f"Karma stalk on {member.name}.") await utils.room_check(ctx)
async def sauce(self, ctx): message = ctx.message args = message.content.split(" ") if not self.sauce_check(message): raise commands.MissingPermissions else: if len(args) != 2: await ctx.send( ">>> " + text.fill("weeb", "sauce_help", prefix=config.prefix)) return BOOK_ID = args[1] async with ctx.typing(): try: response = requests.get( "https://nhentai.net/api/gallery/{BOOK_ID}".format( BOOK_ID=BOOK_ID)) dic = response.json() response.raise_for_status() except requests.HTTPError as http_err: await ctx.send(f"HTTP error occurred: {http_err}") except Exception as err: await ctx.send(f"Error occurred: {err}") else: # Request was successful embed = self.sauce_embed(ctx, dic, BOOK_ID) await ctx.send(embed=embed)
async def nickname_unset(self, ctx): """Unset the nickname""" if ctx.author.nick is None: return await ctx.send( text.fill("shop", "no nick", author=ctx.author.mention)) nick = ctx.author.nick await ctx.author.edit(nick=None, reason="?nickname unset") await ctx.send( text.fill( "shop", "nick removed", author=ctx.author.mention, nick=discord.utils.escape_markdown(nick), )) await self.event.user(ctx.author, ctx.channel, "Nickname reset.")
async def meniny(self, ctx): url = f"http://svatky.adresa.info/json?lang=sk&date={date.today().strftime('%d%m')}" res = requests.get(url).json() names = [] for i in res: names.append(i["name"]) await ctx.send( text.fill("librarian", "nameday sk", name=", ".join(names)))
async def database_remove(self, ctx: commands.Context, member: discord.Member = None, force: str = None): """Remove user from database member: A server member force: "force" string. If omitted, show what will be deleted """ if member is None: return await utils.send_help(ctx) # define variables guild = self.bot.get_guild(config.guild_id) force = self.parseArg(force) try: if force: result = repository.deleteId(discord_id=member.id) else: result = repository.filterId(discord_id=member.id) except Exception as e: return await self.output.error(ctx, text.get("db", "read"), e) d = "Result" if force else "Simulation, run with `force` to apply" if force: embed = self.embed(description=d, color=config.color_success) # delete if result is None or result < 1: return await self.output.error(ctx, text.get("db", "delete error")) embed.add_field(inline=False, name="Success", value=text.fill("db", "delete success", num=result)) embed.add_field( name="Warning", value="Roles and channel access haven't been removed") await self.event.sudo(ctx.author, ctx.channel, "User removed from database: " + member.name) # TODO remove all roles else: # simulate embed = discord.Embed(color=config.color_notify, description=d) for r in result: embed.add_field( inline=False, name=self.dbobj2email(r), value=discord.utils.get(guild.members, id=int(r.discord_id)).mention, ) if len(result) < 1: embed.add_field(name="No entry", value=text.get("db", "not found"), inline=False) await ctx.send(embed=embed, delete_after=config.delay_embed) await utils.delete(ctx)
async def nickname_set(self, ctx, *, nick: str): """Set the nickname Use command `shop` to see prices nick: Your new nickname """ # stop if user does not have nickname set if ctx.author.nick is None and nick is None: return await utils.send_help(ctx) # check if user has karma user = repo_k.getMember(ctx.author.id) if user is None: return await ctx.send( text.fill("shop", "no karma", author=ctx.author.mention)) if user.karma < self.price_nick: return await ctx.send( text.fill( "shop", "not enough karma", author=ctx.author.mention, value=self.price_nick - user.karma, )) if "@" in nick: raise ForbiddenNicknameCharacter("@") # set nickname try: await ctx.author.edit(nick=nick, reason="?nickname") except discord.Forbidden: return await ctx.send(text.get("error", "higher permission")) repo_k.updateMemberKarma(ctx.author.id, -1 * self.price_nick) await ctx.send( text.fill( "shop", "new nick", author=ctx.author.mention, nick=discord.utils.escape_markdown(nick), value=self.price_nick, )) await self.event.user(ctx.author, ctx.channel, f"Nickname changed to {nick}.")
async def karma_vote(self, ctx, emote: str): """Vote for emote's karma value""" message = await ctx.send( text.fill( "karma", "vote info", emote=emote, time=config.get("karma", "vote time"), limit=config.get("karma", "vote limit"), ) ) await message.add_reaction("☑️") await message.add_reaction("0⃣") await message.add_reaction("❎") await self.event.sudo(ctx.author, ctx.channel, f"Vote over value of {emote} started.") await asyncio.sleep(config.get("karma", "vote time") * 60) # update cached message message = await ctx.channel.fetch_message(message.id) positive = 0 negative = 0 neutral = 0 for reaction in message.reactions: if reaction.emoji == "☑️": positive = reaction.count - 1 elif reaction.emoji == "❎": negative = reaction.count - 1 elif reaction.emoji == "0⃣": neutral = reaction.count - 1 if positive + negative + neutral < config.get("karma", "vote limit"): await self.event.sudo(ctx.author, ctx.channel, f"Vote for {emote} failed.") return await ctx.send(text.fill("karma", "vote failed", emote=emote)) result = 0 if positive > negative + neutral: result = 1 elif negative > positive + neutral: result = -1 repo_k.set_emoji_value(str(self._emoteToID(emote)), result) await ctx.send(text.fill("karma", "vote result", emote=emote, value=result)) await self.event.sudo(ctx.author, ctx.channel, f"{emote} karma value voted as {result}.")
async def flip(self, ctx): """Yes/No""" option = random.choice(text.get("random", "flip")) await ctx.send( text.fill("random", "answer", mention=ctx.author.mention, option=option)) await utils.room_check(ctx)
async def sudo_review_remove(self, ctx, id: int): """Remove someone's review""" db_review = repo_r.get(id) if db_review is None: return await ctx.send( text.fill("judge", "no review", mention=ctx.author.mention)) repo_r.remove(id) await self.event.sudo(ctx.author, ctx.channel, f"Review {id} removed") return await ctx.send(text.get("judge", "removed"))
async def roomCheck(self, ctx: commands.Context): """Send an message to prevent bot spamming""" if isinstance(ctx.channel, discord.DMChannel): return botspam = self.getGuild().get_channel(config.channel_botspam) if ctx.channel.id not in config.bot_allowed: await ctx.send( text.fill("server", "botroom redirect", user=ctx.author, channel=botspam))
async def voice_unlock(self, ctx: commands.Context): """Make current voice channel visible""" await ctx.send(text.fill("voice", "wip", mention=ctx.author.mention), delete_after=10) await utils.delete(ctx) return channel = self.getVoiceChannel(ctx) if channel.id not in self.locked: await ctx.send( delete_after=config.get("delay", "user error"), content=text.fill("voice", "unlock error", user=ctx.author), ) return await channel.set_permissions(self.getVerifyRole(), view_channel=True) channel_name = channel.name.replace(" " + self.lock, "") await channel.edit(name=channel_name) self.locked.remove(channel.id) await utils.delete(ctx)
async def voice_lock(self, ctx: commands.Context): """Make current voice channel invisible""" await ctx.send(text.fill("voice", "wip", mention=ctx.author.mention), delete_after=10) await utils.delete(ctx) return channel = self.getVoiceChannel(ctx) if channel.id in self.locked: await ctx.send( delete_after=config.get("delay", "user error"), content=text.fill("voice", "lock error", user=ctx.author), ) return await channel.set_permissions(self.getVerifyRole(), overwrite=None) channel_name = channel.name + " " + self.lock await channel.edit(name=channel_name) self.locked.append(channel.id) await utils.delete(ctx)