aboutsummaryrefslogtreecommitdiffstats
path: root/bot/exts/halloween
diff options
context:
space:
mode:
Diffstat (limited to 'bot/exts/halloween')
-rw-r--r--bot/exts/halloween/candy_collection.py60
-rw-r--r--bot/exts/halloween/hacktoberstats.py79
2 files changed, 38 insertions, 101 deletions
diff --git a/bot/exts/halloween/candy_collection.py b/bot/exts/halloween/candy_collection.py
index bd0b90cc..33e18b24 100644
--- a/bot/exts/halloween/candy_collection.py
+++ b/bot/exts/halloween/candy_collection.py
@@ -1,18 +1,14 @@
-import json
import logging
import random
-# from pathlib import Path
from typing import Union
import discord
+from async_rediscache import RedisCache
from discord.ext import commands
from bot.constants import Channels, Month
from bot.utils.decorators import in_month
-# TODO: Implement substitutes for volume-persistent methods. # noqa: T000
-# from bot.utils.persist import make_persistent
-
log = logging.getLogger(__name__)
# chance is 1 in x range, so 1 in 20 range would give 5% chance (for add candy)
@@ -37,18 +33,15 @@ EMOJIS = dict(
class CandyCollection(commands.Cog):
"""Candy collection game Cog."""
- def __init__(self, bot: commands.Bot):
- self.bot = bot
- # self.json_file = make_persistent(Path("bot", "resources", "halloween", "candy_collection.json"))
+ # User candy amount records
+ candy_records = RedisCache()
- with self.json_file.open() as fp:
- candy_data = json.load(fp)
+ # Candy and skull messages mapping
+ candy_messages = RedisCache()
+ skull_messages = RedisCache()
- self.candy_records = candy_data.get("records", dict())
-
- # Message ID where bot added the candies/skulls
- self.candy_messages = set()
- self.skull_messages = set()
+ def __init__(self, bot: commands.Bot):
+ self.bot = bot
@in_month(Month.OCTOBER)
@commands.Cog.listener()
@@ -63,11 +56,11 @@ class CandyCollection(commands.Cog):
# do random check for skull first as it has the lower chance
if random.randint(1, ADD_SKULL_REACTION_CHANCE) == 1:
- self.skull_messages.add(message.id)
+ await self.skull_messages.set(message.id, "skull")
return await message.add_reaction(EMOJIS['SKULL'])
# check for the candy chance next
if random.randint(1, ADD_CANDY_REACTION_CHANCE) == 1:
- self.candy_messages.add(message.id)
+ await self.candy_messages.set(message.id, "candy")
return await message.add_reaction(EMOJIS['CANDY'])
@in_month(Month.OCTOBER)
@@ -94,17 +87,19 @@ class CandyCollection(commands.Cog):
await self.reacted_msg_chance(message)
return
- if message.id in self.candy_messages and str(reaction.emoji) == EMOJIS['CANDY']:
- self.candy_messages.remove(message.id)
- prev_record = self.candy_records.get(str(user.id), 0)
- self.candy_records[str(user.id)] = prev_record + 1
+ if await self.candy_messages.get(message.id) == "candy" and str(reaction.emoji) == EMOJIS['CANDY']:
+ await self.candy_messages.delete(message.id)
+ if await self.candy_records.contains(user.id):
+ await self.candy_records.increment(user.id)
+ else:
+ await self.candy_records.set(user.id, 1)
- elif message.id in self.skull_messages and str(reaction.emoji) == EMOJIS['SKULL']:
- self.skull_messages.remove(message.id)
+ elif await self.skull_messages.get(message.id) == "skull" and str(reaction.emoji) == EMOJIS['SKULL']:
+ await self.skull_messages.delete(message.id)
- if prev_record := self.candy_records.get(str(user.id)):
+ if prev_record := await self.candy_records.get(user.id):
lost = min(random.randint(1, 3), prev_record)
- self.candy_records[str(user.id)] = prev_record - lost
+ await self.candy_records.decrement(user.id, lost)
if lost == prev_record:
await CandyCollection.send_spook_msg(user, message.channel, 'all of your')
@@ -116,7 +111,6 @@ class CandyCollection(commands.Cog):
return # Skip saving
await reaction.clear()
- await self.bot.loop.run_in_executor(None, self.save_to_json)
async def reacted_msg_chance(self, message: discord.Message) -> None:
"""
@@ -126,11 +120,11 @@ class CandyCollection(commands.Cog):
existing reaction.
"""
if random.randint(1, ADD_SKULL_EXISTING_REACTION_CHANCE) == 1:
- self.skull_messages.add(message.id)
+ await self.skull_messages.set(message.id, "skull")
return await message.add_reaction(EMOJIS['SKULL'])
if random.randint(1, ADD_CANDY_EXISTING_REACTION_CHANCE) == 1:
- self.candy_messages.add(message.id)
+ await self.candy_messages.set(message.id, "candy")
return await message.add_reaction(EMOJIS['CANDY'])
@property
@@ -159,18 +153,15 @@ class CandyCollection(commands.Cog):
"I tried to take your candies but you had none to begin with!")
await channel.send(embed=embed)
- def save_to_json(self) -> None:
- """Save JSON to a local file."""
- with self.json_file.open('w') as fp:
- json.dump(dict(records=self.candy_records), fp)
-
@in_month(Month.OCTOBER)
@commands.command()
async def candy(self, ctx: commands.Context) -> None:
"""Get the candy leaderboard and save to JSON."""
+ records = await self.candy_records.items()
+
def generate_leaderboard() -> str:
top_sorted = sorted(
- ((user_id, score) for user_id, score in self.candy_records.items() if score > 0),
+ ((user_id, score) for user_id, score in records if score > 0),
key=lambda x: x[1],
reverse=True
)
@@ -199,3 +190,4 @@ class CandyCollection(commands.Cog):
def setup(bot: commands.Bot) -> None:
"""Candy Collection game Cog load."""
+ bot.add_cog(CandyCollection(bot))
diff --git a/bot/exts/halloween/hacktoberstats.py b/bot/exts/halloween/hacktoberstats.py
index 4fd5c324..26d75565 100644
--- a/bot/exts/halloween/hacktoberstats.py
+++ b/bot/exts/halloween/hacktoberstats.py
@@ -1,21 +1,17 @@
-import json
import logging
import re
from collections import Counter
from datetime import datetime, timedelta
-# from pathlib import Path
from typing import List, Tuple, Union
import aiohttp
import discord
+from async_rediscache import RedisCache
from discord.ext import commands
from bot.constants import Channels, Month, Tokens, WHITELISTED_CHANNELS
from bot.utils.decorators import in_month, override_in_channel
-# TODO: Implement substitutes for volume-persistent methods. # noqa: T000
-# from bot.utils.persist import make_persistent
-
log = logging.getLogger(__name__)
CURRENT_YEAR = datetime.now().year # Used to construct GH API query
@@ -39,10 +35,11 @@ GITHUB_NONEXISTENT_USER_MESSAGE = (
class HacktoberStats(commands.Cog):
"""Hacktoberfest statistics Cog."""
+ # Stores mapping of user IDs and GitHub usernames
+ linked_accounts = RedisCache()
+
def __init__(self, bot: commands.Bot):
self.bot = bot
- # self.link_json = make_persistent(Path("bot", "resources", "halloween", "github_links.json"))
- self.linked_accounts = self.load_linked_users()
@in_month(Month.SEPTEMBER, Month.OCTOBER, Month.NOVEMBER)
@commands.group(name="hacktoberstats", aliases=("hackstats",), invoke_without_command=True)
@@ -58,8 +55,8 @@ class HacktoberStats(commands.Cog):
if not github_username:
author_id, author_mention = self._author_mention_from_context(ctx)
- if str(author_id) in self.linked_accounts.keys():
- github_username = self.linked_accounts[author_id]["github_username"]
+ if await self.linked_accounts.contains(author_id):
+ github_username = await self.linked_accounts.get(author_id)
logging.info(f"Getting stats for {author_id} linked GitHub account '{github_username}'")
else:
msg = (
@@ -79,30 +76,19 @@ class HacktoberStats(commands.Cog):
"""
Link the invoking user's Github github_username to their Discord ID.
- Linked users are stored as a nested dict:
- {
- Discord_ID: {
- "github_username": str
- "date_added": datetime
- }
- }
+ Linked users are stored in Redis: User ID => GitHub Username.
"""
author_id, author_mention = self._author_mention_from_context(ctx)
if github_username:
- if str(author_id) in self.linked_accounts.keys():
- old_username = self.linked_accounts[author_id]["github_username"]
+ if await self.linked_accounts.contains(author_id):
+ old_username = await self.linked_accounts.get(author_id)
logging.info(f"{author_id} has changed their github link from '{old_username}' to '{github_username}'")
await ctx.send(f"{author_mention}, your GitHub username has been updated to: '{github_username}'")
else:
logging.info(f"{author_id} has added a github link to '{github_username}'")
await ctx.send(f"{author_mention}, your GitHub username has been added")
- self.linked_accounts[author_id] = {
- "github_username": github_username,
- "date_added": datetime.now()
- }
-
- self.save_linked_users()
+ await self.linked_accounts.set(author_id, github_username)
else:
logging.info(f"{author_id} tried to link a GitHub account but didn't provide a username")
await ctx.send(f"{author_mention}, a GitHub username is required to link your account")
@@ -114,7 +100,7 @@ class HacktoberStats(commands.Cog):
"""Remove the invoking user's account link from the log."""
author_id, author_mention = self._author_mention_from_context(ctx)
- stored_user = self.linked_accounts.pop(author_id, None)
+ stored_user = await self.linked_accounts.pop(author_id, None)
if stored_user:
await ctx.send(f"{author_mention}, your GitHub profile has been unlinked")
logging.info(f"{author_id} has unlinked their GitHub account")
@@ -122,48 +108,6 @@ class HacktoberStats(commands.Cog):
await ctx.send(f"{author_mention}, you do not currently have a linked GitHub account")
logging.info(f"{author_id} tried to unlink their GitHub account but no account was linked")
- self.save_linked_users()
-
- def load_linked_users(self) -> dict:
- """
- Load list of linked users from local JSON file.
-
- Linked users are stored as a nested dict:
- {
- Discord_ID: {
- "github_username": str
- "date_added": datetime
- }
- }
- """
- if self.link_json.exists():
- logging.info(f"Loading linked GitHub accounts from '{self.link_json}'")
- with open(self.link_json, 'r', encoding="utf8") as file:
- linked_accounts = json.load(file)
-
- logging.info(f"Loaded {len(linked_accounts)} linked GitHub accounts from '{self.link_json}'")
- return linked_accounts
- else:
- logging.info(f"Linked account log: '{self.link_json}' does not exist")
- return {}
-
- def save_linked_users(self) -> None:
- """
- Save list of linked users to local JSON file.
-
- Linked users are stored as a nested dict:
- {
- Discord_ID: {
- "github_username": str
- "date_added": datetime
- }
- }
- """
- logging.info(f"Saving linked_accounts to '{self.link_json}'")
- with open(self.link_json, 'w', encoding="utf8") as file:
- json.dump(self.linked_accounts, file, default=str)
- logging.info(f"linked_accounts saved to '{self.link_json}'")
-
async def get_stats(self, ctx: commands.Context, github_username: str) -> None:
"""
Query GitHub's API for PRs created by a GitHub user during the month of October.
@@ -491,3 +435,4 @@ class HacktoberStats(commands.Cog):
def setup(bot: commands.Bot) -> None:
"""Hacktoberstats Cog load."""
+ bot.add_cog(HacktoberStats(bot))