Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Identify #101

Merged
merged 5 commits into from
Aug 11, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Implement ;handle identify
  • Loading branch information
krofna committed Aug 5, 2019
commit f8867e8cf2b53a8a4362c09d6c1ea99d87053d66
38 changes: 36 additions & 2 deletions tle/cogs/handles.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import io

import discord
import random
from discord.ext import commands

from tle.util import codeforces_api as cf
Expand Down Expand Up @@ -128,6 +129,7 @@ def _make_pages(users):
class Handles(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.identify_map = dict()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style-wise {} is nicer.


@commands.group(brief='Commands that have to do with handles', invoke_without_command=True)
async def handle(self, ctx):
Expand All @@ -136,6 +138,8 @@ async def handle(self, ctx):

async def update_member_rank_role(self, member, role_to_assign):
role_names_to_remove = {rank.title for rank in cf.RATED_RANKS} - {role_to_assign.name}
if role_to_assign.name not in ['Newbie', 'Pupil', 'Specialist', 'Expert']:
role_names_to_remove.add('Purgatory')
to_remove = [role for role in member.roles if role.name in role_names_to_remove]
if to_remove:
await member.remove_roles(*to_remove, reason='Codeforces rank update')
Expand All @@ -146,10 +150,11 @@ async def update_member_rank_role(self, member, role_to_assign):
@commands.has_role('Admin')
async def set(self, ctx, member: discord.Member, handle: str):
"""Set Codeforces handle of a user."""
# CF API returns correct handle ignoring case, update to it
users = await cf.user.info(handles=[handle])
user = users[0]
await self._set(ctx, member, users[0])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this a typical case where you would write a decorator, but this is fine.


# CF API returns correct handle ignoring case, update to it
async def _set(self, ctx, member, user):
handle = user.handle
cf_common.user_db.cache_cfuser(user)
cf_common.user_db.sethandle(member.id, handle)
Expand All @@ -163,6 +168,35 @@ async def set(self, ctx, member: discord.Member, handle: str):
raise HandleCogError(f'Role for rank `{user.rank.title}` not present in the server')
await self.update_member_rank_role(member, roles[0])

@handle.command(brief='Identify yourself')
async def identify(self, ctx, handle: str):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docstring and usage?

users = await cf.user.info(handles=[handle])
if not users:
await ctx.send('`{handle}` not found on codeforces')
return

invoker = str(ctx.author)
problem = random.choice(cf_common.cache2.problem_cache.problems)
handle, name, url = (users[0].handle, problem.name, problem.url)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels a bit superfluous considering most of these are just used once. Just write them in-place, the names are obvious enough and not too long.

self.identify_map[invoker] = (handle, name, url)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to store the url? It's not used for anything right now afaik.

await ctx.send(f'`{invoker}`, submit a compile error to <{url}> and then run `;handle report`')

@handle.command(brief='Report identification')
async def report(self, ctx):
invoker = str(ctx.author)
if not invoker in self.identify_map:
await ctx.send(f'`{invoker}`, you have nothing to report')
return

handle, prob, url = self.identify_map[invoker]
subs = await cf.user.status(handle=handle, count=5)
if any(sub.problem.name == prob and sub.verdict == 'COMPILATION_ERROR' for sub in subs):
self.identify_map.pop(invoker)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The general wisdom for removing things from dicts in python is to use value = D.pop(key) if you want to capture the value, otherwise just do del D[key].

users = await cf.user.info(handles=[handle])
await self._set(ctx, ctx.author, users[0])
else:
await ctx.send(f'Sorry `{invoker}`, can you try again?')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General note: We probably should write a function that escapes usernames so we actually print the correct thing. Something that prepends *_` with a backslash would do the job.


@handle.command(brief='Get handle by Discord username')
async def get(self, ctx, member: discord.Member):
"""Show Codeforces handle of a user."""
Expand Down
3 changes: 3 additions & 0 deletions tle/cogs/starboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ async def check_and_add_to_starboard(self, starboard_channel_id, payload):
raise StarboardCogError('Starboard channel not found')

channel = self.bot.get_channel(payload.channel_id)
if channel.name == 'gitgud' or 'purgatory' in channel.name:
return

message = await channel.fetch_message(payload.message_id)
if (message.type != discord.MessageType.default or
len(message.content) == 0 and len(message.attachments) == 0):
Expand Down