rewrite: Add economy config.

This commit is contained in:
2023-05-14 12:32:21 +03:00
parent 7f79009ac7
commit e3b2906e67
5 changed files with 485 additions and 254 deletions

View File

@@ -1,5 +1,11 @@
from .cog import Economy import logging
from babel.translator import LocalBabel
logger = logging.getLogger(__name__)
babel = LocalBabel('economy')
async def setup(bot): async def setup(bot):
from .cog import Economy
await bot.add_cog(Economy(bot)) await bot.add_cog(Economy(bot))

View File

@@ -1,265 +1,29 @@
from typing import Optional, Union from typing import Optional, Union
from enum import Enum
import discord import discord
from discord.ext import commands as cmds from discord.ext import commands as cmds
from discord import app_commands as appcmds from discord import app_commands as appcmds
from psycopg import sql from meta import LionCog, LionBot, LionContext, conf
from data import Registry, RowModel, RegisterEnum, ORDER, JOINTYPE, RawExpr
from data.columns import Integer, Bool, String, Column, Timestamp
from meta import LionCog, LionBot, LionContext
from meta.errors import ResponseTimedOut from meta.errors import ResponseTimedOut
from babel import LocalBabel from babel import LocalBabel
from data import ORDER
from core.data import CoreData from utils.ui import Confirm, Pager
from utils.ui import LeoUI, LeoModal, Confirm, Pager
from utils.lib import error_embed, MessageArgs, utc_now from utils.lib import error_embed, MessageArgs, utc_now
from wards import low_management
from . import babel, logger
from .data import EconomyData, TransactionType, AdminActionType
from .settings import EconomySettings
from .settingui import EconomyConfigUI
babel = LocalBabel('economy')
_, _p, _np = babel._, babel._p, babel._np _, _p, _np = babel._, babel._p, babel._np
MAX_COINS = 2**16 MAX_COINS = 2**16
class TransactionType(Enum):
"""
Schema
------
CREATE TYPE CoinTransactionType AS ENUM(
'REFUND',
'TRANSFER',
'SHOP_PURCHASE',
'STUDY_SESSION',
'ADMIN',
'TASKS'
);
"""
REFUND = 'REFUND',
TRANSFER = 'TRANSFER',
PURCHASE = 'SHOP_PURCHASE',
SESSION = 'STUDY_SESSION',
ADMIN = 'ADMIN',
TASKS = 'TASKS',
class AdminActionTarget(Enum):
"""
Schema
------
CREATE TYPE EconAdminTarget AS ENUM(
'ROLE',
'USER',
'GUILD'
);
"""
ROLE = 'ROLE',
USER = 'USER',
GUILD = 'GUILD',
class AdminActionType(Enum):
"""
Schema
------
CREATE TYPE EconAdminAction AS ENUM(
'SET',
'ADD'
);
"""
SET = 'SET',
ADD = 'ADD',
class EconomyData(Registry, name='economy'):
_TransactionType = RegisterEnum(TransactionType, 'CoinTransactionType')
_AdminActionTarget = RegisterEnum(AdminActionTarget, 'EconAdminTarget')
_AdminActionType = RegisterEnum(AdminActionType, 'EconAdminAction')
class Transaction(RowModel):
"""
Schema
------
CREATE TABLE coin_transactions(
transactionid SERIAL PRIMARY KEY,
transactiontype CoinTransactionType NOT NULL,
guildid BIGINT NOT NULL REFERENCES guild_config (guildid) ON DELETE CASCADE,
actorid BIGINT NOT NULL,
amount INTEGER NOT NULL,
bonus INTEGER NOT NULL,
from_account BIGINT,
to_account BIGINT,
refunds INTEGER REFERENCES coin_transactions (transactionid) ON DELETE SET NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT (now() at time zone 'utc')
);
CREATE INDEX coin_transaction_guilds ON coin_transactions (guildid);
"""
_tablename_ = 'coin_transactions'
transactionid = Integer(primary=True)
transactiontype: Column[TransactionType] = Column()
guildid = Integer()
actorid = Integer()
amount = Integer()
bonus = Integer()
from_account = Integer()
to_account = Integer()
refunds = Integer()
created_at = Timestamp()
@classmethod
async def execute_transaction(
cls,
transaction_type: TransactionType,
guildid: int, actorid: int,
from_account: int, to_account: int, amount: int, bonus: int = 0,
refunds: int = None
):
transaction = await cls.create(
transactiontype=transaction_type,
guildid=guildid, actorid=actorid, amount=amount, bonus=bonus,
from_account=from_account, to_account=to_account,
refunds=refunds
)
if from_account is not None:
await CoreData.Member.table.update_where(
guildid=guildid, userid=from_account
).set(coins=(CoreData.Member.coins - (amount + bonus)))
if to_account is not None:
await CoreData.Member.table.update_where(
guildid=guildid, userid=to_account
).set(coins=(CoreData.Member.coins + (amount + bonus)))
return transaction
class ShopTransaction(RowModel):
"""
Schema
------
CREATE TABLE coin_transactions_shop(
transactionid INTEGER PRIMARY KEY REFERENCES coin_transactions (transactionid) ON DELETE CASCADE,
itemid INTEGER NOT NULL REFERENCES shop_items (itemid) ON DELETE CASCADE
);
"""
_tablename_ = 'coin_transactions_shop'
transactionid = Integer(primary=True)
itemid = Integer()
@classmethod
async def purchase_transaction(
cls,
guildid: int, actorid: int,
userid: int, itemid: int, amount: int
):
conn = await cls._connector.get_connection()
async with conn.transaction():
row = await EconomyData.Transaction.execute_transaction(
TransactionType.PURCHASE,
guildid=guildid, actorid=actorid, from_account=userid, to_account=None,
amount=amount
)
return await cls.create(transactionid=row.transactionid, itemid=itemid)
class TaskTransaction(RowModel):
"""
Schema
------
CREATE TABLE coin_transactions_tasks(
transactionid INTEGER PRIMARY KEY REFERENCES coin_transactions (transactionid) ON DELETE CASCADE,
count INTEGER NOT NULL
);
"""
_tablename_ = 'coin_transactions_tasks'
transactionid = Integer(primary=True)
count = Integer()
@classmethod
async def count_recent_for(cls, userid, guildid, interval='24h'):
"""
Retrieve the number of tasks rewarded in the last `interval`.
"""
T = EconomyData.Transaction
query = cls.table.select_where().with_no_adapter()
query.join(T, using=(T.transactionid.name, ), join_type=JOINTYPE.LEFT)
query.select(recent=sql.SQL("SUM({})").format(cls.count.expr))
query.where(
T.to_account == userid,
T.guildid == guildid,
T.created_at > RawExpr(sql.SQL("timezone('utc', NOW()) - INTERVAL {}").format(interval), ()),
)
result = await query
return result[0]['recent'] or 0
@classmethod
async def reward_completed(cls, userid, guildid, count, amount):
"""
Reward the specified member `amount` coins for completing `count` tasks.
"""
# TODO: Bonus logic, perhaps apply_bonus(amount), or put this method in the economy cog?
conn = await cls._connector.get_connection()
async with conn.transaction():
row = await EconomyData.Transaction.execute_transaction(
TransactionType.TASKS,
guildid=guildid, actorid=userid, from_account=None, to_account=userid,
amount=amount
)
return await cls.create(transactionid=row.transactionid, count=count)
class SessionTransaction(RowModel):
"""
Schema
------
CREATE TABLE coin_transactions_sessions(
transactionid INTEGER PRIMARY KEY REFERENCES coin_transactions (transactionid) ON DELETE CASCADE,
sessionid INTEGER NOT NULL REFERENCES session_history (sessionid) ON DELETE CASCADE
);
"""
_tablename_ = 'coin_transactions_sessions'
transactionid = Integer(primary=True)
sessionid = Integer()
class AdminActions(RowModel):
"""
Schema
------
CREATE TABLE economy_admin_actions(
actionid SERIAL PRIMARY KEY,
target_type EconAdminTarget NOT NULL,
action_type EconAdminAction NOT NULL,
targetid INTEGER NOT NULL,
amount INTEGER NOT NULL
);
"""
_tablename_ = 'economy_admin_actions'
actionid = Integer(primary=True)
target_type: Column[AdminActionTarget] = Column()
action_type: Column[AdminActionType] = Column()
targetid = Integer()
amount = Integer()
class AdminTransactions(RowModel):
"""
Schema
------
CREATE TABLE coin_transactions_admin_actions(
actionid INTEGER NOT NULL REFERENCES economy_admin_actions (actionid),
transactionid INTEGER NOT NULL REFERENCES coin_transactions (transactionid),
PRIMARY KEY (actionid, transactionid)
);
CREATE INDEX coin_transactions_admin_actions_transactionid ON coin_transactions_admin_actions (transactionid);
"""
_tablename_ = 'coin_transactions_admin_actions'
actionid = Integer(primary=True)
transactionid = Integer(primary=True)
class Economy(LionCog): class Economy(LionCog):
""" """
Commands Commands
@@ -284,13 +48,25 @@ class Economy(LionCog):
def __init__(self, bot: LionBot): def __init__(self, bot: LionBot):
self.bot = bot self.bot = bot
self.data = bot.db.load_registry(EconomyData()) self.data = bot.db.load_registry(EconomyData())
self.settings = EconomySettings()
self.bonuses = {} self.bonuses = {}
async def cog_load(self): async def cog_load(self):
await self.data.init() await self.data.init()
# ----- Economy Bonus regsitration ----- self.bot.core.guild_config.register_model_setting(self.settings.AllowTransfers)
self.bot.core.guild_config.register_model_setting(self.settings.CoinsPerXP)
configcog = self.bot.get_cog('ConfigCog')
if configcog is None:
logger.critical(
"Attempting to load the EconomyCog before ConfigCog! Failed to crossload configuration group."
)
else:
self.crossload_group(self.configure_group, configcog.configure_group)
# ----- Economy Bonus registration -----
def register_economy_bonus(self, bonus_coro, name=None): def register_economy_bonus(self, bonus_coro, name=None):
name = name or bonus_coro.__name__ name = name or bonus_coro.__name__
self.bonuses[name] = bonus_coro self.bonuses[name] = bonus_coro
@@ -594,10 +370,11 @@ class Economy(LionCog):
) )
) )
else: else:
await ctx.interaction.response.defer()
# Viewing route # Viewing route
MemModel = self.bot.core.data.Member MemModel = self.bot.core.data.Member
if role: if role:
query = MemModel.fetch_where( query = MemModel.table.select_where(
(MemModel.guildid == role.guild.id) & (MemModel.coins != 0) (MemModel.guildid == role.guild.id) & (MemModel.coins != 0)
) )
query.order_by('coins', ORDER.DESC) query.order_by('coins', ORDER.DESC)
@@ -618,7 +395,7 @@ class Economy(LionCog):
"This server has a total balance of {coin_emoji}**{total}**." "This server has a total balance of {coin_emoji}**{total}**."
)).format( )).format(
coin_emoji=cemoji, coin_emoji=cemoji,
total=sum(row.coins for row in rows) total=sum(row['coins'] for row in rows)
) )
else: else:
header = t(_p( header = t(_p(
@@ -628,7 +405,7 @@ class Economy(LionCog):
)).format( )).format(
count=len(targets), count=len(targets),
role_mention=role.mention, role_mention=role.mention,
total=sum(row.coins for row in rows), total=sum(row['coins'] for row in rows),
coin_emoji=cemoji coin_emoji=cemoji
) )
@@ -645,13 +422,13 @@ class Economy(LionCog):
for i, block in enumerate(blocks): for i, block in enumerate(blocks):
lines = [] lines = []
numwidth = len(str(i + len(block))) numwidth = len(str(i + len(block)))
coinwidth = len(str(max(row.coins for row in rows))) coinwidth = len(str(max(row['coins'] for row in rows)))
for j, row in enumerate(block, start=i): for j, row in enumerate(block, start=i*blocklen):
lines.append( lines.append(
lb_format.format( lb_format.format(
pos=j, numwidth=numwidth, pos=j, numwidth=numwidth,
coins=row.coins, coinwidth=coinwidth, coins=row['coins'], coinwidth=coinwidth,
mention=f"<@{row.userid}>" mention=f"<@{row['userid']}>"
) )
) )
lb_block = '\n'.join(lines) lb_block = '\n'.join(lines)
@@ -906,6 +683,18 @@ class Economy(LionCog):
return return
t = self.bot.translator.t t = self.bot.translator.t
if not ctx.lguild.config.get('allow_transfers').value:
await ctx.interaction.response.send_message(
embed=error_embed(
t(_p(
'cmd:send|error:not_allowed',
"Sorry, this server has disabled LionCoin transfers!"
))
)
)
return
Member = self.bot.core.data.Member Member = self.bot.core.data.Member
target_lion = await self.bot.core.lions.fetch_member(ctx.guild.id, target.id) target_lion = await self.bot.core.lions.fetch_member(ctx.guild.id, target.id)
@@ -985,3 +774,54 @@ class Economy(LionCog):
"Unfortunately, I was not able to message the recipient. Perhaps they have me blocked?" "Unfortunately, I was not able to message the recipient. Perhaps they have me blocked?"
)) ))
await ctx.interaction.edit_original_response(embed=embed) await ctx.interaction.edit_original_response(embed=embed)
# -------- Configuration Commands --------
@LionCog.placeholder_group
@cmds.hybrid_group('configure', with_app_command=False)
async def configure_group(self, ctx: LionContext):
# Placeholder group method, not used
pass
@configure_group.command(
name=_p('cmd:configure_economy', "economy"),
description=_p(
'cmd:configure_economy|desc',
"Configure LionCoin Economy"
)
)
@cmds.check(low_management)
async def configure_economy(self, ctx: LionContext,
allow_transfers: Optional[bool] = None,
coins_per_xp: Optional[appcmds.Range[int, 0, 2**15]] = None):
t = self.bot.translator.t
if not ctx.interaction:
return
if not ctx.guild:
return
setting_allow_transfers = ctx.lguild.config.get('allow_transfers')
setting_coins_per_xp = ctx.lguild.config.get('coins_per_xp')
modified = []
if allow_transfers is not None:
setting_allow_transfers.data = allow_transfers
await setting_allow_transfers.write()
modified.append(setting_allow_transfers)
if coins_per_xp is not None:
setting_coins_per_xp.data = coins_per_xp
await setting_coins_per_xp.write()
modified.append(setting_coins_per_xp)
if modified:
desc = '\n'.join(f"{conf.emojis.tick} {setting.update_message}" for setting in modified)
await ctx.reply(
embed=discord.Embed(
colour=discord.Colour.brand_green(),
description=desc
)
)
if ctx.channel.id not in EconomyConfigUI._listening or not modified:
configui = EconomyConfigUI(self.bot, ctx.guild.id, ctx.channel.id)
await configui.run(ctx.interaction)
await configui.wait()

242
src/modules/economy/data.py Normal file
View File

@@ -0,0 +1,242 @@
from enum import Enum
from psycopg import sql
from data import Registry, RowModel, RegisterEnum, JOINTYPE, RawExpr
from data.columns import Integer, Bool, Column, Timestamp
from core.data import CoreData
class TransactionType(Enum):
"""
Schema
------
CREATE TYPE CoinTransactionType AS ENUM(
'REFUND',
'TRANSFER',
'SHOP_PURCHASE',
'STUDY_SESSION',
'ADMIN',
'TASKS'
);
"""
REFUND = 'REFUND',
TRANSFER = 'TRANSFER',
PURCHASE = 'SHOP_PURCHASE',
SESSION = 'STUDY_SESSION',
ADMIN = 'ADMIN',
TASKS = 'TASKS',
class AdminActionTarget(Enum):
"""
Schema
------
CREATE TYPE EconAdminTarget AS ENUM(
'ROLE',
'USER',
'GUILD'
);
"""
ROLE = 'ROLE',
USER = 'USER',
GUILD = 'GUILD',
class AdminActionType(Enum):
"""
Schema
------
CREATE TYPE EconAdminAction AS ENUM(
'SET',
'ADD'
);
"""
SET = 'SET',
ADD = 'ADD',
class EconomyData(Registry, name='economy'):
_TransactionType = RegisterEnum(TransactionType, 'CoinTransactionType')
_AdminActionTarget = RegisterEnum(AdminActionTarget, 'EconAdminTarget')
_AdminActionType = RegisterEnum(AdminActionType, 'EconAdminAction')
class Transaction(RowModel):
"""
Schema
------
CREATE TABLE coin_transactions(
transactionid SERIAL PRIMARY KEY,
transactiontype CoinTransactionType NOT NULL,
guildid BIGINT NOT NULL REFERENCES guild_config (guildid) ON DELETE CASCADE,
actorid BIGINT NOT NULL,
amount INTEGER NOT NULL,
bonus INTEGER NOT NULL,
from_account BIGINT,
to_account BIGINT,
refunds INTEGER REFERENCES coin_transactions (transactionid) ON DELETE SET NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT (now() at time zone 'utc')
);
CREATE INDEX coin_transaction_guilds ON coin_transactions (guildid);
"""
_tablename_ = 'coin_transactions'
transactionid = Integer(primary=True)
transactiontype: Column[TransactionType] = Column()
guildid = Integer()
actorid = Integer()
amount = Integer()
bonus = Integer()
from_account = Integer()
to_account = Integer()
refunds = Integer()
created_at = Timestamp()
@classmethod
async def execute_transaction(
cls,
transaction_type: TransactionType,
guildid: int, actorid: int,
from_account: int, to_account: int, amount: int, bonus: int = 0,
refunds: int = None
):
transaction = await cls.create(
transactiontype=transaction_type,
guildid=guildid, actorid=actorid, amount=amount, bonus=bonus,
from_account=from_account, to_account=to_account,
refunds=refunds
)
if from_account is not None:
await CoreData.Member.table.update_where(
guildid=guildid, userid=from_account
).set(coins=(CoreData.Member.coins - (amount + bonus)))
if to_account is not None:
await CoreData.Member.table.update_where(
guildid=guildid, userid=to_account
).set(coins=(CoreData.Member.coins + (amount + bonus)))
return transaction
class ShopTransaction(RowModel):
"""
Schema
------
CREATE TABLE coin_transactions_shop(
transactionid INTEGER PRIMARY KEY REFERENCES coin_transactions (transactionid) ON DELETE CASCADE,
itemid INTEGER NOT NULL REFERENCES shop_items (itemid) ON DELETE CASCADE
);
"""
_tablename_ = 'coin_transactions_shop'
transactionid = Integer(primary=True)
itemid = Integer()
@classmethod
async def purchase_transaction(
cls,
guildid: int, actorid: int,
userid: int, itemid: int, amount: int
):
conn = await cls._connector.get_connection()
async with conn.transaction():
row = await EconomyData.Transaction.execute_transaction(
TransactionType.PURCHASE,
guildid=guildid, actorid=actorid, from_account=userid, to_account=None,
amount=amount
)
return await cls.create(transactionid=row.transactionid, itemid=itemid)
class TaskTransaction(RowModel):
"""
Schema
------
CREATE TABLE coin_transactions_tasks(
transactionid INTEGER PRIMARY KEY REFERENCES coin_transactions (transactionid) ON DELETE CASCADE,
count INTEGER NOT NULL
);
"""
_tablename_ = 'coin_transactions_tasks'
transactionid = Integer(primary=True)
count = Integer()
@classmethod
async def count_recent_for(cls, userid, guildid, interval='24h'):
"""
Retrieve the number of tasks rewarded in the last `interval`.
"""
T = EconomyData.Transaction
query = cls.table.select_where().with_no_adapter()
query.join(T, using=(T.transactionid.name, ), join_type=JOINTYPE.LEFT)
query.select(recent=sql.SQL("SUM({})").format(cls.count.expr))
query.where(
T.to_account == userid,
T.guildid == guildid,
T.created_at > RawExpr(sql.SQL("timezone('utc', NOW()) - INTERVAL {}").format(interval), ()),
)
result = await query
return result[0]['recent'] or 0
@classmethod
async def reward_completed(cls, userid, guildid, count, amount):
"""
Reward the specified member `amount` coins for completing `count` tasks.
"""
# TODO: Bonus logic, perhaps apply_bonus(amount), or put this method in the economy cog?
conn = await cls._connector.get_connection()
async with conn.transaction():
row = await EconomyData.Transaction.execute_transaction(
TransactionType.TASKS,
guildid=guildid, actorid=userid, from_account=None, to_account=userid,
amount=amount
)
return await cls.create(transactionid=row.transactionid, count=count)
class SessionTransaction(RowModel):
"""
Schema
------
CREATE TABLE coin_transactions_sessions(
transactionid INTEGER PRIMARY KEY REFERENCES coin_transactions (transactionid) ON DELETE CASCADE,
sessionid INTEGER NOT NULL REFERENCES session_history (sessionid) ON DELETE CASCADE
);
"""
_tablename_ = 'coin_transactions_sessions'
transactionid = Integer(primary=True)
sessionid = Integer()
class AdminActions(RowModel):
"""
Schema
------
CREATE TABLE economy_admin_actions(
actionid SERIAL PRIMARY KEY,
target_type EconAdminTarget NOT NULL,
action_type EconAdminAction NOT NULL,
targetid INTEGER NOT NULL,
amount INTEGER NOT NULL
);
"""
_tablename_ = 'economy_admin_actions'
actionid = Integer(primary=True)
target_type: Column[AdminActionTarget] = Column()
action_type: Column[AdminActionType] = Column()
targetid = Integer()
amount = Integer()
class AdminTransactions(RowModel):
"""
Schema
------
CREATE TABLE coin_transactions_admin_actions(
actionid INTEGER NOT NULL REFERENCES economy_admin_actions (actionid),
transactionid INTEGER NOT NULL REFERENCES coin_transactions (transactionid),
PRIMARY KEY (actionid, transactionid)
);
CREATE INDEX coin_transactions_admin_actions_transactionid ON coin_transactions_admin_actions (transactionid);
"""
_tablename_ = 'coin_transactions_admin_actions'
actionid = Integer(primary=True)
transactionid = Integer(primary=True)

View File

@@ -0,0 +1,72 @@
"""
Settings for the Economy Cog.
"""
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, BoolSetting
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 EconomyData
_p = babel._p
class EconomySettings(SettingGroup):
"""
Economy Settings:
coins_per_100xp
allow_transfers
"""
class CoinsPerXP(ModelData, IntegerSetting):
setting_id = 'coins_per_xp'
_display_name = _p('guildset:coins_per_xp', "coins_per_100xp")
_desc = _p(
'guildset:coins_per_xp|desc',
"How many LionCoins to reward members per 100 XP they earn."
)
_long_desc = _p(
'guildset:coins_per_xp|long_desc',
"Members will be rewarded with this many LionCoins for every 100 XP they earn."
)
# This default needs to dynamically depend on the guild mode!
_default = 50
_model = CoreData.Guild
_column = CoreData.Guild.coins_per_centixp.name
@property
def update_message(self):
t = ctx_translator.get().t
return t(_p(
'guildset:coins_per_xp|set_response',
"For every **100** XP they earn, members will now be given {coin}**{amount}**."
)).format(amount=self.value, coin=conf.emojis.coin)
class AllowTransfers(ModelData, BoolSetting):
setting_id = 'allow_transfers'
_display_name = _p('guildset:allow_transfers', "allow_transfers")
_desc = _p(
'guildset:allow_transfers|desc',
"Whether to allow members to transfer LionCoins to each other."
)
_long_desc = _p(
'guildset:allow_transfers|long_desc',
"If disabled, members will not be able to use `/sendcoins` to transfer LionCoinds."
)
_default = True
_model = CoreData.Guild
_column = CoreData.Guild.allow_transfers.name

View File

@@ -0,0 +1,71 @@
import asyncio
import discord
from discord.ui.select import select, Select, ChannelSelect
from discord.ui.button import button, Button, ButtonStyle
from meta import LionBot
from utils.ui import ConfigUI, DashboardSection
from utils.lib import MessageArgs
from .settings import EconomySettings
from . import babel
_p = babel._p
class EconomyConfigUI(ConfigUI):
setting_classes = (
EconomySettings.CoinsPerXP,
EconomySettings.AllowTransfers
)
def __init__(self, bot: LionBot,
guildid: int, channelid: int, **kwargs):
self.settings = bot.get_cog('Economy').settings
super().__init__(bot, guildid, channelid, **kwargs)
async def make_message(self) -> MessageArgs:
t = self.bot.translator.t
title = t(_p(
'ui:economy_config|embed|title',
"Economy Configuration Panel"
))
embed = discord.Embed(
colour=discord.Colour.orange(),
title=title
)
for setting in self.instances:
embed.add_field(**setting.embed_field, inline=False)
args = MessageArgs(embed=embed)
return args
async def reload(self):
lguild = await self.bot.core.lions.fetch_guild(self.guildid)
coins_per_xp = lguild.config.get(self.settings.CoinsPerXP.setting_id)
allow_transfers = lguild.config.get(self.settings.AllowTransfers.setting_id)
self.instances = (
coins_per_xp,
allow_transfers
)
async def refresh_components(self):
await asyncio.gather(
self.edit_button_refresh(),
self.close_button_refresh(),
self.reset_button_refresh(),
)
self._layout = [
(self.edit_button, self.reset_button, self.close_button),
]
class EconomyDashboard(DashboardSection):
section_name = _p(
'dash:economy|title',
"Economy Configuration"
)
configui = EconomyConfigUI
setting_classes = EconomyConfigUI.setting_classes