diff --git a/pyracing/client.py b/pyracing/client.py index e9e0a26..22591df 100644 --- a/pyracing/client.py +++ b/pyracing/client.py @@ -1,7 +1,12 @@ from pyracing import constants as ct from pyracing import logger -from pyracing.helpers import now_five_min_floor +from pyracing.helpers import ( + encode_password, + now_five_min_floor +) + + from pyracing.response_objects import ( career_stats, chart_data, @@ -39,7 +44,7 @@ def __init__(self, username: str, password: str): is to store then in your OS environment and call with os.getenv(). """ self.username = username - self.password = password + self.password = encode_password(username,password) self.session = httpx.AsyncClient() def _rename_numerical_keys(self, response_item, mapping): @@ -99,9 +104,11 @@ async def _build_request(self, url, params): response = await self.session.get( url, params=params, - allow_redirects=False, + #allow_redirects=False, timeout=10.0 ) + + #print(response.request) logger.info(f'Request sent for URL: {response.url}') logger.info(f'Status code of response: {response.status_code}') logger.debug(f'Contents of the response object: {response.__dict__}') @@ -940,13 +947,67 @@ async def league_standings(self, league_id, league_season_id): return league_data.SeasonStandings(response.json()) + + async def getCompletedSessionInfo(self, sessID): + payload = { + 'subsessionID': sessID, + } + mSite = 'https://members.iracing.com/membersite/member' + url = (mSite + '/GetSubsessionResults') + web_fb = await self._build_request(url, payload) + return session_data.SubSessionData(web_fb.json()) + + async def getCalendarBySeason(self, seasonID, leagueID): + payload = { + 'leagueID': leagueID, + 'leagueSeasonID': seasonID, + } + mSite = 'https://members.iracing.com/membersite/member' + url = (mSite + '/GetLeagueCalendarBySeason') + web_fb = await self._build_request(url, payload) + try: + return web_fb.json()["rows"] + except: + return web_fb.json() + + + + async def getActiveSessions(self, leagueID): + payload = { + 'ts': 0, + 'leagueID': leagueID, + 'startRow':1, + 'stopRow': 20 + } + mSite = 'https://members.iracing.com/membersite/member' + url = (mSite + '/GetLeagueSessions') + web_fb = await self._build_request(url, payload) + return web_fb.json()["rows"] + + + async def get_league_members(self, leagueID): + payload = { + 'leagueid': leagueID, + 'lowerBound': 0, + 'upperBound': 100 + } + mSite = 'https://members.iracing.com/membersite/member' + URL_LEAGUE_MEMBERS = (mSite + '/GetLeagueMembers') + url = URL_LEAGUE_MEMBERS + + membersWeb = await self._build_request(url, payload) + return membersWeb.json() + + async def league_seasons(self, league_id): """Get the season for a league""" - payload = {'leagueID': league_id} + payload = {'leagueID': league_id, + 'getInactiveSeasons':1 + } url = ct.URL_LEAGUE_SEASONS response = await self._build_request(url, payload) - + if response.json(): mapping = response.json().get('m') response_data = response.json().get('d') diff --git a/pyracing/helpers.py b/pyracing/helpers.py index be3a6c6..b1c6a6f 100644 --- a/pyracing/helpers.py +++ b/pyracing/helpers.py @@ -1,3 +1,5 @@ +import base64 +import hashlib import math import urllib.parse from time import time @@ -11,6 +13,19 @@ def datetime_from_iracing_timestamp(timestamp): except Exception: return None +def encode_password(username, password): + """ Encodes the username/password combination as a Base64 string for + submission in the password field on iRacing login forms. This is not what + iRacing stores as the hashed password. It is merely to prevent the plain + text version of a user's password from being transmitted to iRacing. + """ + s256Hash = hashlib.sha256((password + username.lower()).encode('utf-8')).digest() + base64Hash = base64.b64encode(s256Hash).decode('utf-8') + + return base64Hash + + + def now_five_min_floor(): """ Takes the current time and rounds down to the nearest five minute mark