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

Add brawlhalla duos

This commit is contained in:
Steffo 2020-03-24 00:02:55 +01:00
parent fa039f35c3
commit d6b4be55af
4 changed files with 169 additions and 13 deletions

View file

@ -6,8 +6,9 @@ from typing import *
from royalnet.commands import * from royalnet.commands import *
from royalnet.utils import * from royalnet.utils import *
from royalnet.serf.telegram.escape import escape as tg_escape from royalnet.serf.telegram.escape import escape as tg_escape
from ..tables import Steam, Brawlhalla from ..tables import Steam, Brawlhalla, BrawlhallaDuo
from ..types import BrawlhallaRank, BrawlhallaMetal, BrawlhallaTier from ..types import BrawlhallaRank, BrawlhallaMetal, BrawlhallaTier
from sqlalchemy import or_, and_
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -36,15 +37,30 @@ class BrawlhallaCommand(Command):
@staticmethod @staticmethod
def _display(bh: Brawlhalla) -> str: def _display(bh: Brawlhalla) -> str:
string = f" [b]{bh.name}[/b]\n\n" string = [f" [b]{bh.name}[/b]", ""]
if bh.rank_1v1: if bh.rank_1v1:
string += f"1v1: [b]{bh.rank_1v1}[/b] ({bh.rating_1v1} MMR)\n" string.append("👤 [b]1v1[/b]")
string.append(f"[b]{bh.rank_1v1}[/b] ({bh.rating_1v1} MMR)")
string.append("")
return string duos = bh.duos
if len(bh.duos) != 0:
string.append(f"👥 [b]2v2[/b]")
for duo in bh.duos:
other = duo.other(bh)
string.append(f"Con [b]{other.steam.user}[/b]: [b]{duo.rank_2v2}[/b] ({duo.rating_2v2} MMR)")
if len(bh.duos) != 0:
string.append("")
return "\n".join(string)
async def _notify(self, async def _notify(self,
obj: Brawlhalla, obj: Union[Brawlhalla, BrawlhallaDuo],
attribute_name: str, attribute_name: str,
old_value: Any, old_value: Any,
new_value: Any): new_value: Any):
@ -53,17 +69,23 @@ class BrawlhallaCommand(Command):
new_rank: Optional[BrawlhallaRank] = new_value new_rank: Optional[BrawlhallaRank] = new_value
if new_rank > old_rank: if new_rank > old_rank:
message = f"📈 [b]{obj.steam.user}[/b] è salito a [b]{new_value}[/b] ({obj.rating_1v1} MMR) in 1v1 su Brawlhalla! Congratulazioni!" message = f"📈 [b]{obj.steam.user}[/b] è salito a [b]{new_value}[/b] ({obj.rating_1v1} MMR) in 1v1 su Brawlhalla! Congratulazioni!"
elif new_rank < old_rank:
message = f"📉 [b]{obj.steam.user}[/b] è sceso a [b]{new_value}[/b] ({obj.rating_1v1} MMR) in 1v1 su Brawlhalla."
else: else:
return message = f"📉 [b]{obj.steam.user}[/b] è sceso a [b]{new_value}[/b] ({obj.rating_1v1} MMR) in 1v1 su Brawlhalla."
await self._send(message)
elif attribute_name == "rank_2v2":
old_rank: Optional[BrawlhallaRank] = old_value
new_rank: Optional[BrawlhallaRank] = new_value
if new_rank > old_rank:
message = f"📈 [b]{obj.one.steam.user}[/b] e [b]{obj.two.steam.user}[/b] sono saliti a [b]{new_value}[/b] ({obj.rating_2v2} MMR) in 2v2 su Brawlhalla! Congratulazioni!"
else:
message = f"📉 [b]{obj.one.steam.user}[/b] e [b]{obj.two.steam.user}[/b] sono scesi a [b]{new_value}[/b] ({obj.rating_2v2} MMR) in 2v2 su Brawlhalla."
await self._send(message) await self._send(message)
@staticmethod @staticmethod
async def _change(obj: Brawlhalla, async def _change(obj: Union[Brawlhalla, BrawlhallaDuo],
attribute_name: str, attribute_name: str,
new_value: Any, new_value: Any,
callback: Callable[[Brawlhalla, str, Any, Any], Awaitable[None]]): callback: Callable[[Union[Brawlhalla, BrawlhallaDuo], str, Any, Any], Awaitable[None]]):
old_value = obj.__getattribute__(attribute_name) old_value = obj.__getattribute__(attribute_name)
if old_value != new_value: if old_value != new_value:
await callback(obj, attribute_name, old_value, new_value) await callback(obj, attribute_name, old_value, new_value)
@ -71,6 +93,7 @@ class BrawlhallaCommand(Command):
async def _update(self, steam: Steam, db_session): async def _update(self, steam: Steam, db_session):
BrawlhallaT = self.alchemy.get(Brawlhalla) BrawlhallaT = self.alchemy.get(Brawlhalla)
DuoT = self.alchemy.get(BrawlhallaDuo)
log.info(f"Updating: {steam}") log.info(f"Updating: {steam}")
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
bh: Brawlhalla = steam.brawlhalla bh: Brawlhalla = steam.brawlhalla
@ -104,6 +127,48 @@ class BrawlhallaCommand(Command):
tier = BrawlhallaTier(int(tier_name)) tier = BrawlhallaTier(int(tier_name))
rank = BrawlhallaRank(metal=metal, tier=tier) rank = BrawlhallaRank(metal=metal, tier=tier)
await self._change(bh, "rank_1v1", rank, self._notify) await self._change(bh, "rank_1v1", rank, self._notify)
for jduo in j.get("2v2", []):
bhduo: Optional[BrawlhallaDuo] = await asyncify(
db_session.query(DuoT)
.filter(
or_(
and_(
DuoT.id_one == jduo["brawlhalla_id_one"],
DuoT.id_two == jduo["brawlhalla_id_two"]
),
and_(
DuoT.id_one == jduo["brawlhalla_id_two"],
DuoT.id_two == jduo["brawlhalla_id_one"]
)
)
)
.one_or_none
)
if bhduo is None:
if bh.brawlhalla_id == jduo["brawlhalla_id_one"]:
otherbh: Optional[Brawlhalla] = await asyncify(
db_session.query(BrawlhallaT).get, jduo["brawlhalla_id_two"]
)
else:
otherbh: Optional[Brawlhalla] = await asyncify(
db_session.query(BrawlhallaT).get, jduo["brawlhalla_id_one"]
)
if otherbh is None:
continue
bhduo = DuoT(
one=bh,
two=otherbh,
)
db_session.add(bhduo)
await self._change(bhduo, "rating_2v2", jduo["rating"], self._notify)
metal_name, tier_name = jduo["tier"].split(" ", 1)
metal = BrawlhallaMetal[metal_name.upper()]
tier = BrawlhallaTier(int(tier_name))
rank = BrawlhallaRank(metal=metal, tier=tier)
await self._change(bhduo, "rank_2v2", rank, self._notify)
await asyncify(db_session.commit) await asyncify(db_session.commit)
async def _updater(self, period: int): async def _updater(self, period: int):
@ -117,8 +182,7 @@ class BrawlhallaCommand(Command):
try: try:
await self._update(steam, session) await self._update(steam, session)
except Exception as e: except Exception as e:
sentry_sdk.capture_exception(e) sentry_exc(e)
log.error(f"Error while updating {steam.user.username}: {e}")
await asyncio.sleep(1) await asyncio.sleep(1)
await asyncify(session.commit) await asyncify(session.commit)
session.close() session.close()

View file

@ -13,6 +13,7 @@ from .brawlhalla import Brawlhalla
from .polls import Poll from .polls import Poll
from .pollcomments import PollComment from .pollcomments import PollComment
from .pollvotes import PollVote from .pollvotes import PollVote
from .brawlhalladuos import BrawlhallaDuo
# Enter the tables of your Pack here! # Enter the tables of your Pack here!
available_tables = [ available_tables = [
@ -30,6 +31,7 @@ available_tables = [
Poll, Poll,
PollComment, PollComment,
PollVote, PollVote,
BrawlhallaDuo,
] ]
# Don't change this, it should automatically generate __all__ # Don't change this, it should automatically generate __all__

View file

@ -15,7 +15,7 @@ class Brawlhalla:
@declared_attr @declared_attr
def _steamid(self): def _steamid(self):
return Column(BigInteger, ForeignKey("steam._steamid"), primary_key=True) return Column(BigInteger, ForeignKey("steam._steamid"), unique=True)
@declared_attr @declared_attr
def steam(self): def steam(self):
@ -52,6 +52,38 @@ class Brawlhalla:
self.metal_1v1 = value.metal self.metal_1v1 = value.metal
self.tier_1v1 = value.tier self.tier_1v1 = value.tier
@property
def duos(self):
return [*self._duos_one, *self._duos_two]
@property
def rating_2v2(self):
duos = sorted(self.duos, key=lambda d: -d.rating)
if len(duos) == 0:
return None
return duos[0].rating_2v2
@property
def tier_2v2(self):
duos = sorted(self.duos, key=lambda d: -d.rating)
if len(duos) == 0:
return None
return duos[0].tier_2v2
@property
def metal_2v2(self):
duos = sorted(self.duos, key=lambda d: -d.rating)
if len(duos) == 0:
return None
return duos[0].metal_2v2
@property
def rank_2v2(self):
duos = sorted(self.duos, key=lambda d: -d.rating)
if len(duos) == 0:
return None
return duos[0].rank_2v2
def __repr__(self): def __repr__(self):
return f"<Brawlhalla account {self._steamid}>" return f"<Brawlhalla account {self._steamid}>"

View file

@ -0,0 +1,58 @@
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declared_attr
from ..types import BrawlhallaRank, BrawlhallaTier, BrawlhallaMetal
class BrawlhallaDuo:
__tablename__ = "brawlhalladuos"
@declared_attr
def id_one(self):
return Column(Integer, ForeignKey("brawlhalla.brawlhalla_id"), primary_key=True)
@declared_attr
def id_two(self):
return Column(Integer, ForeignKey("brawlhalla.brawlhalla_id"), primary_key=True)
@declared_attr
def one(self):
return relationship("Brawlhalla", foreign_keys=self.id_one, backref=backref("_duos_one"))
@declared_attr
def two(self):
return relationship("Brawlhalla", foreign_keys=self.id_two, backref=backref("_duos_two"))
@declared_attr
def rating_2v2(self):
return Column(Integer)
@declared_attr
def tier_2v2(self):
return Column(Enum(BrawlhallaTier))
@declared_attr
def metal_2v2(self):
return Column(Enum(BrawlhallaMetal))
@property
def rank_2v2(self):
return BrawlhallaRank(metal=self.metal_2v2, tier=self.tier_2v2)
@rank_2v2.setter
def rank_2v2(self, value):
if not isinstance(value, BrawlhallaRank):
raise TypeError("rank_1v1 can only be set to BrawlhallaRank values.")
self.metal_2v2 = value.metal
self.tier_2v2 = value.tier
def other(self, bh):
if bh == self.one:
return self.two
elif bh == self.two:
return self.one
else:
raise ValueError("Argument is unrelated to this duo.")
def __repr__(self):
return f"<BrawlhallaDuo {self.id_one} & {self.id_two}>"