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
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"), )
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}")
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)