Exemple #1
0
 async def deck(self, ctx, *, nation: Union[int, Link[Nation]]):
     """Retrieves general info about the specified nation's deck."""
     is_id = isinstance(nation, int)
     if is_id:
         api = Api("cards info", nationid=nation)
     else:
         api = Api("cards info", nationname=nation)
     root = await api
     if not root.INFO.countchildren():
         if is_id:
             return await ctx.send(f"No such deck for ID {nation}.")
         return await ctx.send(f"No such deck for nation {nation!r}.")
     n_id = root.INFO.NAME.text
     if n_id not in self.db_cache:
         self.db_cache[n_id] = {"dbid": root.INFO.ID.pyval}
         await self.config.custom("NATION",
                                  n_id).dbid.set(root.INFO.ID.pyval)
     embed = ProxyEmbed(
         title=n_id.replace("_", " ").title(),
         url=f"https://www.nationstates.net/page=deck/nation={n_id}",
         description=f"{root.INFO.NUM_CARDS.text} cards",
         colour=await ctx.embed_colour(),
         timestamp=datetime.utcfromtimestamp(root.INFO.LAST_VALUED.pyval),
     )
     embed.add_field(name="Bank", value=root.INFO.BANK.text)
     embed.add_field(
         name="Deck Value",
         value=
         f"[{root.INFO.DECK_VALUE.text}](https://www.nationstates.net/nation={n_id}/detail=trend/censusid=86)"
         f"\nRanked #{root.INFO.RANK.text} worldwide, #{root.INFO.REGION_RANK.text} regionally.",
         inline=False,
     )
     embed.set_footer(text="Last Valued")
     await embed.send_to(ctx)
Exemple #2
0
    async def invoice(self, ctx):
        """
        Configure or view settings for automated voice-based permissions.
        """
        if ctx.invoked_subcommand:
            return
        color = await ctx.embed_colour()

        embed = ProxyEmbed(title=f"Current settings", color=color)
        g_settings = await self.config.guild(ctx.guild).all()
        g_msg = []
        for key, value in g_settings.items():
            if value is not None and key == "role":
                value = ctx.guild.get_role(value)
                value = value.name if value else "<Deleted role>"
            key = key.replace("_", " ").title()
            g_msg.append(f"{key}: {value}")
        embed.add_field(name=f"Guild {ctx.guild} settings",
                        value="\n".join(g_msg))

        vc = ctx.author.voice.channel if ctx.author.voice else None
        if vc:
            c_settings = await self.config.channel(vc).all()
            c_msg = []
            for key, value in c_settings.items():
                if value is not None:
                    if key == "role":
                        value = ctx.guild.get_role(value)
                        value = value.name if value else "<Deleted role>"
                    if key == "channel":
                        value = ctx.guild.get_channel(value)
                        value = value.name if value else "<Deleted channel>"
                key = key.replace("_", " ").title()
                c_msg.append(f"{key}: {value}")
            embed.add_field(name=f"Channel {vc} settings",
                            value="\n".join(c_msg))
        await embed.send_to(ctx)
Exemple #3
0
    async def wa(self,
                 ctx,
                 resolution_id: Optional[int] = None,
                 *options: WA.convert):
        """
        Retrieves general info about World Assembly resolutions.

        Defaults to the General Assembly. Use [p]sc to get info about the Security Council.
        If no resolution ID is provided, the current at-vote resolution is used.
        Valid options:
            text - The resolution's text
            votes - The total votes for and against
            nations - The total nations for and against
            delegates - The top ten Delegates for and against
        """
        option = WA.collapse(*options, default=0)
        if resolution_id and option & (WA.NATION | WA.DELEGATE):
            return await ctx.send(
                "The Nations and Delegates options are not available for past resolutions."
            )
        is_sc = ctx.invoked_with == "sc"
        shards = ["resolution"]
        request = {"wa": "2" if is_sc else "1"}
        if option & WA.DELEGATE:
            shards.append("delvotes")
        if resolution_id:
            request["id"] = str(resolution_id)
        else:
            shards.append("lastresolution")
        root = await Api(request, q=shards)
        img = "4dHt6si" if is_sc else "7EMYsJ6"
        if root["RESOLUTION"] is None:
            out = (unescape(root["LASTRESOLUTION"]).replace(
                "<strong>", "**").replace("</strong>", "**"))
            try:
                out = "{}[{}](https://www.nationstates.net{}){}".format(
                    out[:out.index("<a")],
                    out[out.index('">') + 2:out.index("</a")],
                    out[out.index('="') + 2:out.index('">')],
                    out[out.index("</a>") + 4:],
                )
            except ValueError:
                pass
            embed = ProxyEmbed(title="Last Resolution",
                               description=out,
                               colour=await ctx.embed_colour())
            embed.set_thumbnail(url="http://i.imgur.com/{}.jpg".format(img))
            return await embed.send_to(ctx)
        root = root["RESOLUTION"]
        if option & WA.TEXT:
            description = "**Category: {}**\n\n{}".format(
                root["CATEGORY"], escape(root["DESC"], formatting=True))
            short = next(
                pagify(
                    description,
                    delims=("\n", " ", "]"),
                    escape_mass_mentions=False,
                    page_length=2047,
                    priority=True,
                ))
            if len(short) < len(description):
                description = short + "\N{HORIZONTAL ELLIPSIS}"
        else:
            description = "Category: {}".format(root["CATEGORY"])
        if resolution_id:
            impl = root["IMPLEMENTED"]
        else:
            # mobile embeds can't handle the FUTURE
            impl = root["PROMOTED"]  # + (4 * 24 * 60 * 60)  # 4 Days
        embed = ProxyEmbed(
            title=root["NAME"],
            url="https://www.nationstates.net/page={}".format(
                "sc" if is_sc else "ga") if not resolution_id else
            "https://www.nationstates.net/page=WA_past_resolution/id={}/council={}"
            .format(resolution_id, "2" if is_sc else "1"),
            description=description,
            timestamp=datetime.utcfromtimestamp(impl),
            colour=await ctx.embed_colour(),
        )
        try:
            authroot = await Api("fullname flag", nation=root["PROPOSED_BY"])
        except NotFound:
            embed.set_author(
                name=" ".join(root["PROPOSED_BY"].split("_")).title(),
                url="https://www.nationstates.net/page=boneyard?nation={}".
                format(root["PROPOSED_BY"]),
                icon_url="http://i.imgur.com/Pp1zO19.png",
            )
        else:
            embed.set_author(
                name=authroot["FULLNAME"],
                url="https://www.nationstates.net/nation={}".format(
                    root["PROPOSED_BY"]),
                icon_url=authroot["FLAG"],
            )
        embed.set_thumbnail(url="http://i.imgur.com/{}.jpg".format(img))
        if option & WA.DELEGATE:
            for_del_votes = sorted(root.iterfind("DELVOTES_FOR/DELEGATE"),
                                   key=lambda e: e["VOTES"],
                                   reverse=True)[:10]
            against_del_votes = sorted(
                root.iterfind("DELVOTES_AGAINST/DELEGATE"),
                key=lambda e: e["VOTES"],
                reverse=True)[:10]
            if for_del_votes:
                embed.add_field(
                    name="Top Delegates For",
                    value="\t|\t".join(
                        "[{}](https://www.nationstates.net/nation={}) ({})".
                        format(e["NATION"].replace("_", " ").title(),
                               e["NATION"], e["VOTES"])
                        for e in for_del_votes),
                    inline=False,
                )
            if against_del_votes:
                embed.add_field(
                    name="Top Delegates Against",
                    value="\t|\t".join(
                        "[{}](https://www.nationstates.net/nation={}) ({})".
                        format(e["NATION"].replace("_", " ").title(),
                               e["NATION"], e["VOTES"])
                        for e in against_del_votes),
                    inline=False,
                )
        if option & WA.VOTE:
            percent = (100 * root["TOTAL_VOTES_FOR"] /
                       (root["TOTAL_VOTES_FOR"] + root["TOTAL_VOTES_AGAINST"]))
            embed.add_field(
                name="Total Votes",
                value="For {}\t{:◄<13}\t{} Against".format(
                    root["TOTAL_VOTES_FOR"],
                    "►" * int(round(percent / 10)) + str(int(round(percent))) +
                    "%",
                    root["TOTAL_VOTES_AGAINST"],
                ),
            )
        if option & WA.NATION:
            percent = (
                100 * root["TOTAL_NATIONS_FOR"] /
                (root["TOTAL_NATIONS_FOR"] + root["TOTAL_NATIONS_AGAINST"]))
            embed.add_field(
                name="Total Nations",
                value="For {}\t{:◄<13}\t{} Against".format(
                    root["TOTAL_NATIONS_FOR"],
                    "►" * int(round(percent / 10)) + str(int(round(percent))) +
                    "%",
                    root["TOTAL_NATIONS_AGAINST"],
                ),
            )
        embed.set_footer(text="Passed" if resolution_id else "Voting Started")
        await embed.send_to(ctx)
Exemple #4
0
 async def region(self, ctx, *, region: partial(link_extract,
                                                expected="region")):
     """Retrieves general info about a specified NationStates region"""
     api: Api = Api(
         "delegate delegateauth delegatevotes flag founded founder founderauth lastupdate name numnations power tags zombie",
         region=region,
     )
     try:
         root = await api
     except NotFound:
         region = api["region"]
         embed = ProxyEmbed(title=region.replace("_", " ").title(),
                            description="This region does not exist.")
         embed.set_author(name="NationStates",
                          url="https://www.nationstates.net/")
         return await embed.send_to(ctx)
     if root["DELEGATE"] == 0:
         delvalue = "No Delegate"
     else:
         endo = root["DELEGATEVOTES"] - 1
         if endo == 1:
             endo = "{:.0f} endorsement".format(endo)
         else:
             endo = "{:.0f} endorsements".format(endo)
         delvalue = "[{}](https://www.nationstates.net/nation={}) | {}".format(
             root["DELEGATE"].replace("_", " ").title(), root["DELEGATE"],
             endo)
     if "X" in root["DELEGATEAUTH"]:
         delheader = "Delegate"
     else:
         delheader = "Delegate (Non-Executive)"
     tags = {t.text for t in root.iterfind("TAGS/TAG")}
     founderless = "Founderless" in tags
     if root["FOUNDED"] == 0:
         founded = "in Antiquity"
     else:
         founded = root["FOUNDED"]
     if root["FOUNDER"] == 0:
         foundervalue = "No Founder"
     else:
         if founderless:
             url = "https://www.nationstates.net/page=boneyard?nation="
         else:
             url = "https://www.nationstates.net/nation="
         foundervalue = "[{}]({}{}){}".format(
             root["FOUNDER"].replace("_", " ").title(),
             url,
             root["FOUNDER"],
             " (Ceased to Exist)" if founderless else "",
         )
     if founderless:
         founderheader = "Founderless"
     else:
         founderheader = "Founder"
     if not root["FOUNDERAUTH"] or "X" not in root["FOUNDERAUTH"]:
         founderheader += " (Non-Executive)"
     fash = "Fascist" in tags and "Anti-Fascist" not in tags  # why do people hoard tags...
     name = "{}{}".format("\N{LOCK} " if "Password" in tags else "",
                          root["NAME"])
     if fash:
         warning = "\n**```css\n\N{HEAVY EXCLAMATION MARK SYMBOL} Region Tagged as Fascist \N{HEAVY EXCLAMATION MARK SYMBOL}\n```**"
     else:
         warning = ""
     description = "[{} nations](https://www.nationstates.net/region={}/page=list_nations) | Founded {} | Power: {}{}".format(
         root["NUMNATIONS"], root.get("id"), founded, root["POWER"],
         warning)
     embed = ProxyEmbed(
         title=name,
         url="https://www.nationstates.net/region={}".format(
             root.get("id")),
         description=description,
         timestamp=datetime.utcfromtimestamp(root["LASTUPDATE"]),
         colour=0x000001 if fash else 0x8BBC21
         if self._is_zday(ctx.message) else await ctx.embed_colour(),
     )
     embed.set_author(name="NationStates",
                      url="https://www.nationstates.net/")
     if root["FLAG"]:
         embed.set_thumbnail(url=root["FLAG"])
     embed.add_field(name=founderheader, value=foundervalue, inline=False)
     embed.add_field(name=delheader, value=delvalue, inline=False)
     if self._is_zday(ctx.message):
         embed.add_field(
             name="Zombies",
             value="Survivors: {} | Zombies: {} | Dead: {}".format(
                 self._illion(root["ZOMBIE/SURVIVORS"]),
                 self._illion(root["ZOMBIE/ZOMBIES"]),
                 self._illion(root["ZOMBIE/DEAD"]),
             ),
             inline=False,
         )
     embed.set_footer(text="Last Updated")
     await embed.send_to(ctx)
Exemple #5
0
 async def nation(self, ctx, *, nation: partial(link_extract,
                                                expected="nation")):
     """Retrieves general info about a specified NationStates nation"""
     api: Api = Api(
         "census category dbid demonym2plural",
         "flag founded freedom fullname",
         "influence lastlogin motto name",
         "population region wa zombie",
         nation=nation,
         mode="score",
         scale="65 66",
     )
     try:
         root = await api
     except NotFound:
         nation = api["nation"]
         embed = ProxyEmbed(
             title=nation.replace("_", " ").title(),
             url="https://www.nationstates.net/page="
             "boneyard?nation={}".format("_".join(nation.split()).lower()),
             description="This nation does not exist.",
         )
         embed.set_author(name="NationStates",
                          url="https://www.nationstates.net/")
         embed.set_thumbnail(url="http://i.imgur.com/Pp1zO19.png")
         return await embed.send_to(ctx)
     endo = root["CENSUS/SCALE[@id='66']/SCORE"]
     if endo == 1:
         endo = "{:.0f} endorsement".format(endo)
     else:
         endo = "{:.0f} endorsements".format(endo)
     if root["FOUNDED"] == 0:
         root["FOUNDED"] = "in Antiquity"
     embed = ProxyEmbed(
         title=root["FULLNAME"],
         url="https://www.nationstates.net/nation={}".format(
             root.get("id")),
         description="[{}](https://www.nationstates.net/region={})"
         " | {} {} | Founded {}".format(
             root["REGION"],
             "_".join(root["REGION"].lower().split()),
             self._illion(root["POPULATION"]),
             root["DEMONYM2PLURAL"],
             root["FOUNDED"],
         ),
         timestamp=datetime.utcfromtimestamp(root["LASTLOGIN"]),
         colour=0x8BBC21
         if self._is_zday(ctx.message) else await ctx.embed_colour(),
     )
     embed.set_author(name="NationStates",
                      url="https://www.nationstates.net/")
     embed.set_thumbnail(url=root["FLAG"])
     embed.add_field(
         name=root["CATEGORY"],
         value="{}\t|\t{}\t|\t{}".format(
             root["FREEDOM/CIVILRIGHTS"],
             root["FREEDOM/ECONOMY"],
             root["FREEDOM/POLITICALFREEDOM"],
         ),
         inline=False,
     )
     embed.add_field(
         name=root["UNSTATUS"],
         value="{} | {:.0f} influence ({})".format(
             endo, root["CENSUS/SCALE[@id='65']/SCORE"], root["INFLUENCE"]),
         inline=False,
     )
     if self._is_zday(ctx.message):
         embed.add_field(
             name="{}{}".format(
                 (root["ZOMBIE/ZACTION"] or "No Action").title(),
                 " (Unintended)" if root["ZOMBIE/ZACTIONINTENDED"] else "",
             ),
             value="Survivors: {} | Zombies: {} | Dead: {}".format(
                 self._illion(root["ZOMBIE/SURVIVORS"]),
                 self._illion(root["ZOMBIE/ZOMBIES"]),
                 self._illion(root["ZOMBIE/DEAD"]),
             ),
             inline=False,
         )
     embed.add_field(
         name="Cards",
         value=
         ("[{0}'s Deck](https://www.nationstates.net/page=deck/nation={1})\t|"
          "\t[{0}'s Card](https://www.nationstates.net/page=deck/card={2})".
          format(root["NAME"], root.get("id"), root["DBID"])),
     )
     embed.set_footer(text="Last Active")
     await embed.send_to(ctx)
Exemple #6
0
    async def card(self,
                   ctx,
                   season: Optional[int] = 2,
                   *,
                   nation: Optional[Union[int, Link[Nation]]] = None):
        """
        Retrieves general info about the specified card.

        If a number is provided, the bot will look for the card with that ID.
        Otherwise, the bot will look for the specified nation's card.

        If you want to find a nation that has a numerical name,
        use a link or "quotes" to specify that it is a name, and not an ID.
        A season must be specified if this is the case.
        """
        if season is not None and nation is None:
            season, nation = 2, season
        if isinstance(nation, str) and nation not in self.db_cache:
            api = Api("dbid", nation=nation)
            try:
                root = await api
            except NotFound:
                return await ctx.send(
                    f"Nation {nation!r} does not exist. "
                    "Please provide its card ID instead, and I'll remember it for next time."
                )
            n_id, nation = root.get("id"), root.DBID.pyval
            self.db_cache[n_id] = {"dbid": nation}
            await self.config.custom("NATION", n_id).dbid.set(nation)
        else:
            n_id, nation = None, self.db_cache.get(nation,
                                                   {}).get("dbid", nation)
        assert isinstance(nation, int), repr(nation)
        api = Api("card info markets", cardid=nation, season=season)
        root = await api
        if not root.countchildren():
            if n_id:
                return await ctx.send(
                    f"No such S{season} card for nation {n_id!r}.")
            return await ctx.send(f"No such S{season} card for ID {nation!r}.")
        n_id = root.NAME.text.casefold().replace(" ", "_")
        if n_id not in self.db_cache:
            self.db_cache[n_id] = {"dbid": nation}
            await self.config.custom("NATION", n_id).dbid.set(nation)
        embed = ProxyEmbed(
            title=f"The {root.TYPE.pyval} of {root.NAME.pyval}",
            url=
            f"https://www.nationstates.net/page=deck/card={nation}/season={season}",
            colour=CARD_COLORS.get(root.CATEGORY.text, 0),
        )
        embed.set_author(name=root.CATEGORY.text.title())
        embed.set_thumbnail(
            url=
            f"https://www.nationstates.net/images/cards/s{season}/{root.FLAG.pyval}"
        )
        embed.add_field(
            name="Market Value (estimated)",
            value=box(root.MARKET_VALUE.text, lang="swift"),
            inline=False,
        )
        sellers, buyers = [], []
        for market in root.MARKETS.iterchildren():
            # negative price to reverse sorting
            if market.TYPE.text == "bid":
                bisect.insort(buyers,
                              (-market.PRICE.pyval,
                               market.NATION.text.replace("_", " ").title()))
            elif market.TYPE.text == "ask":
                bisect.insort(sellers,
                              (market.PRICE.pyval,
                               market.NATION.text.replace("_", " ").title()))
        if not any((buyers, sellers)):
            return await embed.send_to(ctx)
        max_listed = 5
        max_len = max(len(buyers), len(sellers))
        max_len = min(max_len, max_listed + 1)
        for is_buyers, arr in enumerate((sellers, buyers)):
            pad = "\n\u200b" * max(0, max_len - len(arr))
            if not arr:
                embed.add_field(name="Buyers" if is_buyers else "Sellers",
                                value=box(pad))
                embed.overwrites.set_field_at(
                    is_buyers + 1,
                    name=embed.fields[is_buyers + 1].name,
                    value=box("\u200b", lang="swift"),
                )
                continue
            tarr = [
                f"{-j[0]:.02f}\xa0{j[1]}"
                if is_buyers else f"{j[1]}\xa0{j[0]:.02f}"
                for j in arr[:max_listed]
            ]
            if len(arr) > max_listed:
                num = len(arr) - max_listed
                tarr.append(
                    f"+ {num} more {'bid' if is_buyers else 'ask'}{'' if num == 1 else 's'}\N{HORIZONTAL ELLIPSIS}"
                )
            raw_text = "\n".join(tarr)
            if not is_buyers:
                width = max(map(len, tarr))
                for i, t in enumerate(tarr):
                    tarr[i] = t.rjust(width)
            text = "\n".join(tarr) + pad
            embed.add_field(name="Buyers" if is_buyers else "Sellers",
                            value=box(text, lang="swift"))
            embed.overwrites.set_field_at(
                is_buyers + 1,
                name=embed.fields[is_buyers + 1].name,
                value=box(raw_text, lang="swift"),
            )
        await embed.send_to(ctx)
Exemple #7
0
 async def nation(self, ctx, *, nation: Link[Nation]):
     """Retrieves general info about a specified NationStates nation"""
     api: Api = Api(
         "census category dbid",
         "demonym2plural flag founded freedom",
         "fullname influence lastlogin motto",
         "name population region wa zombie",
         nation=nation,
         mode="score",
         scale="65 66",
     )
     try:
         root = await api
     except NotFound:
         embed = ProxyEmbed(
             title=nation.replace("_", " ").title(),
             url="https://www.nationstates.net/page="
             "boneyard?nation={}".format(nation),
             description="This nation does not exist.",
         )
         embed.set_author(name="NationStates",
                          url="https://www.nationstates.net/")
         embed.set_thumbnail(url="http://i.imgur.com/Pp1zO19.png")
         return await embed.send_to(ctx)
     n_id = root.get("id")
     if n_id not in self.db_cache:
         self.db_cache[n_id] = {"dbid": root.DBID.pyval}
         await self.config.custom("NATION", n_id).dbid.set(root.DBID.pyval)
     endo = root.find("CENSUS/SCALE[@id='66']/SCORE").pyval
     if endo == 1:
         endo = "{:.0f} endorsement".format(endo)
     else:
         endo = "{:.0f} endorsements".format(endo)
     founded = root.FOUNDED.pyval or "in Antiquity"
     embed = ProxyEmbed(
         title=root.FULLNAME.text,
         url="https://www.nationstates.net/nation={}".format(
             root.get("id")),
         description="[{}](https://www.nationstates.net/region={})"
         " | {} {} | Founded {}".format(
             root.REGION.text,
             "_".join(root.REGION.text.lower().split()),
             self._illion(root.POPULATION.pyval),
             root["DEMONYM2PLURAL"].text,
             founded,
         ),
         timestamp=datetime.utcfromtimestamp(root.LASTLOGIN.pyval),
         colour=0x8BBC21
         if self._is_zday(ctx.message) else await ctx.embed_colour(),
     )
     embed.set_author(name="NationStates",
                      url="https://www.nationstates.net/")
     embed.set_thumbnail(url=root.FLAG.text)
     embed.add_field(
         name=root.CATEGORY.pyval,
         value="{}\t|\t{}\t|\t{}".format(
             root.find("FREEDOM/CIVILRIGHTS"),
             root.find("FREEDOM/ECONOMY"),
             root.find("FREEDOM/POLITICALFREEDOM"),
         ),
         inline=False,
     )
     embed.add_field(
         name=root.UNSTATUS.text,
         value="{} | {:.0f} influence ({})".format(
             endo,
             root.find("CENSUS/SCALE[@id='65']/SCORE").pyval,
             root.INFLUENCE.text),
         inline=False,
     )
     if self._is_zday(ctx.message):
         embed.add_field(
             name="{}{}".format(
                 (root.find("ZOMBIE/ZACTION") or "No Action").title(),
                 " (Unintended)"
                 if root.find("ZOMBIE/ZACTIONINTENDED") else "",
             ),
             value="Survivors: {} | Zombies: {} | Dead: {}".format(
                 self._illion(root.find("ZOMBIE/SURVIVORS")),
                 self._illion(root.find("ZOMBIE/ZOMBIES")),
                 self._illion(root.find("ZOMBIE/DEAD")),
             ),
             inline=False,
         )
     embed.add_field(
         name="Cards",
         value=
         ("[{0}'s Deck](https://www.nationstates.net/page=deck/nation={1})\t|"
          "\t[{0}'s Card](https://www.nationstates.net/page=deck/card={2})".
          format(root.NAME.text, n_id, root.DBID.text)),
     )
     embed.set_footer(text="Last Active")
     await embed.send_to(ctx)