130 lines
5.9 KiB
Python
130 lines
5.9 KiB
Python
import calendar
|
|
import logging
|
|
import typing as t
|
|
from contextlib import suppress
|
|
from datetime import datetime, timezone
|
|
|
|
import discord
|
|
from discord.ext import tasks
|
|
from redbot.core import Config, bank
|
|
from redbot.core.i18n import Translator
|
|
from redbot.core.utils.chat_formatting import humanize_number, text_to_file
|
|
|
|
from ..abc import MixinMeta
|
|
|
|
log = logging.getLogger("red.vrt.extendedeconomy.tasks")
|
|
_ = Translator("ExtendedEconomy", __file__)
|
|
|
|
|
|
class Tasks(MixinMeta):
|
|
@tasks.loop(seconds=60)
|
|
async def auto_paydays(self):
|
|
if not self.db.auto_payday_claim:
|
|
return
|
|
cog = self.bot.get_cog("Economy")
|
|
if cog is None:
|
|
return
|
|
eco_conf: Config = cog.config
|
|
is_global = await bank.is_global()
|
|
cur_time = calendar.timegm(datetime.now(tz=timezone.utc).utctimetuple())
|
|
if is_global:
|
|
bankgroup = bank._config._get_base_group(bank._config.USER)
|
|
ecogroup = eco_conf._get_base_group(eco_conf.USER)
|
|
accounts: t.Dict[str, dict] = await bankgroup.all()
|
|
ecousers: t.Dict[str, dict] = await ecogroup.all()
|
|
max_bal = await bank.get_max_balance()
|
|
payday_time = await eco_conf.PAYDAY_TIME()
|
|
payday_credits = await eco_conf.PAYDAY_CREDITS()
|
|
|
|
updated = []
|
|
for user in self.bot.users:
|
|
uid = str(user.id)
|
|
if uid not in accounts or uid not in ecousers:
|
|
# Reduce unnecessary writes for users that havent used economy
|
|
continue
|
|
next_payday = ecousers[uid].get("next_payday", 0) + payday_time
|
|
if cur_time < next_payday:
|
|
# Not ready yet
|
|
continue
|
|
accounts[uid]["balance"] = min(max_bal, accounts[uid]["balance"] + payday_credits)
|
|
ecousers[uid]["next_payday"] = cur_time
|
|
updated.append((f"{user.name} ({user.id}): {humanize_number(payday_credits)}\n", payday_credits))
|
|
|
|
if updated:
|
|
await bankgroup.set(accounts)
|
|
await ecogroup.set(ecousers)
|
|
if self.db.logs.auto_claim:
|
|
log.info(f"Claimed {len(updated)} global paydays")
|
|
ordered = sorted(updated, key=lambda x: x[1], reverse=True)
|
|
claimed = "\n".join([x[0] for x in ordered])
|
|
channel = self.bot.get_channel(self.db.logs.auto_claim)
|
|
if channel is not None:
|
|
with suppress(discord.HTTPException):
|
|
await channel.send(
|
|
f"Claimed {len(updated)} global paydays",
|
|
file=text_to_file(claimed, "paydays.txt"),
|
|
)
|
|
else:
|
|
keys = list(self.db.configs.keys())
|
|
for guild_id in keys:
|
|
guild = self.bot.get_guild(guild_id)
|
|
if guild is None:
|
|
continue
|
|
conf = self.db.configs[guild_id]
|
|
if not conf.auto_claim_roles:
|
|
continue
|
|
|
|
bankgroup = bank._config._get_base_group(bank._config.MEMBER, str(guild_id))
|
|
ecogroup = eco_conf._get_base_group(eco_conf.MEMBER, str(guild_id))
|
|
accounts: t.Dict[str, dict] = await bankgroup.all()
|
|
ecousers: t.Dict[str, dict] = await ecogroup.all()
|
|
max_bal = await bank.get_max_balance(guild)
|
|
payday_time = await eco_conf.guild(guild).PAYDAY_TIME()
|
|
payday_credits = await eco_conf.guild(guild).PAYDAY_CREDITS()
|
|
payday_roles: t.Dict[int, dict] = await eco_conf.all_roles()
|
|
|
|
updated = []
|
|
for member in guild.members:
|
|
uid = str(member.id)
|
|
if uid not in accounts or uid not in ecousers:
|
|
# Reduce unnecessary writes for members that havent used economy
|
|
continue
|
|
next_payday = ecousers[uid].get("next_payday", 0) + payday_time
|
|
if cur_time < next_payday:
|
|
# Not ready yet
|
|
continue
|
|
|
|
to_give = payday_credits
|
|
can_autoclaim = False
|
|
for role in member.roles:
|
|
if role.id in payday_roles:
|
|
role_credits = payday_roles[role.id]["PAYDAY_CREDITS"]
|
|
if conf.stack_paydays:
|
|
to_give += role_credits
|
|
elif role_credits > to_give:
|
|
to_give = role_credits
|
|
|
|
if role.id in conf.auto_claim_roles:
|
|
can_autoclaim = True
|
|
|
|
if not can_autoclaim:
|
|
continue
|
|
|
|
accounts[uid]["balance"] = min(max_bal, accounts[uid]["balance"] + to_give)
|
|
ecousers[uid]["next_payday"] = cur_time
|
|
updated.append((f"{member.name} ({member.id}): {humanize_number(to_give)}\n", to_give))
|
|
|
|
if updated:
|
|
await bankgroup.set(accounts)
|
|
await ecogroup.set(ecousers)
|
|
if conf.logs.auto_claim:
|
|
log.debug(f"Claimed {len(updated)} paydays in {guild.name}")
|
|
ordered = sorted(updated, key=lambda x: x[1], reverse=True)
|
|
claimed = "\n".join([x[0] for x in ordered])
|
|
channel = guild.get_channel(conf.logs.auto_claim)
|
|
if channel is not None:
|
|
with suppress(discord.HTTPException):
|
|
await channel.send(
|
|
f"Claimed {len(updated)} paydays",
|
|
file=text_to_file(claimed, "paydays.txt"),
|
|
)
|