aboutsummaryrefslogtreecommitdiffstats
path: root/bot/cogs/hacktober/monstersurvey.py
diff options
context:
space:
mode:
authorGravatar Leon Sandøy <[email protected]>2018-11-27 21:01:18 +0100
committerGravatar Gareth Coles <[email protected]>2018-11-27 21:01:18 +0100
commit70d2170a0a6594561d59c7d080c4280f1ebcd70b (patch)
tree3eb52bc45b91f3de1cc51a0cb2e710685009dd4d /bot/cogs/hacktober/monstersurvey.py
parentMerge pull request #69 from python-discord/issue/68-with-typing (diff)
Allows you to create Seasons. (#64)
* Allows you to create Season objects which change the bots behavior. For example, a season can determine things like the avatar, the nickname, and which cogs are loaded. Season automatically changes according to the date range you specify when you create it. * removing some hungarian notation. * Automatic season changes will now always happen at a minute past midnight, no matter when the bot started. * catching dunders in the glob. * Refine Season Creation behaviour and structure. * Added channel and role constants, refactored roles into NamedTuples, added role check decorators from the main bot, and added role checks for the season change feature. Yes this is duplicate code from our main bot, but it will just have to be like that for now until we get a bot core running. * replacing the or with an xor and switching out the assert for a UserWarning * New lockfile * changing discord.py to discord-py to prevent pip bug from putting two of them in our lockfile * fixing flake errors * flake8 * Cleaned everything up, but I seem to have introduced some sort of infinite load loop? o.O * Fixing up all bugs in the halloween cogs. This should be ready for merge now. * Add avatar_path baseclass method for consistency. While making it simpler to add avatar urls in new season extensions, it also allows the avatar resource path to be changed in a single place if needed in future. * Avoid shadowing builtin `object`. * Add debug mode, refine bot user editing on season load. The changing of a bot's username and avatar is heavily ratelimited. While testing, restarting the bot and changing seasons is required, and hitting these limits are typical. Instead, when in debug mode, the avatar isn't set and only the nickname is changed to prevent unnecessary account edit requests. In the case that the rate limit is hit when not in debug mode, there's an added fallback to use the nickname instead. * Add cancel load_seasons task on SeasonManager un/reload. Previously the load_seasons task was loaded and looping forever. Even if the cog was unloaded for some reason, it would still be running. On loading the SeasonManager again, it would create a new load_seasons task, while the old one still existed. Adding the cancellation allows the task to end when the cog is unloaded or reloaded, and will help assist with live code changes during development at a later time where it's possible to reload this extension (perhaps when the pending bot core is implemented). * get_season_class helper, season class attribs, fix admin id Changes `get_season`'s date check to not initialise unwanted classes (to avoid needless loading of tasks which would otherwise cause unexpected behaviour). To do this, defining attributes of season classes have been moved from `__init__` as an instance variable, to the class variable level. This also results in `__init__` not needing to be defined for the `SeasonBase` class, and `super().__init__()` not needing to be called in individual season classes, making things cleaner/simpler for them. Adds a helper function for retrieving a season class and combines two unnecessarily separate if statements. Credits to @MarkKoz for the suggestions. Reverts the admin ID mistakenly changed in a previous commit. * Update bot/seasons/halloween/hacktoberstats.py Co-Authored-By: heavysaturn <[email protected]> * Update bot/seasons/halloween/halloween_facts.py Co-Authored-By: heavysaturn <[email protected]> * No more property in halloweenfacts * Changed all aliases to tuples * Made tokens a seperate namedtuple * Update bot/seasons/halloween/spookyavatar.py Co-Authored-By: heavysaturn <[email protected]>
Diffstat (limited to 'bot/cogs/hacktober/monstersurvey.py')
-rw-r--r--bot/cogs/hacktober/monstersurvey.py218
1 files changed, 0 insertions, 218 deletions
diff --git a/bot/cogs/hacktober/monstersurvey.py b/bot/cogs/hacktober/monstersurvey.py
deleted file mode 100644
index 2b78abc6..00000000
--- a/bot/cogs/hacktober/monstersurvey.py
+++ /dev/null
@@ -1,218 +0,0 @@
-import json
-import logging
-import os
-
-from discord import Embed
-from discord.ext import commands
-from discord.ext.commands import Bot, Context
-
-log = logging.getLogger(__name__)
-
-EMOJIS = {
- 'SUCCESS': u'\u2705',
- 'ERROR': u'\u274C'
-}
-
-
-class MonsterSurvey:
- """
- Vote for your favorite monster!
- This command allows users to vote for their favorite listed monster.
- Users may change their vote, but only their current vote will be counted.
- """
-
- def __init__(self, bot: Bot):
- """Initializes values for the bot to use within the voting commands."""
-
- self.bot = bot
- self.registry_location = os.path.join(os.getcwd(), 'bot', 'resources', 'halloween', 'monstersurvey.json')
- with open(self.registry_location, 'r') as jason:
- self.voter_registry = json.load(jason)
-
- def json_write(self):
- log.info("Saved Monster Survey Results")
- with open(self.registry_location, 'w') as jason:
- json.dump(self.voter_registry, jason, indent=2)
-
- def cast_vote(self, id: int, monster: str):
- """
- :param id: The id of the person voting
- :param monster: the string key of the json that represents a monster
- :return: None
- """
-
- vr = self.voter_registry
- for m in vr.keys():
- if id not in vr[m]['votes'] and m == monster:
- vr[m]['votes'].append(id)
- else:
- if id in vr[m]['votes'] and m != monster:
- vr[m]['votes'].remove(id)
-
- def get_name_by_leaderboard_index(self, n):
- n = n - 1
- vr = self.voter_registry
- top = sorted(vr, key=lambda k: len(vr[k]['votes']), reverse=True)
- name = top[n] if n >= 0 else None
- return name
-
- @commands.group(
- name='monster',
- aliases=['ms']
- )
- async def monster_group(self, ctx: Context):
- """
- The base voting command. If nothing is called, then it will return an embed.
- """
-
- if ctx.invoked_subcommand is None:
- async with ctx.typing():
- default_embed = Embed(
- title='Monster Voting',
- color=0xFF6800,
- description='Vote for your favorite monster!'
- )
- default_embed.add_field(
- name='.monster show monster_name(optional)',
- value='Show a specific monster. If none is listed, it will give you an error with valid choices.',
- inline=False)
- default_embed.add_field(
- name='.monster vote monster_name',
- value='Vote for a specific monster. You get one vote, but can change it at any time.',
- inline=False
- )
- default_embed.add_field(
- name='.monster leaderboard',
- value='Which monster has the most votes? This command will tell you.',
- inline=False
- )
- default_embed.set_footer(text=f"Monsters choices are: {', '.join(self.voter_registry.keys())}")
-
- await ctx.send(embed=default_embed)
-
- @monster_group.command(
- name='vote'
- )
- async def monster_vote(self, ctx: Context, name=None):
- """
- Casts a vote for a particular monster, or displays a list of monsters that can be voted for
- if one is not given.
- """
-
- if name is None:
- await ctx.invoke(self.monster_leaderboard)
- return
-
- async with ctx.typing():
- # Check to see if user used a numeric (leaderboard) index to vote
- try:
- idx = int(name)
- name = self.get_name_by_leaderboard_index(idx)
- except ValueError:
- name = name.lower()
-
- vote_embed = Embed(
- name='Monster Voting',
- color=0xFF6800
- )
-
- m = self.voter_registry.get(name)
- if m is None:
- vote_embed.description = f'You cannot vote for {name} because it\'s not in the running.'
- vote_embed.add_field(
- name='Use `.monster show {monster_name}` for more information on a specific monster',
- value='or use `.monster vote {monster}` to cast your vote for said monster.',
- inline=False
- )
- vote_embed.add_field(
- name='You may vote for or show the following monsters:',
- value=f"{', '.join(self.voter_registry.keys())}"
- )
- else:
- self.cast_vote(ctx.author.id, name)
- vote_embed.add_field(
- name='Vote successful!',
- value=f'You have successfully voted for {m["full_name"]}!',
- inline=False
- )
- vote_embed.set_thumbnail(url=m['image'])
- vote_embed.set_footer(text="Please note that any previous votes have been removed.")
- self.json_write()
-
- await ctx.send(embed=vote_embed)
-
- @monster_group.command(
- name='show'
- )
- async def monster_show(self, ctx: Context, name=None):
- """
- Shows the named monster. If one is not named, it sends the default voting embed instead.
-
- :param ctx:
- :param name:
- :return:
- """
-
- if name is None:
- await ctx.invoke(self.monster_leaderboard)
- return
-
- async with ctx.typing():
- # Check to see if user used a numeric (leaderboard) index to vote
- try:
- idx = int(name)
- name = self.get_name_by_leaderboard_index(idx)
- except ValueError:
- name = name.lower()
-
- m = self.voter_registry.get(name)
- if not m:
- await ctx.send('That monster does not exist.')
- await ctx.invoke(self.monster_vote)
- return
-
- embed = Embed(title=m['full_name'], color=0xFF6800)
- embed.add_field(name='Summary', value=m['summary'])
- embed.set_image(url=m['image'])
- embed.set_footer(text=f'To vote for this monster, type .monster vote {name}')
-
- await ctx.send(embed=embed)
-
- @monster_group.command(
- name='leaderboard',
- aliases=['lb']
- )
- async def monster_leaderboard(self, ctx: Context):
- """
- Shows the current standings.
- :param ctx:
- :return:
- """
-
- async with ctx.typing():
- vr = self.voter_registry
- top = sorted(vr, key=lambda k: len(vr[k]['votes']), reverse=True)
- total_votes = sum(len(m['votes']) for m in self.voter_registry.values())
-
- embed = Embed(title="Monster Survey Leader Board", color=0xFF6800)
- for rank, m in enumerate(top):
- votes = len(vr[m]['votes'])
- percentage = ((votes / total_votes) * 100) if total_votes > 0 else 0
- embed.add_field(name=f"{rank+1}. {vr[m]['full_name']}",
- value=(
- f"{votes} votes. {percentage:.1f}% of total votes.\n"
- f"Vote for this monster by typing "
- f"'.monster vote {m}'\n"
- f"Get more information on this monster by typing "
- f"'.monster show {m}'"
- ),
- inline=False)
-
- embed.set_footer(text="You can also vote by their rank number. '.monster vote {number}' ")
-
- await ctx.send(embed=embed)
-
-
-def setup(bot):
- bot.add_cog(MonsterSurvey(bot))
- log.debug("MonsterSurvey COG Loaded")