Compare commits
4 Commits
8421c5359d
...
5efcdd6709
| Author | SHA1 | Date | |
|---|---|---|---|
| 5efcdd6709 | |||
| 0adccaae02 | |||
| a7afa5001d | |||
| d271248812 |
@@ -259,6 +259,31 @@ CREATE TABLE subscriber_events (
|
||||
);
|
||||
|
||||
|
||||
CREATE VIEW event_details AS
|
||||
SELECT
|
||||
events.event_id AS event_id,
|
||||
events.user_id AS user_id,
|
||||
events.document_id AS document_id,
|
||||
events.user_name AS user_name,
|
||||
events.event_type AS event_type,
|
||||
events.occurred_at AS occurred_at,
|
||||
events.created_at AS created_at,
|
||||
plain_events.message AS plain_message,
|
||||
raid_events.visitor_count AS raid_visitor_count,
|
||||
cheer_events.amount AS cheer_amount,
|
||||
cheer_events.cheer_type AS cheer_type,
|
||||
cheer_events.message AS cheer_message,
|
||||
subscriber_events.subscribed_length AS subscriber_length,
|
||||
subscriber_events.tier AS subscriber_tier,
|
||||
subscriber_events.message AS subscriber_message,
|
||||
FROM
|
||||
events
|
||||
LEFT JOIN plain_events USING (event_id)
|
||||
LEFT JOIN raid_events USING (event_id)
|
||||
LEFT JOIN cheer_events USING (event_id)
|
||||
LEFT JOIN subscriber_events USING (event_id)
|
||||
ORDER BY events.occurred_at ASC;
|
||||
|
||||
-- }}}
|
||||
|
||||
-- Specimens {{{
|
||||
|
||||
@@ -76,6 +76,7 @@ async def main():
|
||||
config=conf,
|
||||
initial_extensions=[
|
||||
'core',
|
||||
'twitch',
|
||||
'modules',
|
||||
],
|
||||
web_client=session,
|
||||
|
||||
@@ -47,8 +47,8 @@ class Connector:
|
||||
return AsyncConnectionPool(
|
||||
self._conn_args,
|
||||
open=False,
|
||||
min_size=4,
|
||||
max_size=8,
|
||||
min_size=1,
|
||||
max_size=4,
|
||||
configure=self._setup_connection,
|
||||
kwargs=self._conn_kwargs
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@ from typing import Optional
|
||||
|
||||
from psycopg import AsyncCursor, sql
|
||||
from psycopg.abc import Query, Params
|
||||
from psycopg._encodings import pgconn_encoding
|
||||
from psycopg._encodings import conn_encoding
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -15,7 +15,7 @@ class AsyncLoggingCursor(AsyncCursor):
|
||||
elif isinstance(query, (sql.SQL, sql.Composed)):
|
||||
msg = query.as_string(self)
|
||||
elif isinstance(query, bytes):
|
||||
msg = query.decode(pgconn_encoding(self._conn.pgconn), 'replace')
|
||||
msg = query.decode(conn_encoding(self._conn.pgconn), 'replace')
|
||||
else:
|
||||
msg = repr(query)
|
||||
return msg
|
||||
|
||||
273
src/datamodels.py
Normal file
273
src/datamodels.py
Normal file
@@ -0,0 +1,273 @@
|
||||
from enum import Enum
|
||||
from data import Registry, RowModel, Table, RegisterEnum
|
||||
from data.columns import Integer, String, Timestamp, Column
|
||||
|
||||
|
||||
class EventType(Enum):
|
||||
SUBSCRIBER = 'subscriber',
|
||||
RAID = 'raid',
|
||||
CHEER = 'cheer',
|
||||
PLAIN = 'plain',
|
||||
|
||||
|
||||
class DataModel(Registry):
|
||||
_EventType = RegisterEnum(EventType, 'EventType')
|
||||
|
||||
class UserPreferences(RowModel):
|
||||
"""
|
||||
Schema
|
||||
------
|
||||
CREATE TABLE user_preferences (
|
||||
profileid INTEGER PRIMARY KEY REFERENCES user_profiles (profileid) ON DELETE CASCADE,
|
||||
twitch_name TEXT,
|
||||
preferences TEXT
|
||||
);
|
||||
"""
|
||||
_tablename_ = 'user_preferences'
|
||||
_cache_ = {}
|
||||
|
||||
profileid = Integer(primary=True)
|
||||
twitch_name = String()
|
||||
preferences = String()
|
||||
|
||||
class Dreamer(RowModel):
|
||||
"""
|
||||
Schema
|
||||
------
|
||||
CREATE VIEW dreamers AS
|
||||
SELECT
|
||||
user_profiles.profileid AS user_id,
|
||||
user_preferences.twitch_name AS name,
|
||||
profiles_twitch.userid AS twitch_id,
|
||||
user_preferences.preferences AS preferences,
|
||||
user_profiles.created_at AS created_at
|
||||
FROM
|
||||
user_profiles
|
||||
LEFT JOIN profiles_twitch USING (profileid)
|
||||
LEFT JOIN user_preferences USING (profileid);
|
||||
"""
|
||||
_tablename_ = ''
|
||||
_readonly_ = True
|
||||
|
||||
profileid = Integer(primary=True)
|
||||
name = String()
|
||||
twitch_id = Integer()
|
||||
preferences = String()
|
||||
created_at = Timestamp()
|
||||
|
||||
class Transaction(RowModel):
|
||||
"""
|
||||
Schema
|
||||
------
|
||||
CREATE TABLE user_wallet (
|
||||
transaction_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL REFERENCES user_profiles (profileid) ON DELETE CASCADE,
|
||||
amount INTEGER NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
reference TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
"""
|
||||
_tablename_ = 'user_wallet'
|
||||
_cache_ = {}
|
||||
_immutable_ = True
|
||||
|
||||
transaction_id = Integer(primary=True)
|
||||
user_id = Integer()
|
||||
amount = Integer()
|
||||
description = String()
|
||||
reference = String()
|
||||
created_at = Timestamp()
|
||||
|
||||
|
||||
class StampType(RowModel):
|
||||
"""
|
||||
Schema
|
||||
------
|
||||
CREATE TABLE stamp_types (
|
||||
stamp_type_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
stamp_type_name TEXT UNIQUE NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
"""
|
||||
_tablename_ = 'stamp_types'
|
||||
_cache_ = {}
|
||||
|
||||
stamp_type_id = Integer(primary=True)
|
||||
stamp_type_name = String()
|
||||
created_at = Timestamp()
|
||||
|
||||
class Document(RowModel):
|
||||
"""
|
||||
Schema
|
||||
------
|
||||
CREATE TABLE documents (
|
||||
document_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
document_data VARCHAR NOT NULL,
|
||||
seal INTEGER NOT NULL,
|
||||
metadata TEXT
|
||||
);
|
||||
"""
|
||||
_tablename_ = 'documents'
|
||||
_cache_ = {}
|
||||
|
||||
document_id = Integer(primary=True)
|
||||
document_data = Column()
|
||||
seal = Integer()
|
||||
metadata = String()
|
||||
|
||||
class DocumentStamp(RowModel):
|
||||
"""
|
||||
Schema
|
||||
------
|
||||
CREATE TABLE document_stamps (
|
||||
stamp_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
document_id INTEGER NOT NULL REFERENCES documents (document_id) ON DELETE CASCADE,
|
||||
stamp_type INTEGER NOT NULL REFERENCES stamp_types (stamp_type_id) ON DELETE CASCADE,
|
||||
position_x INTEGER NOT NULL,
|
||||
position_y INTEGER NOT NULL,
|
||||
rotation REAL NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
"""
|
||||
_tablename_ = 'document_stamps'
|
||||
_cache_ = {}
|
||||
|
||||
stamp_id = Integer(primary=True)
|
||||
document_id = Integer()
|
||||
stamp_type = Integer()
|
||||
position_x = Integer()
|
||||
position_y = Integer()
|
||||
rotation: Column[float] = Column()
|
||||
created_at = Timestamp()
|
||||
|
||||
class Events(RowModel):
|
||||
"""
|
||||
Schema
|
||||
------
|
||||
CREATE TABLE events (
|
||||
event_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL REFERENCES user_profiles (profileid) ON DELETE CASCADE,
|
||||
document_id INTEGER REFERENCES documents (document_id) ON DELETE SET NULL,
|
||||
user_name TEXT,
|
||||
event_type EventType NOT NULL,
|
||||
occurred_at TIMESTAMPTZ NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE (event_id, event_type)
|
||||
);
|
||||
"""
|
||||
_tablename_ = 'events'
|
||||
_cache_ = {}
|
||||
|
||||
event_id = Integer(primary=True)
|
||||
user_id = Integer()
|
||||
document_id = Integer()
|
||||
user_name = String()
|
||||
event_type: Column[EventType] = Column()
|
||||
occured_at = Timestamp()
|
||||
created_at = Timestamp()
|
||||
|
||||
plain_events = Table('plain_events')
|
||||
raid_events = Table('raid_events')
|
||||
cheer_events = Table('cheer_events')
|
||||
subscriber_events = Table('subscriber_events')
|
||||
|
||||
class EventDetails(RowModel):
|
||||
"""
|
||||
Schema
|
||||
------
|
||||
CREATE TABLE plain_events (
|
||||
event_id integer PRIMARY KEY,
|
||||
event_type EventType NOT NULL DEFAULT 'plain' CHECK (event_type = 'plain'),
|
||||
message TEXT NOT NULL,
|
||||
FOREIGN KEY (event_id, event_type) REFERENCES events (event_id, event_type)
|
||||
);
|
||||
|
||||
CREATE TABLE raid_events (
|
||||
event_id integer PRIMARY KEY,
|
||||
event_type EventType NOT NULL DEFAULT 'raid' CHECK (event_type = 'raid'),
|
||||
visitor_count INTEGER NOT NULL,
|
||||
FOREIGN KEY (event_id, event_type) REFERENCES events (event_id, event_type)
|
||||
);
|
||||
|
||||
CREATE TABLE cheer_events (
|
||||
event_id integer PRIMARY KEY,
|
||||
event_type EventType NOT NULL DEFAULT 'cheer' CHECK (event_type = 'cheer'),
|
||||
amount INTEGER NOT NULL,
|
||||
cheer_type TEXT,
|
||||
message TEXT,
|
||||
FOREIGN KEY (event_id, event_type) REFERENCES events (event_id, event_type)
|
||||
);
|
||||
|
||||
CREATE TABLE subscriber_events (
|
||||
event_id integer PRIMARY KEY,
|
||||
event_type EventType NOT NULL DEFAULT 'subscriber' CHECK (event_type = 'subscriber'),
|
||||
subscribed_length INTEGER NOT NULL,
|
||||
tier INTEGER NOT NULL,
|
||||
message TEXT,
|
||||
FOREIGN KEY (event_id, event_type) REFERENCES events (event_id, event_type)
|
||||
);
|
||||
|
||||
CREATE VIEW event_details AS
|
||||
SELECT
|
||||
events.event_id AS event_id,
|
||||
events.user_id AS user_id,
|
||||
events.document_id AS document_id,
|
||||
events.user_name AS user_name,
|
||||
events.event_type AS event_type,
|
||||
events.occurred_at AS occurred_at,
|
||||
events.created_at AS created_at,
|
||||
plain_events.message AS plain_message,
|
||||
raid_events.visitor_count AS raid_visitor_count,
|
||||
cheer_events.amount AS cheer_amount,
|
||||
cheer_events.cheer_type AS cheer_type,
|
||||
cheer_events.message AS cheer_message,
|
||||
subscriber_events.subscribed_length AS subscriber_length,
|
||||
subscriber_events.tier AS subscriber_tier,
|
||||
subscriber_events.message AS subscriber_message,
|
||||
FROM
|
||||
events
|
||||
LEFT JOIN plain_events USING (event_id)
|
||||
LEFT JOIN raid_events USING (event_id)
|
||||
LEFT JOIN cheer_events USING (event_id)
|
||||
LEFT JOIN subscriber_events USING (event_id)
|
||||
ORDER BY events.occurred_at ASC;
|
||||
"""
|
||||
_tablename_ = 'event_details'
|
||||
_readonly_ = True
|
||||
|
||||
event_id = Integer(primary=True)
|
||||
user_id = Integer()
|
||||
document_id = Integer()
|
||||
user_name = String()
|
||||
event_type: Column[EventType] = Column()
|
||||
occurred_at = Timestamp()
|
||||
created_at = Timestamp()
|
||||
plain_message = String()
|
||||
raid_visitor_count = Integer()
|
||||
cheer_amount = Integer()
|
||||
cheer_type = String()
|
||||
cheer_message = String()
|
||||
subscriber_length = Integer()
|
||||
subscriber_tier = Integer()
|
||||
subscriber_message = String()
|
||||
|
||||
|
||||
class Specimen(RowModel):
|
||||
"""
|
||||
Schema
|
||||
------
|
||||
CREATE TABLE user_specimens (
|
||||
specimen_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
owner_id INTEGER NOT NULL REFERENCES user_profiles (profileid) ON DELETE CASCADE,
|
||||
born_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
forgotten_at TIMESTAMPTZ
|
||||
);
|
||||
"""
|
||||
_tablename_ = 'user_specimens'
|
||||
_cache_ = {}
|
||||
|
||||
specimen_id = Integer(primary=True)
|
||||
owner_id = Integer(primary=True)
|
||||
born_at = Timestamp()
|
||||
forgotten_at = Timestamp()
|
||||
@@ -203,7 +203,7 @@ class LionBot(Bot):
|
||||
# TODO: Some of these could have more user-feedback
|
||||
logger.debug(f"Handling command error for {ctx}: {exception}")
|
||||
if isinstance(ctx.command, HybridCommand) and ctx.command.app_command:
|
||||
cmd_str = ctx.command.app_command.to_dict()
|
||||
cmd_str = ctx.command.app_command.to_dict(self.tree)
|
||||
else:
|
||||
cmd_str = str(ctx.command)
|
||||
try:
|
||||
|
||||
@@ -133,7 +133,7 @@ class LionTree(CommandTree):
|
||||
return
|
||||
|
||||
set_logging_context(action=f"Run {command.qualified_name}")
|
||||
logger.debug(f"Running command '{command.qualified_name}': {command.to_dict()}")
|
||||
logger.debug(f"Running command '{command.qualified_name}': {command.to_dict(self)}")
|
||||
try:
|
||||
await command._invoke_with_namespace(interaction, namespace)
|
||||
except AppCommandError as e:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
this_package = 'modules'
|
||||
|
||||
active = [
|
||||
'.profiles',
|
||||
'.sysadmin',
|
||||
]
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@ from discord.ext import commands as cmds
|
||||
from twitchAPI.helper import first
|
||||
from twitchAPI.type import AuthScope
|
||||
import twitchio
|
||||
from twitchio.ext import commands
|
||||
from twitchio import User
|
||||
from twitchAPI.object.api import TwitchUser
|
||||
|
||||
|
||||
|
||||
@@ -7,9 +7,8 @@ import discord
|
||||
from discord.ext import commands as cmds
|
||||
|
||||
from twitchAPI.oauth import UserAuthenticator
|
||||
from twitchAPI.twitch import AuthType, Twitch
|
||||
from twitchAPI.twitch import Twitch
|
||||
from twitchAPI.type import AuthScope
|
||||
import twitchio
|
||||
from twitchio.ext import commands
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user