Ejemplo n.º 1
0
 async def call_herald_event(ci, destination: str, event_name: str, **kwargs) -> Dict:
     """Send a :class:`rh.Request` to a specific destination, and wait for a
     :class:`rh.Response`."""
     if self.herald is None:
         raise rc.UnsupportedError("`royalherald` is not enabled on this Constellation.")
     request: rh.Request = rh.Request(handler=event_name, data=kwargs)
     response: rh.Response = await self.herald.request(destination=destination, request=request)
     if isinstance(response, rh.ResponseFailure):
         if response.name == "no_event":
             raise rc.CommandError(f"There is no event named {event_name} in {destination}.")
         elif response.name == "exception_in_event":
             # TODO: pretty sure there's a better way to do this
             if response.extra_info["type"] == "CommandError":
                 raise rc.CommandError(response.extra_info["message"])
             elif response.extra_info["type"] == "UserError":
                 raise rc.UserError(response.extra_info["message"])
             elif response.extra_info["type"] == "InvalidInputError":
                 raise rc.InvalidInputError(response.extra_info["message"])
             elif response.extra_info["type"] == "UnsupportedError":
                 raise rc.UnsupportedError(response.extra_info["message"])
             elif response.extra_info["type"] == "ConfigurationError":
                 raise rc.ConfigurationError(response.extra_info["message"])
             elif response.extra_info["type"] == "ExternalError":
                 raise rc.ExternalError(response.extra_info["message"])
             else:
                 raise TypeError(f"Herald action call returned invalid error:\n"
                                 f"[p]{response}[/p]")
     elif isinstance(response, rh.ResponseSuccess):
         return response.data
     else:
         raise TypeError(f"Other Herald Link returned unknown response:\n"
                         f"[p]{response}[/p]")
Ejemplo n.º 2
0
 async def _call(self, method, *args, **kwargs):
     log.debug(f"Calling {method}")
     try:
         return await ru.asyncify(method, *args, **kwargs)
     except Exception as e:
         raise rc.ExternalError("\n".join(e.args).replace(
             self.token(), "HIDDEN"))
Ejemplo n.º 3
0
    async def update(self, session, obj: Steam, change: Callable[[str, Any], Awaitable[None]]):
        log.debug(f"Getting player data from OpenDota...")
        async with aiohttp.ClientSession() as hcs:
            # Get profile data
            async with hcs.get(f"https://api.opendota.com/api/players/{obj.steamid.as_32}/") as response:
                if response.status != 200:
                    raise rc.ExternalError(f"OpenDota / returned {response.status}!")
                p = await response.json()
                # No such user
                if "profile" not in p:
                    log.debug(f"Not found: {obj}")
                    return
            # Get win/loss data
            async with hcs.get(f"https://api.opendota.com/api/players/{obj.steamid.as_32}/wl") as response:
                if response.status != 200:
                    raise rc.ExternalError(f"OpenDota /wl returned {response.status}!")
                wl = await response.json()
                # No such user
                if wl["win"] == 0 and wl["lose"] == 0:
                    log.debug(f"Not found: {obj}")
                    return
        # Find the Dota record, if it exists
        dota: Dota = obj.dota
        if dota is None:
            # Autocreate the Dota record
            dota = self.alchemy.get(Dota)(steam=obj)
            session.add(dota)
            session.flush()

        # Make a custom change function
        async def change(attribute: str, new: Any):
            await self._change(session=session, obj=dota, attribute=attribute, new=new)

        await change("wins", wl["win"])
        await change("losses", wl["lose"])
        if p["rank_tier"]:
            await change("rank", DotaRank(rank_tier=p["rank_tier"]))
        else:
            await change("rank", None)
Ejemplo n.º 4
0
 async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
     async with aiohttp.ClientSession() as session:
         async with session.get(
                 "https://api.thecatapi.com/v1/images/search") as response:
             if response.status >= 400:
                 raise rc.ExternalError(
                     f"Request returned {response.status}")
             result = await response.json()
             assert len(result) == 1
             cat = result[0]
             assert "url" in cat
             url = cat["url"]
         async with session.get(url) as response:
             img = await response.content.read()
             await data.reply_image(image=io.BytesIO(img))
Ejemplo n.º 5
0
 async def call_herald_event(self, destination: str, event_name: str,
                             **kwargs) -> Dict:
     """Send a :class:`royalherald.Request` to a specific destination, and wait for a
     :class:`royalherald.Response`."""
     if self.herald is None:
         raise rc.UnsupportedError(
             "`royalherald` is not enabled on this serf.")
     request: rh.Request = rh.Request(handler=event_name, data=kwargs)
     response: rh.Response = await self.herald.request(
         destination=destination, request=request)
     if isinstance(response, rh.ResponseFailure):
         if response.name == "no_event":
             raise rc.ProgramError(
                 f"There is no event named {event_name} in {destination}.")
         elif response.name == "error_in_event":
             if response.extra_info["type"] == "CommandError":
                 raise rc.CommandError(response.extra_info["message"])
             elif response.extra_info["type"] == "UserError":
                 raise rc.UserError(response.extra_info["message"])
             elif response.extra_info["type"] == "InvalidInputError":
                 raise rc.InvalidInputError(response.extra_info["message"])
             elif response.extra_info["type"] == "UnsupportedError":
                 raise rc.UnsupportedError(response.extra_info["message"])
             elif response.extra_info["type"] == "ConfigurationError":
                 raise rc.ConfigurationError(response.extra_info["message"])
             elif response.extra_info["type"] == "ExternalError":
                 raise rc.ExternalError(response.extra_info["message"])
             else:
                 raise rc.ProgramError(
                     f"Invalid error in Herald event '{event_name}':\n"
                     f"[b]{response.extra_info['type']}[/b]\n"
                     f"{response.extra_info['message']}")
         elif response.name == "unhandled_exception_in_event":
             raise rc.ProgramError(
                 f"Unhandled exception in Herald event '{event_name}':\n"
                 f"[b]{response.extra_info['type']}[/b]\n"
                 f"{response.extra_info['message']}")
         else:
             raise rc.ProgramError(
                 f"Unknown response in Herald event '{event_name}':\n"
                 f"[b]{response.name}[/b]"
                 f"[p]{response}[/p]")
     elif isinstance(response, rh.ResponseSuccess):
         return response.data
     else:
         raise rc.ProgramError(
             f"Other Herald Link returned unknown response:\n"
             f"[p]{response}[/p]")
Ejemplo n.º 6
0
    async def update(self, session, obj, change: Callable[[str, Any],
                                                          Awaitable[None]]):
        BrawlhallaT = self.alchemy.get(Brawlhalla)
        DuoT = self.alchemy.get(BrawlhallaDuo)
        log.info(f"Updating: {obj}")
        async with aiohttp.ClientSession() as hcs:
            bh: Brawlhalla = obj.brawlhalla
            if bh is None:
                log.debug(f"Checking if player has an account...")
                async with hcs.get(
                        f"https://api.brawlhalla.com/search?steamid={obj.steamid.as_64}&api_key={self.token()}"
                ) as response:
                    if response.status != 200:
                        raise rc.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=obj,
                                     brawlhalla_id=j["brawlhalla_id"],
                                     name=j["name"])
                    session.add(bh)
                    session.flush()

            async with hcs.get(
                    f"https://api.brawlhalla.com/player/{bh.brawlhalla_id}/ranked?api_key={self.token()}"
            ) as response:
                if response.status != 200:
                    raise rc.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(session=session,
                                       obj=bh,
                                       attribute="rating_1v1",
                                       new=j["rating"])
                    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(session=session,
                                       obj=bh,
                                       attribute="rank_1v1",
                                       new=rank)

                    for jduo in j.get("2v2", []):
                        bhduo: Optional[BrawlhallaDuo] = await ru.asyncify(
                            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 ru.asyncify(
                                        session.query(BrawlhallaT).get,
                                        jduo["brawlhalla_id_two"])
                            else:
                                otherbh: Optional[
                                    Brawlhalla] = await ru.asyncify(
                                        session.query(BrawlhallaT).get,
                                        jduo["brawlhalla_id_one"])
                            if otherbh is None:
                                continue
                            bhduo = DuoT(
                                one=bh,
                                two=otherbh,
                            )

                            session.add(bhduo)
                        await self._change(session=session,
                                           obj=bhduo,
                                           attribute="rating_2v2",
                                           new=jduo["rating"])
                        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(session=session,
                                           obj=bhduo,
                                           attribute="rank_2v2",
                                           new=rank)