async def fossil_setup(ctx, fossil): logger.info("checking fossil data") if database.zscore("incorrect:global", string.capwords(str(fossil))) is not None: logger.info("fossil global ok") else: database.zadd("incorrect:global", {string.capwords(str(fossil)): 0}) logger.info("fossil global added") if database.zscore(f"incorrect.user:{ctx.author.id}", string.capwords(str(fossil))) is not None: logger.info("fossil user ok") else: database.zadd(f"incorrect.user:{ctx.author.id}", {string.capwords(str(fossil)): 0}) logger.info("fossil user added") if ctx.guild is not None: logger.info("no dm") if database.zscore(f"incorrect.server:{ctx.guild.id}", string.capwords(str(fossil))) is not None: logger.info("fossil server ok") else: database.zadd(f"incorrect.server:{ctx.guild.id}", {string.capwords(str(fossil)): 0}) logger.info("fossil server added") else: logger.info("dm context")
async def userscore(self, ctx, *, user: typing.Optional[typing.Union[discord.Member, str]] = None): logger.info("command: userscore") await channel_setup(ctx) await user_setup(ctx) if user is not None: if isinstance(user, str): await ctx.send("Not a user!") return usera = user.id logger.info(usera) if database.zscore("users:global", str(usera)) is not None: times = str(int(database.zscore("users:global", str(usera)))) user = f"<@{str(usera)}>" else: await ctx.send("This user does not exist on our records!") return else: if database.zscore("users:global", str(ctx.author.id)) is not None: user = f"<@{str(ctx.author.id)}>" times = str(int(database.zscore("users:global", str(ctx.author.id)))) else: await ctx.send("You haven't used this bot yet! (except for this)") return embed = discord.Embed(type="rich", colour=discord.Color.blurple()) embed.set_author(name="Bird ID - An Ornithology Bot") embed.add_field(name="User Score:", value=f"{user} has answered correctly {times} times.") await ctx.send(embed=embed)
async def bird_setup(ctx, bird): logger.info("checking bird data") if database.zscore("incorrect:global", string.capwords(str(bird))) is not None: logger.info("bird global ok") else: database.zadd("incorrect:global", {string.capwords(str(bird)): 0}) logger.info("bird global added") if database.zscore(f"incorrect.user:{ctx.author.id}", string.capwords(str(bird))) is not None: logger.info("bird user ok") else: database.zadd(f"incorrect.user:{ctx.author.id}", {string.capwords(str(bird)): 0}) logger.info("bird user added") if ctx.guild is not None: logger.info("no dm") if database.zscore(f"incorrect.server:{ctx.guild.id}", string.capwords(str(bird))) is not None: logger.info("bird server ok") else: database.zadd(f"incorrect.server:{ctx.guild.id}", {string.capwords(str(bird)): 0}) logger.info("bird server added") else: logger.info("dm context") if database.exists(f"session.data:{str(ctx.author.id)}"): logger.info("session in session") if database.zscore(f"session.incorrect:{ctx.author.id}", string.capwords(str(bird))) is not None: logger.info("bird session ok") else: database.zadd(f"session.incorrect:{ctx.author.id}", {string.capwords(str(bird)): 0}) logger.info("bird session added") else: logger.info("no session")
async def user_setup(ctx): logger.info("checking user data") if database.zscore("users:global", str(ctx.author.id)) is not None: logger.info("user global ok") else: database.zadd("users:global", {str(ctx.author.id): 0}) logger.info("user global added") await ctx.send("Welcome <@" + str(ctx.author.id) + ">!") if ctx.guild is not None: logger.info("no dm") if database.zscore(f"users.server:{ctx.guild.id}", str(ctx.author.id)) is not None: server_score = database.zscore(f"users.server:{ctx.guild.id}", str(ctx.author.id)) global_score = database.zscore("users:global", str(ctx.author.id)) if server_score is global_score: logger.info("user server ok") else: database.zadd(f"users.server:{ctx.guild.id}", {str(ctx.author.id): global_score}) else: score = int(database.zscore("users:global", str(ctx.author.id))) database.zadd(f"users.server:{ctx.guild.id}", {str(ctx.author.id): score}) logger.info("user server added") else: logger.info("dm context")
async def check(self, ctx, *, guess): logger.info("command: check") await channel_setup(ctx) await user_setup(ctx) current_fossil = str( database.hget(f"channel:{str(ctx.channel.id)}", "fossil"))[2:-1] if current_fossil == "": await ctx.send("You must ask for a fossil first!") else: # if there is a fossil, it checks answer await fossil_setup(ctx, current_fossil) database.hset(f"channel:{str(ctx.channel.id)}", "fossil", "") database.hset(f"channel:{str(ctx.channel.id)}", "answered", "1") if spellcheck(guess.split(" ")[-1], current_fossil.split(" ")[-1]): logger.info("correct") if database.exists(f"session.data:{ctx.author.id}"): logger.info("session active") session_increment(ctx, "correct", 1) await ctx.send("Correct! Good job!") page = wikipedia.page(current_fossil) await ctx.send(page.url) score_increment(ctx, 1) if int(database.zscore("users:global", str(ctx.author.id))) in achievements: number = str( int(database.zscore("users:global", str(ctx.author.id)))) await ctx.send( f"Wow! You have answered {number} fossils correctly!") filename = 'achievements/' + number + ".PNG" with open(filename, 'rb') as img: await ctx.send( file=discord.File(img, filename="award.png")) else: logger.info("incorrect") if database.exists(f"session.data:{ctx.author.id}"): logger.info("session active") session_increment(ctx, "incorrect", 1) incorrect_increment(ctx, str(current_fossil), 1) await ctx.send("Sorry, the fossil was actually " + current_fossil.lower() + ".") page = wikipedia.page(current_fossil) await ctx.send(page.url) logger.info("current_fossil: " + str(current_fossil.lower().replace("-", " "))) logger.info("guess: " + str(guess.lower().replace("-", " ")))
async def channel_setup(ctx): logger.info("checking channel setup") if database.exists(f"channel:{str(ctx.channel.id)}"): logger.info("channel data ok") else: database.hmset( f"channel:{str(ctx.channel.id)}", { "bird": "", "answered": 1, "sBird": "", "sAnswered": 1, "goatsucker": "", "gsAnswered": 1, "prevJ": 20, "prevB": "", "prevS": "", "prevK": 20 } ) # true = 1, false = 0, index 0 is last arg, prevJ is 20 to define as integer logger.info("channel data added") await ctx.send("Ok, setup! I'm all ready to use!") if database.zscore("score:global", str(ctx.channel.id)) is not None: logger.info("channel score ok") else: database.zadd("score:global", {str(ctx.channel.id): 0}) logger.info("channel score added")
async def score(self, ctx): logger.info("command: score") await channel_setup(ctx) await user_setup(ctx) totalCorrect = int(database.zscore("score:global", str(ctx.channel.id))) await ctx.send( f"Wow, looks like a total of {str(totalCorrect)} birds have been answered correctly in this channel! " + "Good job everyone!" )
async def _send_stats(self, ctx, preamble): placings = 5 database_key = f"race.scores:{str(ctx.channel.id)}" if database.zcard(database_key) is 0: logger.info(f"no users in {database_key}") await ctx.send("There are no users in the database.") return if placings > database.zcard(database_key): placings = database.zcard(database_key) leaderboard_list = database.zrevrangebyscore( database_key, "+inf", "-inf", 0, placings, True) embed = discord.Embed( type="rich", colour=discord.Color.blurple(), title=preamble) embed.set_author(name="Bird ID - An Ornithology Bot") leaderboard = "" for i, stats in enumerate(leaderboard_list): if ctx.guild is not None: user = ctx.guild.get_member(int(stats[0])) else: user = None if user is None: user = self.bot.get_user(int(stats[0])) if user is None: user = "******" else: user = f"**{user.name}#{user.discriminator}**" else: user = f"**{user.name}#{user.discriminator}** ({str(user.mention)})" leaderboard += f"{str(i+1)}. {user} - {str(int(stats[1]))}\n" start = int(database.hget(f"race.data:{str(ctx.channel.id)}", "start")) elapsed = str(datetime.timedelta(seconds=round(time.time()) - start)) embed.add_field(name="Options", value=await self._get_options(ctx), inline=False) embed.add_field( name="Stats", value=f"**Race Duration:** `{elapsed}`", inline=False) embed.add_field(name="Leaderboard", value=leaderboard, inline=False) if database.zscore(database_key, str(ctx.author.id)) is not None: placement = int(database.zrevrank( database_key, str(ctx.author.id))) + 1 embed.add_field( name="You:", value=f"You are #{str(placement)}.", inline=False) else: embed.add_field( name="You:", value="You haven't answered any correctly.") await ctx.send(embed=embed)
async def check(self, ctx, *, arg): logger.info("command: check") await channel_setup(ctx) await user_setup(ctx) currentBird = str( database.hget(f"channel:{str(ctx.channel.id)}", "bird"))[2:-1] if currentBird == "": # no bird await ctx.send("You must ask for a bird first!") else: # if there is a bird, it checks answer logger.info("currentBird: " + str(currentBird.lower().replace("-", " "))) logger.info("args: " + str(arg.lower().replace("-", " "))) await bird_setup(ctx, currentBird) sciBird = await get_sciname(currentBird) if spellcheck(arg, currentBird) is True or spellcheck( arg, sciBird) is True: logger.info("correct") database.zincrby("streak:global", 1, str(ctx.author.id)) database.hset(f"channel:{str(ctx.channel.id)}", "bird", "") database.hset(f"channel:{str(ctx.channel.id)}", "answered", "1") if database.exists(f"session.data:{ctx.author.id}"): logger.info("session active") session_increment(ctx, "correct", 1) # check if streak is greater than max, if so, increases max if database.zscore("streak:global", str( ctx.author.id)) > database.zscore( "streak.max:global", str(ctx.author.id)): database.zadd( "streak.max:global", { str(ctx.author.id): database.zscore("streak:global", str( ctx.author.id)) }) await ctx.send("Correct! Good job!" if not database.exists( f"race.data:{str(ctx.channel.id)}" ) else f"**{str(ctx.author.mention)}**, you are correct!") page = wikipedia.page(f"{currentBird} (bird)") await ctx.send(page.url if not database.exists( f"race.data:{str(ctx.channel.id)}") else f"<{page.url}>") score_increment(ctx, 1) if int(database.zscore("users:global", str(ctx.author.id))) in achievement: number = str( int(database.zscore("users:global", str(ctx.author.id)))) await ctx.send( f"Wow! You have answered {number} birds correctly!") filename = 'achievements/' + number + ".PNG" with open(filename, 'rb') as img: await ctx.send( file=discord.File(img, filename="award.png")) if database.exists(f"race.data:{str(ctx.channel.id)}") and str( database.hget(f"race.data:{str(ctx.channel.id)}", "media"))[2:-1] == "image": limit = int( database.hget(f"race.data:{str(ctx.channel.id)}", "limit")) first = database.zrevrange( f"race.scores:{str(ctx.channel.id)}", 0, 0, True)[0] if int(first[1]) >= limit: logger.info("race ending") race = self.bot.get_cog("Race") await race.stop_race_(ctx) else: logger.info("auto sending next bird image") addon, bw = map( str, database.hmget(f"race.data:{str(ctx.channel.id)}", ["addon", "bw"])) birds = self.bot.get_cog("Birds") await birds.send_bird_(ctx, addon[2:-1], bw[2:-1]) else: logger.info("incorrect") database.zadd("streak:global", {str(ctx.author.id): 0}) if database.exists(f"session.data:{str(ctx.author.id)}"): logger.info("session active") session_increment(ctx, "incorrect", 1) incorrect_increment(ctx, str(currentBird), 1) if database.exists(f"race.data:{str(ctx.channel.id)}"): await ctx.send("Sorry, that wasn't the right answer.") else: database.hset(f"channel:{str(ctx.channel.id)}", "bird", "") database.hset(f"channel:{str(ctx.channel.id)}", "answered", "1") await ctx.send("Sorry, the bird was actually " + currentBird.lower() + ".") page = wikipedia.page(f"{currentBird} (bird)") await ctx.send(page.url)
async def checkgoat(self, ctx, *, arg): logger.info("command: checkgoat") await channel_setup(ctx) await user_setup(ctx) currentBird = str( database.hget(f"channel:{str(ctx.channel.id)}", "goatsucker"))[2:-1] if currentBird == "": # no bird await ctx.send("You must ask for a bird first!") else: # if there is a bird, it checks answer await bird_setup(ctx, currentBird) index = goatsuckers.index(currentBird) sciBird = sciGoat[index] database.hset(f"channel:{str(ctx.channel.id)}", "gsAnswered", "1") database.hset(f"channel:{str(ctx.channel.id)}", "goatsucker", "") if spellcheck(arg, currentBird) is True or spellcheck( arg, sciBird) is True: logger.info("correct") database.zincrby("streak:global", 1, str(ctx.author.id)) if database.zscore("streak:global", str( ctx.author.id)) > database.zscore( "streak.max:global", str(ctx.author.id)): database.zadd( "streak.max:global", { str(ctx.author.id): database.zscore("streak:global", str( ctx.author.id)) }) if database.exists(f"session.data:{ctx.author.id}"): logger.info("session active") session_increment(ctx, "correct", 1) await ctx.send("Correct! Good job!") page = wikipedia.page(f"{currentBird} (bird)") await ctx.send(page.url) score_increment(ctx, 1) if int(database.zscore("users:global", str(ctx.author.id))) in achievement: number = str( int(database.zscore("users:global", str(ctx.author.id)))) await ctx.send( f"Wow! You have answered {number} birds correctly!") filename = 'achievements/' + number + ".PNG" with open(filename, 'rb') as img: await ctx.send( file=discord.File(img, filename="award.png")) else: logger.info("incorrect") database.zadd("streak:global", {str(ctx.author.id): 0}) if database.exists(f"session.data:{ctx.author.id}"): logger.info("session active") session_increment(ctx, "incorrect", 1) incorrect_increment(ctx, str(currentBird), 1) await ctx.send("Sorry, the bird was actually " + currentBird.lower() + ".") page = wikipedia.page(f"{currentBird} (bird)") await ctx.send(page.url) logger.info("currentBird: " + str(currentBird.lower().replace("-", " "))) logger.info("args: " + str(arg.lower().replace("-", " ")))
async def streak(ctx): await user_setup(ctx) embed = discord.Embed(type="rich", colour=discord.Color.blurple()) embed.set_author(name="Bird ID - An Ornithology Bot") streakScore = "Your current streak is "+ str(int(database.zscore("streak:global", str(ctx.author.id))))+". Your max streak is " + str(int(database.zscore("streak.max:global", str(ctx.author.id))))+"." embed.add_field(name=f"User Score (Streak)", value=streakScore, inline=False)
async def leaderboard(self, ctx, scope="", page=1): logger.info("command: leaderboard") await channel_setup(ctx) await user_setup(ctx) try: page = int(scope) except ValueError: if scope is "": scope = "global" scope = scope.lower() else: scope = "global" logger.info(f"scope: {scope}") logger.info(f"page: {page}") if not scope in ("global", "server", "g", "s"): logger.info("invalid scope") await ctx.send(f"**{scope} is not a valid scope!**\n*Valid Scopes:* `global, server`") return if page < 1: logger.info("invalid page") await ctx.send("Not a valid number. Pick a positive integer!") return database_key = "" if scope in ("server", "s"): if ctx.guild is not None: database_key = f"users.server:{ctx.guild.id}" scope = "server" else: logger.info("dm context") await ctx.send("**Server scopes are not avaliable in DMs.**\n*Showing global leaderboard instead.*") scope = "global" database_key = "users:global" else: database_key = "users:global" scope = "global" user_amount = int(database.zcard(database_key)) page = (page * 10) - 10 if user_amount is 0: logger.info(f"no users in {database_key}") await ctx.send("There are no users in the database.") return if page > user_amount: page = user_amount - (user_amount % 10) leaderboard_list = database.zrevrangebyscore(database_key, "+inf", "-inf", page, 10, True) embed = discord.Embed(type="rich", colour=discord.Color.blurple()) embed.set_author(name="Bird ID - An Ornithology Bot") leaderboard = "" for i, stats in enumerate(leaderboard_list): if ctx.guild is not None: user = ctx.guild.get_member(int(stats[0])) else: user = None if user is None: user = self.bot.get_user(int(stats[0])) if user is None: user = "******" else: user = f"**{user.name}#{user.discriminator}**" else: user = f"**{user.name}#{user.discriminator}** ({str(user.mention)})" leaderboard += f"{str(i+1+page)}. {user} - {str(int(stats[1]))}\n" embed.add_field(name=f"Leaderboard ({scope})", value=leaderboard, inline=False) if database.zscore(database_key, str(ctx.author.id)) is not None: placement = int(database.zrevrank(database_key, str(ctx.author.id))) + 1 distance = int(database.zrevrange(database_key, placement-2, placement-2, True)[0 ][1]) - int(database.zscore(database_key, str(ctx.author.id))) if placement is 1: embed.add_field(name="You:", value=f"You are #{str(placement)} on the leaderboard.\n" + f"You are in first place.", inline=False) elif distance is 0: embed.add_field(name="You:", value=f"You are #{str(placement)} on the leaderboard.\n" + f"You are tied with #{str(placement-1)}", inline=False) else: embed.add_field(name="You:", value=f"You are #{str(placement)} on the leaderboard.\n" + f"You are {str(distance)} away from #{str(placement-1)}", inline=False) else: embed.add_field(name="You:", value="You haven't answered any correctly.") await ctx.send(embed=embed)
logger.info("no dm") if database.zscore(f"users.server:{ctx.guild.id}", str(ctx.author.id)) is not None: server_score = database.zscore(f"users.server:{ctx.guild.id}", str(ctx.author.id)) global_score = database.zscore("users:global", str(ctx.author.id)) if server_score is global_score: logger.info("user server ok") else: database.zadd(f"users.server:{ctx.guild.id}", {str(ctx.author.id): global_score}) else: score = int(database.zscore("users:global", str(ctx.author.id))) database.zadd(f"users.server:{ctx.guild.id}", {str(ctx.author.id): score}) logger.info("user server added") else: logger.info("dm context") #Add streak if (database.zscore("streak:global", str(UserID)) is not None) and (database.zscore("streak.max:global", str(UserID)) is not None): logger.info("user streak in already") else: database.zadd("streak:global", {str(UserID): 0}) database.zadd("streak.max:global",{str(UserID): 0}) print("added streak") # sets up new birds async def bird_setup(ctx, bird): logger.info("checking bird data") if database.zscore("incorrect:global", string.capwords(str(bird))) is not None: logger.info("bird global ok") else: database.zadd("incorrect:global", {string.capwords(str(bird)): 0}) logger.info("bird global added")
def user_banned(ctx): if database.zscore("banned:global", str(ctx.author.id)) is None: return True else: raise GenericError(code=842)
async def leaderboard(self, ctx, scope="", placings=5): logger.info("command: leaderboard") await channel_setup(ctx) await user_setup(ctx) try: placings = int(scope) except ValueError: if scope is "": scope = "global" scope = scope.lower() else: scope = "global" logger.info(f"scope: {scope}") logger.info(f"placings: {placings}") if not scope in ("global", "server", "g", "s"): logger.info("invalid scope") await ctx.send( f"**{scope} is not a valid scope!**\n*Valid Scopes:* `global, server`" ) return if placings > 10 or placings < 1: logger.info("invalid placings") await ctx.send("Not a valid number. Pick one between 1 and 10!") return database_key = "" if scope in ("server", "s"): if ctx.guild is not None: database_key = f"users.server:{ctx.guild.id}" scope = "server" else: logger.info("dm context") await ctx.send( "**Server scopes are not avaliable in DMs.**\n*Showing global leaderboard instead.*" ) scope = "global" database_key = "users:global" else: database_key = "users:global" scope = "global" if database.zcard(database_key) is 0: logger.info(f"no users in {database_key}") await ctx.send("There are no users in the database.") return if placings > database.zcard(database_key): placings = database.zcard(database_key) leaderboard_list = database.zrevrangebyscore(database_key, "+inf", "-inf", 0, placings, True) embed = discord.Embed(type="rich", colour=discord.Color.blurple()) embed.set_author(name=bot_name) leaderboard = "" for i, stats in enumerate(leaderboard_list): if ctx.guild is not None: user = ctx.guild.get_member(int(stats[0])) else: user = None if user is None: user = self.bot.get_user(int(stats[0])) if user is None: user = "******" else: user = f"**{user.name}#{user.discriminator}**" else: user = f"**{user.name}#{user.discriminator}** ({str(user.mention)})" leaderboard += f"{str(i+1)}. {user} - {str(int(stats[1]))}\n" embed.add_field(name=f"Leaderboard ({scope})", value=leaderboard, inline=False) if database.zscore(database_key, str(ctx.author.id)) is not None: placement = int(database.zrevrank(database_key, str( ctx.author.id))) + 1 embed.add_field( name="You:", value=f"You are #{str(placement)} on the leaderboard.", inline=False) else: embed.add_field(name="You:", value="You haven't answered any correctly.") await ctx.send(embed=embed)