7 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
11 from urllib.parse import quote,unquote
12 from lxml import html,etree
13 from optparse import OptionParser
14 from datetime import date,datetime
15 from dateutil.parser import isoparse
16 from pyrungps.parsegpx import write_parsed_to_db,check_db_for_training
17 from pyrungps.pygpx import GPX
18 from io import BytesIO
20 from tempfile import NamedTemporaryFile
22 from pprint import pprint
24 from pyrungps.render_tiles import queue_render
26 from pyrungps.generate_image import render_all
28 def get_page(uname,year,month):
32 req = requests.get("http://www.gps-sport.net/services/getMonthlyTrainingDataHTML_V2.jsp?userName=%s&year=%s&month=%s&rnd=0.645673"% (uname,year,month), headers = {'User-agent': 'Mozilla/5.0'}, verify=False)
33 page = req.text.encode('utf-8')
34 dom = html.document_fromstring(page)
36 for element, attribute, link, pos in dom.iterlinks():
37 if attribute == "href":
38 if link.startswith("/trainings/"):
39 dummy, dummy, link = link.split('/')
40 name, *ids = link.split('_')
42 trainings.append([ unquote(name), id ])
46 def get_gpx_track(trid,name):
50 req = requests.get("http://www.gps-sport.net/services/trainingGPX.jsp?trainingID=%s&tz=-180" % (trid), verify=False)
52 xml = etree.fromstring(req.text.encode('utf-8'))
56 def get_osm_list(username,password,year,month):
58 url = "https://www.openstreetmap.org/api/0.6/user/gpx_files"
60 req = requests.get(url,auth=(username,password))
62 xml = etree.fromstring(req.text.encode('utf-8'))
67 attrib = dict(gpx_file.attrib)
69 timestamp=datetime.fromtimestamp(isoparse(attrib['timestamp']))
72 for descr in gpx_file.iter('description'):
73 description=descr.text
75 for tag in gpx_file.iter('tag'):
77 if timestamp.year==year and timestamp.month==month and description=='Run.GPS Track':
78 record={ 'id': id, 'sport': sport }
85 def get_osm_gpx(username,password,track_id):
87 url = "https://www.openstreetmap.org/api/0.6/gpx/"+track_id+"/data"
89 req = requests.get(url,auth=(username,password))
90 xml = etree.fromstring(req.text.encode('utf-8'))
94 def get_db_gpx(dbx,track_id):
96 md, res = dbx.files_download(track_id)
98 fs = NamedTemporaryFile(suffix='.tcx',delete = False)
100 fs.write(res.content)
102 fs = NamedTemporaryFile(suffix='.gpx',delete = False)
106 os.system("gpsbabel -i gtrnctr -f "+tmp_tcx_name+" -o gpx -F "+tmp_gpx_name)
108 with open (tmp_gpx_name, "r") as gpxfile:
111 os.remove(tmp_gpx_name)
112 os.remove(tmp_tcx_name)
114 xml = etree.fromstring(data.encode('utf-8'))
117 def get_dbx_list(dbx,username,year,month):
121 for entry in dbx.files_list_folder('').entries:
122 if entry.name == u'Приложения':
123 for entry_app in dbx.files_list_folder(entry.id).entries:
124 if entry_app.name == u'Run.GPS':
125 print("id="+entry_app.id)
126 gpx_list_id=entry_app.id
134 for file in dbx.files_list_folder(gpx_list_id).entries:
136 filename,ext = os.path.splitext(file.name)
139 fyear = int(filename[0:4])
140 fmonth = int(filename[5:7])
141 if fyear == year and fmonth == month:
142 sport = filename[41:]
143 timestamp = datetime.strptime(filename[0:19],'%Y-%m-%dT%H_%M_%S')
144 record={ 'id': file.id, 'timestamp': timestamp, 'sport': sport }
148 fyear = int(filename[0:4])
149 fmonth = int(filename[5:7])
150 if fyear == year and fmonth == month:
151 sport = filename[18:]
152 timestamp = datetime.strptime(filename[0:16],'%Y-%m-%d_%H%M%S')
153 record={ 'id': file.id, 'timestamp': timestamp, 'sport': sport }
161 def sync_db(dbx,username,year,month,dir=".",verbose=False,force=False):
163 training_list = get_dbx_list(dbx,username,year,month)
165 for training in training_list:
167 filename = "%s/%04d/%02d/%s_%s.gpx" % (dir,year,month,training['sport'],training['id'][3:])
168 dirname = "%s/%04d/%02d" % (dir,year,month)
170 if os.path.exists(filename) and not force:
173 print("training %s exists, skipping" % (filename))
182 xml = get_db_gpx(dbx,training['id'])
185 print("writing training %s" % (filename))
190 sport = training['sport']
191 timestamp = gpx.tracks[0].start_time()
194 print("Empty training found, skipping...")
197 print(sport, timestamp)
199 if check_db_for_training(db,sport,timestamp):
200 print("The same training found")
203 gpx.author = username
204 gpx.FixNames(training['sport'])
205 gpx.ProcessTrackSegs()
206 for track in gpx.tracks:
207 track.sport=training['sport']
210 f = open(filename,"wb")
211 f.write(etree.tostring(xml,encoding='UTF-8',pretty_print=True))
213 write_parsed_to_db(db,gpx,filename)
215 queue_render(db,filename)
220 def sync_osm(username,password,year,month,dir=".",verbose=False,force=False):
222 training_list = get_osm_list(username,password,year,month)
224 for training in training_list:
226 filename = "%s/%04d/%02d/%s_%s.gpx" % (dir,year,month,training['sport'],training['id'])
227 dirname = "%s/%04d/%02d" % (dir,year,month)
229 if os.path.exists(filename) and not force:
232 print("training %s exists, skipping" % (filename))
241 xml = get_osm_gpx(username,password,training['id'])
244 print("writing training %s" % (filename))
249 sport = training['sport']
250 timestamp = gpx.tracks[0].start_time()
252 if check_db_for_training(db,sport,timestamp):
253 print("The same training found")
256 gpx.author = username
257 gpx.FixNames(training['sport'])
258 gpx.ProcessTrackSegs()
259 for track in gpx.tracks:
260 track.sport=training['sport']
263 f = open(filename,"wb")
264 f.write(etree.tostring(xml,encoding='UTF-8',pretty_print=True))
266 write_parsed_to_db(db,gpx,filename)
268 queue_render(db,filename)
272 def sync_folder(username,year,month,dir=".",verbose=False,force=False):
274 training_list = get_page(username,year,month)
275 for tr in training_list:
278 filename = "%s/%04d/%02d/%s_%s.gpx" % (dir,year,(month+1),tr[0],tr[1])
279 dirname = "%s/%04d/%02d" % (dir,year,(month+1))
281 if os.path.exists(filename) and not force:
284 print("training %s exists, skipping" % (filename))
293 xml=get_gpx_track(tr[1],tr[0])
296 print("writing training %s" % (filename))
302 timestamp = gpx.tracks[0].start_time()
304 if check_db_for_training(db,sport,timestamp):
305 print("The same training found")
309 gpx.ProcessTrackSegs()
312 f = open(filename,"wb")
313 f.write(etree.tostring(xml,encoding='UTF-8',pretty_print=True))
315 write_parsed_to_db(db,gpx,filename)
317 queue_render(db,filename)
327 parser = OptionParser()
328 parser.add_option("-d", "--dir", dest="dirname",
329 help="write data to directory", metavar="DIR")
330 parser.add_option("-q", "--quiet",
331 action="store_false", dest="verbose", default=True,
332 help="don't print status messages to stdout")
333 parser.add_option("-f", "--force",
334 action="store_true", dest="force", default=False,
335 help="rewrite all files")
336 parser.add_option("-y", "--yearmonth", dest="yearmonth",
337 help="year and month in YYYY-MM format", metavar="YYYY-MM")
338 parser.add_option("-u", "--username", dest="username",
339 help="Run.GPS username")
340 parser.add_option("-o", "--osm-username", dest="osmname",
341 help="OpenStreetMap username")
342 parser.add_option("-p", "--osm-passwd", dest="osmpasswd",
343 help="OpenStreetMap password")
344 parser.add_option("-b", "--dropbox", dest="dropboxauth",
345 help="DropBox Auth token")
346 (options, args) = parser.parse_args()
348 username = options.username
349 osmname = options.osmname
350 osmpwd = options.osmpasswd
351 dbauth = options.dropboxauth
352 if not (username or (osmname and osmpwd) or dbauth):
353 print("Run.GPS username or OSM username/password or Dropbox Auth token is mandatory!")
357 pusername = username+'@Run.GPS'
359 pusername = osmname+'@OSM'
362 dbx = dropbox.Dropbox(dbauth)
363 pusername = dbx.users_get_current_account().email+'@DBX'
366 if options.yearmonth:
367 year,month = options.yearmonth.split('-')
368 month = int(month) -1
370 if month<0 or month>11:
376 print("Year and month should be in YYYY-MM format!")
380 outdir = options.dirname
384 db = outdir + '/gpx.db'
388 print("retrieving trainings for user %s, year %s, month %s to %s" % (pusername,year,month+1,outdir))
390 sync_folder(username,year,month,outdir,options.verbose,options.force)
392 sync_osm(osmname,osmpwd,year,month+1,outdir,options.verbose,options.force)
394 sync_db(dbx,pusername,year,month+1,outdir,options.verbose,options.force)
397 print("retrieving two last months for user %s to %s" % (pusername ,outdir))
399 current_year = now.year
400 current_month = now.month
402 sync_folder(username,current_year,current_month-1,outdir,options.verbose,options.force)
404 sync_osm(osmname,osmpwd,current_year,current_month,outdir,options.verbose,options.force)
406 sync_db(dbx,pusername,current_year,current_month,outdir,options.verbose,options.force)
407 current_month = current_month -1
408 if current_month == 0:
410 current_year = current_year -1
412 sync_folder(username,current_year,current_month-1,outdir,options.verbose,options.force)
414 sync_osm(osmname,osmpwd,current_year,current_month,outdir,options.verbose,options.force)
416 sync_db(dbx,pusername,current_year,current_month,outdir,options.verbose,options.force)
418 render_all(db,'/etc/mapnik-osm-carto-data/veloroad-imposm.xml',640,640)
420 if __name__ == "__main__":