Example #1
0
def main() -> None:
    """Main function for running this module"""

    # Setup API
    API = nsapi.NSRequester(config.userAgent)
    # Set endorser nation to check for
    nation = "kuriko"

    logging.info("Collecting data")
    logging.info("Current time is %s UTC", datetime.datetime.utcnow())
    region, unendorsed = unendorsed_nations(API, nation)

    logging.info("Formatting results")
    # Create output display strings
    header = f"{nation} has not endorsed the following WA Members in {region}:"
    nationURLs = "\n".join(
        # Increment step so that the list is 1-indexed
        f"{step+1}. https://www.nationstates.net/nation={name}"
        for step, name in enumerate(unendorsed)
    )

    # Output unendorsed nations
    logging.info("Writing results")
    with open(nsapi.absolute_path("endorsements.txt"), "w") as f:
        # Header
        print(header, file=f)
        # Formatted nation urls
        print(nationURLs, file=f)

    logging.info("Current time is %s UTC", datetime.datetime.utcnow())
Example #2
0
def main() -> None:
    """Main function"""

    requester = nsapi.NSRequester(config.userAgent)

    for output in answer_all(requester, "nation", "autologin"):
        print(output)
Example #3
0
def main() -> None:
    """Main function"""

    requester = nsapi.NSRequester(config.userAgent)
    with open(nsapi.absolute_path("delegacy.txt"), "w") as f:
        logging.info("Outputting to file.")
        print("Delegacy changes in the last twelve hours")
        print(
            "\n".join(
                re.sub(
                    # In the text returned by NS api, nation names are enclosed by @@
                    # and region names by %%. @@(.*?)@@ is a regex pattern that matches
                    # anything surrounded by the @@, as well as the @@ @@. we pull the nation name
                    # by taking group 1 of the match (0 is the entire match).
                    # the nation name is a group because of the () surround the .*?
                    # .*? lazily matches any number of any characters
                    "%%(.*?)%%",
                    lambda match: f"https://www.nationstates.net/region={match.group(1)}",
                    re.sub(
                        "@@(.*?)@@",
                        lambda match: f"https://www.nationstates.net/nation={match.group(1)}",
                        happening.text,
                    ),
                )
                for happening in delegacy(requester)
            ),
            file=f,
        )
Example #4
0
def main() -> None:
    """Main function, mainly for testing purposes."""

    parser = argparse.ArgumentParser(
        description="Collects various information on WA residents of a region."
    )

    parser.add_argument("region", help="Region to search.")

    parser.add_argument(
        "-c",
        "--count",
        help="Only collect residents with less endorsements than this.",
        type=int,
        default=None,
    )

    parser.add_argument("-o",
                        "--output",
                        help="File name to output to instead of stdout.",
                        default=None)

    # Parse args
    # Check sys.argv first; if no args provided run interactive mode
    if len(sys.argv) <= 1:
        # Interactive mode
        region = input("Region to search: ")
        count_raw = input(
            "Endorsement boundary (type nothing to get all WA): ")
        count: t.Optional[int]
        if count_raw:
            count = int(count_raw)
        else:
            count = None
        output = input("File name to output to: ")
    else:
        args = parser.parse_args()
        region = args.region
        count = args.count

    # Setup requester
    requester = nsapi.NSRequester(config.userAgent)

    # Use api if getting all residents
    if not count:
        nations = residents(requester, region)
    # Use dump if filtering
    else:
        nations = low_endorsements(requester, region, count)

    # print(listLinks(nations))
    # print(nations)
    if output:
        with open(output, "w") as out_file:
            print(listNationCodes(nations), file=out_file)
    else:
        print(listNationCodes(nations))
Example #5
0
def main() -> None:
    """Main function"""

    print(
        "Specify a file to load the nation list from. (Based on this script's directory)"
    )
    print(
        "Nation name and password should be seperated with a single comma, no space."
    )
    inputPath = input("File: ")

    print(
        "\nShould the passwords be interpreted as autologins keys (encrypted versions)? (y/n)"
    )
    autologinInput = input("Interpret as autologins? ").lower()
    if autologinInput in ("yes", "y"):
        isAutologin = True
        print("Okay, will interpret as autologin keys.")
    else:
        isAutologin = False
        print("Okay, will interpret as regular passwords.")

    print(
        "\nEnter a file to generate autologin keys in, or enter nothing to not generate a file."
    )
    outputPath = input("Autologin Output File: ")

    requester = nsapi.NSRequester(config.userAgent)

    # Collect nationlist
    nations = {}
    with open(nsapi.absolute_path(inputPath), "r") as file:
        for line in file:
            # Ignore empty lines
            if not line == "\n":
                # Split exactly once to allow passwords that contain commas
                nation, password = line.strip().split(",", maxsplit=1)
                nations[nation] = password

    output = autologin(requester, nations, isAutologin)

    # Summarize results
    for nation, result in output.items():
        if result:
            string = f"Successfully logged {nation} in. (Region: {result.region})"
            if result.wa:
                string += " (WA)"
            print(string)
        else:
            print(f"Failed to log in {nation}. Likely an incorrect password.")

    # Only generate output if desired
    if outputPath != "":
        with open(nsapi.absolute_path(outputPath), "w") as file:
            for nation, result in output.items():
                print(f"{nation},{result.autologin if result else None}",
                      file=file)
Example #6
0
def main() -> None:
    """Main method for standalone"""

    requester = nsapi.NSRequester(config.userAgent)

    rarity = input("Rarity to search for: ")

    find_rarities(requester, rarity)

    print(f"Saved results to `{rarity}Cards.json`")
Example #7
0
def main() -> None:
    """Main function"""

    # Provide proper user agent to api requester
    requester = nsapi.NSRequester(config.userAgent)

    # Function arguments, could be connected to command line, etc
    nation = "ne hcea"
    lead = "panther"

    # Actually run the bulk logic
    print(uncrossed(requester, nation, lead, duration=3600 * 3))
Example #8
0
def main() -> None:
    """Main function"""

    parser = argparse.ArgumentParser(
        description="Check for WA Delegacy changes.\n",
        epilog=delegacy.__doc__,
    )

    parser.add_argument(
        "-s",
        "--start",
        help="Start time, in timestamp seconds.",
        type=int,
        default=None,
        dest="start",
    )
    parser.add_argument(
        "-e",
        "--end",
        help="End time, in timestamp seconds.",
        type=int,
        default=None,
        dest="end",
    )
    parser.add_argument(
        "-d, --duration",
        help="Duration, in seconds.",
        type=int,
        default=None,
        dest="duration",
    )

    parser.add_argument("-o",
                        "--output",
                        help="Output file to write to.",
                        default=None,
                        dest="output")

    args = parser.parse_args()

    requester = nsapi.NSRequester(config.userAgent)

    results = delegacy(requester,
                       startTime=args.start,
                       endTime=args.end,
                       duration=args.duration)

    if args.output:
        with open("args.output", "w", encoding="utf-8") as file:
            write_output(results, file)
    else:
        write_output(results, sys.stdout)
Example #9
0
def main() -> None:
    """Main function"""

    requester = nsapi.NSRequester(config.userAgent)

    print("Specify the region you want to search for card farmers.")
    region = input("Region: ")

    print(
        "\nOptionally, provide a previous output file that indicates nations to not count."
    )
    print(
        "(i.e. the script will only output nations not in the previous output, i.e. new farmers)."
    )
    print("Or, press enter to not use a previous file.")
    previousPath = input("Previous Output File: ")

    print(
        "\nEnter the name of the output file (defaults to `participants.txt`)")
    outputPath = input("Output Path: ")
    if not outputPath:
        outputPath = "participants.txt"

    # Load previous file if provided
    previous: set[str] = set()
    if previousPath:
        with open(previousPath, "r", encoding="utf-8") as f:
            # Each nation name is surrounded by [nation]...[/nation] tags
            # we remove the leading ones, and then split on the trailing ones
            # this leaves an extra empty element due to the trailing end tag at the end,
            # so that is removed with the slice. This process is done for each line,
            # creating a 2D iterator, which is then flattened using `a for b in c for a in b`
            # (the double for acts like a nested for loop)
            previous = {
                nation
                for nationLine in (
                    line.replace("[nation]", "").split("[/nation]")[:-1]
                    for line in f.readlines()) for nation in nationLine
            }

    participants = check_region(requester, region, previous)

    with open(outputPath, "w", encoding="utf-8") as file:
        for participant in participants:
            print(f"[nation]{participant}[/nation]", file=file, end="")
        # Print a trailing newline
        print("", file=file)

    print(f"\nCollection complete. ({len(participants)} nations selected.)")
Example #10
0
def main() -> None:
    """Main function"""

    requester = nsapi.NSRequester(config.userAgent)

    nation = input("Nation: ")

    try:
        autologin = requester.nation(
            nation, auth=nsapi.Auth(
                password=getpass.getpass("Password: "******"Something went wrong, likely incorrect password")
    else:
        print(f"Autologin: {autologin}")
Example #11
0
def main() -> None:
    """Autlogin a list of nations.

    Each line should contain a <nation>,<password> pair.

    Blank lines and lines without a comma are ignored.
    """

    parser = argparse.ArgumentParser(description="Autologin a list of nations.")
    parser.add_argument(
        "--plain",
        action="store_true",
        dest="plain",
        help="Treat passwords as plaintext instead of autologin keys.",
    )
    parser.add_argument(
        "-o", "--output", default=None, help="Output destination of autologin keys."
    )

    args = parser.parse_args()

    requester = nsapi.NSRequester(config.userAgent)

    # Parse input
    results = []
    for nation, key in (parse_line(line) for line in sys.stdin):
        if key:
            result = login(
                requester,
                nation,
                key if not args.plain else None,
                key if args.plain else None,
            )
            if result:
                string = f"Success: {nation} ({result.region})"
                if result.wa:
                    string += " (WA)"
                print(string)
            else:
                print(f"Failed: {nation}")
            results.append((nation, result))

    # Only generate output if desired
    if args.output:
        with open(args.output, "w", encoding="utf-8") as file:
            for nation, result in results:
                print(f"{nation},{result.autologin if result else None}", file=file)
Example #12
0
def main() -> None:
    """Main function for running this module"""

    # Parse nation from command line
    parser = argparse.ArgumentParser(
        description="Determine who has not been endorsed.")
    parser.add_argument("nation",
                        help="Check who this nation has not endorsed.",
                        default=None)
    parser.add_argument(
        "--format",
        help="Format output.",
        action="store_true",
    )

    args = parser.parse_args()
    nation: str = args.nation if args.nation else input("Nation: ")

    # Setup API
    API = nsapi.NSRequester(config.userAgent)

    logger.info("Collecting data")
    logger.info("Current time is %s UTC", datetime.datetime.utcnow())
    region, unendorsed = unendorsed_nations(API, nation)

    # Output unendorsed nations
    lines: Iterable[str]
    if args.format:
        logger.info("Formatting results")
        # Header
        header = f"{nation} has not endorsed the following WA Members in {region}:"
        # Formatted nation urls
        # Create output display strings
        # Increment step so that the list is 1-indexed
        nation_lines = (f"{step+1}. https://www.nationstates.net/nation={name}"
                        for step, name in enumerate(unendorsed))
        lines = itertools.chain([header], nation_lines)
    else:
        lines = unendorsed

    logger.info("Writing results")
    for line in lines:
        # Print to stdout
        print(line)

    logger.info("Current time is %s UTC", datetime.datetime.utcnow())
Example #13
0
def main() -> None:
    """Main method"""

    requester = nsapi.NSRequester(config.userAgent)

    endings = founder_endings(requester)

    # Define default window in seconds
    # DEFAULT_WINDOW = 24 * 3600
    # beforetime = int(time.time())
    # sincetime = beforetime - DEFAULT_WINDOW

    # # Retrieve endings happening data
    # happenings = requester.world().happenings(
    #     safe=False, sincetime=str(sincetime), beforetime=str(beforetime)
    # )

    print(list(endings))
Example #14
0
def update_roster(
    oldRosterPath: t.Optional[str],
    outputPath: t.Optional[str],
    dataPath: str,
    newPath: t.Optional[str],
    *,
    parse_old: bool = True,
) -> None:
    """Update a roster using the given paths."""

    requester = nsapi.NSRequester(config.userAgent)

    # Collect data
    with open(dataPath, "r", encoding="utf-8") as file:
        known: t.Mapping[str,
                         t.Collection[str]] = normalize_known(json.load(file))

    # collect current/old roster
    current: t.Mapping[str, str]

    if oldRosterPath:
        with open(oldRosterPath, "r", encoding="utf-8") as file:
            current = read_old_roster(file, parse_old)
    else:
        # read from stdin
        current = read_old_roster(sys.stdin, parse_old)
    current = normalize(current)

    # compare
    deltas = wa_deltas(requester, current, known)
    results = wa_changes(deltas)

    # Summarize results
    if outputPath:
        with open(outputPath, "w", encoding="utf-8") as file:
            print_output(file, results)
    else:
        print_output(sys.stdout, results)

    # Optionally output reorganized known data
    if newPath:
        with open(newPath, "w", encoding="utf-8") as file:
            print_known(file, reorganize(known, extract_new(deltas)))
Example #15
0
def main() -> None:
    """Main function"""

    print(
        "Specify a json file to load the nation data from. (Based on this script's directory)"
    )
    inputPath = input("File: ")

    print("Specify a json file to load old WA data from for comparison.")
    oldDataPath = input("Old Data File: ")

    print(
        "\nEnter a file to generate output in, or enter nothing to output to standard output."
    )
    outputPath = input("Output File: ")

    requester = nsapi.NSRequester(config.userAgent)

    # Collect data
    with open(nsapi.absolute_path(inputPath), "r") as file:
        nations: t.Mapping[str, t.Collection[str]] = json.load(file)

    # collect current/old roster
    with open(nsapi.absolute_path(oldDataPath), "r") as file:
        current: t.Mapping[str, str] = json.load(file)

    output = check_roster(requester, nations)

    # compare
    changes = {
        nation: output[nation] if nation in output else Result(None)
        for nation, oldWA in current.items()
        if nation not in output or output[nation].wa != oldWA
    }

    # Summarize results
    if outputPath != "":
        with open(nsapi.absolute_path(outputPath), "w") as file:
            print_output(file, changes)
    else:
        print_output(sys.stdout, changes)
Example #16
0
def main() -> None:
    """Main function"""

    requester = nsapi.NSRequester(config.userAgent)

    print("Enter keywords to search for, split with commas.")
    print("Any region with at least one keyword in the WFE is returned.")
    keywords = input("Keywords: ").split(",")

    print("Enter the minimum number of residents of a region.")
    print("Regions with less residents than this number will not be reported.")
    print("0 can be used to report all regions that match the keywords.")
    minimum = int(input("Minimum: "))

    print("\nResults:")
    for region in factbook_searcher(requester,
                                    *keywords,
                                    populationMinimum=minimum):
        print(
            f"https://www.nationstates.net/region={nsapi.clean_format(region.name)}"
        )
Example #17
0
def main() -> None:
    """Execute main module operations."""
    nsapi.enable_logging()

    parser = argparse.ArgumentParser(description="""
            Determine which nations are deployed.
            Takes roster data from stdin and outputs results to stdout.
        """)
    parser.add_argument("leads",
                        nargs="*",
                        metavar="lead",
                        help="Lead nations to check.")

    args = parser.parse_args()

    roster = json.load(sys.stdin)

    requester = nsapi.NSRequester(config.userAgent)

    deploys = deployments(requester, args.leads, roster)

    for lead, endos in deploys.items():
        print(format_deployed(lead, endos))
Example #18
0
def main() -> None:
    """Main function, mainly for testing purposes."""

    requester = nsapi.NSRequester("HN67 API Reader")

    print(listLinks(residents(requester, "shinka")))
Example #19
0
def main(argv: t.Optional[t.Sequence[str]] = None) -> None:
    """Main function.

    If args is provided, it is passed to the argparser.
    Otherwise, first falls back on sys.argv, and then stdin.
    """

    delim = "\t"

    parser = argparse.ArgumentParser(
        description="Checks the status of a list of nations.")

    parser.add_argument(
        "source",
        help=
        """File name or URL to retrieve data from. Expects a tsv formatted file,
            with the first row being a header including 'nation'. The output will be this data
            with the new data columns appended.
        """,
    )

    parser.add_argument(
        "-u",
        "--url",
        action="store_true",
        help=
        "Specifies to treat the source argument as a URL, instead of file path.",
    )

    parser.add_argument(
        "output",
        help="""File path to write output table to. Outputs a tsv file.""")

    # Parse args, checking argument, then sys, then stdin
    if argv:
        args = parser.parse_args(argv)
    elif len(sys.argv) > 1:
        args = parser.parse_args()
    else:
        inputString = input("Arguments (One line, -h for help): ")
        args = parser.parse_args(shlex.split(inputString))

    # Get input data
    if args.url:
        text = requests.get(args.source).text
        table = [line.split(delim) for line in text.splitlines()]
    else:
        with open(args.source) as file:
            table = [line.strip().split(delim) for line in file.readlines()]

    # Create requester
    requester = nsapi.NSRequester(config.userAgent)

    output = report_status(requester, table)

    # Define generator
    combined = (itertools.chain.from_iterable(twopart)
                for twopart in zip(table, output))

    # Write output
    logging.info("Writing output to %s", os.path.abspath(args.output))
    with open(args.output, "w") as file:
        for line in combined:
            print("\t".join(line), file=file)
Example #20
0
def main() -> None:
    """Main function"""

    # Provide proper user agent to api requester
    requester = nsapi.NSRequester(config.userAgent)

    # Function arguments, could be connected to command line, etc

    # Get nations
    nations = []

    print("Enter the name of the file to load nations from.")
    print("Nation names in the file can be divided by commas and lines.")
    print("If you dont wont to load from a file, just press enter.")
    fileName = input("File name: ")
    if fileName != "":
        # Read each line, and split on ,
        with open(fileName, "r") as file:
            for line in file:
                nations.extend(line.strip().split(","))

    print("\nEnter the names of any regions to search.")
    print("Every nation in any of the regions provided will be searched.")
    print(
        "Seperate multiple regions with a comma, no space (e.g. 'REGION1,REGION 2,REGION 3')."
    )
    print("Enter nothing to not search any regions.")
    regionsInput = input("Regions: ")
    if regionsInput != "":
        regions = regionsInput.split(",")
        for region in regions:
            nations.extend(
                requester.region(region).shard("nations").split(":"))

    print("\nEnter the names of additional nations you want to search.")
    print(
        "Seperate names with a comma, no space (e.g. 'NATION,NATION II,NATION III')."
    )
    extraNations = input("Nations: ")
    # If they enter nothing, we dont want to add an empty string
    if extraNations != "":
        nations.extend(extraNations.split(","))

    print(f"\n Checking the following nations: {nations}.")

    print("\nEnter the card rarities you want to view.")
    print(
        "Possibile rarities are: 'common', 'uncommon', 'rare', 'ultra-rare', 'epic', 'legendary'."
    )
    print("You can provide multiple by seperating with a comma, no space.")
    print("(e.g. 'common,ultra-rare,legendary')")
    print("Alternatively, enter nothing to view all rarities.")
    raritiesInput = input("Rarities: ")
    if raritiesInput == "":
        rarities = [
            "common", "uncommon", "rare", "ultra-rare", "epic", "legendary"
        ]
    else:
        # rarities are case insensitive
        rarities = [rarity.lower() for rarity in raritiesInput.split(",")]

    print("Enter whether to collect duplicates of a card on the same nation.")
    print(
        "Enter 'yes'/'y' to collect duplicates, or 'no' (or anything else) to not."
    )
    print(
        "'no' will cause each card to have its own row, even if they are duplicates."
    )
    collectInput = input("Collect duplicates? ").lower()
    if collectInput in ("yes", "y"):
        collect = True
        print("Will collect duplicates.")
    else:
        collect = False
        print("Will not collect duplicates.")

    # Actually run the bulk logic
    data = sorted_cards(requester, nations)
    names = named_cards(requester, extracted_cards(data))
    # Output the data as a csv file format
    path = Path("cardsort.csv").resolve()
    with open(path, "w") as f:
        # Write the csv headers
        headers = "card, cardName, nation, rarity"
        # Only add copies header if collecting
        if collect:
            headers += ", copies"
        print(headers, file=f)
        # Unpack the (triple?) mapping, which basically sorts for us
        for rarity, rarityData in data.items():
            # Only output the rarity if desired
            if rarity in rarities:
                for nation, nationData in rarityData.items():
                    for card, count in nationData.items():
                        # Unroll duplicates if collect option is false
                        row = ("https://www.nationstates.net/page=deck/"
                               f"card={card.id}/season={card.season}"
                               f", {names[card.id]}, {nation}, {rarity}")
                        if not collect:
                            for _ in range(count):
                                print(
                                    row,
                                    file=f,
                                )
                        # Write each data in a different column
                        else:
                            print(
                                row + f", {count}",
                                file=f,
                            )
    print(f"Outputted to {path}")
    # prevents the window from immediately closing if opened standalone
    time.sleep(2)
Example #21
0
def main() -> None:
    """Main function"""

    # Create requester
    requester = nsapi.NSRequester(config.userAgent)

    print("Provide a data file to work through.")
    print(
        "Ideally, the file should be a csv-type text format, with each row in this format:"
    )
    print("<card_link>,<sender>,<receiver>,<sender_password>")
    print(
        "e.g.: 'https://www.nationstates.net/page=deck/card=926511/season=1,hn67,hn67_ii,aPassword"
    )
    print(
        "Technically, only the 'card=num/season=num' part of the link is required."
    )
    print(
        "Also, the password is only required for the first occurence of a nation."
    )
    print(
        "If your password contains a comma (','), it should be enclosed with double quotes (\")."
    )
    print(
        "The path to the file is relative to this script. If the file is in the same directory,"
    )
    print("just enter the name (e.g. 'gifts.csv')")
    dataPath = input("Data file: ")

    print("\nInstead of saving your password in the file,"
          " you can alternatively provide an API autologin,")
    print("which is a encrypted by NationStates version.")
    print("Enter 'yes'/'y' to interpret the passwords as autologins,"
          " or 'no' (or anything else) to not.")
    autologinInput = input("Interpret password fields as autologin? ").lower()
    if autologinInput in ("yes", "y"):
        autologin = True
        print("Interpreting password field as autologins.")
    else:
        autologin = False

    # We save Nation objects so that they can all use the same Auth, i.e. pin
    nations: MutableMapping[str, nsapi.Nation] = {}

    with open(nsapi.absolute_path(dataPath), "r", newline="") as file:
        csvReader = csv.reader(file)
        for row in csvReader:
            try:
                # We need to prepare or find the nation object first (of the sender)
                nation = nsapi.clean_format(row[1])
                if nation not in nations:
                    nations[nation] = requester.nation(nation)
                    # Update the nation auth using given password (or autologin)
                    # Autologin is True if the passwords are actually autologins
                    if autologin:
                        nations[nation].login(row[3])
                    else:
                        nations[nation].auth = nsapi.Auth(password=row[3])
                # Now we can delegate to the function
                send_card(link=row[0], sender=nations[nation], receiver=row[2])
                print(f"Sent {row[0]} from {nation} to {row[2]}")
            # Broad error cause we want to catch anything, so the whole
            # program doesnt crash. logs the message
            except Exception as exception:  # pylint: disable=broad-except
                print("Failed to send a card. Error:", exception)
Example #22
0
def main() -> None:
    """Main entrypoint"""
    requester = nsapi.NSRequester(config.userAgent)
Example #23
0
def main() -> None:
    """Main method"""

    # TODO add type checking into the arguments?
    # would possibly provide better error messages

    parser = argparse.ArgumentParser(
        description="Count the issues answered by a set of nations.")

    subparsers = parser.add_subparsers(
        help="The possible modes, rerun with [mode] -h for more info.",
        dest="sub",
    )

    datesParser = subparsers.add_parser("dates")

    datesParser.add_argument("start",
                             help="The start date, in YYYY-MM-DD format.")

    datesParser.add_argument("end", help="The end date, in YYYY-MM-DD format.")

    datesParser.add_argument(
        "-m",
        "--month",
        help="The month to use for a report. Defaults to month of end date.",
        default=None,
    )

    monthParser = subparsers.add_parser("month")

    monthParser.add_argument(
        "month",
        help=("The month to count across, in YYYY-MM format. "
              "Compares issue counts from YYYY-MM-01 to (MM+1)-01."),
    )

    # monthParser.add_argument(
    parser.add_argument(
        "-r",
        "--report",
        action="store_true",
        help=("Create output in report mode. Produces a formatted file in "
              "Issue Payout Reports folder for the given month. "
              "The report is labelled using the month of the starting date, "
              "unless specified by month parameter."),
    )

    # XKI Puppet List
    default_source = (
        "https://docs.google.com/spreadsheets/d/e/2PACX-1vSem15AVLXgdjxWBZOnWRFnF6NwkY0gVKPYI8"
        "aWuHJzlbyILBL3o1F5GK1hSK3iiBlXLIZBI5jdpkVr/pub?gid=1588413756&single=true&output=tsv"
    )

    parser.add_argument(
        "-s",
        "--source",
        help=("""URL or file name to retrieve nation list from. Expects either
            one or two nations seperated by a tab per line, where the second
            is interpreted as the puppetmaster. Defaults to the XKI puppets URL."""
              ),
        default=default_source,
    )

    parser.add_argument(
        "-f",
        "--file",
        action="store_true",
        help="Makes the script source from a file instead of URL.",
    )

    parser.add_argument(
        "-o",
        "--output",
        help=
        "File name to write (raw) output to. Outputs to stdout if not provided.",
        default=None,
    )

    if len(sys.argv) > 1:
        args = parser.parse_args()
    else:
        inputString = input("Arguments (One line, -h for help): ")
        args = parser.parse_args(shlex.split(inputString))

    requester = nsapi.NSRequester(config.userAgent)

    # Get input data
    if args.file:
        with open(nsapi.absolute_path(args.source)) as file:
            nations = [line.split("\t") for line in file.readlines()]
    else:
        text = requests.get(args.source).text
        nations = [line.split("\t") for line in text.split("\r\n")]

    # Convert to puppetmaster dicts
    # nation[1] is "" if no master, which is falsy
    # Clean the format of all the names
    puppets = {
        nsapi.clean_format(nation[0]): nsapi.clean_format(nation[1])
        if nation[1] else nsapi.clean_format(nation[0])
        for nation in nations
    }

    # Convert dates to start and end date objects
    if args.sub == "dates":
        start = datetime.date.fromisoformat(args.start)
        end = datetime.date.fromisoformat(args.end)
        # Usually makes sense to have the 'month' (for reports) be the ending date if not provided
        if args.month:
            month = datetime.date.fromisoformat(args.month + "-01")
        else:
            month = end.replace(day=1)
    elif args.sub == "month":
        month = datetime.date.fromisoformat(args.month + "-01")
        # Last day of previous month, i.e. 08 -> 07-31
        start = month - datetime.timedelta(days=1)
        # Last day of this month, i.e. 08 -> 08-31
        end = month.replace(
            day=calendar.monthrange(month.year, month.month)[1])

    logging.info("month: %s start: %s end: %s", month, start, end)

    counts = count_change(requester, puppets.keys(), start, end)
    changes = counts[0]

    # Collect puppetmaster counts
    collected_count = {puppetmaster: 0 for puppetmaster in puppets.values()}
    for puppet, change in changes.items():
        collected_count[puppets[puppet]] += change

    def write_output(file: t.TextIO) -> None:
        for puppetmaster, count in collected_count.items():
            print(f"{puppetmaster},{count}", file=file)

    # Write output
    if args.output is not None:
        with open(args.output, "w") as file:
            write_output(file)
    else:
        write_output(sys.stdout)

    # Generate report if chosen.
    # Check the subcommand first, because if month
    # wasnt chosen, the .report attribute wont exist
    # this avoids any exception due to lazy eval
    # if args.sub == "month" and args.report:
    if args.report:
        report = generate_report(month, collected_count)
        # Check for output directory
        if not os.path.isdir(nsapi.absolute_path("IssuePayoutReports")):
            os.mkdir(nsapi.absolute_path("IssuePayoutReports"))
        # Write the report
        with open(
                nsapi.absolute_path(
                    # Format the month to always be 2-digit
                    f"IssuePayoutReports/issuePayoutReport_{month.year}-{month.month:0>2d}.txt"
                ),
                "w",
        ) as f:
            f.write(report)
Example #24
0
def main() -> None:
    """Main function"""
    requester = nsapi.NSRequester(config.userAgent)
    with open("defenderNations.txt", "w") as f:
        print(assemble_defender_announcment(requester), file=f)
Example #25
0
import config
import nsapi
from cards import rarityfinder

PUPPET_SPREADSHEET = "https://docs.google.com/spreadsheets/d/e/2PACX-1vQolEKIC63tiAK1qpAGac6e-eT99-rjFl6oI8UYf0Rt2CVwWp9KsjOPk8R65O8SS_1yS2Af2fBfR7ly/pub?gid=1588413756&single=true&output=tsv"  # pylint: disable=line-too-long # noqa

# Set logging level
level = logging.INFO
logging.basicConfig(level=level)
# Name logger
logger = logging.getLogger()
# Change nsapi logging level
nsapi.logger.setLevel(level=level)

requester = nsapi.NSRequester(config.userAgent)

# load legendary cards
rarityfinder.verify_rarity_data(requester, "legendary")
cards = rarityfinder.load_rarity_data("legendary")

# load member nations
response = requests.get(PUPPET_SPREADSHEET)
members = {
    nsapi.clean_format(line.split("\t")[0])
    for line in response.text.split("\r\n")
}

print("Enter the timestamp to check trading since,")
print("or press enter to default to the first day of the previous month.")
boundInput = input("Timestamp: ")