1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-23 11:34:18 +00:00

💥 Fiorygi-related commands

This commit is contained in:
Steffo 2021-04-25 02:31:15 +02:00
parent 37d482736d
commit 827dd0a836
Signed by: steffo
GPG key ID: 6965406171929D01
11 changed files with 379 additions and 31 deletions

View file

@ -48,16 +48,21 @@ register_telegram(commands.ping, ["ping"])
register_telegram(commands.ship, ["ship"], r"(?P<first>[A-Za-z]+)[\s+&]+(?P<second>[A-Za-z]+)") register_telegram(commands.ship, ["ship"], r"(?P<first>[A-Za-z]+)[\s+&]+(?P<second>[A-Za-z]+)")
register_telegram(commands.emojify, ["emojify"], r"(?P<message>.+)") register_telegram(commands.emojify, ["emojify"], r"(?P<message>.+)")
register_telegram(commands.dog_any, ["dog", "doggo", "cane", "woof", "bau"]) register_telegram(commands.dog_any, ["dog", "doggo", "cane", "woof", "bau"])
register_telegram(commands.dog_breedlist, ["dog", "doggo", "cane", "woof", "bau"], "(?:list|help|aiuto)") register_telegram(commands.dog_breedlist, ["dog", "doggo", "cane", "woof", "bau"], r"(?:list|help|aiuto)")
register_telegram(commands.dog_breed, ["dog", "doggo", "cane", "woof", "bau"], "(?P<breed>[A-Za-z/]+)") register_telegram(commands.dog_breed, ["dog", "doggo", "cane", "woof", "bau"], r"(?P<breed>[A-Za-z/]+)")
register_telegram(commands.fortune, ["fortune"]) register_telegram(commands.fortune, ["fortune"])
register_telegram(commands.pmots, ["pmots"]) register_telegram(commands.pmots, ["pmots"])
register_telegram(commands.spell, ["spell", "cast"], "(?P<spellname>.+)") register_telegram(commands.spell, ["spell", "cast"], r"(?P<spellname>.+)")
register_telegram(commands.smecds, ["smecds"]) register_telegram(commands.smecds, ["smecds"])
register_telegram(commands.man, ["man", "help"], "(?P<commandname>[A-Za-z]+)") register_telegram(commands.man, ["man", "help"], r"(?P<commandname>[A-Za-z]+)")
register_telegram(commands.login, ["login"]) register_telegram(commands.login, ["login"])
register_telegram(commands.whoami, ["whoami"]) register_telegram(commands.whoami, ["whoami"])
register_telegram(commands.balance, ["balance", "fiorygi"]) register_telegram(commands.fiorygi_balance_self, ["balance"])
register_telegram(commands.fiorygi_balance_other, ["balance"], r"(?P<target>\S+)")
register_telegram(commands.fiorygi_give, ["give"], r"(?P<target>\S+)\s+(?P<amount>[0-9]+)\s+(?P<reason>.+)")
register_telegram(commands.fiorygi_magick, ["magick"], r"(?P<target>\S+)\s+(?P<amount>[0-9]+)\s+(?P<reason>.+)")
register_telegram(commands.fiorygi_transactions_self, ["transactions"])
register_telegram(commands.fiorygi_transactions_other, ["transactions"], r"(?P<target>\S+)")
pda.implementations["telethon.1"].register_conversation(r) pda.implementations["telethon.1"].register_conversation(r)

View file

@ -1 +1,2 @@
from .login import * from .login import *
from .target import *

40
royalpack/bolts/target.py Normal file
View file

@ -0,0 +1,40 @@
"""
"""
from __future__ import annotations
import functools
import logging
import royalnet.engineer as engi
import sqlalchemy.orm as so
import royalpack.database as db
log = logging.getLogger(__name__)
def with_target():
"""
.. todo:: Document this.
"""
def decorator(f):
@functools.wraps(f)
async def decorated(_msg: engi.Message, _session: so.Session, target: str, **f_kwargs):
user = db.UserAlias.find(session=_session, string=target)
if user is None:
await _msg.reply(text=f"⚠️ L'utente specificato non esiste.")
return
return await f(_msg=_msg, _session=_session, **f_kwargs, _target=user)
return decorated
return decorator
__all__ = (
"with_target",
)

View file

@ -14,4 +14,4 @@ from .smecds import *
from .man import * from .man import *
from .login import * from .login import *
from .whoami import * from .whoami import *
from .balance import * from .fiorygi import *

View file

@ -1,16 +0,0 @@
import royalnet.engineer as engi
import royalpack.database as rd
import royalpack.bolts as rb
@engi.use_database(rd.lazy_session_class)
@rb.use_ryglogin(allow_anonymous=False)
@engi.TeleportingConversation
async def balance(*, _sentry: engi.Sentry, _msg: engi.Message, _user: rd.User, **__):
"""
Visualizza il tuo portafoglio di fiorygi.
"""
await _msg.reply(text=f"💰 Al momento, possiedi \uE01Bƒ {_user.fiorygi}\uE00B.")
__all__ = ("balance",)

View file

@ -0,0 +1,207 @@
import royalnet.engineer as engi
import royalpack.database as db
import royalpack.bolts as rb
import sqlalchemy.sql as ss
import functools
@engi.use_database(db.lazy_session_class)
@rb.use_ryglogin(allow_anonymous=False)
@engi.TeleportingConversation
async def fiorygi_balance_self(*, _user: db.User, _msg: engi.Message, **__):
"""
Visualizza il tuo portafoglio attuale di fiorygi.
"""
await _msg.reply(text=f"💰 Attualmente, possiedi \uE01Bƒ {_user.fiorygi}\uE00B.")
@engi.use_database(db.lazy_session_class)
@rb.with_target()
@engi.TeleportingConversation
async def fiorygi_balance_other(*, _target: db.User, _session: db.SessionType, _msg: engi.Message, **__):
"""
Visualizza il portafoglio di fiorygi di un altro membro.
"""
await _msg.reply(text=f"💰 {_target} possiede \uE01Bƒ {_target.fiorygi}\uE00B.")
def render(transaction: db.Transaction, user: db.User):
row = []
if transaction.plus == user:
is_plus = True
other = transaction.minus
else:
is_plus = False
other = transaction.plus
if transaction.amount != 0:
row.append(f"{'' if is_plus else ''} \uE01Bƒ {transaction.amount}\uE00B")
if other is not None:
row.append(f"\uE011{'da' if is_plus else 'a'} {other}\uE001")
if transaction.reason:
row.append(f"{transaction.reason}")
return " - ".join(row)
@engi.use_database(db.lazy_session_class)
@rb.use_ryglogin(allow_anonymous=False)
@engi.TeleportingConversation
async def fiorygi_transactions_self(*, _session: db.SessionType, _user: db.User, _msg: engi.Message, **__):
"""
Visualizza le ultime 10 transazioni del tuo portafoglio.
"""
transactions = _session.execute(
ss.select(
db.Transaction
).where(
ss.or_(
db.Transaction.minus == _user,
db.Transaction.plus == _user,
)
).order_by(
db.Transaction.timestamp.desc()
).limit(
10
)
).scalars()
msg = map(functools.partial(render, user=_user), transactions)
await _msg.reply(text="\n\n".join(msg))
@engi.use_database(db.lazy_session_class)
@rb.with_target()
@engi.TeleportingConversation
async def fiorygi_transactions_other(*, _session: db.SessionType, _target: db.User, _msg: engi.Message, **__):
"""
Visualizza le ultime 10 transazioni del portafoglio di un membro.
"""
transactions = _session.execute(
ss.select(
db.Transaction
).where(
ss.or_(
db.Transaction.minus == _target,
db.Transaction.plus == _target,
)
).order_by(
db.Transaction.timestamp.desc()
).limit(
10
)
).scalars()
msg = map(functools.partial(render, user=_target), transactions)
await _msg.reply(text="\n\n".join(msg))
@engi.use_database(db.lazy_session_class)
@rb.use_ryglogin(allow_anonymous=False)
@rb.with_target()
@engi.TeleportingConversation
async def fiorygi_give(
*,
_user: db.User,
_target: db.User,
_msg: engi.Message,
_session: db.SessionType,
amount: int,
reason: str,
**__
):
"""
Dai dei fiorygi a un altro membro.
"""
if amount <= 0:
await _msg.reply(text=f"⚠️ Puoi trasferire solo numeri interi positivi di fiorygi.")
return
if _user.fiorygi < amount:
await _msg.reply(text=f"⚠️ Non hai sufficienti fiorygi per effettuare il trasferimento.")
return
if _user == _target:
await _msg.reply(text=f"⚠️ Non puoi dare fiorygi a te stesso!")
return
trans = db.Transaction(
minus=_user,
plus=_target,
amount=amount,
reason=reason,
)
_session.add(trans)
_user.fiorygi -= amount
_target.fiorygi += amount
_session.commit()
await _msg.reply(text=f"💸 Hai trasferito \uE01Bƒ {amount}\uE00B a {_target}.")
@engi.use_database(db.lazy_session_class)
@rb.use_ryglogin(allow_anonymous=False)
@rb.with_target()
@engi.TeleportingConversation
async def fiorygi_magick(
*,
_user: db.User,
_target: db.User,
_msg: engi.Message,
_session: db.SessionType,
amount: int,
reason: str,
**__
):
"""
Modifica il portafoglio di fiorygi di un membro.
"""
if _user.sub != "auth0|5ed2debf7308300c1ea230c3":
await _msg.reply(text=f"⚠️ Non sei autorizzato ad eseguire questo comando.")
return
if amount >= 0:
trans = db.Transaction(
minus=None,
plus=_target,
amount=amount,
reason=reason,
)
else:
trans = db.Transaction(
minus=_target,
plus=None,
amount=amount,
reason=reason,
)
_session.add(trans)
_target.fiorygi += amount
_session.commit()
await _msg.reply(text=f"🏦 Hai modificato il portafoglio di {_target} di \uE01Bƒ {amount}\uE00B.")
__all__ = (
"fiorygi_balance_self",
"fiorygi_balance_other",
"fiorygi_give",
"fiorygi_magick",
"fiorygi_transactions_self",
"fiorygi_transactions_other",
)

View file

@ -66,6 +66,7 @@ async def login(*, _msg: engi.Message, _session: so.Session, _imp, **__):
) )
user = await register_user_generic(session=_session, user_info=ui) user = await register_user_generic(session=_session, user_info=ui)
uas = await register_user_alias(session=_session, user_info=ui)
log.debug(f"Committing session...") log.debug(f"Committing session...")
_session.commit() _session.commit()
@ -246,9 +247,45 @@ async def register_user_generic(
email=user_info['email'], email=user_info['email'],
) )
session.merge(user) session.merge(user)
return user return user
async def register_user_alias(
session: so.Session,
user_info: dict[str, t.Any],
):
"""
.. todo:: Document this.
"""
log.debug("Syncing user aliases...")
uas = [
db.UserAlias(
user_fk=user_info["sub"],
name=user_info["name"]
),
db.UserAlias(
user_fk=user_info["sub"],
name=user_info["nickname"]
),
db.UserAlias(
user_fk=user_info["sub"],
name=user_info["email"]
),
db.UserAlias(
user_fk=user_info["sub"],
name=user_info["sub"]
),
]
for ua in uas:
session.merge(ua)
return uas
async def register_user_telethon( async def register_user_telethon(
session: so.Session, session: so.Session,
user_info: dict[str, t.Any], user_info: dict[str, t.Any],

View file

@ -1,8 +1,8 @@
"""Second revision """First revision
Revision ID: 8b28a4a94552 Revision ID: c6aacbd5d796
Revises: Revises:
Create Date: 2021-04-18 00:38:17.976303 Create Date: 2021-04-25 01:00:49.131019
""" """
from alembic import op from alembic import op
@ -11,7 +11,7 @@ import sqlalchemy_utils
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
revision = '8b28a4a94552' revision = 'c6aacbd5d796'
down_revision = None down_revision = None
branch_labels = None branch_labels = None
depends_on = None depends_on = None
@ -116,7 +116,7 @@ def upgrade():
sa.Column('user_fk', sa.String(), nullable=False), sa.Column('user_fk', sa.String(), nullable=False),
sa.Column('name', sa.String(), nullable=False), sa.Column('name', sa.String(), nullable=False),
sa.ForeignKeyConstraint(['user_fk'], ['users.sub'], ), sa.ForeignKeyConstraint(['user_fk'], ['users.sub'], ),
sa.PrimaryKeyConstraint('user_fk') sa.PrimaryKeyConstraint('user_fk', 'name')
) )
op.create_table('user_title_association', op.create_table('user_title_association',
sa.Column('user_fk', sa.String(), nullable=True), sa.Column('user_fk', sa.String(), nullable=True),

View file

@ -0,0 +1,33 @@
"""Add timestamp to transactions
Revision ID: e6b0d97063a1
Revises: c6aacbd5d796
Create Date: 2021-04-25 02:18:44.248837
"""
from alembic import op
import sqlalchemy as sa
import sqlalchemy_utils
# revision identifiers, used by Alembic.
revision = 'e6b0d97063a1'
down_revision = 'c6aacbd5d796'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('fiorygi_transactions', sa.Column('timestamp', sqlalchemy_utils.types.arrow.ArrowType(), nullable=True))
op.add_column('fiorygi_treasures', sa.Column('creation_time', sqlalchemy_utils.types.arrow.ArrowType(), nullable=False))
op.add_column('fiorygi_treasures', sa.Column('find_time', sqlalchemy_utils.types.arrow.ArrowType(), nullable=False))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('fiorygi_treasures', 'find_time')
op.drop_column('fiorygi_treasures', 'creation_time')
op.drop_column('fiorygi_transactions', 'timestamp')
# ### end Alembic commands ###

View file

@ -1,8 +1,9 @@
from __future__ import annotations from __future__ import annotations
import typing as t
import sqlalchemy as s import sqlalchemy as s
import sqlalchemy.sql as ss
import sqlalchemy.orm as so import sqlalchemy.orm as so
import sqlalchemy.ext.declarative as sed import sqlalchemy.ext.declarative as sed
import sqlalchemy.ext.associationproxy as seap
import sqlalchemy_utils as su import sqlalchemy_utils as su
import royalnet.alchemist as ra import royalnet.alchemist as ra
import colour import colour
@ -38,6 +39,9 @@ class User(Base, ra.ColRepr, ra.Updatable):
title_fk = s.Column(su.UUIDType, s.ForeignKey("titles.uuid")) title_fk = s.Column(su.UUIDType, s.ForeignKey("titles.uuid"))
fiorygi = s.Column(s.Integer, nullable=False, default=0) fiorygi = s.Column(s.Integer, nullable=False, default=0)
def __str__(self):
return self.name
class UserAlias(Base, ra.ColRepr, ra.Updatable): class UserAlias(Base, ra.ColRepr, ra.Updatable):
""" """
@ -48,7 +52,21 @@ class UserAlias(Base, ra.ColRepr, ra.Updatable):
user_fk = s.Column(s.String, s.ForeignKey("users.sub"), primary_key=True) user_fk = s.Column(s.String, s.ForeignKey("users.sub"), primary_key=True)
user = so.relationship("User", backref="aliases") user = so.relationship("User", backref="aliases")
name = s.Column(s.String, nullable=False) name = s.Column(s.String, nullable=False, primary_key=True)
@so.validates("name")
def convert_lower(self, key, value: str) -> str:
return value.lower()
@classmethod
def find(cls, session: so.Session, string: str) -> t.Optional[User]:
ua = session.execute(
ss.select(cls).where(cls.name == string)
).scalar()
return ua.user if ua else None
def __str__(self):
return self.name
class TelegramAccount(Base, ra.ColRepr, ra.Updatable): class TelegramAccount(Base, ra.ColRepr, ra.Updatable):
@ -80,6 +98,9 @@ class TelegramAccount(Base, ra.ColRepr, ra.Updatable):
else: else:
return f"[{self.name}](tg://user?id={self.tg_id})" return f"[{self.name}](tg://user?id={self.tg_id})"
def __str__(self):
return self.name()
class DiscordAccount(Base, ra.ColRepr, ra.Updatable): class DiscordAccount(Base, ra.ColRepr, ra.Updatable):
""" """
@ -98,6 +119,9 @@ class DiscordAccount(Base, ra.ColRepr, ra.Updatable):
def name(self) -> str: def name(self) -> str:
return f"{self.username}#{self.discriminator}" return f"{self.username}#{self.discriminator}"
def __str__(self):
return self.name()
class SteamAccount(Base, ra.ColRepr, ra.Updatable): class SteamAccount(Base, ra.ColRepr, ra.Updatable):
""" """
@ -114,6 +138,9 @@ class SteamAccount(Base, ra.ColRepr, ra.Updatable):
# TODO: make steamid return steam.steamid.SteamID objects # TODO: make steamid return steam.steamid.SteamID objects
def __str__(self):
return self.persona_name
class OsuAccount(Base, ra.ColRepr, ra.Updatable): class OsuAccount(Base, ra.ColRepr, ra.Updatable):
""" """
@ -128,6 +155,9 @@ class OsuAccount(Base, ra.ColRepr, ra.Updatable):
username = s.Column(s.String) username = s.Column(s.String)
avatar_url = s.Column(su.URLType) avatar_url = s.Column(su.URLType)
def __str__(self):
return self.username
class LeagueAccount(Base, ra.ColRepr, ra.Updatable): class LeagueAccount(Base, ra.ColRepr, ra.Updatable):
""" """
@ -143,6 +173,9 @@ class LeagueAccount(Base, ra.ColRepr, ra.Updatable):
summoner_name = s.Column(s.String, nullable=False) summoner_name = s.Column(s.String, nullable=False)
avatar_id = s.Column(s.Integer, nullable=False) avatar_id = s.Column(s.Integer, nullable=False)
def __str__(self):
return self.summoner_name
class Title(Base, ra.ColRepr, ra.Updatable): class Title(Base, ra.ColRepr, ra.Updatable):
""" """
@ -159,6 +192,9 @@ class Title(Base, ra.ColRepr, ra.Updatable):
unlocked_by = so.relationship("User", secondary=user_title_association, backref="unlocked_titles") unlocked_by = so.relationship("User", secondary=user_title_association, backref="unlocked_titles")
def __str__(self):
return self.name
class DiarioGroup(Base, ra.ColRepr, ra.Updatable): class DiarioGroup(Base, ra.ColRepr, ra.Updatable):
""" """
@ -203,13 +239,14 @@ class Transaction(Base, ra.ColRepr, ra.Updatable):
id = s.Column(s.Integer, primary_key=True) id = s.Column(s.Integer, primary_key=True)
minus_fk = s.Column(s.String, s.ForeignKey("users.sub")) minus_fk = s.Column(s.String, s.ForeignKey("users.sub"))
minus = so.relationship("User", foreign_keys=(minus_fk,)) minus = so.relationship("User", foreign_keys=(minus_fk,), backref="transactions_minus")
plus_fk = s.Column(s.String, s.ForeignKey("users.sub")) plus_fk = s.Column(s.String, s.ForeignKey("users.sub"))
plus = so.relationship("User", foreign_keys=(plus_fk,)) plus = so.relationship("User", foreign_keys=(plus_fk,), backref="transactions_plus")
amount = s.Column(s.Integer, nullable=False) amount = s.Column(s.Integer, nullable=False)
reason = s.Column(s.Text) reason = s.Column(s.Text)
timestamp = s.Column(su.ArrowType)
class Treasure(Base, ra.ColRepr, ra.Updatable): class Treasure(Base, ra.ColRepr, ra.Updatable):
@ -222,9 +259,11 @@ class Treasure(Base, ra.ColRepr, ra.Updatable):
creator_fk = s.Column(s.String, s.ForeignKey("users.sub")) creator_fk = s.Column(s.String, s.ForeignKey("users.sub"))
creator = so.relationship("User", foreign_keys=(creator_fk,)) creator = so.relationship("User", foreign_keys=(creator_fk,))
creation_time = s.Column(su.ArrowType, nullable=False)
finder_fk = s.Column(s.String, s.ForeignKey("users.sub")) finder_fk = s.Column(s.String, s.ForeignKey("users.sub"))
finder = so.relationship("User", foreign_keys=(finder_fk,)) finder = so.relationship("User", foreign_keys=(finder_fk,))
find_time = s.Column(su.ArrowType, nullable=False)
value = s.Column(s.Integer, nullable=False) value = s.Column(s.Integer, nullable=False)
message = s.Column(s.Text) message = s.Column(s.Text)

View file

@ -14,8 +14,10 @@ lazy_session_class = royalnet.lazy.Lazy(lambda e: sqlalchemy.orm.sessionmaker(bi
The uninitialized sqlalchemy session class. The uninitialized sqlalchemy session class.
""" """
SessionType = sqlalchemy.orm.Session
__all__ = ( __all__ = (
"lazy_engine", "lazy_engine",
"lazy_session_class", "lazy_session_class",
"SessionType",
) )