From e667602620a51576e354de24d0b5b90b726dab9f Mon Sep 17 00:00:00 2001 From: NW/RL Date: Mon, 1 Apr 2024 23:08:44 -0500 Subject: Make debugging easier --- steamrelationships/sr.py | 119 +++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 55 deletions(-) (limited to 'steamrelationships') diff --git a/steamrelationships/sr.py b/steamrelationships/sr.py index 429eec2..22e941e 100644 --- a/steamrelationships/sr.py +++ b/steamrelationships/sr.py @@ -10,12 +10,13 @@ class SteamRelationships: scanlist: list = [] # To be populated by recurse() reqjson: str = "requests.json" - def __init__(self, webapikey: str, timeout: int = 30, reqdelay: float = 0.5, delayrand: float = 1.25, reqsafetybuffer: float = 0.9, reqjson: str = "requests.json") -> None: + def __init__(self, webapikey: str, timeout: int = 30, timeout_retries: int = 5, reqdelay: float = 0.5, delayrand: float = 1.25, reqsafetybuffer: float = 0.9, reqjson: str = "requests.json") -> None: """ (str/int) webapikey - Steam dev api key required to use Steam's ISteamUser/GetFriendList interface Request Options: - (int/float) timeout (Default: 30) - Seconds to wait before timing out a request. + (int) timeout (Default: 30) - Seconds to wait before timing out a request. + (int) timeout_retries (Default: 5) Number of times to retry a request after timing out (float) reqdelay (Default: 0.5) - Default amount of seconds to wait between sending each request to Steam (float) delayrand (Default: 1.25) - The max percentage of extra delay to randomly add to each request (1 = no randomness, <1 = randomly shorter, >1 = randomly longer) (float) reqsafetybuffer (Default: 0.9) - Highest percent of Steam's API request limit you are willing to run @@ -28,11 +29,14 @@ class SteamRelationships: self.webapikey = webapikey self.timeout = timeout + self.timeout_retries = timeout_retries self.reqdelay = reqdelay self.delayrand = delayrand self.reqsafetybuffer = reqsafetybuffer self.reqjson = reqjson + + def _readjsonfile(self, filepath: str = "") -> dict: if not filepath: filepath = self.reqjson @@ -48,7 +52,7 @@ class SteamRelationships: # If the file does not exist, create one and slap an empty list in it except FileNotFoundError: - print(f"File {filepath} does not exist. Generating empty json file...") + print(f"[_readjsonfile] File {filepath} does not exist. Generating empty json file...") try: with open(filepath, "w+") as newfile: json.dump({time.time_ns(): [0, []]}, newfile, indent=4) @@ -56,12 +60,12 @@ class SteamRelationships: return self._readjsonfile(filepath) - except: - print("Couldn't create new file") + except Exception as e: + print(f"[_readjsonfile] Couldn't create new file ({e})") return {} - except: - print("Other unknown error occured") + except Exception as e: + print(f"[_readjsonfile] Other unknown error occured ({e})") return {} return final @@ -75,8 +79,8 @@ class SteamRelationships: try: jsoncontents = self._readjsonfile(filename) - except: - print(f"Could not get the contents of file {filename}") + except Exception as e: + print(f"[_checkrequests] Could not get the contents of file {filename} ({e})") return -1 # Check the current date. If over 1 day since last entry, add a new entry. Otherwise, edit the current day's entry [note, 1 day in nanoseconds = (8.64 * (10 ** 13)) ] @@ -92,7 +96,7 @@ class SteamRelationships: jsoncontents[list(jsoncontents.keys())[-1]][1].append(checktime) else: - print(f"Daily request limit reached ({jsoncontents[list(jsoncontents.keys())[-1]][0]}/{CONST.STEAMAPI_MAXREQ * self.reqsafetybuffer}). Please try again tomorrow, or increase \"reqsafetybuffer\" (currently: {self.reqsafetybuffer})") + print(f"[_checkrequests] Daily request limit reached ({jsoncontents[list(jsoncontents.keys())[-1]][0]}/{CONST.STEAMAPI_MAXREQ * self.reqsafetybuffer}). Please try again tomorrow, or increase \"reqsafetybuffer\" (currently: {self.reqsafetybuffer})") return 0 # Update the json file @@ -101,68 +105,73 @@ class SteamRelationships: json.dump(jsoncontents, jsonfile, indent=4) jsonfile.close() - except: - print("Could not update json file") + except Exception as e: + print("[_checkrequests] Could not update json file ({e})") return -1 return jsoncontents[list(jsoncontents.keys())[-1]][0] - def _getFriendsList(self, steamid64: str = None) -> dict: - # example url: http://api.steampowered.com/ISteamUser/GetFriendList/v0001/?key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&steamid=76561197960435530&relationship=friend + + + def _getFriendsList(self, steamid64: str, retrys: int = 0) -> dict: if not steamid64: - print("Requested id must not be blank") + print("[_getFriendsList] No steamid64 given") return {} - # Format url and make a request - url = "https://api.steampowered.com/ISteamUser/GetFriendList/v0001/" - options = {"key": self.webapikey, "steamid": steamid64, "relationship": "friend"} + url: str = "https://api.steampowered.com/ISteamUser/GetFriendList/v0001/" + options: dict = {"key": self.webapikey, "steamid": steamid64, "format": "json"} + result: object = None + + # Get the result + try: + result = self.session.get(url, params=options, timeout=self.timeout) - # BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING # - # BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING # - # BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING # + except requests.exceptions.Timeout: + print(f"[_getFriendsList] Request timed out (No response for {self.timeout} seconds)") + if retrys <= self.timeout_retries: + print(f"[_getFriendsList] Retrying request... (Attempt {retrys}/{self.timeout_retries})") + return self._getFriendsList(steamid64, retrys + 1) - # TODO: FIX THIS SO IT DOESN"T EXPLODE EVERYTHING ALL THE TIME - response: object - if self._checkrequests() > 0: - response = self.session.get(url, params=options, timeout=self.timeout) # GET should be as secure as POST because ssl is being used + print("[_getFriendsList] Retry limit reached") + return {} - else: - return None + except Exception as e: + print(f"[_getFriendsList] Other error in contacting steam ({e})") + return {} - # TODO: Implement proper error checking so that this doesn't just break if someone has a private friends list - if response.status_code == requests.codes.ok: - return response.json() + # Error out on request error + if result.status_code != requests.codes.ok: + print("[_getFriendsList] Got bad status code") + return {} - return None + # Get the json contents from the response + resultjson: dict = {} + try: + resultjson = result.json() - def parseFriendsList(self, friendslist: dict = None) -> list: - if not friendslist: - return None + except requests.exceptions.JSONDecodeError: + print("[_getFriendsList] Could not decode json response for some reason") + return {} - final = [] - for friend in friendslist['friendslist']['friends']: - final.append(friend['steamid']) + except Exception as e: + print(f"[_getFriendsList] Unknown error in getting json response ({e})") + return {} - return final + return resultjson - # Do a basic scan for a single id - def basic_scan(self, id: str) -> list: - return self.parseFriendsList(self._getFriendsList(id)) + def _parseFriendsList(self, friendsdict: dict) -> list: + if not friendsdict: + print("[_parseFriendsList] Empty friends dict given") + return [] - def recursive_scan(self, startid: str, ): - scans: dict = {} - alreadyscanned: list = [] - scans[startid] = self.basic_scan(startid) - alreadyscanned.append(startid) - - tempscans: dict = {} - for person in scans: - for friend in scans[person]: - if friend not in alreadyscanned: - tempscans[friend] = self.basic_scan(tempscans) - alreadyscanned.append(friend) + friends: list = [] + try: + for friend in friendsdict['friendslist']['friends']: + friends.append(f"{friend}") - scans.update(tempscans) + except Exception as e: + print("[_parseFriendsList] Error parsing friendsdict ({e})") + friends.clear() - return \ No newline at end of file + return friends \ No newline at end of file -- cgit v1.2.3