def testFile(self, filename): logging.debug('>>') logging.debug("Testing " + filename) try: #parse filename as xml xmldoc = etree.parse(filename) #Parse XML schema xmlschema_doc = etree.parse(self.main_data_path+"schemas/GarminTrainingCenterDatabase_v1-gpsbabel.xsd") xmlschema = etree.XMLSchema(xmlschema_doc) if (xmlschema.validate(xmldoc)): #Valid file self.xmldoc = xmldoc #Possibly multiple entries in file self.activities = self.getActivities(xmldoc) for (sport, activities) in self.activities: logging.debug("Found %d tracks for %s sport in %s" % (len(activities), sport, filename)) for activity in activities: startTime = getDateTime(self.getStartTimeFromActivity(activity)) inDatabase = self.inDatabase(activity, startTime) duration = self.getDetails(activity, startTime) distance = "" index = "%d:%d" % (self.activities.index((sport, activities)), activities.index(activity)) self.activitiesSummary.append( (index, inDatabase, startTime[1].strftime("%Y-%m-%dT%H:%M:%S"), distance , str(duration), sport, ) ) #print self.activitiesSummary return True except: #Not valid file return False return False
def testFile(self, filename): logging.debug('>>') logging.debug("Testing " + filename) #Check if file is a GPX try: #parse as xml xmldoc = etree.parse(filename) #Parse XML schema xmlschema_doc = etree.parse(self.main_data_path + "schemas/Topografix_gpx11-Nokia.xsd") xmlschema = etree.XMLSchema(xmlschema_doc) if (xmlschema.validate(xmldoc)): #Valid gpx file self.xmldoc = xmldoc startTime = getDateTime(self.startTimeFromFile(xmldoc)) indatabase = self.inDatabase(xmldoc, startTime) sport = self.getSport(xmldoc) duration = self.getDetails(xmldoc, startTime) distance = "" self.activitiesSummary.append(( 0, indatabase, startTime[1].strftime("%Y-%m-%dT%H:%M:%S"), distance, str(duration), sport, )) return True except: #Not gpx file return False return False
def testFile(self, filename): logging.debug('>>') logging.debug("Testing " + filename) #Check if file is a garmintools dump try: with open(filename, 'r') as f: xmlString = f.read() #add a root element to make correct xml fileString = BytesIO(b"<root>" + xmlString + b"</root>") #parse string as xml xmldoc = etree.parse(fileString) #Parse XML schema xmlschema_doc = etree.parse(self.main_data_path+"schemas/garmintools.xsd") xmlschema = etree.XMLSchema(xmlschema_doc) if (xmlschema.validate(xmldoc)): #Valid garmintools file self.xmldoc = xmldoc startTime = getDateTime(self.startTimeFromFile(xmldoc)) indatabase = self.inDatabase(xmldoc, startTime) sport = self.getSport(xmldoc) distance, duration = self.getDetails(xmldoc, startTime) distance = distance / 1000.0 self.activitiesSummary.append( (0, indatabase, startTime[1].strftime("%Y-%m-%dT%H:%M:%S"), "%0.2f" % distance , str(duration), sport, ) ) return True except: #Not garmintools dump file return False return False
def testFile(self, filename): logging.debug('>>') logging.debug("Testing " + filename) #Check if file is a GPX try: #parse as xml xmldoc = etree.parse(filename) #Parse XML schema xmlschema_doc = etree.parse(self.main_data_path+"schemas/Topografix_gpx11.xsd") xmlschema = etree.XMLSchema(xmlschema_doc) if (xmlschema.validate(xmldoc)): #Valid gpx file self.xmldoc = xmldoc startTime = getDateTime(self.startTimeFromFile(xmldoc)) indatabase = self.inDatabase(xmldoc, startTime) sport = self.getSport(xmldoc) duration = self.getDetails(xmldoc, startTime) distance = "" self.activitiesSummary.append( (0, indatabase, startTime[1].strftime("%Y-%m-%dT%H:%M:%S"), distance , str(duration), sport, ) ) return True except: #Not gpx file logging.debug("Traceback: %s" % traceback.format_exc()) return False return False
def test_getDateTime(self): utctime, localtime = getDateTime('Tue Nov 24 17:29:05 UTC 2015') self.assertEqual( datetime.datetime(2015, 11, 24, 17, 29, 5, tzinfo=tzutc()), utctime) self.assertEqual( datetime.datetime(2015, 11, 24, 19, 29, 5, tzinfo=tzlocal()), localtime)
def getDetails(self, activity, startTime): logging.debug(">>") distance = 0 duration = 0 laps = activity.findall( ".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}Lap" ) if laps: for lap in laps: lap_duration = float( lap.findtext( ".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}TotalTimeSeconds" )) lap_distance = float( lap.findtext( ".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}DistanceMeters" )) logging.debug("Lap distance (m): %f | duration (s): %f" % (lap_distance, lap_duration)) distance += lap_distance duration += lap_duration hours = int(duration) // 3600 minutes = (int(duration) / 60) % 60 seconds = int(duration) % 60 duration_hhmmss = "%02d:%02d:%02d" % (hours, minutes, seconds) logging.debug( "Activity distance (m): %f | duration (hh:mm:ss - s): %s - %f" % (distance, duration_hhmmss, duration)) else: points = activity.findall( ".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}Trackpoint" ) while True: lastPoint = points[-1] try: distance = lastPoint.find( ".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}DistanceMeters" ) if distance is None: points = points[:-1] continue time = lastPoint.find( ".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}Time" ) distance = distance.text time = time.text break except: #Try again without the last point (i.e work from end until find time and distance) points = points[:-1] continue duration_hhmmss = getDateTime(time)[0] - startTime[0] logging.debug( "Activity distance (m): %s | duration (hh:mm:ss): %s" % (distance, duration_hhmmss)) logging.debug("<<") return float(distance), duration_hhmmss
def getDetails(self, activity, startTime): points = activity.findall(".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v1}Trackpoint") while True: lastPoint = points[-1] try: time = lastPoint.find(".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v1}Time") time = time.text break except: #Try again without the last point (i.e work from end until find time) points = points[:-1] continue return getDateTime(time)[0]-startTime[0]
def buildActivitiesSummary(self): self.activities = self.getActivities() for activity in self.activities: startTime = getDateTime(self.getStartTimeFromActivity(activity)) inDatabase = self.inDatabase(startTime) sport = self.getSport(activity) distance, duration = self.getDetails(activity, startTime) distance = distance / 1000.0 self.activitiesSummary.append((self.activities.index(activity), inDatabase, startTime[1].strftime("%Y-%m-%dT%H:%M:%S"), "%0.2f" % distance , str(duration), sport, ))
def getDetails(self, tree, startTime): root = tree.getroot() points = root.findall(".//point") while True: lastPoint = points[-1] try: distance = lastPoint.get("distance") if distance is None: points = points[:-1] continue time = lastPoint.get("time") break except: points = points[:-1] continue return float(distance), getDateTime(time)[0] - startTime[0]
def getDetails(self, tree, startTime): root = tree.getroot() points = root.findall(".//point") while True: lastPoint = points[-1] try: distance = lastPoint.get("distance") if distance is None: points = points[:-1] continue time = lastPoint.get("time") break except: points = points[:-1] continue return float(distance), getDateTime(time)[0]-startTime[0]
def getDetails(self, activity, startTime): points = activity.findall( ".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v1}Trackpoint" ) while True: lastPoint = points[-1] try: time = lastPoint.find( ".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v1}Time" ) time = time.text break except: #Try again without the last point (i.e work from end until find time) points = points[:-1] continue return getDateTime(time)[0] - startTime[0]
def testFile(self, filename): logging.debug('>>') logging.debug("Testing " + filename) try: #parse filename as xml xmldoc = etree.parse(filename) #Parse XML schema xmlschema_doc = etree.parse( self.main_data_path + "schemas/GarminTrainingCenterDatabase_v1-gpsbabel.xsd") xmlschema = etree.XMLSchema(xmlschema_doc) if (xmlschema.validate(xmldoc)): #Valid file self.xmldoc = xmldoc #Possibly multiple entries in file self.activities = self.getActivities(xmldoc) for (sport, activities) in self.activities: logging.debug("Found %d tracks for %s sport in %s" % (len(activities), sport, filename)) for activity in activities: startTime = getDateTime( self.getStartTimeFromActivity(activity)) inDatabase = self.inDatabase(activity, startTime) duration = self.getDetails(activity, startTime) distance = "" index = "%d:%d" % (self.activities.index( (sport, activities)), activities.index(activity)) self.activitiesSummary.append(( index, inDatabase, startTime[1].strftime("%Y-%m-%dT%H:%M:%S"), distance, str(duration), sport, )) #print self.activitiesSummary return True except: #Not valid file return False return False
def getDetails(self, activity, startTime): logging.debug(">>") distance = 0 duration = 0 laps = activity.findall(".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}Lap") if laps: for lap in laps: lap_duration = float(lap.findtext(".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}TotalTimeSeconds")) lap_distance = float(lap.findtext(".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}DistanceMeters")) logging.debug("Lap distance (m): %f | duration (s): %f" % (lap_distance, lap_duration)) distance += lap_distance duration += lap_duration hours = int(duration)//3600 minutes = (int(duration)/60)%60 seconds = int(duration)%60 duration_hhmmss = "%02d:%02d:%02d" % (hours, minutes, seconds) logging.debug("Activity distance (m): %f | duration (hh:mm:ss - s): %s - %f" % (distance, duration_hhmmss, duration)) else: points = activity.findall(".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}Trackpoint") while True: lastPoint = points[-1] try: distance = lastPoint.find(".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}DistanceMeters") if distance is None: points = points[:-1] continue time = lastPoint.find(".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}Time") distance = distance.text time = time.text break except: #Try again without the last point (i.e work from end until find time and distance) points = points[:-1] continue duration_hhmmss = getDateTime(time)[0]-startTime[0] logging.debug("Activity distance (m): %s | duration (hh:mm:ss): %s" % (distance, duration_hhmmss)) logging.debug("<<") return float(distance), duration_hhmmss
def testFile(self, filename): logging.debug('>>') logging.debug("Testing " + filename) #Check if file is a garmintools dump try: with open(filename, 'r') as f: xmlString = f.read() #add a root element to make correct xml fileString = BytesIO(b"<root>" + xmlString + b"</root>") #parse string as xml xmldoc = etree.parse(fileString) #Parse XML schema xmlschema_doc = etree.parse(self.main_data_path + "schemas/garmintools.xsd") xmlschema = etree.XMLSchema(xmlschema_doc) if (xmlschema.validate(xmldoc)): #Valid garmintools file self.xmldoc = xmldoc startTime = getDateTime(self.startTimeFromFile(xmldoc)) indatabase = self.inDatabase(xmldoc, startTime) sport = self.getSport(xmldoc) distance, duration = self.getDetails(xmldoc, startTime) distance = distance / 1000.0 self.activitiesSummary.append(( 0, indatabase, startTime[1].strftime("%Y-%m-%dT%H:%M:%S"), "%0.2f" % distance, str(duration), sport, )) return True except: #Not garmintools dump file return False return False
def getDetails(self, tree, startTime): root = tree.getroot() #Get all times from file times = root.findall(".//{http://www.topografix.com/GPX/1/1}time") time = times[-1].text return getDateTime(time)[0] - startTime[0]
def on_buttonCSVImport_clicked(self, widget): logging.debug('>>') #Determine values dateCol = self.cbCSVDate.get_active() distanceCol = self.cbCSVDistance.get_active() durationCol = self.cbCSVDuration.get_active() titleCol = self.cbCSVTitle.get_active() sportCol = self.cbCSVSport.get_active() avgspeedCol = self.cbCSVAvgSpeed.get_active() maxspeedCol = self.cbCSVMaxSpeed.get_active() calCol = self.cbCSVCal.get_active() accCol = self.cbCSVAccent.get_active() desCol = self.cbCSVDescent.get_active() hrCol = self.cbCSVHR.get_active() maxHRCol = self.cbCSVMaxHR.get_active() paceCol = self.cbCSVPace.get_active() maxPaceCol = self.cbCSVMaxPace.get_active() commentsCol = self.cbCSVComments.get_active() if dateCol == 0: #Error need to have at least a date self.updateStatusbar( self.statusbarCSVImport, _("ERROR: Must define at least a date column")) return #Import... #Get selected file if not os.path.isfile(self.CSVfilename): return #Read as delimited file csvfile = open(self.CSVfilename, 'rb') reader = csv.reader(csvfile, delimiter=self.delimiter) #Process File for i, row in enumerate(reader): if self.has_header and i == 0: #Ignore first row continue if not row: continue data = Activity() #Determine dates _date = getDateTime(row[dateCol - 1]) #year, month, day = date.split("-") date = _date[1].strftime("%Y-%m-%d") zuluDateTime = _date[0].strftime("%Y-%m-%dT%H:%M:%SZ") localDateTime = str(_date[1]) data.date = _date[1].date() data.date_time_utc = zuluDateTime data.date_time_local = localDateTime if distanceCol: try: data.distance = locale.atof(row[distanceCol - 1]) except: data.distance = 0 else: data.distance = 0 if durationCol: #calculate duration in sec... try: _duration = row[durationCol - 1] except: _duration = 0 if _duration.count(':') == 2: #Have 00:00:00 duration h, m, s = _duration.split(':') try: durationSec = int(h) * 3600 + int(m) * 60 + int(s) except: logging.debug("Error calculating duration for '%s'" % _duration) durationSec = None else: try: durationSec = locale.atoi(_duration) except: #Unknown duration logging.debug("Could not determine duration for '%s'" % _duration) durationSec = None if durationSec is not None: data.duration = durationSec data.time = str(durationSec) if titleCol: try: data.title = row[titleCol - 1] except: pass if self.checkbCSVForceSport.get_active(): sport = self.pytrainer_main.record.getSport(gtk_str( self.comboCSVForceSport.get_active_text()), add=True) data.sport = sport elif sportCol: #retrieving sport id (adding sport if it doesn't exist yet) sport = self.pytrainer_main.record.getSport(row[sportCol - 1], add=True) data.sport = sport else: self.comboCSVForceSport.set_active(0) sport = self.pytrainer_main.record.getSport(gtk_str( self.comboCSVForceSport.get_active_text()), add=True) data.sport = sport if avgspeedCol: # try: data.average = locale.atof(row[avgspeedCol - 1]) except: pass if maxspeedCol: try: data.maxspeed = locale.atof(row[maxspeedCol - 1]) except: pass if calCol: try: data.calories = locale.atoi(row[calCol - 1]) except: pass if accCol: try: data.upositive = locale.atof(row[accCol - 1]) except: pass if desCol: try: data.unegative = locale.atof(row[desCol - 1]) except: pass if hrCol: try: data.beats = locale.atof(row[hrCol - 1]) except: pass if maxHRCol: try: data.maxbeats = locale.atof(row[maxHRCol - 1]) except: pass if paceCol: try: data.pace = locale.atof(row[paceCol - 1]) except: pass if maxPaceCol: try: data.maxpace = locale.atof(row[maxPaceCol - 1]) except: pass if commentsCol: try: data.comments = row[commentsCol - -1] except: pass #Insert into DB self.pytrainer_main.ddbb.session.add(data) self.pytrainer_main.ddbb.session.commit() #Display message.... self.updateStatusbar(self.statusbarCSVImport, _("Import completed. %d rows processed") % i) #Disable import button self.buttonCSVImport.set_sensitive(0) logging.debug('<<')
def test_getDateTime(self): utctime, localtime = getDateTime('Tue Nov 24 17:29:05 UTC 2015') self.assertEqual(datetime.datetime(2015, 11, 24, 17, 29, 5, tzinfo=tzutc()), utctime) self.assertEqual(datetime.datetime(2015, 11, 24, 19, 29, 5, tzinfo=tzlocal()), localtime)
def getDetails(self, tree, startTime): root = tree.getroot() #Get all times from file times = root.findall(".//{http://www.topografix.com/GPX/1/1}time") time = times[-1].text return getDateTime(time)[0]-startTime[0]