Exemplo n.º 1
0
class BaseTwitchPlugin:
    def __init__(self, bot):
        self.bot = bot
        self.bancho_queue = self.bot.config.get('bancho_queue')
        self.bancho_nick = self.bot.config.get('bancho_nick')
        self.osu = OsuApi(self.bot.config.get('osu_api_key'),
                          connector=AHConnector())
        tillerino_key = self.bot.config.get('tillerino_api_key')
        if tillerino_key:
            self.tillerino = TillerinoApi(tillerino_key)
        else:
            self.tillerino = None
        self.twitch_channel = self.bot.config.get('twitch_channel')
        if not self.twitch_channel.startswith('#'):
            self.twitch_channel = '#{}'.format(self.twitch_channel)

    @irc3.event(irc3.rfc.CONNECTED)
    def connected(self, **kw):
        self.bot.log.info('[twitch] Connected to twitch as {}'.format(
            self.bot.nick))
        self.join(self.twitch_channel)

    def join(self, channel):
        self.bot.log.info('[twitch] Trying to join channel {}'.format(channel))
        self.bot.join(channel)

    def part(self, channel):
        self.bot.log.info('[twitch] Leaving channel {}'.format(channel))
        self.bot.part(channel)

    @asyncio.coroutine
    def _get_pp(self, beatmap, mods=OsuMod.NoMod):
        if self.tillerino:
            try:
                with async_timeout.timeout(15):
                    data = yield from self.tillerino.beatmapinfo(
                        beatmap.beatmap_id, mods=mods.value)
                if data:
                    if 'starDiff' in data:
                        # use Tillerino star rating since it factors in mods
                        beatmap.difficultyrating = data['starDiff']
                    pp = {
                        float(acc): pp_val
                        for acc, pp_val in data.get('ppForAcc', {}).items()
                    }
                    if pp:
                        beatmap.pp = pp
                        return pp
            except (HTTPError, asyncio.TimeoutError) as e:
                self.bot.log.debug('[twitch] {}'.format(e))
        beatmap.pp = None
        return None

    def validate_beatmaps(self, beatmaps, **kwargs):
        """Return subset of maps in beatmaps that pass validation criteria

        Raises:
            BeatmapValidationError if a map fails validation

        Override this method in subclasses as needed
        """
        return beatmaps

    @asyncio.coroutine
    def _beatmap_msg(self, beatmap, mods=OsuMod.NoMod):
        if mods == OsuMod.NoMod:
            mod_string = ''
        else:
            mod_string = ' +{:s}'.format(mods)
        beatmap = self._apply_mods(beatmap, mods)
        # get pp before generating message since it may update star rating based on
        yield from self._get_pp(beatmap, mods=mods)
        msg = '[{}] {} - {} [{}] (by {}){}, ♫ {:g}, ★ {:.2f}'.format(
            beatmap.approved.name.capitalize(),
            beatmap.artist,
            beatmap.title,
            beatmap.version,
            beatmap.creator,
            mod_string,
            beatmap.bpm,
            round(beatmap.difficultyrating, 2),
        )
        if beatmap.pp:
            msg = ' | '.join([
                msg,
                '95%: {}pp'.format(round(beatmap.pp[.95])),
                '98%: {}pp'.format(round(beatmap.pp[.98])),
                '100%: {}pp'.format(round(beatmap.pp[1.0])),
            ])
        return msg

    @asyncio.coroutine
    def _request_mapset(self,
                        match,
                        mask,
                        target,
                        mods=OsuMod.NoMod,
                        **kwargs):
        try:
            with async_timeout.timeout(15):
                mapset = yield from self.osu.get_beatmaps(
                    beatmapset_id=match.group('mapset_id'),
                    include_converted=0)
            if not mapset:
                return (None, None)
            mapset = sorted(mapset, key=lambda x: x.difficultyrating)
        except (HTTPError, asyncio.TimeoutError) as e:
            self.bot.log.debug('[twitch] {}'.format(e))
            return (None, None)
        try:
            beatmap = self.validate_beatmaps(mapset, **kwargs)[-1]
        except BeatmapValidationError as e:
            return (None, e.reason)
        msg = yield from self._beatmap_msg(beatmap, mods=mods)
        return (beatmap, msg)

    @asyncio.coroutine
    def _request_beatmap(self,
                         match,
                         mask,
                         target,
                         mods=OsuMod.NoMod,
                         **kwargs):
        try:
            with async_timeout.timeout(10):
                beatmaps = yield from self.osu.get_beatmaps(
                    beatmap_id=match.group('beatmap_id'), include_converted=0)
            if not beatmaps:
                return (None, None)
        except (HTTPError, asyncio.TimeoutError) as e:
            self.bot.log.debug('[twitch] {}'.format(e))
            return (None, None)
        try:
            beatmap = self.validate_beatmaps(beatmaps, **kwargs)[0]
        except BeatmapValidationError as e:
            return (None, e.reason)
        msg = yield from self._beatmap_msg(beatmap, mods=mods)
        return (beatmap, msg)

    def _badge_list(self, badges):
        """Parse twitch badge ircv3 tags into a list"""
        b_list = []
        for x in badges.split(','):
            (badge, version) = x.split('/', 1)
            b_list.append(badge)
        return b_list

    def _is_sub(self, privmsg_tags):
        """Check if twitch irc3 tags include sub (or mod) badge"""
        badges = self._badge_list(privmsg_tags.get('badges', ''))
        if any(b in badges
               for b in ['broadcaster', 'moderator', 'subscriber']):
            return True
        elif privmsg_tags.get('mod', 0) == 1:
            return True
        elif privmsg_tags.get('subscriber', 0) == 1:
            return True

    @asyncio.coroutine
    def _request_beatmapsets(self, match, mask, target, **kwargs):
        """Handle "new" osu web style beatmapsets links"""
        if match.group('beatmap_id'):
            return self._request_beatmap(match, mask, target, **kwargs)
        else:
            return self._request_mapset(match, mask, target, **kwargs)

    def _bancho_msg(self, mask, beatmap, mods=OsuMod.NoMod):
        m, s = divmod(beatmap.total_length, 60)
        if mods == OsuMod.NoMod:
            mod_string = ''
        else:
            mod_string = ' +{:s}'.format(mods)
        bancho_msg = ' '.join([
            '{} >'.format(mask.nick),
            '[http://osu.ppy.sh/b/{} {} - {} [{}]]{}'.format(
                beatmap.beatmap_id,
                beatmap.artist,
                beatmap.title,
                beatmap.version,
                mod_string,
            ),
            '{}:{:02d} ★ {:.2f} ♫ {:g} AR{:g} OD{:g}'.format(
                m,
                s,
                round(beatmap.difficultyrating, 2),
                beatmap.bpm,
                round(beatmap.diff_approach, 1),
                round(beatmap.diff_overall, 1),
            ),
        ])
        if beatmap.pp:
            bancho_msg = ' | '.join([
                bancho_msg,
                '95%: {}pp'.format(round(beatmap.pp[.95])),
                '98%: {}pp'.format(round(beatmap.pp[.98])),
                '100%: {}pp'.format(round(beatmap.pp[1.0])),
            ])
        return bancho_msg

    def _parse_mods(self, mods):
        mod_dict = {
            'NF': OsuMod.NoFail,
            'EZ': OsuMod.Easy,
            'HD': OsuMod.Hidden,
            'HR': OsuMod.HardRock,
            'SD': OsuMod.SuddenDeath,
            'DT': OsuMod.DoubleTime,
            'RX': OsuMod.Relax,
            'HT': OsuMod.HalfTime,
            'NC': OsuMod.Nightcore,
            'FL': OsuMod.Flashlight,
            'SO': OsuMod.SpunOut,
            'AP': OsuMod.Autopilot,
            'PF': OsuMod.Perfect,
        }
        if (len(mods) % 2) != 0:
            mods = mods[:-1]
        mod_flags = OsuMod.NoMod
        for mod in [mods.upper()[i:i + 2] for i in range(0, len(mods), 2)]:
            mod_flags |= mod_dict.get(mod, OsuMod.NoMod)
        return mod_flags

    def _mod_ar(self, ar, ar_mul, speed_mul):
        ar0_ms = 1800
        ar5_ms = 1200
        ar10_ms = 450
        ar_ms_step1 = (ar0_ms - ar5_ms) / 5.0
        ar_ms_step2 = (ar5_ms - ar10_ms) / 5.0

        ar_ms = ar5_ms
        ar *= ar_mul
        if ar < 5.0:
            ar_ms = ar0_ms - ar_ms_step1 * ar
        else:
            ar_ms = ar5_ms - ar_ms_step2 * (ar - 5.0)
        # cap between 0-10 before applying HT/DT
        ar_ms = min(ar0_ms, max(ar10_ms, ar_ms))
        ar_ms /= speed_mul
        if ar_ms > ar5_ms:
            ar = (ar0_ms - ar_ms) / ar_ms_step1
        else:
            ar = 5.0 + (ar5_ms - ar_ms) / ar_ms_step2
        return ar

    def _mod_od(self, od, od_mul, speed_mul):
        od0_ms = 79.5
        od10_ms = 19.5
        od_ms_step = (od0_ms - od10_ms) / 10.0

        od *= od_mul
        od_ms = od0_ms - math.ceil(od_ms_step * od)
        # cap between 0-10 before applying HT/DT
        od_ms = min(od0_ms, max(od10_ms, od_ms))
        od_ms /= speed_mul
        od = (od0_ms - od_ms) / od_ms_step
        return od

    def _apply_mods(self, beatmap, mods=OsuMod.NoMod):
        """Return a copy of beatmap with difficulty modifiers applied"""
        if mods == OsuMod.NoMod:
            return beatmap

        modded = beatmap

        if (OsuMod.DoubleTime
                | OsuMod.Nightcore) in mods and OsuMod.HalfTime not in mods:
            speed_mul = 1.5
        elif OsuMod.HalfTime in mods and (OsuMod.DoubleTime
                                          | OsuMod.Nightcore) not in mods:
            speed_mul = .75
        else:
            speed_mul = 1.0
        modded.bpm *= speed_mul

        if OsuMod.HardRock in mods and OsuMod.Easy not in mods:
            od_ar_hp_mul = 1.4
            cs_mul = 1.3
        elif OsuMod.Easy in mods and OsuMod.HardRock not in mods:
            od_ar_hp_mul = .5
            cs_mul = .5
        else:
            od_ar_hp_mul = 1.0
            cs_mul = 1.0
        modded.diff_approach = self._mod_ar(beatmap.diff_approach,
                                            od_ar_hp_mul, speed_mul)
        modded.diff_overall = self._mod_ar(beatmap.diff_overall, od_ar_hp_mul,
                                           speed_mul)
        modded.diff_drain = min(10.0, beatmap.diff_drain * od_ar_hp_mul)
        modded.diff_size = min(10.0, beatmap.diff_size * cs_mul)

        return modded

    @irc3.event(irc3.rfc.PRIVMSG)
    @asyncio.coroutine
    def request_beatmap(self,
                        tags=None,
                        mask=None,
                        target=None,
                        data=None,
                        bancho_target=None,
                        **kwargs):
        if not target.is_channel or not data:
            return
        patterns = [
            (r'https?://osu\.ppy\.sh/b/(?P<beatmap_id>\d+)',
             self._request_beatmap),
            (r'https?://osu\.ppy\.sh/s/(?P<mapset_id>\d+)',
             self._request_mapset),
            (r'https?://osu\.ppy\.sh/beatmapsets/(?P<mapset_id>\d+)(#(?P<mode>[a-z]+))?(/(?P<beatmap_id>\d+))?',
             self._request_beatmapsets),
        ]
        for pattern, callback in patterns:
            mod_pattern = r'(/?\s*\+?(?P<mods>[A-Za-z]+))?'
            m = re.search(''.join([pattern, mod_pattern]), data)
            if m:
                if m.group('mods'):
                    mod_flags = self._parse_mods(m.group('mods'))
                else:
                    mod_flags = OsuMod.NoMod
                (beatmap, msg) = yield from callback(m,
                                                     mask,
                                                     target,
                                                     mods=mod_flags,
                                                     **kwargs)
                if beatmap:
                    bancho_msg = self._bancho_msg(mask,
                                                  beatmap,
                                                  mods=mod_flags)
                    if not bancho_target:
                        bancho_target = self.bancho_nick
                    yield from self.bancho_queue.put(
                        (bancho_target, bancho_msg))
                if msg:
                    self.bot.privmsg(target, msg)
                break

    @command
    @asyncio.coroutine
    def stats(self, mask, target, args, default_user=None):
        """Check stats for an osu! player

            %%stats [<username>]...
        """
        self.bot.log.debug('[twitch] !stats {}'.format(args))
        if target.is_channel:
            dest = target
        else:
            dest = mask
        osu_username = '******'.join(args.get('<username>')).strip()
        if not osu_username:
            if default_user:
                osu_username = default_user
            else:
                osu_username = self.bancho_nick
        try:
            with async_timeout.timeout(10):
                users = yield from self.osu.get_user(osu_username)
        except (HTTPError, asyncio.TimeoutError) as e:
            self.bot.log.debug('[twitch] {}'.format(e))
            users = []
        if not users:
            self.bot.privmsg(
                dest, 'Could not find osu! user {}'.format(osu_username))
            return
        user = users[0]
        msg = ' | '.join([
            user.username,
            'PP: {:,} (#{:,})'.format(user.pp_raw, user.pp_rank),
            'Acc: {:g}%'.format(round(user.accuracy, 2)),
            'Score: {:,}'.format(user.total_score),
            'Plays: {:,} (lv{})'.format(user.playcount,
                                        math.floor(user.level)),
            'https://osu.ppy.sh/users/{}'.format(user.user_id),
        ])
        self.bot.privmsg(dest, msg)
Exemplo n.º 2
0
from pyecharts.faker import Collector, Faker
from pyecharts.globals import ThemeType
from pyecharts.components import Table, Image
from pyecharts.options import ComponentTitleOpts
from pyecharts.commons.utils import JsCode
from osuapi import OsuApi, ReqConnector, OsuMode
import requests
api = OsuApi("13a36d70fd32e2f87fd2a7a89e4f52d54ab337a1", connector=ReqConnector())

user_name = input('Please enter osu! user name:')


#######################  get mapper beatmaps info  #######################

try:
    beatmap_list= api.get_beatmaps(since=None, beatmapset_id=None, beatmap_id=None, username=user_name, mode=None, include_converted=True, beatmap_hash=None, limit=500)    
    df_beatmap = pd.DataFrame()
    for beatmap in beatmap_list:
        df_beatmap_1 = pd.DataFrame( dict(beatmap), index=[0])
        df_beatmap = df_beatmap.append(df_beatmap_1, ignore_index=True)
except:
    print('No results for user name')
    sys.exit()

if len(beatmap_list)==0:
    print('Player has no map')
    sys.exit()
    
    
#######################  data collation  #######################
Exemplo n.º 3
0
import requests
from osuapi import OsuApi, ReqConnector
import json

api = OsuApi("f0bfd051b9e0dba2d56b96a71b416061593d7f31",
             connector=ReqConnector())
user = "******"
scoreThreshold = 5000000000

results = api.get_user_recent(user, limit=1)

recentScore = results[0]

beatmaps = api.get_beatmaps(beatmap_id=recentScore.beatmap_id, limit=1)
beatmapData = beatmaps[0]

debugMessage = "User {} ({}) got a score of {} and rank {} on beatmap {} (#{}) at {}"
print(
    debugMessage.format(user, recentScore.user_id, recentScore.score,
                        recentScore.rank, beatmapData.title,
                        recentScore.beatmap_id, recentScore.date))
Exemplo n.º 4
0
#get map details
filename=playername+"_"+str(datetime.date.today())
fw=open("Users\\"+filename+".txt","w")
for i in range(100):
	c.execute("CREATE TABLE IF NOT EXISTS BEATMAPS(BEATMAP_ID INTEGER, TITLE TEXT, LINK TEXT, CREATOR TEXT, BPM REAL, SR REAL, LENGTH INTEGER, DIFFICULTY TEXT)")
	try:
		map = dump[i].split(" ")
		if map[0] in scoreidonly:
			continue
	except:
		pass
	c.execute("SELECT * FROM BEATMAPS WHERE BEATMAP_ID=?", (int(map[0]),))
	data = c.fetchone()
	if data is None:
		result = api.get_beatmaps(beatmap_id=int(map[0]))
		if len(result) == 0:
			continue
		link = ("https://osu.ppy.sh/b/"+str(map[0]) + "?m=0")
		c.execute("INSERT INTO BEATMAPS VALUES(?,?,?,?,?,?,?,?)", (int(map[0]), result[0].title, link,result[0].creator, result[0].bpm, result[0].difficultyrating, result[0].total_length, result[0].version))		
	c.execute("SELECT * FROM BEATMAPS WHERE BEATMAP_ID=?", (int(map[0]),))
	data = c.fetchone()
	mod = findmaxmod(map[0], modcounter)
	outstring=data[1] + "\t" + data[7] + "\t" + mod + "\t" + "SR: " + str(data[5])[:3] + " BPM: " + str(data[4]) + " Length: " + str(data[6])+ " "
	outstring += data[3] + "\t" + data[2]
	fw.write(outstring)
	fw.write("\n")

#final steps
conn.commit()
fw.close()
Exemplo n.º 5
0
class OsuTracker(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.config = confparser.get("config.json")

        self.api = OsuApi(key=self.config.osu_token, connector=ReqConnector())
        self.last_check_datetime = datetime.datetime.utcnow()
        self.tracking_channel = None
        self.tracked_users = self.get_tracked_users()

        self.tracker_task_loop.start()

    def cog_unload(self):
        self.tracker_task_loop.cancel()

    @tasks.loop(seconds=30)
    async def tracker_task_loop(self):
        for user in self.tracked_users:
            scores = self.api.get_user_best(user['name'], limit=20)
            for s in [s for s in scores if s.date > self.last_check_datetime]:
                bmap = self.api.get_beatmaps(beatmap_id=s.beatmap_id)[0]
                msg = f"{user['nick']} abım {bmap.title} - {bmap.version} mapınde {int(round(s.pp))} pp play yapmıs\n" \
                      f"helal abım <@{user['discord'].id}>\n".lower().replace('i', 'ı')
                await self.tracking_channel.send(msg)
        self.last_check_datetime = datetime.datetime.utcnow()

    def get_tracked_users(self):
        with open("tracked_users.json", "r") as f:
            data = json.load(f) if not json.load(f) == {} else None
        users = []
        if data:
            for u in data['users']:
                users.append({
                    "name": u['name'],
                    "discord": self.bot.get_user(id=u['discord_id']),
                    "nick": u['nick']
                })
        return users

    def add_to_tracked_users_file(self, osu_username, discord_id, nick):
        with open("tracked_users.json", "w") as f:
            data = json.load(f)
            if data == {}:
                data = {
                    "users": [{
                        "name": osu_username,
                        "discord_id": discord_id,
                        "nick": nick
                    }]
                }
            else:
                data['users'].append({
                    "name": osu_username,
                    "discord_id": discord_id,
                    "nick": nick
                })
                data.update()
            print(data)
            json.dump(data, f)

    @commands.command()
    @commands.check(permissions.is_owner)
    async def osutrack(self, ctx, mem: discord.Member, osu_username, nick):
        if osu_username not in [u['name'] for u in self.tracked_users]:
            try:
                osu_id = self.api.get_user(osu_username)[0].user_id
                self.tracked_users.append({
                    "name": osu_username,
                    "nick": nick,
                    "discord": mem
                })
                self.add_to_tracked_users_file(osu_username,
                                               discord_id=mem.id,
                                               nick=nick)
                await ctx.send(
                    f"tracking started : {str(mem)}, osu id : {osu_id}")
            except:
                await ctx.send(f"couldn't start tracking")
        else:
            await ctx.send(f"already tracking : {str(mem)}")

    @commands.command()
    @commands.check(permissions.is_owner)
    async def setch(self, ctx):
        self.tracking_channel = ctx
        await ctx.send(f"ok")
Exemplo n.º 6
0
class OsuModule:
    def __init__(self, client):
        self.client = client
        self.database = self.client.database
        self.api = OsuApi(self.database.get_osu_api_key(),
                          connector=ReqConnector())

    # Completed with Rich embed.
    @commands.command(name='osu')
    async def osu(self, ctx, *params, member: discord.Member = None):
        if member is None and len(params) == 0:
            discord_id = ctx.message.author.id

            self.database.cursor.execute(
                "SELECT `osu_id` FROM `users` WHERE `discord_id` = ?",
                (discord_id, ))
            osu_id = self.database.cursor.fetchone()[0]

            embed = self.display_profile(osu_id)
            await ctx.send(embed=embed)

        elif len(params) > 0:
            for osu_id in params:
                embed = self.display_profile(osu_id)
                await ctx.send(embed=embed)

        if member is not None:
            print(member.id)
            self.database.cursor.execute(
                "SELECT `osu_id` FROM `users` WHERE `discord_id` = ?",
                (member.id, ))

            osu_id = self.database.cursor.fetchone()[0]

            embed = self.display_profile(osu_id)
            await ctx.send(embed=embed)

    @commands.command(name='top')
    async def top(self, ctx, *params):
        (user, amt) = self.params_seperator(ctx, *params)
        embed = self.top_scores(user, amt)
        await ctx.send(embed=embed)

    @commands.command(name='recent')  # Completed With Rich Embed.
    async def recent(self, ctx, *params):
        (user, amt) = self.params_seperator(ctx, *params)
        embed = self.recent_scores(user, amt)
        await ctx.send(embed=embed)

    @commands.command(name='set')
    async def set(self, ctx, param):
        discord_id = ctx.message.author.id
        osu_id = self.api.get_user(param)[0].user_id
        self.database.cursor.execute(
            "SELECT `osu_id` FROM `users` WHERE `discord_id` = ?",
            (discord_id, ))
        data = self.database.cursor.fetchone()
        if data is None:
            self.database.cursor.execute(
                "INSERT INTO `users`(`discord_id`, `osu_id`, `days`, `total`) VALUES (?, ?, 0, 0)",
                (discord_id, osu_id))
            self.database.db.commit()
            title = 'Succesfully set {} IGN as {}'.format(
                ctx.message.author, param)
            embed = discord.Embed(title=title, colour=0xDEADBF)
            await ctx.send(embed=embed)
        else:
            await ctx.send("Record Already Exists")

    @commands.command(name='compare')
    async def compare(self, ctx, user1, user2):
        embed = self.check(user1, user2)
        await ctx.send(embed=embed)

    @commands.command(name='topr')
    async def topr(self, ctx, *params):
        (user, amt) = self.params_seperator(ctx, *params)
        embed = self.recent_top(user, amt)
        await ctx.send(embed=embed)

    def display_profile(self, param):
        # Obtaining Profile from Paramerter.
        profile = self.api.get_user(param)

        # Local Stuff
        title = "osu! Profile for " + profile[0].username
        thumbnail = "https://a.ppy.sh/" + str(profile[0].user_id)
        user_url = "https://osu.ppy.sh/users/" + str(profile[0].user_id)

        # Embed Creation.
        embed = discord.Embed(title=title,
                              timestamp=datetime.utcnow(),
                              url=user_url,
                              color=0xFF0418,
                              footer="Osu India bot v.1.0")

        # thumbnails
        embed.set_thumbnail(url=thumbnail)
        # PP
        embed.add_field(name="PP", value=str(profile[0].pp_raw), inline=True)
        # Rank
        embed.add_field(name="Rank",
                        value='#' + str(profile[0].pp_rank),
                        inline=True)
        # Playcount
        embed.add_field(name="Playcount",
                        value=str(profile[0].playcount),
                        inline=True)
        # Accuracy
        embed.add_field(name="Accuracy",
                        value=str(profile[0].accuracy)[:6],
                        inline=True)
        # Country Indentification.
        embed.add_field(name="Country",
                        value=str(profile[0].country),
                        inline=True)
        # Country Rank.
        embed.add_field(name="Country Rank",
                        value='#' + str(profile[0].pp_country_rank),
                        inline=True)
        return embed

    def top_scores(self, user, amt):
        # Api Call
        scores = self.api.get_user_best(user, limit=amt)

        # Local Stuff.
        title = "Top {} Scores for {}".format(amt, user)
        count = 1

        # Embed
        embed = discord.Embed(title=title,
                              timestamp=datetime.utcnow(),
                              color=0xFF0418,
                              footer="Osu India bot v.1.0")
        # Fields.
        for score in scores:
            beatmap = self.api.get_beatmaps(beatmap_id=score.beatmap_id)
            Title = "#{}. {}[{}] +**{}**".format(count, beatmap[0].title,
                                                 beatmap[0].version,
                                                 score.enabled_mods)
            Value = "PP:{}\n Played {}".format(
                score.pp, self.time_elapsed(str(score.date)))
            embed.add_field(name=Title, value=Value, inline=False)
            count += 1
        return embed

    def recent_scores(self, user, amt):
        scores = self.api.get_user_recent(user, limit=amt)
        title = "Recent {} scores for {}".format(amt, user)
        count = 1

        # Discord Embed Creation.
        embed = discord.Embed(title=title,
                              timestamp=datetime.utcnow(),
                              color=0xFF0418,
                              footer="Osu India bot v0.2.0")

        # Looping over all Scores and adding fields.
        for score in scores:
            beatmap = self.api.get_beatmaps(beatmap_id=score.beatmap_id)
            name = "#{}. {}[{}] +**{}**".format(count, beatmap[0].title,
                                                beatmap[0].version,
                                                score.enabled_mods)

            time_delta = str(score.date)

            value = "*Played {}\n SR: {}".format(
                self.time_elapsed(time_delta),
                str(beatmap[0].difficultyrating)[:5])

            embed.add_field(name=name, value=value, inline=False)
            count += 1

        return embed

    # Hacked this together using 3 lists, modifications needed
    def recent_top(self, user, amt):
        scores_list = []
        scores = self.api.get_user_best(user, limit=100)

        for i in range(100):
            scores_list.append((i + 1, scores[i]))

        # sort according to date
        scores_sorted = sorted(scores_list,
                               key=lambda score: score[1].date,
                               reverse=True)

        title = "Recent {} top scores for {}".format(amt, user)
        count = 1

        # Embed
        embed = discord.Embed(title=title,
                              timestamp=datetime.utcnow(),
                              color=0xFF0418,
                              footer="Osu India bot v0.2.0")
        # Fields.
        for score in scores_sorted:
            if count > amt:
                break

            beatmap = self.api.get_beatmaps(beatmap_id=score[1].beatmap_id)
            name = "#{}. {}[{}] +**{}**".format(score[0], beatmap[0].title,
                                                beatmap[0].version,
                                                score[1].enabled_mods)

            value = "PP:{}\n Played {}".format(
                score[1].pp, self.time_elapsed(str(score[1].date)))

            embed.add_field(name=name, value=value, inline=False)
            count += 1

        return embed

    def check(self, user1, user2):
        # major formatting required
        # to add avatar pic no clue how to
        p1 = self.api.get_user(user1)
        p2 = self.api.get_user(user2)

        title = "Comparing stats for " + user1 + " and " + user2

        desc = "\t\t" + user1 + "  |  " + user2 + "\t\t\n"  # \t or multiple spaces not working
        desc += "**Rank :**\t " + str(p1[0].pp_rank) + "  |  " + str(
            p2[0].pp_rank) + "\n"
        desc += "**Country Rank :**\t " + str(
            p1[0].pp_country_rank) + "  |  " + str(
                p2[0].pp_country_rank) + "\n"
        desc += "**PP :**\t " + str(p1[0].pp_raw) + "  |  " + str(
            p2[0].pp_raw) + "\n"
        desc += "**Accuracy :**\t " + str(p1[0].accuracy)[:5] + "  |  " + str(
            p2[0].accuracy)[:5] + "\n"

        score1 = self.api.get_user_best(user1, limit=1)
        score2 = self.api.get_user_best(user2, limit=1)

        desc += "**Top Play :**\t " + str(score1[0].pp) + "  |  " + str(
            score2[0].pp) + "\n"
        desc += "**Playcount :**\t " + str(p1[0].playcount) + "  |  " + str(
            p2[0].playcount) + "\n"

        embed = discord.Embed(title=title, description=desc, colour=0xDEADBF)

        return embed

    def time_elapsed(self, datestr):
        parsed_date = datetime.strptime(datestr, "%Y-%m-%d %H:%M:%S")
        today = datetime.utcnow()

        time_delta = relativedelta(today, parsed_date)

        years = abs(time_delta.years)
        months = abs(time_delta.months)
        days = abs(time_delta.days)
        hours = abs(time_delta.hours)
        minutes = abs(time_delta.minutes)
        seconds = abs(time_delta.seconds)

        time_elapsed = ""

        if (years > 0):
            time_elapsed += "{} year{}, ".format(years,
                                                 "s" if years != 1 else "")
        if (months > 0):
            time_elapsed += "{} month{}, ".format(months,
                                                  "s" if months != 1 else "")
        if (days > 0):
            time_elapsed += "{} day{}, ".format(days, "s" if days != 1 else "")
        if (hours > 0):
            time_elapsed += "{} hour{}, ".format(hours,
                                                 "s" if hours != 1 else "")
        if (minutes > 0):
            time_elapsed += "{} minute{}, ".format(minutes,
                                                   "s" if minutes != 1 else "")
        if (seconds > 0):
            time_elapsed += "{} second{} ago".format(
                seconds, "s" if seconds != 1 else "")

        return time_elapsed

    def params_seperator(self, ctx, *params):
        # Default user AND default amount
        if len(params) == 0:
            self.database.cursor.execute(
                "SELECT `osu_id` FROM `users` WHERE `discord_id` = ?",
                (ctx.message.author.id, ))
            osu_id = self.database.cursor.fetchone()[0]
            if osu_id is None:
                return (None, None)
            user = self.api.get_user(osu_id)[0].username
            amt = 5
        # Only default amount
        elif len(params) == 1:
            user = self.tag_to_id(ctx)
            if user is False:
                return (None, None)
            if user is None:
                user = params[0]
            amt = 5
        # No defaults
        else:
            user = self.tag_to_id(ctx)
            if user is False:
                return (None, None)
            if user is None:
                user = params[0]
            amt = params[1]
        return (user, amt)

    def tag_to_id(self, ctx):
        user_list = ctx.message.mentions
        if len(user_list) == 0:
            return None
        else:
            user_id = user_list[0].id
            self.database.cursor.execute(
                "SELECT `osu_id` FROM `users` WHERE `discord_id` = ?",
                (user_id, ))
            osu_id = self.database.cursor.fetchone()[0]
            if osu_id is None:
                return False
            return self.api.get_user(osu_id)[0].username

    def new_recent(self, user_id):
        scores = self.api.get_user_best(user_id, limit=50)
        new_scores = []
        last_checked = datetime.now(
        )  # need to save the last checked to a file
        scores_sorted = sorted(scores, key=lambda s: s.date,
                               reverse=True)  # sort according to date
        for score in scores_sorted:
            if score.date > last_checked:
                new_scores.append(score)
            else:
                break
        print("New Recent was executed")
        return new_scores