示例#1
0
 def getActiveSeasonEvents(self):
     """Get active (current) season events."""
     _current_season_events_attrs = [
         'current_season_events', 'eventdays', 'eventchannel'
     ]
     if not any([hasattr(self, a) for a in _current_season_events_attrs
                 ]) or not _checkattr(self, 'current_season_events'):
         self.fetchActiveSeasonEvents()
     return (self.current_season_events, self.eventdays, self.eventchannel)
示例#2
0
    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
示例#3
0
    def _checkItinerary(self):
        """
        Check itinerary.

        If rally not known, use active rally.
        Also set a default startListId.
        """
        _itinerary_items = [
            'itinerary', 'legs', 'sections', 'controls', 'stages'
        ]
        if not all([_checkattr(self, i) for i in _itinerary_items]):
            self.fetchItinerary()
示例#4
0
    def db_connect(self, dbname=None):
        """
        Connect to a db.

        Give the file a randomly generated name if one not provided.
        """
        dbname = dbname or f'{uuid.uuid4().hex}.db'
        if not _checkattr(self, dbname) or (dbname and self.dbname != dbname):
            self.dbname = dbname
        else:
            self.dbname = dbname

        self.db = Database(self.dbname)
示例#5
0
    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')
示例#6
0
    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')
示例#7
0
 def call(self):
     """Check attributes. If any missing, grab data as required."""
     (attrs, func2) = func(self)
     if not attrs:
         return None
     if isinstance(attrs, str):
         attrs = [attrs]
     # Don't call the function if all the attributes that would be set
     # by calling it are already set.
     if not all([_checkattr(self, a) for a in attrs]):
         func2()
     if len(attrs) > 1:
         return tuple(getattr(self, a) for a in attrs)
     return getattr(self, attrs[0])
示例#8
0
    def getStageIds(self, typ='all', response='dict'):
        """Return stageIDs by stage status."""
        if _checkattr(self, 'stages'):
            if typ == 'all':
                _df = self.stages[['code', 'rallyid', 'stageId']]
            else:
                if typ == 'completed':
                    _statuses = ['Completed', 'Interrupted']
                elif typ == 'onlycompleted':
                    _statuses = ['Completed']
                elif typ == 'interrupted':
                    _statuses = ['Interrupted']
                _df = self.stages[self.stages['status'].isin(_statuses)][[
                    '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 mongodb_checkconn(self, host=None, port=None):
     """Check existence of a MongoDB connection and try to create it otherwise."""
     if not _checkattr(self, 'mongo_conn'):
         self.mongodb_connect(host, port)
示例#10
0
 def _checkStages(self, sdbRallyId=None):
     """Return a stages list or lookup list for active rally."""
     # Have we got an sdbRallyId?
     if not _checkattr(self, 'stages'):
         self.fetchStages(sdbRallyId=None)
示例#11
0
 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)
示例#12
0
    def upsert(self, table, data=None, pk=None):
        """
        Upsert data to database.

        If we forget to create a database, this will create one.
        """
        print(f'upserting into {table}')
        _upserts = []

        if isinstance(table, str):
            if _notnull(data) and pk is not None:
                # One table
                _upserts.append((table, data, pk))
            # Check data is None. It may be {}, which would be data...
            elif hasattr(self, table) and data is None and pk is not None:
                # One table, data from self attribute
                data = getattr(self, table)
                _upserts.append((table, data, pk))
        elif isinstance(table, tuple) and len(table) == 2 and _isnull(data):
            (_table, _pk) = table
            if isinstance(_table, str) and hasattr(self,
                                                   _table) and _pk is not None:
                _data = getattr(self, _table)
                _upserts.append((_table, _data, _pk))
        elif isinstance(table, list) and _isnull(data):
            # Several tables from self  attributes: [(table, pk), ..]
            for _t in table:
                if isinstance(_t, tuple) and len(_t) == 2:
                    (_table, _pk) = _t
                    if isinstance(_table, str) and hasattr(
                            self, _table) and _pk is not None:
                        _data = getattr(self, _table)
                        _upserts.append((_table, _data, _pk))

        # TO DO - if the pk is none, and data is a df, use the df index?

        if not _checkattr(self, 'dbname') and not _checkattr(self, 'db'):
            self.db_connect()

        # The alter=True allows us the table to be modified if we have extra columns
        for (_table, _data, _pk) in _upserts:
            # TO DO - the try is to cope with this issue:
            # https://github.com/simonw/sqlite-utils/issues/73#issuecomment-571138093
            # The ignore does not result in a dupe: the original row is left in place
            if isinstance(
                    _data,
                    pd.DataFrame) and _notnull(_data) and _pk is not None:
                try:
                    self.db[_table].upsert_all(_data.to_dict(orient='records'),
                                               pk=_pk,
                                               alter=True)
                except:
                    try:
                        self.db[_table].insert_all(
                            _data.to_dict(orient='records'),
                            pk=_pk,
                            alter=True,
                            replace=True)
                    except:
                        warning(f"Couldn't add data to {_table} with PK {_pk}")

            elif isinstance(_data, dict) and _data and _pk is not None:
                try:
                    self.db[_table].upsert_all(_data, pk=_pk, alter=True)
                except:
                    try:
                        self.db[_table].insert_all(_data,
                                                   pk=_pk,
                                                   alter=True,
                                                   replace=True)
                    except:
                        warning(f"Couldn't add data to {_table} with PK {_pk}")
示例#13
0
 def getRally(self):
     """Get external rally details."""
     attrs = ['rally', 'eligibilities', 'groups']
     if not all([_checkattr(self, a) for a in attrs]):
         self.fetchRally()
     return tuple(getattr(self, a) for a in attrs)