Example #1
0
    def _write_rides(self, start, end, athlete, rewrite=False):

        sess = db.session

        api_ride_entries = data.list_rides(
            athlete=athlete, start_date=start, end_date=end, exclude_keywords=app.config.get("BAFS_EXCLUDE_KEYWORDS")
        )

        start_notz = start.replace(
            tzinfo=None
        )  # Because MySQL doesn't like it and we are not storing tz info in the db.

        q = sess.query(model.Ride)
        q = q.filter(and_(model.Ride.athlete_id == athlete.id, model.Ride.start_date >= start_notz))
        db_rides = q.all()

        # Quickly filter out only the rides that are not in the database.
        returned_ride_ids = set([r.id for r in api_ride_entries])
        stored_ride_ids = set([r.id for r in db_rides])
        new_ride_ids = list(returned_ride_ids - stored_ride_ids)
        removed_ride_ids = list(stored_ride_ids - returned_ride_ids)

        num_rides = len(api_ride_entries)

        for (i, strava_activity) in enumerate(api_ride_entries):
            self.logger.debug("Processing ride: {0} ({1}/{2})".format(strava_activity.id, i + 1, num_rides))

            if rewrite or not strava_activity.id in stored_ride_ids:
                try:
                    ride = data.write_ride(strava_activity)
                    self.logger.info(
                        "[NEW RIDE]: {id} {name!r} ({i}/{num}) ".format(
                            id=strava_activity.id, name=strava_activity.name, i=i + 1, num=num_rides
                        )
                    )
                    sess.commit()
                except Exception as x:
                    self.logger.debug(
                        "Error writing out ride, will attempt to add/update RideError: {0}".format(strava_activity.id)
                    )
                    sess.rollback()
                    try:
                        ride_error = sess.query(model.RideError).get(strava_activity.id)
                        if ride_error is None:
                            self.logger.exception(
                                "[ERROR] Unable to write ride (skipping): {0}".format(strava_activity.id)
                            )
                            ride_error = model.RideError()
                        else:
                            # We already have a record of the error, so log that message with less verbosity.
                            self.logger.warning(
                                "[ERROR] Unable to write ride (skipping): {0}".format(strava_activity.id)
                            )

                        ride_error.athlete_id = athlete.id
                        ride_error.id = strava_activity.id
                        ride_error.name = strava_activity.name
                        ride_error.start_date = strava_activity.start_date_local
                        ride_error.reason = str(x)
                        ride_error.last_seen = datetime.now()  # FIXME: TZ?
                        sess.add(ride_error)

                        sess.commit()
                    except:
                        self.logger.exception("Error adding ride-error entry.")
                else:
                    sess.commit()
                    try:
                        # If there is an error entry, then we should remove it.
                        q = sess.query(model.RideError)
                        q = q.filter(model.RideError.id == ride.id)
                        deleted = q.delete(synchronize_session=False)
                        if deleted:
                            self.logger.info("Removed matching error-ride entry for {0}".format(strava_activity.id))
                        sess.commit()
                    except:
                        self.logger.exception("Error maybe-clearing ride-error entry.")
            else:
                self.logger.info(
                    "[SKIPPED EXISTING]: {id} {name!r} ({i}/{num}) ".format(
                        id=strava_activity.id, name=strava_activity.name, i=i + 1, num=num_rides
                    )
                )

        # Remove any rides that are in the database for this athlete that were not in the returned list.
        if removed_ride_ids:
            q = sess.query(model.Ride)
            q = q.filter(model.Ride.id.in_(removed_ride_ids))
            deleted = q.delete(synchronize_session=False)
            self.logger.info("Removed {0} no longer present rides for athlete {1}.".format(deleted, athlete))
        else:
            self.logger.info("(No removed rides for athlete {0}.)".format(athlete))

        sess.commit()
Example #2
0
    def _write_rides(self, start, end, athlete, rewrite=False):

        sess = db.session

        api_ride_entries = data.list_rides(athlete=athlete, start_date=start, end_date=end,
                                           exclude_keywords=app.config.get('BAFS_EXCLUDE_KEYWORDS'))

        start_notz = start.replace(
            tzinfo=None)  # Because MySQL doesn't like it and we are not storing tz info in the db.

        q = sess.query(model.Ride)
        q = q.filter(and_(model.Ride.athlete_id == athlete.id,
                          model.Ride.start_date >= start_notz))
        db_rides = q.all()

        # Quickly filter out only the rides that are not in the database.
        returned_ride_ids = set([r.id for r in api_ride_entries])
        stored_ride_ids = set([r.id for r in db_rides])
        new_ride_ids = list(returned_ride_ids - stored_ride_ids)
        removed_ride_ids = list(stored_ride_ids - returned_ride_ids)

        num_rides = len(api_ride_entries)

        for (i, strava_activity) in enumerate(api_ride_entries):
            self.logger.debug("Processing ride: {0} ({1}/{2})".format(strava_activity.id, i + 1, num_rides))

            if rewrite or not strava_activity.id in stored_ride_ids:
                try:
                    ride = data.write_ride(strava_activity)
                    self.logger.info("[NEW RIDE]: {id} {name!r} ({i}/{num}) ".format(id=strava_activity.id,
                                                                                     name=strava_activity.name,
                                                                                     i=i + 1,
                                                                                     num=num_rides))
                    sess.commit()
                except Exception as x:
                    self.logger.debug("Error writing out ride, will attempt to add/update RideError: {0}".format(strava_activity.id))
                    sess.rollback()
                    try:
                        ride_error = sess.query(model.RideError).get(strava_activity.id)
                        if ride_error is None:
                            self.logger.exception("[ERROR] Unable to write ride (skipping): {0}".format(strava_activity.id))
                            ride_error = model.RideError()
                        else:
                            # We already have a record of the error, so log that message with less verbosity.
                            self.logger.warning("[ERROR] Unable to write ride (skipping): {0}".format(strava_activity.id))

                        ride_error.athlete_id = athlete.id
                        ride_error.id = strava_activity.id
                        ride_error.name = strava_activity.name
                        ride_error.start_date = strava_activity.start_date_local
                        ride_error.reason = str(x)
                        ride_error.last_seen = datetime.now()  # FIXME: TZ?
                        sess.add(ride_error)

                        sess.commit()
                    except:
                        self.logger.exception("Error adding ride-error entry.")
                else:
                    sess.commit()
                    try:
                        # If there is an error entry, then we should remove it.
                        q = sess.query(model.RideError)
                        q = q.filter(model.RideError.id == ride.id)
                        deleted = q.delete(synchronize_session=False)
                        if deleted:
                            self.logger.info("Removed matching error-ride entry for {0}".format(strava_activity.id))
                        sess.commit()
                    except:
                        self.logger.exception("Error maybe-clearing ride-error entry.")
            else:
                self.logger.info("[SKIPPED EXISTING]: {id} {name!r} ({i}/{num}) ".format(id=strava_activity.id,
                                                                                         name=strava_activity.name,
                                                                                         i=i + 1,
                                                                                         num=num_rides))

        # Remove any rides that are in the database for this athlete that were not in the returned list.
        if removed_ride_ids:
            q = sess.query(model.Ride)
            q = q.filter(model.Ride.id.in_(removed_ride_ids))
            deleted = q.delete(synchronize_session=False)
            self.logger.info("Removed {0} no longer present rides for athlete {1}.".format(deleted, athlete))
        else:
            self.logger.info("(No removed rides for athlete {0}.)".format(athlete))

        sess.commit()
Example #3
0
def _write_rides(start, team=None, athlete_id=None, rewrite=False):
    
    logger = logging.getLogger('sync')
    
    if team and athlete_id:
        raise ValueError("team and athlete params are mutually exclusive")
    elif team is None and athlete_id is None:
        raise ValueError("either team or athlete_id param is required")
    
    sess = db.session
    
    if team:
        api_ride_entries = data.list_rides(club_id=team.id, start_date=start, exclude_keywords=app.config.get('BAFS_EXCLUDE_KEYWORDS'))
        q = sess.query(model.Ride)
        q = q.filter(and_(model.Ride.athlete_id.in_(sess.query(model.Athlete.id).filter(model.Athlete.team_id==team.id)),
                          model.Ride.start_date >= start))
        db_rides = q.all()
    else:
        api_ride_entries = data.list_rides(athlete_id=athlete_id, start_date=start, exclude_keywords=app.config.get('BAFS_EXCLUDE_KEYWORDS'))
        q = sess.query(model.Ride)
        q = q.filter(and_(model.Ride.athlete_id == athlete_id,
                          model.Ride.start_date >= start))
        db_rides = q.all()
    
    # Quickly filter out only the rides that are not in the database.
    returned_ride_ids = set([r.id for r in api_ride_entries])
    stored_ride_ids = set([r.id for r in db_rides])
    new_ride_ids = list(returned_ride_ids - stored_ride_ids)
    removed_ride_ids = list(stored_ride_ids - returned_ride_ids)
    
    if rewrite:
        num_rides = len(api_ride_entries)
    else:
        num_rides = len(new_ride_ids)
    
    # If we are "clearing" the system, then we'll just use all the returned rides as the "new" rides.
    
    for (i, ri_entry) in enumerate(api_ride_entries):
        logger.info("Processing ride: {0} ({1}/{2})".format(ri_entry.id, i, num_rides))
        if rewrite or not ri_entry.id in stored_ride_ids:
            ride = data.write_ride(ri_entry.id, team=team)
            logger.debug("Wrote ride: %r" % (ride,))
        else:
            logger.debug("Skipping existing ride: {id} - {name!r}".format(name=ri_entry.name,id=ri_entry.id))

    # Remove any rides that are in the database for this team that were not in the returned list.
    if removed_ride_ids:
        q = sess.query(model.Ride)
        q = q.filter(model.Ride.id.in_(removed_ride_ids))
        deleted = q.delete(synchronize_session=False)
        if team:
            logger.info("Removed {0} no longer present rides for team {1}.".format(deleted, team.id))
        else:
            logger.info("Removed {0} no longer present rides for athlete {1}.".format(deleted, athlete_id))
    else:
        if team:
            logger.info("(No removed rides for team {0!r}.)".format(team))
        else:
            logger.info("(No removed rides for athlete {0}.)".format(athlete_id))
    
    
    sess.commit() 
        
    # Write out any efforts associated with these rides (not already in database)
    q = sess.query(model.Ride).filter_by(efforts_fetched=False)
    for ride in q.all():
        logger.info("Writing out efforts for {0!r}".format(ride))
        data.write_ride_efforts(ride)