mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 19:44:20 +00:00
Change the backpack database schema
This commit is contained in:
parent
355514cb6a
commit
87569fd364
10 changed files with 160 additions and 28 deletions
|
@ -157,14 +157,19 @@ def run(config_filename: str):
|
||||||
|
|
||||||
log.info("All processes started!")
|
log.info("All processes started!")
|
||||||
if constellation_process is not None:
|
if constellation_process is not None:
|
||||||
|
log.info("Waiting for Constellation to stop...")
|
||||||
constellation_process.join()
|
constellation_process.join()
|
||||||
if telegram_process is not None:
|
if telegram_process is not None:
|
||||||
|
log.info("Waiting for Serf.Telegram to stop...")
|
||||||
telegram_process.join()
|
telegram_process.join()
|
||||||
if discord_process is not None:
|
if discord_process is not None:
|
||||||
|
log.info("Waiting for Serf.Discord to stop...")
|
||||||
discord_process.join()
|
discord_process.join()
|
||||||
if matrix_process is not None:
|
if matrix_process is not None:
|
||||||
|
log.info("Waiting for Serf.Matrix to stop...")
|
||||||
matrix_process.join()
|
matrix_process.join()
|
||||||
if herald_process is not None:
|
if herald_process is not None:
|
||||||
|
log.info("Waiting for Herald to stop...")
|
||||||
herald_process.join()
|
herald_process.join()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
# Imports go here!
|
# Imports go here!
|
||||||
from .version import VersionCommand
|
from .royalnetversion import RoyalnetversionCommand
|
||||||
|
from .royalnetsync import RoyalnetsyncCommand
|
||||||
|
from .royalnetroles import RoyalnetrolesCommand
|
||||||
|
from .royalnetaliases import RoyalnetaliasesCommand
|
||||||
|
|
||||||
# Enter the commands of your Pack here!
|
# Enter the commands of your Pack here!
|
||||||
available_commands = [
|
available_commands = [
|
||||||
VersionCommand,
|
RoyalnetversionCommand,
|
||||||
|
RoyalnetsyncCommand,
|
||||||
|
RoyalnetrolesCommand,
|
||||||
|
RoyalnetaliasesCommand,
|
||||||
]
|
]
|
||||||
|
|
||||||
# Don't change this, it should automatically generate __all__
|
# Don't change this, it should automatically generate __all__
|
||||||
|
|
24
royalnet/backpack/commands/royalnetaliases.py
Normal file
24
royalnet/backpack/commands/royalnetaliases.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
from typing import *
|
||||||
|
import royalnet
|
||||||
|
import royalnet.commands as rc
|
||||||
|
import royalnet.utils as ru
|
||||||
|
from ..tables.telegram import Telegram
|
||||||
|
from ..tables.discord import Discord
|
||||||
|
|
||||||
|
|
||||||
|
class RoyalnetaliasesCommand(rc.Command):
|
||||||
|
name: str = "royalnetaliases"
|
||||||
|
|
||||||
|
description: str = "Display your Royalnet aliases."
|
||||||
|
|
||||||
|
syntax: str = ""
|
||||||
|
|
||||||
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
|
author = await data.get_author(error_if_none=True)
|
||||||
|
|
||||||
|
msg = [
|
||||||
|
"👤 You currently have these aliases:",
|
||||||
|
*list(map(lambda r: f"- {r}", author.aliases))
|
||||||
|
]
|
||||||
|
|
||||||
|
await data.reply("\n".join(msg))
|
24
royalnet/backpack/commands/royalnetroles.py
Normal file
24
royalnet/backpack/commands/royalnetroles.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
from typing import *
|
||||||
|
import royalnet
|
||||||
|
import royalnet.commands as rc
|
||||||
|
import royalnet.utils as ru
|
||||||
|
from ..tables.telegram import Telegram
|
||||||
|
from ..tables.discord import Discord
|
||||||
|
|
||||||
|
|
||||||
|
class RoyalnetrolesCommand(rc.Command):
|
||||||
|
name: str = "royalnetroles"
|
||||||
|
|
||||||
|
description: str = "Display your Royalnet roles."
|
||||||
|
|
||||||
|
syntax: str = ""
|
||||||
|
|
||||||
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
|
author = await data.get_author(error_if_none=True)
|
||||||
|
|
||||||
|
msg = [
|
||||||
|
"👤 You currently have these roles:",
|
||||||
|
*list(map(lambda r: f"- {r}", author.roles))
|
||||||
|
]
|
||||||
|
|
||||||
|
await data.reply("\n".join(msg))
|
|
@ -6,8 +6,8 @@ from ..tables.telegram import Telegram
|
||||||
from ..tables.discord import Discord
|
from ..tables.discord import Discord
|
||||||
|
|
||||||
|
|
||||||
class SyncCommand(rc.Command):
|
class RoyalnetsyncCommand(rc.Command):
|
||||||
name: str = "sync"
|
name: str = "royalnetsync"
|
||||||
|
|
||||||
description: str = "Connect your chat account to Royalnet!"
|
description: str = "Connect your chat account to Royalnet!"
|
||||||
|
|
|
@ -2,8 +2,8 @@ import royalnet.version
|
||||||
from royalnet.commands import *
|
from royalnet.commands import *
|
||||||
|
|
||||||
|
|
||||||
class VersionCommand(Command):
|
class RoyalnetversionCommand(Command):
|
||||||
name: str = "version"
|
name: str = "royalnetversion"
|
||||||
|
|
||||||
description: str = "Display the current Royalnet version."
|
description: str = "Display the current Royalnet version."
|
||||||
|
|
|
@ -5,6 +5,7 @@ from .discord import Discord
|
||||||
from .matrix import Matrix
|
from .matrix import Matrix
|
||||||
from .aliases import Alias
|
from .aliases import Alias
|
||||||
from .tokens import Token
|
from .tokens import Token
|
||||||
|
from .roles import Role
|
||||||
|
|
||||||
# Enter the tables of your Pack here!
|
# Enter the tables of your Pack here!
|
||||||
available_tables = {
|
available_tables = {
|
||||||
|
@ -14,6 +15,7 @@ available_tables = {
|
||||||
Matrix,
|
Matrix,
|
||||||
Alias,
|
Alias,
|
||||||
Token,
|
Token,
|
||||||
|
Role,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Don't change this, it should automatically generate __all__
|
# Don't change this, it should automatically generate __all__
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
from typing import *
|
|
||||||
from sqlalchemy import Column, \
|
from sqlalchemy import Column, \
|
||||||
Integer, \
|
Integer, \
|
||||||
String, \
|
String, \
|
||||||
ForeignKey
|
ForeignKey
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from sqlalchemy.ext.declarative import declared_attr
|
from sqlalchemy.ext.declarative import declared_attr
|
||||||
import royalnet.utils as ru
|
|
||||||
|
|
||||||
|
|
||||||
class Alias:
|
class Alias:
|
||||||
|
@ -21,16 +19,9 @@ class Alias:
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def user(self):
|
def user(self):
|
||||||
return relationship("User", backref="aliases")
|
return relationship("User", backref="_aliases")
|
||||||
|
|
||||||
@classmethod
|
def __init__(self, user, alias: str):
|
||||||
async def find_user(cls, alchemy, session, alias: Union[str, int]):
|
|
||||||
result = await ru.asyncify(session.query(alchemy.get(cls)).filter_by(alias=alias.lower()).one_or_none)
|
|
||||||
if result is not None:
|
|
||||||
result = result.user
|
|
||||||
return result
|
|
||||||
|
|
||||||
def __init__(self, user: str, alias: str):
|
|
||||||
self.user = user
|
self.user = user
|
||||||
self.alias = alias.lower()
|
self.alias = alias.lower()
|
||||||
|
|
||||||
|
|
32
royalnet/backpack/tables/roles.py
Normal file
32
royalnet/backpack/tables/roles.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
from sqlalchemy import Column, \
|
||||||
|
Integer, \
|
||||||
|
String, \
|
||||||
|
ForeignKey
|
||||||
|
from sqlalchemy.orm import relationship
|
||||||
|
from sqlalchemy.ext.declarative import declared_attr
|
||||||
|
|
||||||
|
|
||||||
|
class Role:
|
||||||
|
__tablename__ = "role"
|
||||||
|
|
||||||
|
@declared_attr
|
||||||
|
def user_id(self):
|
||||||
|
return Column(Integer, ForeignKey("users.uid"), primary_key=True)
|
||||||
|
|
||||||
|
@declared_attr
|
||||||
|
def role(self):
|
||||||
|
return Column(String, primary_key=True)
|
||||||
|
|
||||||
|
@declared_attr
|
||||||
|
def user(self):
|
||||||
|
return relationship("User", backref="_roles")
|
||||||
|
|
||||||
|
def __init__(self, user, role: str):
|
||||||
|
self.user = user
|
||||||
|
self.role = role.lower()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<Alias {str(self)}>"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.role}->{self.user_id}"
|
|
@ -1,9 +1,15 @@
|
||||||
|
from typing import *
|
||||||
import bcrypt
|
import bcrypt
|
||||||
|
import royalnet.utils as ru
|
||||||
from sqlalchemy import Column, \
|
from sqlalchemy import Column, \
|
||||||
Integer, \
|
Integer, \
|
||||||
String, \
|
String, \
|
||||||
LargeBinary
|
LargeBinary, \
|
||||||
|
inspect
|
||||||
from sqlalchemy.ext.declarative import declared_attr
|
from sqlalchemy.ext.declarative import declared_attr
|
||||||
|
from .roles import Role
|
||||||
|
from .aliases import Alias
|
||||||
|
from ...utils import JSON, asyncify
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyAttributeOutsideInit
|
# noinspection PyAttributeOutsideInit
|
||||||
|
@ -18,36 +24,78 @@ class User:
|
||||||
def username(self):
|
def username(self):
|
||||||
return Column(String, unique=True, nullable=False)
|
return Column(String, unique=True, nullable=False)
|
||||||
|
|
||||||
|
@declared_attr
|
||||||
|
def email(self):
|
||||||
|
return Column(String, unique=True)
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def password(self):
|
def password(self):
|
||||||
return Column(LargeBinary)
|
return Column(LargeBinary)
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def role(self):
|
def avatar_url(self):
|
||||||
return Column(String, nullable=False)
|
return Column(String)
|
||||||
|
|
||||||
@declared_attr
|
@staticmethod
|
||||||
def avatar(self):
|
async def find_user(alchemy, session, alias: Union[str, int]):
|
||||||
return Column(LargeBinary)
|
result = await ru.asyncify(session.query(alchemy.get(Alias)).filter_by(alias=alias.lower()).one_or_none)
|
||||||
|
if result is not None:
|
||||||
|
result = result.user
|
||||||
|
return result
|
||||||
|
|
||||||
def json(self):
|
def json(self) -> JSON:
|
||||||
return {
|
return {
|
||||||
"uid": self.uid,
|
"uid": self.uid,
|
||||||
"username": self.username,
|
"username": self.username,
|
||||||
"role": self.role,
|
"email": self.email,
|
||||||
"avatar": self.avatar
|
"password_set": self.password is not None,
|
||||||
|
"avatar_url": self.avatar_url,
|
||||||
|
"roles": self.roles,
|
||||||
|
"aliases": self.aliases
|
||||||
}
|
}
|
||||||
|
|
||||||
def set_password(self, password: str):
|
def set_password(self, password: str) -> None:
|
||||||
byte_password: bytes = bytes(password, encoding="UTF8")
|
byte_password: bytes = bytes(password, encoding="UTF8")
|
||||||
self.password = bcrypt.hashpw(byte_password, bcrypt.gensalt(14))
|
self.password = bcrypt.hashpw(byte_password, bcrypt.gensalt(14))
|
||||||
|
|
||||||
def test_password(self, password: str):
|
def test_password(self, password: str) -> bool:
|
||||||
if self.password is None:
|
if self.password is None:
|
||||||
raise ValueError("No password is set")
|
raise ValueError("No password is set")
|
||||||
byte_password: bytes = bytes(password, encoding="UTF8")
|
byte_password: bytes = bytes(password, encoding="UTF8")
|
||||||
return bcrypt.checkpw(byte_password, self.password)
|
return bcrypt.checkpw(byte_password, self.password)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def roles(self) -> list:
|
||||||
|
return list(map(lambda a: a.role, self._roles))
|
||||||
|
|
||||||
|
def add_role(self, alchemy, role: str) -> None:
|
||||||
|
role = role.lower()
|
||||||
|
session = inspect(self).session
|
||||||
|
session.add(alchemy.get(Role)(user=self, role=role))
|
||||||
|
|
||||||
|
async def delete_role(self, alchemy, role: str) -> None:
|
||||||
|
role = role.lower()
|
||||||
|
session = inspect(self).session
|
||||||
|
role = await asyncify(session.query(alchemy.get(Role)).filter_by(user=self, role=role).one_or_none)
|
||||||
|
if role is not None:
|
||||||
|
session.delete(role)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def aliases(self) -> list:
|
||||||
|
return list(map(lambda a: a.alias, self._aliases))
|
||||||
|
|
||||||
|
def add_alias(self, alchemy, alias: str) -> None:
|
||||||
|
alias = alias.lower()
|
||||||
|
session = inspect(self).session
|
||||||
|
session.add(alchemy.get(Alias)(user=self, alias=alias))
|
||||||
|
|
||||||
|
async def delete_alias(self, alchemy, alias: str) -> None:
|
||||||
|
alias = alias.lower()
|
||||||
|
session = inspect(self).session
|
||||||
|
alias = await asyncify(session.query(alchemy.get(Alias)).filter_by(user=self, alias=alias).one_or_none)
|
||||||
|
if alias is not None:
|
||||||
|
session.delete(alias)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<{self.__class__.__qualname__} {self.username}>"
|
return f"<{self.__class__.__qualname__} {self.username}>"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue