1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-30 15:04:18 +00:00
royalnet/royalpack/commands/brawlhalla.py

205 lines
9.1 KiB
Python
Raw Normal View History

2020-03-19 15:26:11 +00:00
import asyncio
import logging
import sentry_sdk
import aiohttp
from typing import *
from royalnet.commands import *
from royalnet.utils import *
from royalnet.serf.telegram.escape import escape as tg_escape
2020-03-23 23:02:55 +00:00
from ..tables import Steam, Brawlhalla, BrawlhallaDuo
2020-03-19 15:26:11 +00:00
from ..types import BrawlhallaRank, BrawlhallaMetal, BrawlhallaTier
2020-03-23 23:02:55 +00:00
from sqlalchemy import or_, and_
2020-03-19 15:26:11 +00:00
log = logging.getLogger(__name__)
class BrawlhallaCommand(Command):
name: str = "brawlhalla"
aliases = ["bh", "bruhalla", "bruhlalla"]
description: str = "Visualizza le tue statistiche di Dota!"
syntax: str = ""
def __init__(self, interface: CommandInterface):
super().__init__(interface)
2020-04-28 18:03:22 +00:00
if self.interface.name == "telegram" and self.config["Brawlhalla"]["updater"]:
2020-04-26 16:09:06 +00:00
self.loop.create_task(self._updater(7200))
2020-03-19 15:26:11 +00:00
async def _send(self, message):
client = self.serf.client
await self.serf.api_call(client.send_message,
chat_id=self.config["Telegram"]["main_group_id"],
text=tg_escape(message),
parse_mode="HTML",
disable_webpage_preview=True)
@staticmethod
def _display(bh: Brawlhalla) -> str:
2020-03-23 23:02:55 +00:00
string = [f" [b]{bh.name}[/b]", ""]
2020-03-19 15:26:11 +00:00
if bh.rank_1v1:
2020-03-23 23:02:55 +00:00
string.append("👤 [b]1v1[/b]")
string.append(f"[b]{bh.rank_1v1}[/b] ({bh.rating_1v1} MMR)")
string.append("")
2020-03-19 15:26:11 +00:00
2020-03-23 23:02:55 +00:00
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)
2020-03-19 15:26:11 +00:00
async def _notify(self,
2020-03-23 23:02:55 +00:00
obj: Union[Brawlhalla, BrawlhallaDuo],
2020-03-19 15:26:11 +00:00
attribute_name: str,
old_value: Any,
new_value: Any):
if attribute_name == "rank_1v1":
old_rank: Optional[BrawlhallaRank] = old_value
new_rank: Optional[BrawlhallaRank] = new_value
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!"
2020-03-23 23:02:55 +00:00
else:
2020-03-19 15:26:11 +00:00
message = f"📉 [b]{obj.steam.user}[/b] è sceso a [b]{new_value}[/b] ({obj.rating_1v1} MMR) in 1v1 su Brawlhalla."
2020-03-23 23:02:55 +00:00
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!"
2020-03-19 15:26:11 +00:00
else:
2020-03-23 23:02:55 +00:00
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."
2020-03-19 15:26:11 +00:00
await self._send(message)
@staticmethod
2020-03-23 23:02:55 +00:00
async def _change(obj: Union[Brawlhalla, BrawlhallaDuo],
2020-03-19 15:26:11 +00:00
attribute_name: str,
new_value: Any,
2020-03-23 23:02:55 +00:00
callback: Callable[[Union[Brawlhalla, BrawlhallaDuo], str, Any, Any], Awaitable[None]]):
2020-03-19 15:26:11 +00:00
old_value = obj.__getattribute__(attribute_name)
if old_value != new_value:
await callback(obj, attribute_name, old_value, new_value)
obj.__setattr__(attribute_name, new_value)
async def _update(self, steam: Steam, db_session):
BrawlhallaT = self.alchemy.get(Brawlhalla)
2020-03-23 23:02:55 +00:00
DuoT = self.alchemy.get(BrawlhallaDuo)
2020-03-19 15:26:11 +00:00
log.info(f"Updating: {steam}")
async with aiohttp.ClientSession() as session:
bh: Brawlhalla = steam.brawlhalla
if bh is None:
log.debug(f"Checking if player has an account...")
async with session.get(f"https://api.brawlhalla.com/search?steamid={steam.steamid.as_64}&api_key={self.config['Brawlhalla']['api_key']}") as response:
if response.status != 200:
raise ExternalError(f"Brawlhalla API /search returned {response.status}!")
j = await response.json()
if j == {} or j == []:
log.debug("No account found.")
return
bh = BrawlhallaT(
steam=steam,
brawlhalla_id=j["brawlhalla_id"],
name=j["name"]
)
db_session.add(bh)
message = f"↔️ Account {bh} connesso a {bh.steam.user}!"
await self._send(message)
async with session.get(f"https://api.brawlhalla.com/player/{bh.brawlhalla_id}/ranked?api_key={self.config['Brawlhalla']['api_key']}") as response:
if response.status != 200:
raise ExternalError(f"Brawlhalla API /ranked returned {response.status}!")
j = await response.json()
if j == {} or j == []:
log.debug("No ranked info found.")
else:
await self._change(bh, "rating_1v1", j["rating"], self._notify)
metal_name, tier_name = j["tier"].split(" ", 1)
metal = BrawlhallaMetal[metal_name.upper()]
tier = BrawlhallaTier(int(tier_name))
rank = BrawlhallaRank(metal=metal, tier=tier)
await self._change(bh, "rank_1v1", rank, self._notify)
2020-03-23 23:02:55 +00:00
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)
2020-03-19 15:26:11 +00:00
await asyncify(db_session.commit)
async def _updater(self, period: int):
log.info(f"Started updater with {period}s period")
while True:
log.info(f"Updating...")
session = self.alchemy.Session()
log.info("")
steams = session.query(self.alchemy.get(Steam)).all()
for steam in steams:
try:
await self._update(steam, session)
except Exception as e:
2020-03-23 23:02:55 +00:00
sentry_exc(e)
2020-03-19 15:26:11 +00:00
await asyncio.sleep(1)
await asyncify(session.commit)
session.close()
log.info(f"Sleeping for {period}s")
await asyncio.sleep(period)
async def run(self, args: CommandArgs, data: CommandData) -> None:
author = await data.get_author(error_if_none=True)
found_something = False
message = ""
for steam in author.steam:
await self._update(steam, data.session)
if steam.brawlhalla is None:
continue
found_something = True
message += self._display(steam.brawlhalla)
message += "\n"
if not found_something:
raise UserError("Nessun account di Brawlhalla trovato.")
await data.reply(message)