def insertRecord(self, list_options, laps=None, equipment=None): logging.debug('>>') #Create entry for activity in records table if list_options is None: logging.info('No data provided, abort adding entry') return None logging.debug('list_options: ' + str(list_options)) record = self._formatRecordNew(list_options, Activity()) self.pytrainer_main.ddbb.session.add(record) id_record = record.id gpxOrig = list_options["rcd_gpxfile"] # Load laps from gpx if not provided by the caller if laps is None and os.path.isfile(gpxOrig): gpx = Gpx(self.data_path, gpxOrig) laps = self.lapsFromGPX(gpx) #Create entry(s) for activity in laps table if laps is not None: for lap in laps: new_lap = Lap(**lap) record.Laps.append(new_lap) if equipment: record.equipment = self.pytrainer_main.ddbb.session.query( Equipment).filter(Equipment.id.in_(equipment)).all() self.pytrainer_main.ddbb.session.commit() if os.path.isfile(gpxOrig): gpxDest = self.pytrainer_main.profile.gpxdir gpxNew = gpxDest + "/%d.gpx" % id_record #Leave original file in place... #shutil.move(gpxOrig, gpxNew) #logging.debug('Moving '+gpxOrig+' to '+gpxNew) shutil.copy(gpxOrig, gpxNew) logging.debug('Copying ' + gpxOrig + ' to ' + gpxNew) logging.debug('<<') return record.id
def getLaps(self, id_record): logging.debug('--') laps = self.pytrainer_main.ddbb.select( "laps", "id_lap, record, elapsed_time, distance, start_lat, start_lon, end_lat, end_lon, calories, lap_number, intensity, max_speed, avg_hr, max_hr, laptrigger, comments", "record=\"%s\"" % id_record) if laps is None or laps == []: #No laps stored - update DB logging.debug("No laps in DB for record %d" % id_record) #print ("No laps in DB for record %d" % id_record) gpx_dest = self.pytrainer_main.profile.gpxdir gpxfile = gpx_dest + "/%d.gpx" % id_record gpx = Gpx(self.data_path, gpxfile) laps = self.lapsFromGPX(gpx) if laps is not None: for lap in laps: lap['record'] = id_record #Add reference to entry in record table lap_keys = ", ".join(map(str, lap.keys())) lap_values = lap.values() self.insertLaps(lap_keys, lap.values()) #Try to get lap info again #TODO? refactor laps = self.pytrainer_main.ddbb.select( "laps", "id_lap, record, elapsed_time, distance, start_lat, start_lon, end_lat, end_lon, calories, lap_number, intensity, max_speed, avg_hr, max_hr, laptrigger, comments", "record=\"%s\"" % id_record) return laps
def summaryFromGPX(self, gpxOrig, entry): """29.03.2008 - dgranda Retrieves info which will be stored in DB from GPX file args: path to source GPX file returns: list with fields and values, list of laps """ logging.debug('>>') gpx = Gpx(self.data_path, gpxOrig) distance, time, maxspeed, maxheartrate = gpx.getMaxValues() #if time == 0: #invalid record # print "Invalid record" # return (None, None) upositive, unegative = gpx.getUnevenness() if time > 0: speed = distance * 3600 / time time_hhmmss = [time // 3600, (time / 60) % 60, time % 60] else: speed = 0 time_hhmmss = [0, 0, 0] summaryRecord = {} summaryRecord['rcd_gpxfile'] = gpxOrig summaryRecord['rcd_sport'] = entry[0] summaryRecord['rcd_date'] = gpx.getDate() summaryRecord['rcd_calories'] = gpx.getCalories() summaryRecord['rcd_comments'] = '' summaryRecord['rcd_title'] = '' summaryRecord[ 'rcd_time'] = time_hhmmss #ToDo: makes no sense to work with arrays summaryRecord['rcd_distance'] = "%0.2f" % distance if speed == 0: summaryRecord['rcd_pace'] = "0" else: summaryRecord['rcd_pace'] = "%d.%02d" % ((3600 / speed) / 60, (3600 / speed) % 60) if maxspeed == 0: summaryRecord['rcd_maxpace'] = "0" else: summaryRecord['rcd_maxpace'] = "%d.%02d" % ((3600 / maxspeed) / 60, (3600 / maxspeed) % 60) summaryRecord['rcd_average'] = speed summaryRecord['rcd_maxvel'] = maxspeed summaryRecord['rcd_beats'] = gpx.getHeartRateAverage() summaryRecord['rcd_maxbeats'] = maxheartrate summaryRecord['rcd_upositive'] = upositive summaryRecord['rcd_unegative'] = unegative if entry[ 1] == "": # coming from new track dialog (file opening) #TODO This if-else needs checking summaryRecord['date_time_utc'], summaryRecord[ 'date_time_local'] = gpx.getStartTimeFromGPX(gpxOrig) # else: # coming from GPS device # summaryRecord['date_time_utc'] = entry[1] # summaryRecord['date_time_local'] = entry[1] # print "#TODO fix record summaryRecord local and utc time..." # logging.debug('summary: ' + str(summaryRecord)) laps = self.lapsFromGPX(gpx) logging.debug('<<') return summaryRecord, laps
def actualize_fromgpx(self, gpxfile): logging.debug(">>") from lib.gpx import Gpx gpx = Gpx(self.data_path, gpxfile) tracks = gpx.getTrackRoutes() if len(tracks) > 1: time = unixtime2date(tracks[0][1]) self.recordwindow.rcd_date.set_text(time) self._actualize_fromgpx(gpx) else: msg = _( "The gpx file seems to be a several days records. Perhaps you will need to edit your gpx file" ) from gui.warning import Warning warning = Warning(self.data_path, self._actualize_fromgpx, [gpx]) warning.set_text(msg) warning.run() logging.debug("<<")
def actualize_fromgpx(self,gpxfile): #TODO remove? - should never have multiple tracks per GPX file logging.debug('>>') logging.debug('loading file: '+gpxfile) gpx = Gpx(self.data_path,gpxfile) tracks = gpx.getTrackRoutes() if len(tracks) == 1: logging.debug('Just 1 track') self._actualize_fromgpx(gpx) elif len(tracks) > 1: logging.debug('Found '+str(len(tracks))+' tracks') self._select_trkfromgpx(gpxfile,tracks) else: msg = _("pytrainer can't import data from your gpx file") from gui.warning import Warning warning = Warning(self.data_path) warning.set_text(msg) warning.run() logging.debug('<<')
def actualize_fromgpx(self,gpxfile): logging.debug(">>") #self.pytrainer_main.ddbb.connect() from lib.gpx import Gpx gpx = Gpx(self.data_path,gpxfile) tracks = gpx.getTrackRoutes() if len(tracks) > 1: time = self.date.unixtime2date(tracks[0][1]) self.recordwindow.rcd_date.set_text(time) self._actualize_fromgpx(gpx) else: msg = _("The gpx file seems to be a several days records. Perhaps you will need to edit your gpx file") from gui.warning import Warning warning = Warning(self.data_path,self._actualize_fromgpx,[gpx]) warning.set_text(msg) warning.run() #self.pytrainer_main.ddbb.disconnect() logging.debug("<<")
def summaryFromGPX(self, gpxOrig, entry): """29.03.2008 - dgranda Retrieves info which will be stored in DB from GPX file args: path to source GPX file returns: list with fields and values, list of laps """ logging.debug(">>") gpx = Gpx(self.data_path, gpxOrig) distance, time, maxspeed, maxheartrate = gpx.getMaxValues() # if time == 0: #invalid record # print "Invalid record" # return (None, None) upositive, unegative = gpx.getUnevenness() if time > 0: speed = distance * 3600 / time time_hhmmss = [time // 3600, (time / 60) % 60, time % 60] else: speed = 0 time_hhmmss = [0, 0, 0] summaryRecord = {} summaryRecord["rcd_gpxfile"] = gpxOrig summaryRecord["rcd_sport"] = entry[0] summaryRecord["rcd_date"] = gpx.getDate() summaryRecord["rcd_calories"] = gpx.getCalories() summaryRecord["rcd_comments"] = "" summaryRecord["rcd_title"] = "" summaryRecord["rcd_time"] = time_hhmmss # ToDo: makes no sense to work with arrays summaryRecord["rcd_distance"] = "%0.2f" % distance if speed == 0: summaryRecord["rcd_pace"] = "0" else: summaryRecord["rcd_pace"] = "%d.%02d" % ((3600 / speed) / 60, (3600 / speed) % 60) if maxspeed == 0: summaryRecord["rcd_maxpace"] = "0" else: summaryRecord["rcd_maxpace"] = "%d.%02d" % ((3600 / maxspeed) / 60, (3600 / maxspeed) % 60) summaryRecord["rcd_average"] = speed summaryRecord["rcd_maxvel"] = maxspeed summaryRecord["rcd_beats"] = gpx.getHeartRateAverage() summaryRecord["rcd_maxbeats"] = maxheartrate summaryRecord["rcd_upositive"] = upositive summaryRecord["rcd_unegative"] = unegative if entry[1] == "": # coming from new track dialog (file opening) #TODO This if-else needs checking summaryRecord["date_time_utc"], summaryRecord["date_time_local"] = gpx.getStartTimeFromGPX(gpxOrig) # else: # coming from GPS device # summaryRecord["date_time_utc"] = entry[1] # summaryRecord["date_time_local"] = entry[1] # print "#TODO fix record summaryRecord local and utc time..." # logging.debug("summary: " + str(summaryRecord)) laps = self.lapsFromGPX(gpx) logging.debug("<<") return summaryRecord, laps
def __actualize_fromgpx(self, gpxfile, name=None): logging.debug('>>') gpx = Gpx(self.data_path, gpxfile, name) self._actualize_fromgpx(gpx) logging.debug('<<')
import os from lib.gpx import Gpx #gpx = Gpx("ok.gpx") gpx = Gpx("rr.gpx") #gpx = Gpx("laufen.gpx") #gpx = Gpx("test/integration/valid.gpx") data = gpx.process(force=True) a = gpx.geo_data print(data)
def add(): tags = Tag.select(Tag.value).distinct() #pylint: disable=E1111 if request.method == "POST": # Validate uploaded file if 'gpx-file' not in request.files: flash("No file uploaded", "error") return redirect(request.url) gpx_file = request.files['gpx-file'] if gpx_file.filename == '': flash("No file selected", "error") return redirect(request.url) if not allowed_file(gpx_file.filename): flash("Only .gpx files supported!", "error") return redirect(request.url) # Store gpx file in filesystem gpx_filename = secure_filename(gpx_file.filename) gpx_filename = "%s_%s.gpx" % ( gpx_filename[:-4], int( datetime.now().timestamp())) # add timestamp to filename gpx_fspath = os.path.join(UPLOAD_BASE_DIR, UPLOAD_DIR, gpx_filename) os.makedirs(os.path.dirname(gpx_fspath), exist_ok=True) gpx_file.save(gpx_fspath) try: # Use gpx library to extract meta information from gpx file gpx = Gpx(gpx_fspath, True) gpx_metadata = gpx.process( force=True) # TODO: improve gpx lib and set force to False # Read form values: tags and name track_name = request.form.get( "name") or "Unnamend activity on %s" % gpx_metadata["date"] tags = request.form.getlist('tag-select') new_tags = request.form.get("new-tags").replace(" ", "") if new_tags != "": tags += new_tags.split(",") tags.append(gpx_metadata["date"][:4]) # implicit add of the year tags = set(tags) # Remove duplicate tags # Create DB ORM objects new_track = Track(name=track_name, date=gpx_metadata["date"], path=os.path.join(UPLOAD_DIR, gpx_filename)) # Read statistics new_track_stats = Statistic( track=new_track, distance_m=gpx_metadata["total_distance"], duration_s=gpx_metadata["duration"], duration_total_s=gpx_metadata["total_duration"], max_speed=gpx_metadata["max_speed"], avg_speed=gpx_metadata["avg_speed"], elevation_up_m=gpx_metadata["total_ascent"], elevation_down_m=gpx_metadata["total_descent"]) except Exception as e: flash("Error during gpx file processing: %s" % e, "error") # Clean up if 'new_track' in locals(): new_track.delete_instance() if 'new_track_stats' in locals(): new_track_stats.delete_instance() os.remove( os.path.join(os.path.dirname(os.path.realpath(__file__)), UPLOAD_BASE_DIR, UPLOAD_DIR, gpx_filename)) return redirect(request.url) # Store objects in DB new_track.save() new_track_stats.save() for tag in tags: my_tag = Tag(track=new_track, value=tag) my_tag.save() flash("Track '%s' added sucessfully." % track_name, "info") return redirect(url_for("show")) else: return render_template("add.html", tags=tags)
def summaryFromGPX(self, gpxOrig, entry): """29.03.2008 - dgranda Retrieves info which will be stored in DB from GPX file args: path to source GPX file returns: list with fields and values, list of laps """ logging.debug('>>') gpx = Gpx(self.data_path,gpxOrig) distance, time, maxspeed, maxheartrate = gpx.getMaxValues() #if time == 0: #invalid record # print "Invalid record" # return (None, None) upositive,unegative = gpx.getUnevenness() if time > 0: speed = distance*3600/time time_hhmmss = [time//3600,(time/60)%60,time%60] else: speed = 0 time_hhmmss = [0,0,0] summaryRecord = {} summaryRecord['rcd_gpxfile'] = gpxOrig summaryRecord['rcd_sport'] = entry[0] summaryRecord['rcd_date'] = gpx.getDate() summaryRecord['rcd_calories'] = gpx.getCalories() summaryRecord['rcd_comments'] = '' summaryRecord['rcd_title'] = '' summaryRecord['rcd_time'] = time_hhmmss #ToDo: makes no sense to work with arrays summaryRecord['rcd_distance'] = "%0.2f" %distance if speed == 0: summaryRecord['rcd_pace'] = "0" else: summaryRecord['rcd_pace'] = "%d.%02d" %((3600/speed)/60,(3600/speed)%60) if maxspeed == 0: summaryRecord['rcd_maxpace'] = "0" else: summaryRecord['rcd_maxpace'] = "%d.%02d" %((3600/maxspeed)/60,(3600/maxspeed)%60) summaryRecord['rcd_average'] = speed summaryRecord['rcd_maxvel'] = maxspeed summaryRecord['rcd_beats'] = gpx.getHeartRateAverage() summaryRecord['rcd_maxbeats'] = maxheartrate summaryRecord['rcd_upositive'] = upositive summaryRecord['rcd_unegative'] = unegative if entry[1]=="": # coming from new track dialog (file opening) #TODO This if-else needs checking summaryRecord['date_time_utc'], summaryRecord['date_time_local'] = gpx.getStartTimeFromGPX(gpxOrig) # else: # coming from GPS device # summaryRecord['date_time_utc'] = entry[1] # summaryRecord['date_time_local'] = entry[1] # print "#TODO fix record summaryRecord local and utc time..." # logging.debug('summary: '+str(summaryRecord)) laps = self.lapsFromGPX(gpx) # Heartrate data can't be retrieved if no trackpoints present, calculating from lap info lap_avg_hr, lap_max_hr = self.hrFromLaps(laps) logging.debug("HR data from laps. Average: %s | Maximum hr: %s" % (lap_avg_hr, lap_max_hr)) if int(summaryRecord['rcd_beats']) > 0: logging.debug("Average heartbeat - Summary: %s | Laps: %s" % (summaryRecord['rcd_beats'], lap_avg_hr)) else: logging.debug("No average heartbeat found, setting value (%s) from laps", lap_avg_hr) summaryRecord['rcd_beats'] = lap_avg_hr if int(summaryRecord['rcd_maxbeats']) > 0: logging.debug("Max heartbeat - Summary: %s | Laps: %s" % (summaryRecord['rcd_maxbeats'], lap_max_hr)) else: logging.debug("No max heartbeat found, setting value (%s) from laps", lap_max_hr) summaryRecord['rcd_maxbeats'] = lap_max_hr logging.debug('<<') return summaryRecord, laps