1
Fork 0
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:
Steffo 2020-05-06 21:22:48 +02:00
parent 355514cb6a
commit 87569fd364
10 changed files with 160 additions and 28 deletions

View file

@ -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()

View file

@ -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__

View 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))

View 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))

View file

@ -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!"

View file

@ -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."

View file

@ -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__

View file

@ -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()

View 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}"

View file

@ -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}>"