File: file_gpxplus.py

package info (click to toggle)
pytrainer 2.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, sid
  • size: 4,876 kB
  • sloc: python: 15,914; perl: 6,084; xml: 195; sql: 151; makefile: 83; sh: 45
file content (127 lines) | stat: -rw-r--r-- 3,980 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# -*- coding: iso-8859-1 -*-

#Copyright (C) Fiz Vazquez vud1@sindominio.net
# Modified by dgranda

#This program is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public License
#as published by the Free Software Foundation; either version 2
#of the License, or (at your option) any later version.

#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.

#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

import logging
import os
import traceback
from lxml import etree
from pytrainer.lib.date import getDateTime
from pytrainer.core.activity import Activity
from sqlalchemy.orm import exc

class gpxplus():
	def __init__(self, parent = None, data_path = None):
		self.parent = parent
		self.pytrainer_main = parent.parent
		self.tmpdir = self.pytrainer_main.profile.tmpdir
		self.main_data_path = data_path
		self.data_path = os.path.dirname(__file__)
		self.xmldoc = None
		self.activitiesSummary = []

	def getXmldoc(self):
		''' Function to return parsed xmlfile '''
		return self.xmldoc

	def getFileType(self):
		return _("GPS eXchange file")

	def getActivitiesSummary(self):
		return self.activitiesSummary

	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 inDatabase(self, tree, startTime):
		#comparing date and start time (sport may have been changed in DB after import)
		time = startTime
		if time is None:
			return False
		time = time[0].strftime("%Y-%m-%dT%H:%M:%SZ")
		try:
			self.parent.parent.ddbb.session.query(Activity).filter(Activity.date_time_utc == time).one()
			return True
		except exc.NoResultFound:
			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 getSport(self, tree):
		#No sport in GPX file
		return None

	def startTimeFromFile(self, tree):
		""" Function to return the first time element from a GPX 1.1 file (skipping not mandatory metadata section) """
		root = tree.getroot()
		timeElement = root.xpath(".//g:time[not(parent::g:metadata)]", namespaces={'g':'http://www.topografix.com/GPX/1/1'})[0]
		if timeElement is not None:
			return timeElement.text
		return None

	def getGPXFile(self, ID, file_id):
		"""
			Generate GPX file based on activity ID

			Returns (sport, GPX filename)
		"""
		sport = None
		gpxFile = None
		if ID == "0": #Only one activity in file
			gpxFile = "%s/gpx-%s-%s.gpx" % (self.tmpdir, file_id, ID)
			sport = self.getSport(self.xmldoc)
			self.createGPXfile(gpxFile, self.xmldoc)
		return sport, gpxFile

	def createGPXfile(self, gpxfile, tree):
		tree.write(gpxfile, xml_declaration=True, encoding='UTF-8')