Files
croccybot/src/tracking/text/settings.py

232 lines
8.5 KiB
Python

from typing import Optional
import asyncio
from collections import defaultdict
from settings.groups import SettingGroup
from settings.data import ModelData, ListData
from settings.setting_types import ChannelListSetting, IntegerSetting
from meta.config import conf
from meta.sharding import THIS_SHARD
from meta.logger import log_wrap
from core.data import CoreData
from babel.translator import ctx_translator
from . import babel, logger
from .data import TextTrackerData
_p = babel._p
class TextTrackerSettings(SettingGroup):
"""
Guild settings:
xp per period (guild_config.period_xp)
additional xp per hundred words (guild_config.word_xp)
coins per hundred xp (guild_config.xp_coins)
untracked channels (untracked_text_channels(channelid PK, guildid FK))
"""
class XPPerPeriod(ModelData, IntegerSetting):
setting_id = 'xp_per_period'
_set_cmd = 'configure message_exp'
_display_name = _p('guildset:xp_per_period', "xp_per_5min")
_desc = _p(
'guildset:xp_per_period|desc',
"How much XP members will be given every 5 minute period they are active."
)
_long_desc = _p(
'guildset:xp_per_period|long_desc',
"Amount of message XP to give members for each 5 minute period in which they are active (send a message). "
"Note that this XP is only given *once* per period."
)
_accepts = _p(
'guildset:xp_per_period|accepts',
"Number of message XP to reward per 5 minute active period."
)
_default = 101 # TODO: Make a dynamic default based on the global setting?
_model = CoreData.Guild
_column = CoreData.Guild.xp_per_period.name
@property
def update_message(self):
t = ctx_translator.get().t
return t(_p(
'guildset:xp_per_period|set_response',
"For every **5** minutes they are active (i.e. in which they send a message), "
"members will now be given **{amount}** XP."
)).format(amount=self.value)
class WordXP(ModelData, IntegerSetting):
setting_id = 'word_xp'
_set_cmd = 'configure message_exp'
_display_name = _p('guildset:word_xp', "xp_per_100words")
_desc = _p(
'guildset:word_xp|desc',
"How much XP members will be given per hundred words they write."
)
_long_desc = _p(
'guildset:word_xp|long_desc',
"Amount of message XP to be given (additionally to the XP per period) for each hundred words. "
"Useful for rewarding communication."
)
_accepts = _p(
'guildset:word_xp|accepts',
"Number of XP to reward per hundred words sent."
)
_default = 50
_model = CoreData.Guild
_column = CoreData.Guild.xp_per_centiword.name
@property
def update_message(self):
t = ctx_translator.get().t
return t(_p(
'guildset:word_xp|set_response',
"For every **100** words they send, members will now be rewarded an additional **{amount}** XP."
)).format(amount=self.value)
class UntrackedTextChannels(ListData, ChannelListSetting):
setting_id = 'untracked_text_channels'
_display_name = _p('guildset:untracked_text_channels', "untracked_text_channels")
_desc = _p(
'guildset:untracked_text_channels|desc',
"Channels in which Message XP will not be given."
)
_long_desc = _p(
'guildset:untracked_text_channels|long_desc',
"Messages sent in these channels will not count towards a member's message XP. "
"If a category is selected, then all channels under the category will also be untracked."
)
_accepts = _p(
'guildset:untracked_text_channels|accepts',
"Comma separated list of untracked text channel names or ids."
)
_notset_str = _p(
'guildset:untracked_text_channels|notset',
"Not Set (all text channels will be tracked.)"
)
_default = None
_table_interface = TextTrackerData.untracked_channels
_id_column = 'guildid'
_data_column = 'channelid'
_order_column = 'channelid'
_cache = {}
@property
def update_message(self):
t = ctx_translator.get().t
if self.data:
resp = t(_p(
'guildset:untracked_text_channels|set_response|set',
"Messages in or under the following channels will be ignored: {channels}"
)).format(channels=self.formatted)
else:
resp = t(_p(
'guildset:untracked_text_channels|set_response|notset',
"Message XP will now be tracked in every channel."
))
return resp
@property
def set_str(self) -> str:
t = ctx_translator.get().t
return t(_p(
'guildset:untracked_text_channels|set_using',
"Channel selector below"
))
@classmethod
@log_wrap(action='Cache Untracked Text Channels')
async def setup(cls, bot):
"""
Pre-load untracked text channels for every guild on the current shard.
"""
data: TextTrackerData = bot.db.registries['TextTrackerData']
# TODO: Filter by joining on guild_config with last_left = NULL
# Otherwise we are also caching all the guilds we left
rows = await data.untracked_channels.select_where(THIS_SHARD)
new_cache = defaultdict(list)
count = 0
for row in rows:
new_cache[row['guildid']].append(row['channelid'])
count += 1
cls._cache.clear()
cls._cache.update(new_cache)
logger.info(f"Loaded {count} untracked text channels on this shard.")
class TextTrackerGlobalSettings(SettingGroup):
"""
Configure global XP rates for the text tracker.
"""
class XPPerPeriod(ModelData, IntegerSetting):
setting_id = 'xp_per_period'
_set_cmd = 'leo configure experience_rates'
_display_name = _p('botset:xp_per_period', "xp_per_5min")
_desc = _p(
'botset:xp_per_period|desc',
"How much global XP members will be given every 5 minute period they are active."
)
_long_desc = _p(
'botset:xp_per_period|long_desc',
"Amount of global message XP to give members "
"for each 5 minute period in which they are active (send a message). "
"Note that this XP is only given *once* per period."
)
_accepts = _p(
'botset:xp_per_period|accepts',
"Number of message XP to reward per 5 minute active period."
)
_default = 101
_model = TextTrackerData.BotConfigText
_column = TextTrackerData.BotConfigText.xp_per_period.name
@property
def update_message(self):
t = ctx_translator.get().t
return t(_p(
'leoset:xp_per_period|set_response',
"For every **5** minutes they are active (i.e. in which they send a message), "
"all users will now be given **{amount}** global XP."
)).format(amount=self.value)
class WordXP(ModelData, IntegerSetting):
setting_id = 'word_xp'
_set_cmd = 'leo configure experience_rates'
_display_name = _p('botset:word_xp', "xp_per_100words")
_desc = _p(
'botset:word_xp|desc',
"How much global XP members will be given per hundred words they write."
)
_long_desc = _p(
'botset:word_xp|long_desc',
"Amount of global message XP to be given (additionally to the XP per period) for each hundred words. "
"Useful for rewarding communication."
)
_accepts = _p(
'botset:word_xp|accepts',
"Number of XP to reward per hundred words sent."
)
_default = 50
_model = TextTrackerData.BotConfigText
_column = TextTrackerData.BotConfigText.xp_per_centiword.name
@property
def update_message(self):
t = ctx_translator.get().t
return t(_p(
'leoset:word_xp|set_response',
"For every **100** words they send, users will now be rewarded an additional **{amount}** global XP."
)).format(amount=self.value)