rewrite: Core components.
This commit is contained in:
@@ -52,7 +52,11 @@ async def main():
|
|||||||
shardname=shardname,
|
shardname=shardname,
|
||||||
db=db,
|
db=db,
|
||||||
config=conf,
|
config=conf,
|
||||||
initial_extensions=['utils', 'core', 'analytics', 'babel', 'tracking.voice', 'modules'],
|
initial_extensions=[
|
||||||
|
'utils', 'core', 'analytics', 'babel',
|
||||||
|
'modules',
|
||||||
|
'tracking.voice', 'tracking.text',
|
||||||
|
],
|
||||||
web_client=session,
|
web_client=session,
|
||||||
app_ipc=shard_talk,
|
app_ipc=shard_talk,
|
||||||
testing_guilds=conf.bot.getintlist('admin_guilds'),
|
testing_guilds=conf.bot.getintlist('admin_guilds'),
|
||||||
|
|||||||
@@ -1,12 +1,28 @@
|
|||||||
|
from enum import Enum
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from psycopg import sql
|
from psycopg import sql
|
||||||
from cachetools import TTLCache
|
from cachetools import TTLCache
|
||||||
|
|
||||||
from data import Table, Registry, Column, RowModel
|
from data import Table, Registry, Column, RowModel, RegisterEnum
|
||||||
from data.models import WeakCache
|
from data.models import WeakCache
|
||||||
from data.columns import Integer, String, Bool, Timestamp
|
from data.columns import Integer, String, Bool, Timestamp
|
||||||
|
|
||||||
|
|
||||||
|
class RankType(Enum):
|
||||||
|
"""
|
||||||
|
Schema
|
||||||
|
------
|
||||||
|
CREATE TYPE RankType AS ENUM(
|
||||||
|
'XP',
|
||||||
|
'VOICE',
|
||||||
|
'MESSAGE'
|
||||||
|
);
|
||||||
|
"""
|
||||||
|
XP = 'XP',
|
||||||
|
VOICE = 'VOICE',
|
||||||
|
MESSAGE = 'MESSAGE',
|
||||||
|
|
||||||
|
|
||||||
class CoreData(Registry, name="core"):
|
class CoreData(Registry, name="core"):
|
||||||
class AppConfig(RowModel):
|
class AppConfig(RowModel):
|
||||||
"""
|
"""
|
||||||
@@ -141,7 +157,10 @@ class CoreData(Registry, name="core"):
|
|||||||
left_at TIMESTAMPTZ,
|
left_at TIMESTAMPTZ,
|
||||||
locale TEXT,
|
locale TEXT,
|
||||||
timezone TEXT,
|
timezone TEXT,
|
||||||
force_locale BOOLEAN
|
force_locale BOOLEAN,
|
||||||
|
season_start TIMESTAMPTZ,
|
||||||
|
xp_per_period INTEGER,
|
||||||
|
xp_per_centiword INTEGER
|
||||||
);
|
);
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -205,7 +224,16 @@ class CoreData(Registry, name="core"):
|
|||||||
locale = String()
|
locale = String()
|
||||||
force_locale = Bool()
|
force_locale = Bool()
|
||||||
|
|
||||||
unranked_rows = Table('unranked_rows')
|
season_start = Timestamp()
|
||||||
|
rank_type: Column[RankType] = Column()
|
||||||
|
rank_channel = Integer()
|
||||||
|
dm_ranks = Bool()
|
||||||
|
|
||||||
|
xp_per_period = Integer()
|
||||||
|
xp_per_centiword = Integer()
|
||||||
|
coins_per_centixp = Integer()
|
||||||
|
|
||||||
|
allow_transfers = Bool()
|
||||||
|
|
||||||
donator_roles = Table('donator_roles')
|
donator_roles = Table('donator_roles')
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,35 @@ class Lions(LionCog):
|
|||||||
self.lion_guilds[guildid] = lguild
|
self.lion_guilds[guildid] = lguild
|
||||||
return lguild
|
return lguild
|
||||||
|
|
||||||
|
async def fetch_guilds(self, *guildids) -> dict[int, LionGuild]:
|
||||||
|
"""
|
||||||
|
Fetch (or create) multiple LionGuilds simultaneously, using cache where possible.
|
||||||
|
"""
|
||||||
|
guild_map = {}
|
||||||
|
missing = set()
|
||||||
|
for guildid in guildids:
|
||||||
|
lguild = self.lion_guilds.get(guildid, None)
|
||||||
|
guild_map[guildid] = lguild
|
||||||
|
if lguild is None:
|
||||||
|
missing.add(guildid)
|
||||||
|
|
||||||
|
if missing:
|
||||||
|
rows = await self.data.Guild.fetch_where(guildid=list(missing))
|
||||||
|
missing.difference_update(row.guildid for row in rows)
|
||||||
|
|
||||||
|
if missing:
|
||||||
|
new_rows = await self.data.Guild.table.insert_many(
|
||||||
|
('guildid',),
|
||||||
|
*((guildid,) for guildid in missing)
|
||||||
|
).with_adapter(self.data.Guild._make_rows)
|
||||||
|
rows = (*rows, *new_rows)
|
||||||
|
|
||||||
|
for row in rows:
|
||||||
|
guildid = row.guildid
|
||||||
|
self.lion_guilds[guildid] = guild_map[guildid] = LionGuild(self.bot, row)
|
||||||
|
|
||||||
|
return guild_map
|
||||||
|
|
||||||
async def fetch_member(self, guildid, userid, member: Optional[discord.Member] = None) -> LionMember:
|
async def fetch_member(self, guildid, userid, member: Optional[discord.Member] = None) -> LionMember:
|
||||||
"""
|
"""
|
||||||
Fetch the given LionMember, using cache for data if possible.
|
Fetch the given LionMember, using cache for data if possible.
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class LionGuild(Timezoned):
|
|||||||
@property
|
@property
|
||||||
def guild_mode(self):
|
def guild_mode(self):
|
||||||
# TODO: Configuration, data, and settings for this...
|
# TODO: Configuration, data, and settings for this...
|
||||||
return GuildMode.StudyGuild
|
return GuildMode.VoiceGuild
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def timezone(self) -> pytz.timezone:
|
def timezone(self) -> pytz.timezone:
|
||||||
|
|||||||
@@ -180,9 +180,10 @@ class LocalQueueHandler(QueueHandler):
|
|||||||
|
|
||||||
|
|
||||||
class WebHookHandler(logging.StreamHandler):
|
class WebHookHandler(logging.StreamHandler):
|
||||||
def __init__(self, webhook_url, batch=False, loop=None):
|
def __init__(self, webhook_url, prefix="", batch=False, loop=None):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.webhook_url = webhook_url
|
self.webhook_url = webhook_url
|
||||||
|
self.prefix = prefix
|
||||||
self.batched = ""
|
self.batched = ""
|
||||||
self.batch = batch
|
self.batch = batch
|
||||||
self.loop = loop
|
self.loop = loop
|
||||||
@@ -264,15 +265,16 @@ class WebHookHandler(logging.StreamHandler):
|
|||||||
async def _send(self, message, as_file=False):
|
async def _send(self, message, as_file=False):
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
webhook = Webhook.from_url(self.webhook_url, session=session)
|
webhook = Webhook.from_url(self.webhook_url, session=session)
|
||||||
if as_file or len(message) > 2000:
|
if as_file or len(message) > 1900:
|
||||||
with StringIO(message) as fp:
|
with StringIO(message) as fp:
|
||||||
fp.seek(0)
|
fp.seek(0)
|
||||||
await webhook.send(
|
await webhook.send(
|
||||||
|
f"{self.prefix}\n`{message.splitlines()[0]}`",
|
||||||
file=File(fp, filename="logs.md"),
|
file=File(fp, filename="logs.md"),
|
||||||
username=log_app.get()
|
username=log_app.get()
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
await webhook.send(message, username=log_app.get())
|
await webhook.send(self.prefix + '\n' + message, username=log_app.get())
|
||||||
|
|
||||||
|
|
||||||
handlers = []
|
handlers = []
|
||||||
@@ -281,12 +283,12 @@ if webhook := conf.logging['general_log']:
|
|||||||
handlers.append(handler)
|
handlers.append(handler)
|
||||||
|
|
||||||
if webhook := conf.logging['error_log']:
|
if webhook := conf.logging['error_log']:
|
||||||
handler = WebHookHandler(webhook, batch=False)
|
handler = WebHookHandler(webhook, prefix=conf.logging['error_prefix'], batch=False)
|
||||||
handler.setLevel(logging.ERROR)
|
handler.setLevel(logging.ERROR)
|
||||||
handlers.append(handler)
|
handlers.append(handler)
|
||||||
|
|
||||||
if webhook := conf.logging['critical_log']:
|
if webhook := conf.logging['critical_log']:
|
||||||
handler = WebHookHandler(webhook, batch=False)
|
handler = WebHookHandler(webhook, prefix=conf.logging['critical_prefix'], batch=False)
|
||||||
handler.setLevel(logging.CRITICAL)
|
handler.setLevel(logging.CRITICAL)
|
||||||
handlers.append(handler)
|
handlers.append(handler)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user