Exemplo n.º 1
0
def autologin(requester: nsapi.NSRequester, nations: Mapping[str, str],
              isAutologin: bool) -> Mapping[str, Optional[Result]]:
    """Autologins a list of nations, from the nations dict of {nation: password/autologin}.
    If isAutologin is true, the passwords are interpreted as autologins.
    Returns a dict mapping from nations to autologins.
    If the autologin value of the returned mapping is None, that means the login failed.
    """
    output: Dict[str, Optional[Result]] = {}
    for nation, password in nations.items():
        # Check how to interpret password
        if isAutologin:
            nationAPI = requester.nation(nation,
                                         nsapi.Auth(autologin=password))
        else:
            nationAPI = requester.nation(nation, nsapi.Auth(password=password))
        # Try making the shard request
        try:
            shards = nationAPI.shards("region", "ping", "wa")
        except nsapi.APIError:
            output[nation] = None
        else:
            output[nation] = Result(
                autologin=nationAPI.get_autologin(),
                region=shards["region"],
                wa=shards["unstatus"].startswith("WA"),
            )
    return output
Exemplo n.º 2
0
def unendorsed_nations_v2(
    requester: nsapi.NSRequester, endorser: str
) -> Tuple[str, Iterable[str]]:
    """Finds all WA members of the nation's region who have not been endorsed
    Returns a tuple containing the region, and a iterable of unendorsed nations
    """

    # Retrieve endorser region and endorsement list
    logging.info("Collecting WA Members")
    info = requester.nation(endorser).shards("region", "endorsements")
    region = info["region"]
    endorsements = set(info["endorsements"].split(","))

    # Retrieve regional citizens by cross referencing residents and wa members
    citizens = set(requester.wa().shard("members").split(",")) & set(
        requester.region(region).shard("nations").split(":")
    )

    # Optionally only check nations who havent endorsed the endorser
    nations = citizens - endorsements

    # Check each nation's endorsments
    logging.info("Checking WA members for endorsement")
    nonendorsed = [
        nation
        for nation in nations
        if endorser not in requester.nation(nation).shard("endorsements")
    ]

    return (region, nonendorsed)
Exemplo n.º 3
0
def answer_all(
    requester: nsapi.NSRequester,
    name: str,
    autologin: str,
    optionNum: Optional[int] = None,
) -> Iterable[Tuple[int, int, str]]:
    """Answers all available issues on the nation.
    If optionNum is provided, attempts to answer all issues with that option
    (starting at 0, so 0 is the first option).
    If an issue does not have that many options, answers with the last.
    Counts by available options, not all options.
    Returns tuples encoding (id, option, description).
    """
    # Create and add authentication to the nation API object
    nation = requester.nation(name)
    nation.login(autologin)
    # Prepare output list
    output: List[Tuple[int, int, str]] = []
    # Iterate through all available issues
    for issue in nation.issues():
        # Use the option requested
        if optionNum:
            option = list(issue.options.keys())[optionNum]
        # If none, answer randomly
        else:
            option = random.choice(list(issue.options.keys()))
        info = nation.answer_issue(issue=issue.id, option=option)
        # info[1] should be the DESC node
        output.append((issue.id, option, info[1].text if info[1].text else ""))
    return output
Exemplo n.º 4
0
def check_region(requester: nsapi.NSRequester,
                 region: str,
                 previous: Container[str] = None) -> Sequence[str]:
    """Checks all nations in the specified region for trading card activity.
    Makes at most 1 + region population requests (1 for each nation).
    A nation does not qualify if it is in the `previous` container.
    """
    # If a previous list is not provided, use an empty set
    if not previous:
        previous = set()

    participants = []

    # Grabs all residents of the region
    residents = requester.region(region).shard("nations").split(":")

    # Make a request for each resident
    for nation in residents:
        if nation not in previous:
            info = requester.nation(nation).deck_info()
            # Save the nation if it meets any of the requirments
            if (info.numCards > 0 or info.bank > 0 or info.lastValued
                    or info.lastPackOpened):
                participants.append(nation)

    return participants
Exemplo n.º 5
0
def unendorsed_nations(
    requester: nsapi.NSRequester, endorser: str
) -> Tuple[str, Iterable[str]]:
    """Finds all WA members of the nation's region who have not been endorsed
    Returns a tuple containing the region, and a iterable of unendorsed nations
    """

    # Collect region
    region = requester.nation(endorser).shard("region")

    # Load downloaded nation file
    # Pack into conversion generator to simplify transformations
    nationDump = requester.dumpManager().nations()

    # Pull all nations in the region that are WA members
    # Use generator because we dont need to generate a list that is never used
    logging.info("Collecting %s WA Members", region)
    waMembers = [
        nation
        for nation in nationDump
        if nation.region == region and nation.WAStatus.startswith("WA")
    ]

    # Pull nations who are not endorsed
    logging.info("Collecting WA members who have not been endorsed")
    nonendorsed = [
        # Save name string, converting to lowercase, underscore format
        clean_format(nation.name)
        for nation in waMembers
        # Check if unendorsed by checking endorsements
        if endorser not in nation.endorsements
    ]

    return (region, nonendorsed)
Exemplo n.º 6
0
def login(
    requester: nsapi.NSRequester,
    nation: str,
    autologin: t.Optional[str],
    password: t.Optional[str],
) -> t.Optional[Result]:
    """Attempts to log in a nation via NS API.

    Returns None on failure.

    At least one of password or autologin must be provided;
    autologin is used if both are provided.
    """
    # Create API object
    nationAPI = requester.nation(
        nation, auth=nsapi.Auth(autologin=autologin, password=password)
    )
    # Try making the shard request
    try:
        shards = nationAPI.shards("region", "ping", "wa")
    except nsapi.APIError:
        # None indicates any failure
        return None
    else:
        return Result(
            autologin=nationAPI.get_autologin(),
            region=shards["region"],
            wa=shards["unstatus"].startswith("WA"),
        )
Exemplo n.º 7
0
def deployed(
    requester: nsapi.NSRequester,
    lead: str,
    roster: t.Mapping[str, t.Iterable[str]],
) -> t.Collection[str]:
    """Determine who are deployed and endorsing the lead."""
    # Obtain endorsement list of lead
    endos = map(nsapi.clean_format, requester.nation(lead).endorsements())
    # Invert roster into puppet -> main form
    owners = {
        nsapi.clean_format(switcher): main
        for main, switchers in roster.items() for switcher in switchers
    }
    # Also include main nations
    owners.update({main: main for main in roster.keys()})
    # Return owners who have a nation endoing lead
    return [owners[nation] for nation in endos if nation in owners]
Exemplo n.º 8
0
def sorted_cards(
    requester: nsapi.NSRequester, nations: Iterable[str]
) -> Mapping[str, Mapping[str, Mapping[nsapi.CardIdentifier, int]]]:
    """Searchs the trading card decks of the given nations (by name), and sorts by rarity
    Returns a mapping with {rarity: {nation: {card: quantity}}} structure.
    Always includes exactly `common`, `uncommon`, `rare`, `ultra-rare`, `epic`, and `legendary`
    """
    # Prepare output structure with rarities
    # empty string key should catch any Card objects that dont have a category for some reason
    out: MutableMapping[str,
                        MutableMapping[str,
                                       MutableMapping[nsapi.CardIdentifier,
                                                      int]]] = {
                                                          "common": {},
                                                          "uncommon": {},
                                                          "rare": {},
                                                          "ultra-rare": {},
                                                          "epic": {},
                                                          "legendary": {},
                                                          "": {},
                                                      }
    # Sort the deck of each nation
    for nation in nations:
        # Retrieve the deck of the nation (1 request)
        deck = requester.nation(nation).deck()
        # Parse each card in the deck, sorting into appropriate rarity bin
        for card in deck:
            # We dont wrap the out[] indexing in a try, since there should never be a error:
            # if for some reason the card doesnt have a category, it should have "" and
            # get placed in that bin
            rarityDict = out[card.rarity]
            # ensure this nation exists in this rarity bin
            try:
                nationDict = rarityDict[nation]
            except KeyError:
                rarityDict[nation] = {}
                nationDict = rarityDict[nation]
            # creates the card: num key-value pair if it doesnt exist
            # otherwise, increment the count
            try:
                nationDict[card] += 1
            except KeyError:
                nationDict[card] = 1

    return out
Exemplo n.º 9
0
def uncrossed(requester: nsapi.NSRequester,
              nation: str,
              lead: str,
              duration: int = 3600) -> Iterable[str]:
    """Returns a iterable of non-recently endorsed nations sourced from lead endorsements
    `duration` is the number of seconds to check back in the nation's endo happenings
    """

    # Source endorsement list from lead
    logging.info("Retrieving lead endorser list")
    nations: Set[str] = set(
        requester.nation(nation).shard("endorsements").split(","))

    # Retrieve recent endo happenings in text form
    timestamp = int(time.time()) - duration
    logging.info("Retrieving endo happenings of nation since %s", timestamp)
    endos: List[str] = [
        happening.text for happening in requester.world().happenings(
            view=f"nation.{nation}",
            filter="endo",
            sincetime=str(timestamp),
        )
    ]

    # Parse endo happening texts
    # A text can be one of the following two 'distinct' forms:
    # based on 'hn67' == nation
    # '@@hn67@@ endorsed @@hn67_ii@@.' (outgoing)
    # '@@hn67_ii@@ endorsed @@hn67@@.' (incoming)
    # we only care about outgoing endorsements
    # the endorsed nation is retrieved using the following process:
    # .split() transforms the above outgoing example to ['', 'hn67', 'endorsed', 'hn67_ii', '']
    # index [3] retrieves the endorsed nation, index [1] retrieves the endorser
    # [1] is used to verify outgoing ( by checking == nation), and [3] retrieves the endorsee
    # Note: Splitting twice, could be optimized with pre-comprehension, for loop, or walrus operator
    logging.info("Filtering for outgoing endorsements")
    outgoing: Set[str] = set(
        text.split("@@")[3] for text in endos if text.split("@@")[1] == nation)

    # Unendorsed is obtained by subtracting the outgoing endorsements from the lead endorsement list
    logging.info("Obtaining uncross endorsed nations")
    unendorsed = nations - outgoing
    return unendorsed
Exemplo n.º 10
0
def retrieve_status(requester: nsapi.NSRequester, nation: str) -> Status:
    """Retrieves info on the nation provided."""

    # Check region, wa, and cte
    try:
        shard_info = requester.nation(nation).shards("region", "wa")
    except nsapi.ResourceError:
        return Status(
            nsapi.clean_format(nation),
            True,
            None,
            None,
        )
    else:
        return Status(
            nsapi.clean_format(nation),
            False,
            shard_info["region"],
            shard_info["unstatus"],
        )
Exemplo n.º 11
0
def is_wa(requester: nsapi.NSRequester, nation: str) -> bool:
    """Checks if the nation is in the WA"""
    try:
        return requester.nation(nation).wa().startswith("WA")
    except nsapi.ResourceError:
        return False