예제 #1
0
async def who(ctx: commands.Context, username: str) -> None:

    user = get_user(username, bot)

    if user is not None:
        info = get_user_info(user)
        add_footer(info.embed, ctx.message.author)
        await info.send(ctx)
        return

    # Look for nearest matches, if they exist
    users = bot.get_guild(guild_id).members  # type: List[discord.Member]
    # Just using sequencematcher because its simple and no need to install extra Library
    # If keen on better distrance metrics, look at installing Jellyfish or Fuzzy Wuzzy
    similarities = [(member,
                     max(
                         SequenceMatcher(None, username.lower(),
                                         member.display_name.lower()).ratio(),
                         SequenceMatcher(None, username.lower(),
                                         member.name.lower()).ratio()))
                    for member in users]
    similarities.sort(key=lambda tup: tup[1], reverse=True)

    # unlikely to get 5 with >70% match anyway...
    top_matches = [x for x in similarities[:5]
                   if x[1] > 0.7]  # type: List[Tuple[discord.Member, float]]

    uids = [x[0].id for x in top_matches]
    infos = requests.get("https://dev.openstudyroom.org/league/discord-api/",
                         params={
                             'uids': uids
                         }).json()

    # Split and recombine so that OSR members appear top of list
    osr_members = [
        x for x in top_matches if infos.get(str(x[0].id)) is not None
    ]
    not_osr_members = [x for x in top_matches if x not in osr_members]
    top_matches = osr_members + not_osr_members

    message = ''
    for _i, x in enumerate(top_matches):
        message += '\n{}\N{COMBINING ENCLOSING KEYCAP}**{}**#{} {}'.format(
            _i + 1, x[0].display_name, x[0].discriminator,
            user_rank(x[0], infos))
    if username in roles_dict:
        message += "\n\n However, `" + username + "` is a valid role. Did you mean `!list " + username + "`?"
    nearest_or_sorry = '", nearest matches:' if top_matches else '", sorry'
    embed = discord.Embed(description=message,
                          title='No users by the exact name "' + username +
                          nearest_or_sorry)
    add_footer(embed, ctx.message.author)
    msg = await ctx.send(embed=embed)

    for _i, match in enumerate(
            top_matches):  # type: Tuple[int, Tuple[discord.Member, float]]
        await msg.add_reaction(str(_i + 1) + '\N{COMBINING ENCLOSING KEYCAP}')

    SPECIAL_MESSAGES[msg.id] = WhoMessage(msg, ctx.message.author,
                                          [x[0] for x in top_matches])
예제 #2
0
async def rank(ctx: commands.Context, username: str = None) -> None:
    """Show rank graphs for OGS and KGS servers."""
    if username is None:
        last_message = await ctx.message.channel.history(limit=1).flatten()
        user = last_message[0].author
    else:
        user = get_user(username, bot)

    if user is not None:
        infos = requests.get("https://openstudyroom.org/league/discord-api/",
                             params={
                                 'uids': [user.id]
                             }).json()
        info = infos.get(str(user.id))
        if info is not None:
            kgs_username = info.get('kgs_username')
            ogs_username = info.get('ogs_username')
            ogs_id = info.get('ogs_id')
            if kgs_username is not None:
                embed = discord.Embed(title="KGS rank history for " +
                                      str(username),
                                      color=0xeee657)
                embed.set_image(url="http://www.gokgs.com/servlet/graph/" +
                                kgs_username + "-en_US.png")
                add_footer(embed, ctx.author)
                await ctx.send(embed=embed)
            if ogs_username is not None:

                def format_gorank(value):
                    if value == 0:
                        return "1d"
                    elif value > 0:
                        return str(int(value)) + "k"
                    elif value < 0:
                        return str(1 + abs(int(value))) + "d"

                r = requests.get(
                    'https://online-go.com/termination-api/player/' +
                    str(ogs_id) + '/rating-history?speed=overall&size=0')
                rl = r.text.split('\n')
                rank = []
                dates = []
                for game in range(1, len(rl) - 1):
                    rank.append(30 - (31.25) *
                                math.log(float(rl[game].split('\t')[4]) / 850))
                    dates.append(
                        datetime.utcfromtimestamp(int(
                            rl[game].split('\t')[0])).strftime('%d/%m/%Y'))

                x = [datetime.strptime(d, '%d/%m/%Y').date() for d in dates]
                y = range(len(x))

                fig, ax = plt.subplots(nrows=1, ncols=1)
                plt.plot(x, rank, color=(0, 194 / 255, 0))

                ax.xaxis.set_major_formatter(mdates.DateFormatter('\n%Y'))
                ax.xaxis.set_major_locator(mdates.YearLocator())
                ax.invert_yaxis()

                fig.canvas.draw()
                labels = [
                    format_gorank(float(item.get_text().replace('−', '-')))
                    for item in ax.get_yticklabels()
                ]
                ax.set_yticklabels(labels)
                fig.patch.set_facecolor((236 / 255, 236 / 255, 176 / 255))
                ax.patch.set_facecolor('black')
                ax.yaxis.grid(linewidth=0.2)
                plt.title("OGS Rank history for " + ogs_username)

                fig.savefig('Rank.png', bbox_inches='tight')

                file = discord.File('Rank.png',
                                    filename="OGS Rank history for " +
                                    ogs_username + ".png")
                await ctx.send(file=file)

                os.remove('Rank.png')
        return
    # Look for nearest matches, if they exist
    users = bot.get_guild(guild_id).members  # type: List[discord.Member]
    # Just using sequencematcher because its simple and no need to install extra Library
    # If keen on better distrance metrics, look at installing Jellyfish or Fuzzy Wuzzy
    similarities = [(member,
                     max(
                         SequenceMatcher(None, username.lower(),
                                         member.display_name.lower()).ratio(),
                         SequenceMatcher(None, username.lower(),
                                         member.name.lower()).ratio()))
                    for member in users]
    similarities.sort(key=lambda tup: tup[1], reverse=True)

    # unlikely to get 5 with >70% match anyway...
    top_matches = [x for x in similarities[:5]
                   if x[1] > 0.7]  # type: List[Tuple[discord.Member, float]]

    uids = [x[0].id for x in top_matches]
    infos = requests.get("https://openstudyroom.org/league/discord-api/",
                         params={
                             'uids': uids
                         }).json()

    # Split and recombine so that OSR members appear top of list
    osr_members = [
        x for x in top_matches if infos.get(str(x[0].id)) is not None
    ]
    not_osr_members = [x for x in top_matches if x not in osr_members]
    top_matches = osr_members + not_osr_members

    message = ''
    for _i, x in enumerate(top_matches):
        message += '\n{}\N{COMBINING ENCLOSING KEYCAP}**{}**#{} {}'.format(
            _i + 1, x[0].display_name, x[0].discriminator,
            user_rank(x[0], infos))
    if username in roles_dict:
        message += "\n\n However, `" + username + "` is a valid role. Did you mean `!list " + username + "`?"
    nearest_or_sorry = '", nearest matches:' if top_matches else '", sorry'
    embed = discord.Embed(description=message,
                          title='No users by the exact name "' + username +
                          nearest_or_sorry)
    add_footer(embed, ctx.message.author)
    msg = await ctx.send(embed=embed)