feat(shard): 🎉 Initialize the rewrite.

This commit is contained in:
Nyeki.py
2024-11-13 02:09:47 -03:00
parent a7f64de5b4
commit d9d752c730
85 changed files with 1912 additions and 7626 deletions
@@ -1,104 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
CREATE TABLE IF NOT EXISTS "call" (
"id" SERIAL NOT NULL PRIMARY KEY,
"started_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"ended_at" TIMESTAMPTZ
);
CREATE TABLE IF NOT EXISTS "server" (
"id" BIGSERIAL NOT NULL PRIMARY KEY,
"prefix" VARCHAR(3) NOT NULL DEFAULT 'p.'
);
CREATE TABLE IF NOT EXISTS "channel" (
"id" BIGSERIAL NOT NULL PRIMARY KEY,
"enabled" BOOL,
"webhook_id" BIGINT,
"webhook_url" TEXT,
"call_id" INT REFERENCES "call" ("id") ON DELETE CASCADE,
"server_id" BIGINT NOT NULL REFERENCES "server" ("id") ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS "user" (
"id" BIGSERIAL NOT NULL PRIMARY KEY,
"username" VARCHAR(32) NOT NULL,
"is_masked" BOOL NOT NULL DEFAULT False,
"is_moderator" BOOL NOT NULL DEFAULT False
);
CREATE TABLE IF NOT EXISTS "profile" (
"id" SERIAL NOT NULL PRIMARY KEY,
"avatar_url" TEXT NOT NULL,
"name" VARCHAR(32) NOT NULL,
"color" INT,
"server_id" BIGINT REFERENCES "server" ("id") ON DELETE CASCADE,
"user_id" BIGINT NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE,
CONSTRAINT "uid_profile_user_id_903480" UNIQUE ("user_id", "server_id")
);
CREATE TABLE IF NOT EXISTS "calluserchannelrelationship" (
"id" SERIAL NOT NULL PRIMARY KEY,
"is_masked" BOOL NOT NULL,
"mask" BIGINT NOT NULL,
"call_id" INT NOT NULL REFERENCES "call" ("id") ON DELETE CASCADE,
"channel_id" BIGINT NOT NULL REFERENCES "channel" ("id") ON DELETE CASCADE,
"profile_id" INT NOT NULL REFERENCES "profile" ("id") ON DELETE CASCADE,
"user_id" BIGINT NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE,
CONSTRAINT "uid_callusercha_call_id_fad9b8" UNIQUE ("call_id", "user_id", "channel_id")
);
CREATE TABLE IF NOT EXISTS "message" (
"id" BIGSERIAL NOT NULL PRIMARY KEY,
"mask" BIGINT,
"was_deleted" BOOL NOT NULL DEFAULT False,
"propagation_id" BIGINT,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"call_id" INT NOT NULL REFERENCES "call" ("id") ON DELETE CASCADE,
"channel_id" BIGINT NOT NULL REFERENCES "channel" ("id") ON DELETE CASCADE,
"profile_id" INT NOT NULL REFERENCES "profile" ("id") ON DELETE CASCADE,
"propagation_channel_id" BIGINT REFERENCES "channel" ("id") ON DELETE CASCADE,
"replying_to_id" BIGINT REFERENCES "message" ("id") ON DELETE SET NULL,
"user_id" BIGINT NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS "idx_message_propaga_f0803c" ON "message" ("propagation_id");
CREATE TABLE IF NOT EXISTS "messagecontent" (
"id" SERIAL NOT NULL PRIMARY KEY,
"content" VARCHAR(4096) NOT NULL,
"was_propagated" BOOL NOT NULL DEFAULT True,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"message_id" BIGINT NOT NULL REFERENCES "message" ("id") ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS "report" (
"id" SERIAL NOT NULL PRIMARY KEY,
"reason" VARCHAR(500) NOT NULL,
"priority" INT NOT NULL,
"status" SMALLINT NOT NULL DEFAULT 2,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"reported_by_id" BIGINT REFERENCES "user" ("id") ON DELETE CASCADE,
"call_id" INT NOT NULL UNIQUE REFERENCES "call" ("id") ON DELETE CASCADE
);
COMMENT ON COLUMN "report"."status" IS 'ACCEPTED: 0\nDECLINED: 1\nON_REVIEW: 2';
CREATE TABLE IF NOT EXISTS "ban" (
"id" SERIAL NOT NULL PRIMARY KEY,
"notification_message_id" BIGINT,
"reason" VARCHAR(500) NOT NULL,
"appeal" VARCHAR(500),
"status" SMALLINT NOT NULL DEFAULT 0,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"expires_at" TIMESTAMPTZ,
"banned_by_id" BIGINT NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE,
"report_id" INT REFERENCES "report" ("id") ON DELETE SET NULL,
"user_id" BIGINT NOT NULL REFERENCES "user" ("id") ON DELETE NO ACTION
);
CREATE INDEX IF NOT EXISTS "idx_ban_notific_ea7b58" ON "ban" ("notification_message_id");
CREATE INDEX IF NOT EXISTS "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");
COMMENT ON COLUMN "ban"."status" IS 'VALID: 0\nON_REVIEW: 1\nAPPEAL_ACCEPTED: 2\nAPPEAL_DECLINED: 3';
CREATE TABLE IF NOT EXISTS "aerich" (
"id" SERIAL NOT NULL PRIMARY KEY,
"version" VARCHAR(255) NOT NULL,
"app" VARCHAR(100) NOT NULL,
"content" JSONB NOT NULL
);"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
"""
@@ -0,0 +1,55 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
CREATE TABLE IF NOT EXISTS "channel" (
"id" BIGSERIAL NOT NULL PRIMARY KEY,
"server_id" BIGINT NOT NULL,
"is_enabled" BOOL NOT NULL DEFAULT True
);
CREATE INDEX IF NOT EXISTS "idx_channel_server__d5ded1" ON "channel" ("server_id");
CREATE INDEX "idx_channel_server__d940e4" ON "channel" ("server_id", "is_enabled");
COMMENT ON TABLE "channel" IS 'A channel.';
CREATE TABLE IF NOT EXISTS "user" (
"id" BIGSERIAL NOT NULL PRIMARY KEY,
"is_masked" BOOL NOT NULL DEFAULT False,
"is_moderator" BOOL NOT NULL DEFAULT False,
"is_supporter_until" TIMESTAMPTZ
);
COMMENT ON TABLE "user" IS 'A user.';
CREATE TABLE IF NOT EXISTS "report" (
"id" SERIAL NOT NULL PRIMARY KEY,
"message_id" BIGINT NOT NULL UNIQUE,
"message_content" TEXT NOT NULL,
"channel_id" BIGINT NOT NULL,
"user_id" BIGINT NOT NULL,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"resolved" BOOL NOT NULL DEFAULT False,
"resolved_at" TIMESTAMPTZ,
"resolved_by_id" BIGINT NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS "idx_report_resolve_32f036" ON "report" ("resolved");
COMMENT ON TABLE "report" IS 'A report of a message.';
CREATE TABLE IF NOT EXISTS "ban" (
"id" SERIAL NOT NULL PRIMARY KEY,
"user_id" BIGINT NOT NULL,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"expires_at" TIMESTAMPTZ,
"created_by_id" BIGINT NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE,
"expired_by_id" BIGINT REFERENCES "user" ("id") ON DELETE CASCADE,
"report_id" INT REFERENCES "report" ("id") ON DELETE CASCADE
);
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");
COMMENT ON TABLE "ban" IS 'A ban.';
CREATE TABLE IF NOT EXISTS "aerich" (
"id" SERIAL NOT NULL PRIMARY KEY,
"version" VARCHAR(255) NOT NULL,
"app" VARCHAR(100) NOT NULL,
"content" JSONB NOT NULL
);"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
"""
@@ -1,15 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "server" ADD "leaderboard_calls_count" INT NOT NULL DEFAULT 0;
ALTER TABLE "server" ADD "leaderboard_position" INT NOT NULL DEFAULT 0;
CREATE INDEX "idx_server_leaderb_47c354" ON "server" ("leaderboard_position");"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_server_leaderb_47c354";
ALTER TABLE "server" DROP COLUMN "leaderboard_calls_count";
ALTER TABLE "server" DROP COLUMN "leaderboard_position";"""
@@ -1,11 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "server" ADD "vanity_code" VARCHAR(32);"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "server" DROP COLUMN "vanity_code";"""
@@ -1,13 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "ban" DROP COLUMN "appeal";
ALTER TABLE "ban" DROP COLUMN "status";"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "ban" ADD "appeal" VARCHAR(500);
ALTER TABLE "ban" ADD "status" SMALLINT NOT NULL DEFAULT 0;"""
@@ -1,11 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "user" ADD "found_easter_eggs" SMALLINT NOT NULL DEFAULT 0;"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "user" DROP COLUMN "found_easter_eggs";"""
@@ -1,11 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "report" ALTER COLUMN "priority" TYPE DOUBLE PRECISION USING "priority"::DOUBLE PRECISION;"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "report" ALTER COLUMN "priority" TYPE INT USING "priority"::INT;"""
@@ -1,19 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_ban_user_id_37a9cf";
ALTER TABLE "ban" ADD "unbanned_by_id" BIGINT;
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
ALTER TABLE "ban" ADD CONSTRAINT "fk_ban_user_e41857cf" FOREIGN KEY ("unbanned_by_id") REFERENCES "user" ("id") ON DELETE CASCADE;
CREATE INDEX "idx_report_status_d6b157" ON "report" ("status", "priority");;"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_report_status_d6b157";
ALTER TABLE "ban" DROP CONSTRAINT "fk_ban_user_e41857cf";
DROP INDEX "idx_ban_user_id_37a9cf";
ALTER TABLE "ban" DROP COLUMN "unbanned_by_id";
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");"""
@@ -1,21 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_report_status_d6b157";
DROP INDEX "idx_ban_user_id_37a9cf";
ALTER TABLE "report" ADD "reviewed_by_id" BIGINT;
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
CREATE INDEX "idx_report_status_d6b157" ON "report" ("status", "priority");;
ALTER TABLE "report" ADD CONSTRAINT "fk_report_user_67e68360" FOREIGN KEY ("reviewed_by_id") REFERENCES "user" ("id") ON DELETE SET NULL;"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "report" DROP CONSTRAINT "fk_report_user_67e68360";
DROP INDEX "idx_report_status_d6b157";
DROP INDEX "idx_ban_user_id_37a9cf";
ALTER TABLE "report" DROP COLUMN "reviewed_by_id";
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
CREATE INDEX "idx_report_status_d6b157" ON "report" ("status", "priority");;"""
@@ -1,21 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_report_status_d6b157";
DROP INDEX "idx_ban_user_id_37a9cf";
ALTER TABLE "user" ADD "is_deleting" BOOL NOT NULL DEFAULT False;
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
CREATE INDEX "idx_report_status_d6b157" ON "report" ("status", "priority");;
CREATE INDEX "idx_user_is_dele_2b4cfd" ON "user" ("is_deleting");"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_report_status_d6b157";
DROP INDEX "idx_user_is_dele_2b4cfd";
DROP INDEX "idx_ban_user_id_37a9cf";
ALTER TABLE "user" DROP COLUMN "is_deleting";
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
CREATE INDEX "idx_report_status_d6b157" ON "report" ("status", "priority");;"""
@@ -1,11 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "ban" ALTER COLUMN "banned_by_id" DROP NOT NULL;"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "ban" ALTER COLUMN "banned_by_id" SET NOT NULL;"""
@@ -0,0 +1,17 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_channel_server__d940e4";
DROP INDEX "idx_ban_user_id_37a9cf";
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
CREATE INDEX "idx_channel_server__d940e4" ON "channel" ("server_id", "is_enabled");;"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_channel_server__d940e4";
DROP INDEX "idx_ban_user_id_37a9cf";
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
CREATE INDEX "idx_channel_server__d940e4" ON "channel" ("server_id", "is_enabled");;"""
@@ -1,11 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "ban" DROP CONSTRAINT "ban_user_id_fkey";"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "ban" ADD CONSTRAINT "ban_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "user" ("id") ON DELETE NO ACTION;"""
@@ -0,0 +1,17 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_channel_server__d940e4";
DROP INDEX "idx_ban_user_id_37a9cf";
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
CREATE INDEX "idx_channel_server__d940e4" ON "channel" ("server_id", "is_enabled");;"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_channel_server__d940e4";
DROP INDEX "idx_ban_user_id_37a9cf";
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
CREATE INDEX "idx_channel_server__d940e4" ON "channel" ("server_id", "is_enabled");;"""
@@ -1,11 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "server" ALTER COLUMN "prefix" TYPE VARCHAR(5) USING "prefix"::VARCHAR(5);"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "server" ALTER COLUMN "prefix" TYPE VARCHAR(3) USING "prefix"::VARCHAR(3);"""
@@ -0,0 +1,17 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_channel_server__d940e4";
DROP INDEX "idx_ban_user_id_37a9cf";
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
CREATE INDEX "idx_channel_server__d940e4" ON "channel" ("server_id", "is_enabled");;"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_channel_server__d940e4";
DROP INDEX "idx_ban_user_id_37a9cf";
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
CREATE INDEX "idx_channel_server__d940e4" ON "channel" ("server_id", "is_enabled");;"""
@@ -1,17 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "calluserchannelrelationship" ADD "created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE "user" ADD "leaderboard_position" INT;
CREATE INDEX "idx_callusercha_created_e72939" ON "calluserchannelrelationship" ("created_at");
CREATE INDEX "idx_user_leaderb_1dcee5" ON "user" ("leaderboard_position");"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_callusercha_created_e72939";
DROP INDEX "idx_user_leaderb_1dcee5";
ALTER TABLE "user" DROP COLUMN "leaderboard_position";
ALTER TABLE "calluserchannelrelationship" DROP COLUMN "created_at";"""
@@ -0,0 +1,19 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_channel_server__d940e4";
DROP INDEX "idx_ban_user_id_37a9cf";
ALTER TABLE "report" DROP COLUMN "resolved_by_id";
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
CREATE INDEX "idx_channel_server__d940e4" ON "channel" ("server_id", "is_enabled");;"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_channel_server__d940e4";
DROP INDEX "idx_ban_user_id_37a9cf";
ALTER TABLE "report" ADD "resolved_by_id" BIGINT;
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
CREATE INDEX "idx_channel_server__d940e4" ON "channel" ("server_id", "is_enabled");;"""
@@ -1,11 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "user" ADD "joined_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP;"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "user" DROP COLUMN "joined_at";"""
@@ -0,0 +1,21 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_channel_server__d940e4";
DROP INDEX "idx_ban_user_id_37a9cf";
ALTER TABLE "report" ADD "resolved_by_id" BIGINT;
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
CREATE INDEX "idx_channel_server__d940e4" ON "channel" ("server_id", "is_enabled");;
ALTER TABLE "report" ADD CONSTRAINT "fk_report_user_e65f1760" FOREIGN KEY ("resolved_by_id") REFERENCES "user" ("id") ON DELETE CASCADE;"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_channel_server__d940e4";
ALTER TABLE "report" DROP CONSTRAINT "fk_report_user_e65f1760";
DROP INDEX "idx_ban_user_id_37a9cf";
ALTER TABLE "report" DROP COLUMN "resolved_by_id";
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
CREATE INDEX "idx_channel_server__d940e4" ON "channel" ("server_id", "is_enabled");;"""
@@ -1,11 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "user" ADD "leaderboard_calls_count" INT;"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "user" DROP COLUMN "leaderboard_calls_count";"""
@@ -1,11 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
CREATE INDEX "idx_ban_created_490013" ON "ban" ("created_at");"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_ban_created_490013";"""
@@ -1,11 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
CREATE INDEX "idx_user_usernam_9987ab" ON "user" ("username");"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX "idx_user_usernam_9987ab";"""
@@ -1,11 +0,0 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "server" ADD "name" VARCHAR(100);"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "server" DROP COLUMN "name";"""
+91 -394
View File
@@ -1,406 +1,103 @@
from datetime import datetime
from datetime import datetime, timezone
import enum
from tortoise import models, fields, indexes
import discord
from discord import webhook
import aiohttp
from payphone.core import config, constants
from payphone.cogs.easter import EasterEggCommand
class User(models.Model):
id: int = fields.BigIntField(primary_key=True)
username: str = fields.CharField(max_length=32, db_index=True)
is_masked: bool = fields.BooleanField(default=False)
is_moderator: bool = fields.BooleanField(default=False)
is_deleting: bool = fields.BooleanField(default=False, db_index=True)
found_easter_eggs: int = fields.IntEnumField(EasterEggCommand, default=0)
profiles: fields.BackwardFKRelation["Profile"]
call_rss: fields.BackwardFKRelation["CallUserChannelRelationship"]
leaderboard_position: int | None = fields.IntField(
default=None, null=True, db_index=True
)
leaderboard_calls_count: int | None = fields.IntField(default=None, null=True)
joined_at: datetime = fields.DatetimeField(auto_now_add=True)
class Call(models.Model):
started_at = fields.DatetimeField(auto_now_add=True, db_index=True)
ended_at = fields.DatetimeField(null=True, default=None)
channels: fields.BackwardFKRelation["Channel"]
call_rss: fields.BackwardFKRelation["CallUserChannelRelationship"]
report: fields.BackwardOneToOneRelation["Report"]
messages: fields.BackwardFKRelation["Message"]
class Profile(models.Model):
user: fields.ForeignKeyRelation["User"] = fields.ForeignKeyField(
"models.User", related_name="profiles", on_delete=fields.OnDelete.CASCADE
)
user_id: int
server: fields.ForeignKeyNullableRelation["Server"] = fields.ForeignKeyField(
"models.Server",
related_name="profiles",
null=True,
on_delete=fields.OnDelete.CASCADE,
)
avatar_url: str = fields.TextField()
name: str = fields.CharField(max_length=32)
color: int | None = fields.IntField(null=True, default=None)
call_rss: fields.BackwardFKRelation["CallUserChannelRelationship"]
@property
def jump_url(self) -> str:
"""The URL that'll open the user in Discord.
Returns:
str: The URL.
"""
return f"discord://-/users/{self.user_id}"
@property
def link(self) -> str:
"""A markdown link that opens the user in Discord.
Returns:
str: The markdown link.
"""
return f"[{self.name}]({self.jump_url})"
@property
def embed_author(self) -> discord.EmbedAuthor:
"""Returns this profile as an EmbedAuthor object.
Returns:
discord.EmbedAuthor: The EmbedAuthor object.
"""
return discord.EmbedAuthor(name=self.name, icon_url=self.avatar_url)
class Meta:
unique_together = [("user_id", "server_id")]
class Server(models.Model):
id: int = fields.BigIntField(primary_key=True)
name: str = fields.CharField(max_length=100, null=True, default=None)
prefix: str = fields.CharField(max_length=5, default="p.")
leaderboard_position: int = fields.IntField(default=0, db_index=True)
leaderboard_calls_count: int = fields.IntField(default=0)
vanity_code: str = fields.CharField(max_length=32, null=True, default=None)
channels: fields.BackwardFKRelation["Channel"]
profiles: fields.BackwardFKRelation["Profile"]
class Channel(models.Model):
id = fields.BigIntField(primary_key=True)
server: fields.ForeignKeyRelation[Server] = fields.ForeignKeyField(
"models.Server", related_name="channels", on_delete=fields.OnDelete.CASCADE
)
call: fields.ForeignKeyNullableRelation["Call"] = fields.ForeignKeyField(
"models.Call", null=True, related_name="channels"
)
enabled: bool | None = fields.BooleanField(null=True, default=None)
webhook_id: int | None = fields.BigIntField(null=True)
webhook_url: str | None = fields.TextField(null=True)
call_rss: fields.BackwardFKRelation["CallUserChannelRelationship"]
messages: fields.BackwardFKRelation["Message"]
propagated_messages: fields.BackwardFKRelation["Message"]
def webhook(self, session: aiohttp.ClientSession) -> webhook.Webhook | None:
"""Initializes the channel's webhook instance.
Args:
session (aiohttp.ClientSession): An initialized aiohttp client session.
Returns:
webhook.Webhook | None: The webhook, or None if not initialized.
"""
if self.webhook_url is None:
return None
return webhook.Webhook.from_url(
self.webhook_url, session=session, bot_token=config.TOKEN
)
class Meta:
index = [("server_id", "enabled")]
class CallUserChannelRelationship(models.Model):
call: fields.ForeignKeyRelation["Call"] = fields.ForeignKeyField(
"models.Call", related_name="call_rss", on_delete=fields.OnDelete.CASCADE
)
user: fields.ForeignKeyRelation["User"] = fields.ForeignKeyField(
"models.User", related_name="call_rss", on_delete=fields.OnDelete.CASCADE
)
profile: fields.ForeignKeyRelation["Profile"] = fields.ForeignKeyField(
"models.Profile", related_name="call_rss", on_delete=fields.OnDelete.CASCADE
)
channel: fields.ForeignKeyRelation["Channel"] = fields.ForeignKeyField(
"models.Channel", related_name="call_rss", on_delete=fields.OnDelete.CASCADE
)
is_masked: bool = fields.BooleanField()
mask: int = fields.BigIntField()
created_at: datetime = fields.DatetimeField(auto_now_add=True, db_index=True)
@property
def mask_name(self) -> str:
"""Returns the mask's name.
Returns:
str: The mask's name.
"""
try:
mask = constants.Mask(self.mask)
except ValueError:
mask = constants.CatMask(self.mask)
return mask.name.replace("_", " ").lower().title()
@property
def display_name(self) -> str:
"""Returns the displayed name.
Returns:
str: The displayed name.
"""
if self.is_masked:
return self.mask_name
return self.profile.name
@property
def display_avatar(self) -> str:
"""Returns the displayed avatar URL.
Returns:
str: The displayed avatar URL.
"""
if self.is_masked:
try:
mask = constants.Mask(self.mask)
except ValueError:
mask = constants.CatMask(self.mask)
return f"https://payphone.nyeki.dev/assets/masks/{mask.name.lower().replace("_", "-")}.png"
return self.profile.avatar_url
@property
def mask_emoji(self) -> str:
"""Returns the mask's emoji.
Returns:
str: The mask's emoji (<:name:id>).
"""
try:
mask = constants.Mask(self.mask)
except ValueError:
mask = constants.CatMask(self.mask)
mask_name = mask.name.lower().replace("_", "")
return f"<:{mask_name}:{self.mask}>"
class Meta:
unique_together = [("call_id", "user_id", "channel_id")]
class Message(models.Model):
id = fields.BigIntField(primary_key=True)
call: fields.ForeignKeyRelation["Call"] = fields.ForeignKeyField(
"models.Call", related_name="messages", on_delete=fields.OnDelete.CASCADE
)
call_id: int
channel: fields.ForeignKeyRelation["Channel"] = fields.ForeignKeyField(
"models.Channel", related_name="messages", on_delete=fields.OnDelete.CASCADE
)
channel_id: int
user = fields.ForeignKeyRelation("models.User", on_delete=fields.OnDelete.CASCADE)
user_id: int
profile: fields.ForeignKeyRelation["Profile"] = fields.ForeignKeyField(
"models.Profile", on_delete=fields.OnDelete.CASCADE
)
profile_id: int
replying_to: fields.ForeignKeyNullableRelation["Message"] = fields.ForeignKeyField(
"models.Message",
related_name="replies",
on_delete=fields.OnDelete.SET_NULL,
null=True,
default=None,
)
mask = fields.BigIntField(null=True)
was_deleted = fields.BooleanField(default=False)
propagation_id = fields.BigIntField(null=True, db_index=True)
propagation_channel: fields.ForeignKeyNullableRelation["Channel"] = (
fields.ForeignKeyField(
"models.Channel", related_name="propagated_messages", null=True
)
)
propagation_channel_id: int
created_at = fields.DatetimeField(auto_now_add=True)
contents: fields.BackwardFKRelation["MessageContent"]
@property
def mask_name(self) -> str:
"""Returns the mask's name.
Returns:
str: The mask's name.
"""
try:
mask = constants.Mask(self.mask)
except ValueError:
mask = constants.CatMask(self.mask)
return mask.name.replace("_", " ").lower().title()
@property
def display_name(self) -> str:
"""Returns the displayed name.
Returns:
str: The displayed name.
"""
if self.mask is not None:
return self.mask_name
return self.profile.name
@property
def display_avatar(self) -> str:
"""Returns the displayed avatar URL.
Returns:
str: The displayed avatar URL.
"""
if self.mask is not None:
try:
mask = constants.Mask(self.mask)
except ValueError:
mask = constants.CatMask(self.mask)
return f"https://payphone.nyeki.dev/assets/masks/{mask.name.lower().replace("_", "-")}.png"
return self.profile.avatar_url
@property
def mask_emoji(self) -> str:
"""Returns the mask's emoji.
Returns:
str: The mask's emoji (<:name:id>).
"""
try:
mask = constants.Mask(self.mask)
except ValueError:
mask = constants.CatMask(self.mask)
mask_name = mask.name.lower().replace("_", "")
return f"<:{mask_name}:{self.mask}>"
def jump_url(self, is_this_channel: bool = True) -> str | None:
"""Returns the jump URL for this message.
Args:
is_this_channel (bool, optional): Whether the message sent in this channel or not.
Defaults to True.
Returns:
str | None: The URL, or None if the message was not propagated.
"""
if not is_this_channel:
return f"https://discord.com/channels/{self.channel.server_id}/{self.channel.id}/{self.id}"
if self.propagation_id is not None:
return f"https://discord.com/channels/{self.propagation_channel.server_id}/{self.propagation_channel.id}/{self.propagation_id}"
return None
class MessageContent(models.Model):
message = fields.ForeignKeyField(
"models.Message", related_name="contents", on_delete=fields.OnDelete.CASCADE
)
message_id: int
content = fields.CharField(max_length=4096)
was_propagated = fields.BooleanField(default=True)
created_at = fields.DatetimeField(auto_now_add=True)
class ReportStatus(enum.IntEnum):
ACCEPTED = 0
DECLINED = 1
ON_REVIEW = 2
from tortoise import models, fields
class Report(models.Model):
call: fields.OneToOneRelation["Call"] = fields.OneToOneField(
"models.Call", related_name="report"
)
reported_by: fields.ForeignKeyNullableRelation["User"] = fields.ForeignKeyField(
"models.User", null=True, on_delete=fields.OnDelete.CASCADE
)
reviewed_by: fields.ForeignKeyNullableRelation["User"] = fields.ForeignKeyField(
"models.User", null=True, on_delete=fields.OnDelete.SET_NULL, related_name="reports_reviewed"
)
reason: str = fields.CharField(max_length=500)
priority: float = fields.FloatField()
status: ReportStatus = fields.IntEnumField(
ReportStatus, default=ReportStatus.ON_REVIEW, db_index=True
)
created_at: datetime = fields.DatetimeField(auto_now_add=True)
"""
A report of a message.
"""
class Meta:
indexes = [indexes.Index(fields=("status", "priority"))]
message_id = fields.BigIntField(unique=True)
message_content = fields.TextField()
channel_id = fields.BigIntField()
user_id = fields.BigIntField()
created_at = fields.DatetimeField(auto_now_add=True)
resolved = fields.BooleanField(default=False, index=True)
resolved_at = fields.DatetimeField(null=True)
resolved_by = fields.ForeignKeyField("models.User", null=True)
class UserFlag(enum.IntFlag):
"""
Flags for a user.
"""
NONE = 0
MODERATOR = 1
SUPPORTER = 2
class User(models.Model):
"""
A user.
"""
id = fields.BigIntField(pk=True)
is_masked = fields.BooleanField(default=False)
is_moderator = fields.BooleanField(default=False)
is_supporter_until = fields.DatetimeField(null=True)
@property
def flags(self) -> UserFlag:
"""
The flags of the user.
"""
flags = UserFlag.NONE
if self.is_moderator:
flags |= UserFlag.MODERATOR
if (
self.is_supporter_until is not None
and self.is_supporter_until > datetime.now(timezone.utc)
):
flags |= UserFlag.SUPPORTER
return flags
class Ban(models.Model):
user_id: int = fields.BigIntField()
report: fields.ForeignKeyNullableRelation["Report"] = fields.ForeignKeyField(
"models.Report",
related_name="bans",
null=True,
on_delete=fields.OnDelete.SET_NULL,
)
notification_message_id: int = fields.BigIntField(null=True, db_index=True)
reason: str = fields.CharField(max_length=500)
banned_by: fields.ForeignKeyRelation["User"] = fields.ForeignKeyField(
"models.User", related_name="bans_created", null=True
)
unbanned_by: fields.ForeignKeyNullableRelation["User"] = fields.ForeignKeyField(
"models.User", related_name="bans_removed", null=True, default=None
)
created_at: datetime = fields.DatetimeField(auto_now_add=True, db_index=True)
expires_at: datetime | None = fields.DatetimeField(null=True)
"""
A ban.
"""
user_id = fields.BigIntField()
report = fields.ForeignKeyField("models.Report", null=True)
created_at = fields.DatetimeField(auto_now_add=True)
expires_at = fields.DatetimeField(null=True)
created_by = fields.ForeignKeyField("models.User", related_name="created_bans")
expired_by = fields.ForeignKeyField("models.User", related_name="bans", null=True)
class Meta:
indexes = [indexes.Index(fields=("user_id", "expires_at"))]
"""
Meta information.
"""
indexes = [
models.Index(fields=["user_id", "expires_at"]),
]
class Channel(models.Model):
"""
A channel.
"""
id = fields.BigIntField(pk=True)
server_id = fields.BigIntField(index=True)
is_enabled = fields.BooleanField(default=True)
class Meta:
"""
Meta information.
"""
indexes = [
models.Index(fields=["server_id", "is_enabled"]),
]
+26 -2
View File
@@ -1,9 +1,33 @@
import tortoise
from payphone.core import config
from payphone.core import constants
CONFIG = {
"connections": {
"default": {
"engine": "tortoise.backends.asyncpg",
"credentials": {
"host": "localhost" if constants.IS_DEBUG else "postgresql",
"port": "5432",
"user": "payphone",
"password": "payphone",
"database": "payphone",
},
"minsize": 5,
"maxsize": 100,
},
},
"apps": {
"models": {
"models": ["payphone.db.models", "aerich.models"],
"default_connection": "default",
}
},
}
async def init() -> None:
"""Initialize the database and it's connections."""
await tortoise.Tortoise.init(config.TORTOISE_ORM, use_tz=True)
await tortoise.Tortoise.init(CONFIG, use_tz=True)
-85
View File
@@ -1,85 +0,0 @@
from typing import Tuple
import discord
from payphone.db import models
async def get_channel(channel: discord.TextChannel) -> models.Channel:
"""Returns a channel from the database, creating or updating it if it already exists.
Args:
channel (discord.TextChannel): The channel to fetch.
Returns:
models.Channel: The channel row.
"""
row, _ = await models.Channel.update_or_create(
id=channel.id, server=channel.guild.id
)
channel_name = channel.name.replace("discord", "d").replace("wumpus", "w")
webhook_name = f"Payphone #{channel_name}"
if row.webhook_id is None:
webhook = await channel.create_webhook(
name=webhook_name, reason="First call started in channel."
)
row.webhook_id = webhook.id
row.webhook_url = webhook.url
await row.save(update_fields=["webhook_id", "webhook_url"])
else:
found = False
for webhook in await channel.webhooks():
if webhook.id != row.webhook_id:
if webhook.token is None:
await webhook.delete(reason="Webhook is unaccessible by Payphone.")
break
else:
found = True
if not found:
webhook = await channel.create_webhook(
name=webhook_name, reason="Previous webhook was deleted."
)
row.webhook_id = webhook.id
row.webhook_url = webhook.url
await row.save(update_fields=["webhook_id", "webhook_url"])
return row
async def get_user(
user: discord.User | discord.Member,
) -> Tuple[models.User, models.Profile]:
"""Returns a user from the database, creating or updating it if it already exists.
Args:
user (discord.User | discord.Member): The user or member to fetch.
Returns:
Tuple[models.User, models.Profile]: The user and profile.
"""
user_row, _ = await models.User.update_or_create(
{"username": user.name}, id=user.id
)
profile_row, _ = await models.Profile.update_or_create(
{
"avatar_url": user.display_avatar.url,
"name": user.display_name or user.name,
},
user=user_row,
server_id=user.guild.id if isinstance(user, discord.Member) else None,
)
return (user_row, profile_row)