예제 #1
0
 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
예제 #2
0
 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
예제 #3
0
    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
예제 #4
0
    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("<<")
예제 #5
0
    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('<<')
예제 #6
0
	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("<<")
예제 #7
0
	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('<<')
예제 #8
0
    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
예제 #9
0
 def __actualize_fromgpx(self, gpxfile, name=None):
     logging.debug('>>')
     gpx = Gpx(self.data_path, gpxfile, name)
     self._actualize_fromgpx(gpx)
     logging.debug('<<')
예제 #10
0
파일: testgpx.py 프로젝트: mjb6/track-db
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)
예제 #11
0
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)
예제 #12
0
	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