def getStartlistId(stage='', startListId=None, legs=None, stages=None): """Get a generic startListId.""" # We essentially hack the precedence ordering # TO DO - we should warn from this # If passed something as first parameter (stage) that is actually # a startListId and we have no startListId, use _stage as startListId _stage = _jsInt(stage) if startListId is None and _stage and legs and _stage in legs[ 'startListId']: startListId = _stage # If we don't have a valid startListId, try to finesse one from stage if _isnull(_jsInt(startListId)) or not (legs and _jsInt(startListId) and _jsInt(startListId) in legs['startListId']): # If the startListId is a str, is it a stage designator? if isinstance(startListId, str) and startListId.startswith('SS'): stage = startListId if stage and isinstance(stage, str) and stage.lower().startswith('current'): startListId = getCurrentLeg(legs=legs)['startListId'] elif stage: stage_details = getStageDetails(startListId, stages=stages) if _notnull(stage_details): startListId = stage_details['startListId'] if not startListId: startListId = getCurrentLeg(legs=legs)['startListId'] return startListId
def _checkStartListId(self, startListId=None): """Return a startlistId or look one up.""" self._checkItinerary() if not startListId or not _jsInt(startListId): # TO DO - Should we do this? #self.startListId = int(self.legs.loc[0, 'startListId']) self.startListId = getStartlistId(startListId=startListId, legs=self.legs, stages=self.stages) else: self.startListId = _jsInt(startListId or self.startListId)
def getStageTimes(sdbRallyId, stageId, raw=False, func=_parseStageTimes): """Get stage times for specified rally and stage""" args = { "command": "getStageTimes", "context": { "sdbRallyId": _jsInt(sdbRallyId), "activeStage": { "stageId": _jsInt(stageId) } } } return _get_and_handle_response(URL, args, func, nargs=1, raw=raw)
def _checkStageId(self, sdbRallyId=None, stageId=None, fallback='lastCompleted'): """Return a stage ID or lookup a current one.""" self._checkRallyId(sdbRallyId) stageId = _jsInt(stageId) # One method for finding a stage ID - last completed if not stageId: if 'lastCompleted': stageId = _jsInt(self.lastCompletedStage()) # What else? Most recent still running, else lastCompleted? return stageId
def getItinerary(sdbRallyId=None, raw=False, func=_parseItinerary): """Get itinerary details for specified rally.""" if not sdbRallyId: event, days, channels = getActiveRally() sdbRallyId = int(event.loc[0, 'id']) args = { "command": "getItinerary", "context": { "sdbRallyId": _jsInt(sdbRallyId) } } if sdbRallyId: extracols = {'rallyid': sdbRallyId} else: extracols = {} # TO DO - could we annotate with a looked up rally id? #Presumably from eg getActiveRally()? Or more generally ActiveSeasonEvents return _get_and_handle_response(URL, args, func, nargs=5, raw=raw, extracols=extracols)
def __init__(self, sdbRallyId=None, stageId=None, live=False, autoseed=False, nowarn=True, dbname=None): """Rallystage class. Builds on rally stages.""" WRCRallyStages.__init__(self, sdbRallyId=sdbRallyId, live=live, autoseed=autoseed, nowarn=nowarn, dbname=dbname) if not nowarn: if not sdbRallyId: warnings.warn("sdbRallyId should really be set...") if not stageId: warnings.warn("stageId should really be set...") self.stageId = _jsInt(stageId) if autoseed: fetchData(self.sdbRallyId, stageId)
def getOverall(sdbRallyId, stageId, raw=False, func=_parseOverall): """Get overall standings for specified rally and stage.""" args = { "command": "getOverall", "context": { "sdbRallyId": _jsInt(sdbRallyId), "activeStage": { "stageId": _jsInt(stageId) } } } return _get_and_handle_response(URL, args, func, nargs=1, raw=raw, extracols={'stageId': stageId})
def _checkRallyId(self, sdbRallyId=None): """Return a rally ID or lookup active one.""" sdbRallyId = _jsInt(sdbRallyId) or self.sdbRallyId if not _checkattr(self, 'sdbRallyId'): self.activerally = WRCActiveRally() self.sdbRallyId = self.activerally.sdbRallyId self.name = self.activerally.name return self.sdbRallyId
def getRetirements(sdbRallyId, raw=False, func=_parseRetirements): """Get retirements for specified rally.""" args = { "command": "getRetirements", "context": { "sdbRallyId": _jsInt(sdbRallyId) } } return _get_and_handle_response(URL, args, func, nargs=1, raw=raw)
def getStagewinners(sdbRallyId, raw=False, func=_parseStagewinners): """Get stage winners for specified rally.""" args = { "command": "getStagewinners", "context": { "sdbRallyId": _jsInt(sdbRallyId) } } return _get_and_handle_response(URL, args, func, nargs=1, raw=raw)
def __init__(self, season_external_id=None, autoseed=False, nowarn=True, dbname=None): """Add WRCBase class. Autoseed with season details if required.""" WRCBase.__init__(self, nowarn=nowarn, dbname=dbname) self.season_external_id = _jsInt(season_external_id) if not self.season_external_id and autoseed: self._check_season_external_id()
def fetchSeasonExternalId(self, season_external_id=None): """Fetch a season external ID howsoever we can.""" # Get current one from active rally # It's also available from current_season_events event, days, channels = getActiveRally() self.event, self.days, self.channels = event, days, channels # The returned np.int64 is not JSON serialisable self.season_external_id = _jsInt(event.loc[0, 'season.externalId']) # Upsert the data if there's a db connection self.dbfy([('event', 'id'), ('days', 'id'), ('channels', 'id')])
def fetchStageTimes(self, sdbRallyId=None, stageId=None): """Fetch the data from WRC API.""" stageId = _jsInt(stageId) self._checkRallyId(sdbRallyId) self._checkStages(self.sdbRallyId) self._checkStageId(self.sdbRallyId, stageId) if self.stageStatus(stageId) == 'ToRun': return if stageId: self.stagetimes[stageId] = getStageTimes(self.sdbRallyId, stageId) self.dbfy('stagetimes', self.stagetimes[stageId], ['stageId', 'entryId'])
def __init__(self, sdbRallyId=None, autoseed=False, nowarn=True, dbname=None): """Initialise things that have a rallyId.""" WRCBase.__init__(self, nowarn=nowarn, dbname=dbname) self.warner(not sdbRallyId, "sdbRallyId should really be set...") self.sdbRallyId = _jsInt(sdbRallyId) if autoseed: self._checkRallyId(sdbRallyId)
def getStageIdsFromCode(self, codes=None, response='dict'): """Return a stageID from one or more codes.""" # TO DO: this should really run through getStageIdFromCode() codes = [f'SS{_jsInt(c)}' if _jsInt(c) else c for c in listify(codes)] if codes and _checkattr(self, 'stages'): _df = self.stages[self.stages['code'].isin(codes)][[ 'code', 'rallyid', 'stageId' ]] if response == 'df': return _df elif response == 'tuples': return list(_df.itertuples(index=False, name=None)) return _df.set_index('code').to_dict(orient='index')
def getStageIdFromCode(self, code=None): """Return a stageID from a single codes.""" # Accept: 'SS1', '1', 1 if _jsInt(code): code = f'SS{code}' if code and isinstance(code, str) and _checkattr(self, 'stages'): _df = self.stages[self.stages['code'] == code][[ 'rallyid', 'stageId' ]] return tuple(_df.iloc[0]) elif code and isinstance(code, list): # TO DO - this might be dangerous if we are expecting a single tuple response return getStageIdsFromCode(code, response='tuples')
def __init__(self, sdbRallyId=None, live=False, autoseed=False, nowarn=True, dbname=None): """Rally stages class;. Builds on itinerary.""" WRCItinerary.__init__(self, sdbRallyId=None, live=False, autoseed=autoseed, dbname=dbname) self.sdbRallyId = _jsInt(sdbRallyId) if autoseed: self._checkStages(self.sdbRallyId)
def getStageDetails(stageNum, stages=None): """Get stage details from stage number (eg SS1).""" if _isnull(stages): # TO DO - if the class calls this, the data is obtained but not returned itinerary, legs, sections, controls, stages = getItinerary() if isinstance(stageNum, str) and stageNum.startswith('SS'): pass elif _jsInt(stageNum): stageNum = f'SS{stageNum}' else: stageNum = None stages_idx = stages.where(stages['code'] == stageNum).last_valid_index() if stages_idx is not None: return stages.loc[stages_idx] return None
def getRally(sdbRallyId, raw=False, func=_parseRally): """Get rally details for specified rally.""" args = { "command": "getRally", "context": { "sdbRallyId": _jsInt(sdbRallyId) } } return _get_and_handle_response(URL, args, func, nargs=3, raw=raw, renamecols={ 'rallyId': 'externalIdRally', 'eventId': 'externalIdEvent' }, extracols={'sdbRallyId': sdbRallyId})
def getStartlist(stage='', startListId=None, legs=None, stages=None, raw=False, func=_parseStartlist): """Get a generic startlist.""" startListId = getStartlistId(stage=stage, startListId=startListId, legs=legs, stages=stages) args = { 'command': 'getStartlist', 'context': { 'activeItineraryLeg': { 'startListId': _jsInt(startListId) } } } return _get_and_handle_response(URL, args, func, nargs=2, raw=raw)
def fetchSplitTimes(self, sdbRallyId=None, stageId=None): """Get split times data from WRC API. Add to db if available.""" stageId = _jsInt(stageId) self._checkRallyId(sdbRallyId) self._checkStages(self.sdbRallyId) self._checkStageId(self.sdbRallyId, stageId) if self.stageStatus(stageId) == 'ToRun': return if stageId: (self.splitPoints[stageId], self.entrySplitPointTimes[stageId], self.splitPointTimes[stageId]) = getSplitTimes( self.sdbRallyId, stageId) self.dbfy('splitPoints', self.splitPoints[stageId], ['splitPointId', 'stageId']) self.dbfy('entrySplitPointTimes', self.entrySplitPointTimes[stageId], ['stageId', 'entryId']) self.dbfy( 'splitPointTimes', self.splitPointTimes[stageId], ['splitPointTimeId', 'splitPointId', 'entryId', 'stageId'])
def __init__(self, startListId=None, live=False, autoseed=True, nowarn=False, dbname=None): """Startlist class, builds on itinerary class.""" WRCItinerary.__init__(self, live=live, autoseed=autoseed, dbname=dbname) self.startListId = _jsInt(startListId) self.startList = None self.startListItems = None self.startLists = {} if not nowarn and not self.startListId: warnings.warn("startListId should really be set..") if self.startListId or autoseed: self.fetchStartList(self.startListId)
def _check_season_external_id(self, season_external_id=None): """Check that season_external_id exists and if not, get one.""" self.season_external_id = _jsInt( season_external_id) or self.season_external_id if not _checkattr(self, 'season_external_id'): self.fetchSeasonExternalId(season_external_id)