Data system refactor and core redesign for public.

Redesigned data and core systems to be public-capable.
This commit is contained in:
2021-09-12 11:04:49 +03:00
parent 459a728968
commit 0183b63c55
33 changed files with 1170 additions and 790 deletions

View File

@@ -1,3 +1,9 @@
from .sysadmin import *
from .guild_admin import *
from .meta import *
from .economy import *
from .study import *
from .user_config import *
from .workout import *
from .todo import *
# from .moderation import *

View File

@@ -1,2 +1,3 @@
from . import module
from .module import module
from . import commands

View File

@@ -1,6 +1,8 @@
from core import User
from core.tables import users
from cmdClient.checks import in_guild
import data
from data import tables
from core import Lion
from utils import interactive # noqa
from .module import module
@@ -11,17 +13,19 @@ second_emoji = "🥈"
third_emoji = "🥉"
# TODO: in_guild ward
@module.cmd(
"topcoin",
short_help="View the LionCoin leaderboard.",
aliases=('topc', 'ctop')
"cointop",
group="Statistics",
desc="View the LionCoin leaderboard.",
aliases=('topc', 'ctop', 'topcoins', 'topcoin', 'cointop100'),
help_aliases={'cointop100': "View the LionCoin top 100."}
)
@in_guild()
async def cmd_topcoin(ctx):
"""
Usage``:
{prefix}topcoin
{prefix}topcoin 100
{prefix}cointop
{prefix}cointop 100
Description:
Display the LionCoin leaderboard, or top 100.
@@ -30,15 +34,17 @@ async def cmd_topcoin(ctx):
# Handle args
if ctx.args and not ctx.args == "100":
return await ctx.error_reply(
"**Usage:**`{prefix}topcoin` or `{prefix}topcoin100`.".format(prefix=ctx.client.prefix)
"**Usage:**`{prefix}topcoin` or `{prefix}topcoin100`.".format(prefix=ctx.best_prefix)
)
top100 = ctx.args == "100"
top100 = (ctx.args == "100" or ctx.alias == "contop100")
# Flush any pending coin transactions
User.sync()
Lion.sync()
# Fetch the leaderboard
user_data = users.select_where(
user_data = tables.lions.select_where(
guildid=ctx.guild.id,
userid=data.NOT([m.id for m in ctx.guild_settings.unranked_roles.members]),
select_columns=('userid', 'coins'),
_extra="ORDER BY coins DESC " + ("LIMIT 100" if top100 else "")
)

View File

@@ -1,4 +1,4 @@
from cmdClient import Module
from LionModule import LionModule
module = Module("Economy")
module = LionModule("Economy")

View File

@@ -0,0 +1,3 @@
from .module import module
from . import help

View File

@@ -0,0 +1,5 @@
from .module import module
from . import admin
# from . import video_channels
from . import Ticket

View File

@@ -1,2 +1,9 @@
from .module import module
from . import commands
from . import data
from . import admin
from . import badge_tracker
from . import time_tracker
from . import top_cmd
from . import studybadge_cmd
from . import stats_cmd

View File

@@ -1,111 +0,0 @@
import datetime as dt
from core import User
from core.tables import users
from utils import interactive # noqa
from .module import module
first_emoji = "🥇"
second_emoji = "🥈"
third_emoji = "🥉"
# TODO: in_guild ward
@module.cmd(
"top",
short_help="View the Study Time leaderboard.",
aliases=('ttop', 'toptime')
)
async def cmd_top(ctx):
"""
Usage``:
{prefix}top
{prefix}top 100
Description:
Display the study time leaderboard, or the top 100.
Use the paging reactions or send `p<n>` to switch pages (e.g. `p11` to switch to page 11).
"""
# Handle args
if ctx.args and not ctx.args == "100":
return await ctx.error_reply(
"**Usage:**`{prefix}top` or `{prefix}top100`.".format(prefix=ctx.client.prefix)
)
top100 = ctx.args == "100"
# Flush any pending coin transactions
User.sync()
# Fetch the leaderboard
user_data = users.select_where(
select_columns=('userid', 'tracked_time'),
_extra="ORDER BY tracked_time DESC " + ("LIMIT 100" if top100 else "")
)
# Quit early if the leaderboard is empty
if not user_data:
return await ctx.reply("No leaderboard entries yet!")
# Extract entries
author_index = None
entries = []
for i, (userid, time) in enumerate(user_data):
member = ctx.guild.get_member(userid)
name = member.display_name if member else str(userid)
name = name.replace('*', ' ').replace('_', ' ')
num_str = "{}.".format(i+1)
hours = time // 3600
minutes = time // 60 % 60
seconds = time % 60
time_str = "{}:{:02}:{:02}".format(
hours,
minutes,
seconds
)
if ctx.author.id == userid:
author_index = i
entries.append((num_str, name, time_str))
# Extract blocks
blocks = [entries[i:i+20] for i in range(0, len(entries), 20)]
block_count = len(blocks)
# Build strings
header = "Study Time Top 100" if top100 else "Study Time Leaderboard"
if block_count > 1:
header += " (Page {{page}}/{})".format(block_count)
# Build pages
pages = []
for i, block in enumerate(blocks):
max_num_l, max_name_l, max_time_l = [max(len(e[i]) for e in block) for i in (0, 1, 2)]
body = '\n'.join(
"{:>{}} {:<{}} \t {:>{}} {} {}".format(
entry[0], max_num_l,
entry[1], max_name_l + 2,
entry[2], max_time_l + 1,
first_emoji if i == 0 and j == 0 else (
second_emoji if i == 0 and j == 1 else (
third_emoji if i == 0 and j == 2 else ''
)
),
"" if author_index is not None and author_index == i * 20 + j else ""
)
for j, entry in enumerate(block)
)
title = header.format(page=i+1)
line = '='*len(title)
pages.append(
"```md\n{}\n{}\n{}```".format(title, line, body)
)
# Finally, page the results
await ctx.pager(pages, start_at=(author_index or 0)//20 if not top100 else 0)

View File

@@ -1,4 +1,4 @@
from cmdClient import Module
from LionModule import LionModule
module = Module("Study_Stats")
module = LionModule("Study_Stats")

View File

@@ -1 +1,3 @@
from .module import module
from .exec_cmds import *

View File

@@ -5,35 +5,45 @@ import asyncio
from cmdClient import cmd, checks
from core import Lion
from LionModule import LionModule
"""
Exec level commands to manage the bot.
Commands provided:
async:
Executes provided code in an async executor
exec:
Executes code using standard python exec
eval:
Executes code and awaits it if required
"""
@cmd("reboot")
@cmd("shutdown",
desc="Sync data and shutdown.",
group="Bot Admin",
aliases=('restart', 'reboot'))
@checks.is_owner()
async def cmd_reboot(ctx):
async def cmd_shutdown(ctx):
"""
Usage``:
reboot
Description:
Update the timer status save file and reboot the client.
Run unload tasks and shutdown/reboot.
"""
ctx.client.interface.update_save("reboot")
ctx.client.interface.shutdown()
await ctx.reply("Saved state. Rebooting now!")
# Run module logout tasks
for module in ctx.client.modules:
if isinstance(module, LionModule):
await module.unload(ctx.client)
# Reply and logout
await ctx.reply("All modules synced. Shutting down!")
await ctx.client.close()
@cmd("async")
@cmd("async",
desc="Execute arbitrary code with `async`.",
group="Bot Admin")
@checks.is_owner()
async def cmd_async(ctx):
"""
@@ -55,7 +65,9 @@ async def cmd_async(ctx):
output))
@cmd("eval")
@cmd("eval",
desc="Execute arbitrary code with `eval`.",
group="Bot Admin")
@checks.is_owner()
async def cmd_eval(ctx):
"""

View File

@@ -0,0 +1,6 @@
from .module import module
from . import Tasklist
from . import admin
from . import data
from . import commands

View File

@@ -0,0 +1,5 @@
from .module import module
from . import admin
from . import data
from . import tracker