You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
|
Feb
(1) |
Mar
(15) |
Apr
(20) |
May
(2) |
Jun
(9) |
Jul
(3) |
Aug
(2) |
Sep
(17) |
Oct
(16) |
Nov
(38) |
Dec
(40) |
2010 |
Jan
(51) |
Feb
(11) |
Mar
(24) |
Apr
(31) |
May
(24) |
Jun
(3) |
Jul
(9) |
Aug
(1) |
Sep
(29) |
Oct
(33) |
Nov
(81) |
Dec
(6) |
2011 |
Jan
(2) |
Feb
(4) |
Mar
(13) |
Apr
(4) |
May
(24) |
Jun
(4) |
Jul
(19) |
Aug
(46) |
Sep
(10) |
Oct
(28) |
Nov
(31) |
Dec
|
From: <dg...@us...> - 2011-11-04 18:47:45
|
Revision: 918 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=918&view=rev Author: dgranda Date: 2011-11-04 18:47:39 +0000 (Fri, 04 Nov 2011) Log Message: ----------- Syncing calculations of distance, time, speed and pace - ticket #152 Modified Paths: -------------- pytrainer/trunk/pytrainer/gui/windowrecord.py Modified: pytrainer/trunk/pytrainer/gui/windowrecord.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowrecord.py 2011-11-04 18:44:51 UTC (rev 917) +++ pytrainer/trunk/pytrainer/gui/windowrecord.py 2011-11-04 18:47:39 UTC (rev 918) @@ -19,6 +19,7 @@ from __future__ import division import os import logging +import traceback import gtk, gobject from SimpleGladeApp import SimpleGladeApp from windowcalendar import WindowCalendar @@ -442,13 +443,29 @@ return None def on_calctime_clicked(self,widget): + logging.debug(">>") try: - distance = self.rcd_distance.get_text() - average = self.rcd_average.get_text() - time_in_hour = float(distance)/float(average) + distance = float(self.rcd_distance.get_text()) # distance is mandatory! + # we need either pace or speed + try: + average = float(self.rcd_average.get_text()) + time_in_hour = distance/average + logging.debug("Distance: %0.3f km (mi) | Speed: %0.2f -> Time: %.f hours " %(distance,average,time_in_hour)) + pace = self.parent.pace_from_float(60/average) + logging.debug("Setting pace: %s" %pace) + self.rcd_pace.set_text(pace) + except: + pace_dec = self.parent.pace_to_float(self.rcd_pace.get_text()) + time_in_hour = pace_dec*distance/60.0 + logging.debug("Distance: %0.3f km (mi) | Pace_dec: %0.2f -> Time: %.f hours" %(distance,pace_dec,time_in_hour)) + speed = distance/time_in_hour + logging.debug("Setting average speed: %0.2f" %speed) + self.rcd_average.set_text("%0.2f" %speed) self.set_recordtime(time_in_hour) except: + logging.debug("Traceback: %s" % traceback.format_exc()) pass + logging.debug("<<") def update_activity_data(self, row, gpx_file, sport): self.activity_data[row]["rcd_comments"] = "" @@ -634,7 +651,7 @@ logging.debug("Average pace: %s" %pace) self.rcd_pace.set_text(pace) logging.debug("<<") - + def on_calccalories_clicked(self,widget): sport = self.rcd_sport.get_active_text() hour = self.rcd_hour.get_value_as_int() @@ -660,17 +677,33 @@ self.rcd_calories.set_text(str(calories)) def on_calcdistance_clicked(self,widget): + logging.debug(">>") try: hour = self.rcd_hour.get_value_as_int() min = self.rcd_min.get_value_as_int() sec = self.rcd_second.get_value_as_int() time = sec + (min*60) + (hour*3600) time_in_hour = time/3600.0 - average = float(self.rcd_average.get_text()) - distance = average*time_in_hour + # we need either pace or speed + try: + average = float(self.rcd_average.get_text()) + distance = average*time_in_hour + logging.debug("Time: %d seconds | Speed: %0.2f -> Distance: %0.3f km (mi)" %(time,average,distance)) + pace = self.parent.pace_from_float(60/average) + logging.debug("Setting pace: %s" %pace) + self.rcd_pace.set_text(pace) + except: + pace_dec = self.parent.pace_to_float(self.rcd_pace.get_text()) + distance = time/(60.0*pace_dec) + logging.debug("Time: %d seconds | Pace_dec: %0.2f -> Distance: %0.3f km (mi)" %(time,pace_dec,distance)) + speed = distance/time_in_hour + logging.debug("Setting average speed: %0.2f" %speed) + self.rcd_average.set_text("%0.2f" %speed) self.set_distance(distance) except: + logging.debug("Traceback: %s" % traceback.format_exc()) pass + logging.debug("<<") def set_distance(self,distance): self.rcd_distance.set_text("%0.2f" %distance) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2011-11-04 18:44:57
|
Revision: 917 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=917&view=rev Author: dgranda Date: 2011-11-04 18:44:51 +0000 (Fri, 04 Nov 2011) Log Message: ----------- Correct calculation between pace and decimal pace and viceversa - Ticket #71 Modified Paths: -------------- pytrainer/trunk/pytrainer/record.py Modified: pytrainer/trunk/pytrainer/record.py =================================================================== --- pytrainer/trunk/pytrainer/record.py 2011-11-04 11:20:39 UTC (rev 916) +++ pytrainer/trunk/pytrainer/record.py 2011-11-04 18:44:51 UTC (rev 917) @@ -83,11 +83,17 @@ def pace_to_float(self, value): '''Take a mm:ss or mm.ss and return float''' - value = value.replace(':', '.') try: - value = float(value) - except ValueError: - value = None + value = float(value) + except: + if ":" in value: # 'mm:ss' found + mins, sec = value.split(":") + value = float(mins + "." + "%02d" %round(int(sec)*5/3)) + elif "," in value: + value = float(value.replace(',','.')) + else: + logging.error("Wrong value provided: %s" %value) + value = None return value def pace_from_float(self, value): @@ -97,7 +103,9 @@ _value = "%0.2f" % float(value) except ValueError: _value = str(value) - return _value.replace('.',':') + mins, sec_dec = _value.split(".") + pace = mins + ":" + "%02d" %round(int(sec_dec)*3/5) + return pace def _formatRecordNew (self, list_options): """20.07.2008 - dgranda This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2011-11-04 11:20:45
|
Revision: 916 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=916&view=rev Author: dgranda Date: 2011-11-04 11:20:39 +0000 (Fri, 04 Nov 2011) Log Message: ----------- Pace and speed calculated in same method - ticket #152 Modified Paths: -------------- pytrainer/trunk/glade/newrecord.glade pytrainer/trunk/pytrainer/gui/windowrecord.py pytrainer/trunk/pytrainer/record.py pytrainer/trunk/pytrainer/waypoint.py Modified: pytrainer/trunk/glade/newrecord.glade =================================================================== --- pytrainer/trunk/glade/newrecord.glade 2011-11-01 09:26:11 UTC (rev 915) +++ pytrainer/trunk/glade/newrecord.glade 2011-11-04 11:20:39 UTC (rev 916) @@ -560,7 +560,7 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="use_underline">True</property> - <signal name="clicked" handler="on_calcaverage_clicked"/> + <signal name="clicked" handler="on_calcavs_clicked"/> </widget> <packing> <property name="left_attach">4</property> @@ -699,7 +699,7 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="use_underline">True</property> - <signal name="clicked" handler="on_calcpace_clicked"/> + <signal name="clicked" handler="on_calcavs_clicked"/> </widget> <packing> <property name="left_attach">4</property> Modified: pytrainer/trunk/pytrainer/gui/windowrecord.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowrecord.py 2011-11-01 09:26:11 UTC (rev 915) +++ pytrainer/trunk/pytrainer/gui/windowrecord.py 2011-11-04 11:20:39 UTC (rev 916) @@ -86,7 +86,7 @@ if time != None: self.setTime(time) if distance!=None and time!=None: - self.on_calcaverage_clicked(None) + self.on_calcavs_clicked(None) if upositive != None: self.rcd_upositive.set_text(self.uc.height(upositive)) if unegative != None: @@ -608,41 +608,32 @@ while gtk.events_pending(): # This allows the GUI to update gtk.main_iteration() # before completion of this entire action self.show_treeviewEntries_row(path[0]) - - def on_calcaverage_clicked(self,widget): - try: - hour = self.rcd_hour.get_value_as_int() - min = self.rcd_min.get_value_as_int() - sec = self.rcd_second.get_value_as_int() - time = sec + (min*60) + (hour*3600) - time_in_hour = time/3600.0 - distance = float(self.rcd_distance.get_text()) - average = distance/time_in_hour - self.rcd_average.set_text("%0.2f" %average) - except: - pass - - def on_calcpace_clicked(self,widget): + + def on_calcavs_clicked(self,widget): + logging.debug(">>") hour = self.rcd_hour.get_value_as_int() min = self.rcd_min.get_value_as_int() sec = self.rcd_second.get_value_as_int() time = sec + (min*60) + (hour*3600) if time<1: + logging.debug("Seems no time value (%s) has been entered, nothing to calculate." %time) return False - time_in_min = time/60.0 distance = float(self.rcd_distance.get_text()) if distance<1: + logging.debug("Seems no distance value (%s) has been entered, nothing to calculate." %distance) return False - #Calc Pace - average = time_in_min/distance - #Tranform pace to mm.ss - min = int(average) - per_min = average - min - sec = float(per_min) * 60 / 100 - dec_pace = min + sec + logging.debug("Time: %d seconds | Distance: %0.2f km (mi)" %(time,distance)) + # Average speed + average_speed = distance*3600.0/time + logging.debug("Average speed: %0.2f" %average_speed) + self.rcd_average.set_text("%0.2f" %average_speed) + # Average pace + dec_pace = 60/average_speed #Transform pace to mm:ss pace = self.parent.pace_from_float(dec_pace) + logging.debug("Average pace: %s" %pace) self.rcd_pace.set_text(pace) + logging.debug("<<") def on_calccalories_clicked(self,widget): sport = self.rcd_sport.get_active_text() Modified: pytrainer/trunk/pytrainer/record.py =================================================================== --- pytrainer/trunk/pytrainer/record.py 2011-11-01 09:26:11 UTC (rev 915) +++ pytrainer/trunk/pytrainer/record.py 2011-11-04 11:20:39 UTC (rev 916) @@ -489,8 +489,7 @@ self.recordwindow.set_maxspeed(maxspeed) self.recordwindow.set_maxhr(maxheartrate) self.recordwindow.set_recordtime(time/60.0/60.0) - self.recordwindow.on_calcaverage_clicked(None) - self.recordwindow.on_calcpace_clicked(None) + self.recordwindow.on_calcavs_clicked(None) self.recordwindow.on_calccalories_clicked(None) self.recordwindow.rcd_maxpace.set_text("%d.%02d" %((3600/maxspeed)/60,(3600/maxspeed)%60)) logging.debug('<<') Modified: pytrainer/trunk/pytrainer/waypoint.py =================================================================== --- pytrainer/trunk/pytrainer/waypoint.py 2011-11-01 09:26:11 UTC (rev 915) +++ pytrainer/trunk/pytrainer/waypoint.py 2011-11-04 11:20:39 UTC (rev 916) @@ -100,5 +100,5 @@ self.recordwindow.rcd_unegative.set_text(str(unegative)) self.recordwindow.set_distance(distance) self.recordwindow.set_recordtime(time/60.0/60.0) - self.recordwindow.on_calcaverage_clicked(None) + self.recordwindow.on_calcavs_clicked(None) logging.debug("<<") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aza...@us...> - 2011-11-01 09:26:20
|
Revision: 915 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=915&view=rev Author: azapletal Date: 2011-11-01 09:26:11 +0000 (Tue, 01 Nov 2011) Log Message: ----------- Dependency list extended (INSTALL) Modified Paths: -------------- pytrainer/trunk/INSTALL Modified: pytrainer/trunk/INSTALL =================================================================== --- pytrainer/trunk/INSTALL 2011-11-01 08:55:26 UTC (rev 914) +++ pytrainer/trunk/INSTALL 2011-11-01 09:26:11 UTC (rev 915) @@ -32,6 +32,7 @@ wordpresslib (already distributed within pytrainer tarball, wordpress extension) httplib2 >= 0.6.0 (wordpress extension) SOAPpy >= 0.11.6 (dotclear extension) +GDAL (Elevation correction, via "gdal-python" or "python-gdal") 2.- Installation process This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2011-11-01 08:55:33
|
Revision: 914 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=914&view=rev Author: dgranda Date: 2011-11-01 08:55:26 +0000 (Tue, 01 Nov 2011) Log Message: ----------- Updating changelog Modified Paths: -------------- pytrainer/trunk/CHANGES Modified: pytrainer/trunk/CHANGES =================================================================== --- pytrainer/trunk/CHANGES 2011-11-01 08:53:44 UTC (rev 913) +++ pytrainer/trunk/CHANGES 2011-11-01 08:55:26 UTC (rev 914) @@ -10,7 +10,7 @@ - Manpage for pytrainer - #125 [872] [874] - Create sport service - #138 [838] [840 - 845] [850] [850 - 856] [875] [880] - Provide means to run all unit tests - #139 [837] - - Discrete version migration - #132 [815 - 836] [839] [864] [865] [899 - 906] + - Discrete version migration - #132 [815 - 836] [839] [864] [865] [899 - 906] [911] - Totals tab - #60 [766] [800] [801] [802] [803] - Display projected times in record view, including ranking - #116 [782] [785] [811] - Ascent and descent figures shown in all views. Added time spent moving and paused in record view (thanks to Friso) - #114 [781] @@ -22,11 +22,12 @@ * Fixes - - Fixed support to import TCXv2 files - [907 - 909] + - pytrainer quits when exporting activities in csv format [912] + - Importing TCXv2 files failed - [907 - 909] - Date value was not saved in "Athlete" tab - #149 [898] - Fixed encoding issue that prevented some days of the week and associated information to be shown in stacked bars graph under week tab [897] - Cannot edit record created from GPX import with null sport reference - #147 [881] - - Pytrainer crashes when closing edit record dialog - #146 [879] + - pytrainer crashes when closing edit record dialog - #146 [879] - Added zero padding to overcome lap order issue - #145 [878] - Updated french localization - thanks to Vincent, Pierr [876] [895] - Heartrate figures from profile are retrieved independently so only those which fail are set to default value [873] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2011-11-01 08:53:54
|
Revision: 913 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=913&view=rev Author: dgranda Date: 2011-11-01 08:53:44 +0000 (Tue, 01 Nov 2011) Log Message: ----------- Listing pytrainer dependencies as much distribution agnostic as possible Modified Paths: -------------- pytrainer/trunk/INSTALL Modified: pytrainer/trunk/INSTALL =================================================================== --- pytrainer/trunk/INSTALL 2011-10-31 17:35:47 UTC (rev 912) +++ pytrainer/trunk/INSTALL 2011-11-01 08:53:44 UTC (rev 913) @@ -7,28 +7,31 @@ Here you are dependencies for pytrainer. Of course you must have a working environment with proper shell configuration and typical GNU tools to uncompress (gunzip) and untar (tar) files. -1.1.- Packages (Fedora 15 working versions as of 2011.08.28 for 1.9.0, package names might change in other distributions) +1.1.- Packages -python-2.7.1 -python-devel-2.7.1 (to run installation from tarball) -python-matplotlib-1.0.1 -python-dateutil-1.5.1 -pywebkitgtk-1.1.8 (see ticket #131) -pygtk2-libglade-2.24.0 -pygtk2-2.24.0 -SOAPpy-0.11.6 -python-lxml-2.3.1 -libxml2-python-2.7.8 -libxml2-2.7.8 -libxslt-python-1.1.26 -libxslt-1.1.26 -sqlite-3.7.5 (sqlite is preferred to mysql as databas as database, MySQL-python has been reported to be installed if so) -python-sqlalchemy-0.6.8 (sqlalchemy >= 0.6.4) -python-migrate-0.6 (sqlalchemy-migrate >=0.6.0) +python >= 2.5 (python >= 3.0 not checked on 2011/11!) +distutils >= 2.5 (python-devel, to run installation from tarball) +dateutil >= 1.5 (python-dateutil) +GTK+ > 2 +PyGTK > 2 +libglade >= 2.6.4 (libglade, pygtk2-libglade) +pywebkitgtk >= 1.1.8 (see ticket #131) +matplotlib >= 0.99.x (python-matplotlib) +python-lxml >= 2.2 +libxml2 >= 2.7.8 +libxml2-python >= 2.7.8 +libxslt >= 1.1.26 +libxslt-python >= 1.1.26 +sqlite >= 3.2.0 (sqlite is preferred to mysql as database, MySQL-python has been reported to be installed if so) +sqlalchemy >= 0.6.4 +sqlalchemy-migrate >= 0.6.0 -- Only needed if correspondent plugin is enabled: -gpsbabel-1.3.5 ("Garmin via GPSBabel 1.3.5" aka garmin_hr) - No longer available in official F15 repositories -garmintools-0.10 ("Garmin via garmintools" aka garmintools_full) - No longer available in official F15 repositories +- Only needed if correspondent plugin or extension is enabled: +gpsbabel == 1.3.5 ("GoogleEarth" and "Garmin via GPSBabel 1.3.5" aka "garmin_hr") +garmintools >= 0.10 ("Import from Garmin GPS device (via garmintools)" aka "garmintools_full" plugin) +wordpresslib (already distributed within pytrainer tarball, wordpress extension) +httplib2 >= 0.6.0 (wordpress extension) +SOAPpy >= 0.11.6 (dotclear extension) 2.- Installation process This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2011-10-31 17:35:53
|
Revision: 912 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=912&view=rev Author: dgranda Date: 2011-10-31 17:35:47 +0000 (Mon, 31 Oct 2011) Log Message: ----------- Fixed issue that made pytrainer quit when exporting activities in csv format Modified Paths: -------------- pytrainer/trunk/pytrainer/gui/filechooser.py pytrainer/trunk/pytrainer/lib/fileUtils.py pytrainer/trunk/pytrainer/save.py Modified: pytrainer/trunk/pytrainer/gui/filechooser.py =================================================================== --- pytrainer/trunk/pytrainer/gui/filechooser.py 2011-10-31 13:12:25 UTC (rev 911) +++ pytrainer/trunk/pytrainer/gui/filechooser.py 2011-10-31 17:35:47 UTC (rev 912) @@ -20,9 +20,11 @@ from SimpleGladeApp import SimpleGladeApp import gtk +import logging class FileChooser(SimpleGladeApp): def __init__(self,data_path = None, parent = None, method = None, action = None): + logging.debug('>>') self.data_path = data_path self.filename = None self.parent = parent @@ -36,26 +38,35 @@ filter.add_pattern("*.gpx") self.filechooserdialog.set_filter(filter) else: - self.button14.set_label("Save") + self.button14.set_label(_("Save")) self.filechooserdialog.set_action(gtk.FILE_CHOOSER_ACTION_SAVE) - print self.filechooserdialog.get_action() self.filechooserdialog.set_current_name("*.csv") + logging.debug('<<') def on_accept_clicked(self,widget): + logging.debug('>>') try: self.filename = self.filechooserdialog.get_filename() + logging.debug("Filename chosen: %s" % self.filename) except AttributeError: if self.filename is None: + logging.debug("No valid filename has been chosen. Exiting") self.quit() return + logging.debug("Parent: %s | Method: %s" %(self.parent, self.method)) parentmethod = getattr(self.parent,self.method) parentmethod() + logging.debug("Closing current window") self.closewindow() + logging.debug('<<') def on_cancel_clicked(self,widget): + logging.debug(">>") self.closewindow() + logging.debug('<<') def closewindow(self): - #self.filechooserdialog.hide() - self.filechooserdialog = None - self.quit() + if self.filechooserdialog is not None: + self.filechooserdialog.hide() + else: + logging.debug('GTK Dialog no longer exists, nothing to do') Modified: pytrainer/trunk/pytrainer/lib/fileUtils.py =================================================================== --- pytrainer/trunk/pytrainer/lib/fileUtils.py 2011-10-31 13:12:25 UTC (rev 911) +++ pytrainer/trunk/pytrainer/lib/fileUtils.py 2011-10-31 17:35:47 UTC (rev 912) @@ -16,14 +16,22 @@ #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 + class fileUtils: - def __init__(self, filename, data): - self.filename = filename - self.data = data + def __init__(self, filename, data): + self.filename = filename + self.data = data - def run(self): - out = open(self.filename, 'w') - out.write(self.data) - out.close() + def run(self): + logging.debug('>>') + if self.data is not None: + logging.debug("Writing in %s " % self.filename) + out = open(self.filename, 'w') + out.write(self.data) + out.close() + else: + logging.error("Nothing to write in %s" % self.filename) + logging.debug('<<') Modified: pytrainer/trunk/pytrainer/save.py =================================================================== --- pytrainer/trunk/pytrainer/save.py 2011-10-31 13:12:25 UTC (rev 911) +++ pytrainer/trunk/pytrainer/save.py 2011-10-31 17:35:47 UTC (rev 912) @@ -18,6 +18,8 @@ from lib.fileUtils import fileUtils from gui.filechooser import FileChooser +import logging +import traceback class Save: def __init__(self, data_path = None, record = None): @@ -25,33 +27,39 @@ self.data_path = data_path def run(self): + logging.debug('>>') self.filewindow = FileChooser(self.data_path, self, "savecsvfile") - self.filewindow.run() + #self.filewindow.run() + logging.debug('<<') def savecsvfile(self): + logging.debug('>>') filename = self.filewindow.filename records = self.record.getAllrecord() # CSV Header content = "date,distance,time,beats,comments,average,calories\n" - for record in records: - line = "" - for i, data in enumerate(record): - if i in [1, 3, 5]: - try: - data = round(data, 2) - except: - pass - data = "%s" %data - data = data.replace(",", " ") - data = data.replace("\n", " ") - data = data.replace("\r", " ") - if i>0: - line += ",%s" %data - else: - line += "%s" %data - content += "%s\n" %line - file = fileUtils(filename,content) - file.run() - + try: + for record in records: + line = "" + for i, data in enumerate(record): + if i in [1, 3, 5]: + try: + data = round(data, 2) + except: + pass + data = "%s" %data + data = data.replace(",", " ") + data = data.replace("\n", " ") + data = data.replace("\r", " ") + if i>0: + line += ",%s" %data + else: + line += "%s" %data + content += "%s\n" %line + logging.info("Record data successfully retrieved. Choosing file to save it") + file = fileUtils(filename,content) + file.run() + except: + logging.debug("Traceback: %s" % traceback.format_exc()) + logging.debug('<<') - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-10-31 13:12:31
|
Revision: 911 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=911&view=rev Author: ncjones Date: 2011-10-31 13:12:25 +0000 (Mon, 31 Oct 2011) Log Message: ----------- Don't execute update queries while result set still open. Modified Paths: -------------- pytrainer/trunk/pytrainer/upgrade/versions/version014.py Modified: pytrainer/trunk/pytrainer/upgrade/versions/version014.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/version014.py 2011-10-24 22:11:37 UTC (rev 910) +++ pytrainer/trunk/pytrainer/upgrade/versions/version014.py 2011-10-31 13:12:25 UTC (rev 911) @@ -86,6 +86,8 @@ def upgrade(migrate_engine): sport_rows = migrate_engine.execute("select id_sports, weight, color, met, max_pace from sports") + sport_normalizers = [] for (id, weight, color, met, max_pace) in sport_rows: - _SportNormalizer(id, weight, color, met, max_pace).normalize(migrate_engine) - sport_rows.close() + sport_normalizers.append(_SportNormalizer(id, weight, color, met, max_pace)) + for sport_normalizer in sport_normalizers: + sport_normalizer.normalize(migrate_engine) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2011-10-24 22:11:44
|
Revision: 910 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=910&view=rev Author: dgranda Date: 2011-10-24 22:11:37 +0000 (Mon, 24 Oct 2011) Log Message: ----------- Updating changelog. Minor changes in INSTALL file Modified Paths: -------------- pytrainer/trunk/CHANGES pytrainer/trunk/INSTALL Modified: pytrainer/trunk/CHANGES =================================================================== --- pytrainer/trunk/CHANGES 2011-10-24 21:30:25 UTC (rev 909) +++ pytrainer/trunk/CHANGES 2011-10-24 22:11:37 UTC (rev 910) @@ -1,15 +1,16 @@ See the pytrainer roadmap for more information http://sourceforge.net/apps/trac/pytrainer/roadmap -- PyTrainer changes for 1.9.0: +- pytrainer changes for 1.9.0: * New functionality + - Added portuguese localization (thanks to Pedro Ribeiro) - [896] - Option added in localization script (utils/translator.sh) to generate only .pot file - [888 - 892] - Galician localization (thanks to Kaptan) - [885 - 887] [893] - Manpage for pytrainer - #125 [872] [874] - Create sport service - #138 [838] [840 - 845] [850] [850 - 856] [875] [880] - Provide means to run all unit tests - #139 [837] - - Discrete version migration - #132 [815 - 836] [839] [864] [865] + - Discrete version migration - #132 [815 - 836] [839] [864] [865] [899 - 906] - Totals tab - #60 [766] [800] [801] [802] [803] - Display projected times in record view, including ranking - #116 [782] [785] [811] - Ascent and descent figures shown in all views. Added time spent moving and paused in record view (thanks to Friso) - #114 [781] @@ -17,14 +18,17 @@ - Display laps information on record summary page - #109 #122 [768 - 772] [775] [777] [778] [788] [812] [813] - Coloring Google Maps path by speed/pace - thanks to Jonathan - #107 [765] - Added swedish localization (thanks to Per) - #98 [756 - 760] - - Add startup option for choosing console or file logging. When "console" is chosen all logging messsages are sent to stdout instead of a log file. [755] + - Added startup option for choosing console or file logging. When "console" is chosen all logging messsages are sent to stdout instead of a log file. [755] * Fixes - - Cannot edit record created from GPX import with null sport reference #147 [881] + - Fixed support to import TCXv2 files - [907 - 909] + - Date value was not saved in "Athlete" tab - #149 [898] + - Fixed encoding issue that prevented some days of the week and associated information to be shown in stacked bars graph under week tab [897] + - Cannot edit record created from GPX import with null sport reference - #147 [881] - Pytrainer crashes when closing edit record dialog - #146 [879] - Added zero padding to overcome lap order issue - #145 [878] - - Updated french localization - thanks to Vincent [876] + - Updated french localization - thanks to Vincent, Pierr [876] [895] - Heartrate figures from profile are retrieved independently so only those which fail are set to default value [873] - Active/Rest times are not calculated for activities with only one lap - [811] - Activity's data (equipment and title) missing when importing activity from file - #105 #137 [866 - 868] @@ -52,7 +56,7 @@ - Fix so only once instance of preferences dialog can be open at a time - #74 [753] -- PyTrainer changes for 1.8.0: +- pytrainer changes for 1.8.0: * New functionality - Equipment management (thx to Nathan) [571] [572] [573] [598] [678] [679] [680] [685] [698] [699] [707] [708] [711] [717] [718] #12 @@ -117,7 +121,7 @@ - Update DB check to ensure time == duration [736] - Updating credits [740] [743] -- PyTrainer changes for 1.7.2: +- pytrainer changes for 1.7.2: * Lap DB table created and code changed to populate and use the table [507] [508] [509] * Moved some global variables to class variables in main.py [513] @@ -150,7 +154,7 @@ - plugins tab added - provides alternative way of viewing and running import plugins [512] - device import NOT functional -- PyTrainer changes for 1.7.1: +- pytrainer changes for 1.7.1: * New import plugin - Garmintools - svn [430], [431], [436], [452], [453], [459], [460], [461], [463], [464], [486], [487], [488] - both file (dump file) and device import implemented @@ -183,7 +187,7 @@ - file import functional - device import NOT functional -- PyTrainer changes for 1.7.0: +- pytrainer changes for 1.7.0: Updated Spanish translation (svn rev 420,423,424) Updated French translation (svn rev 421) @@ -203,7 +207,7 @@ Several improvements in plugins handling (svn rev 350,353,360,378,422) Import GPX files (svn rev 349) -- PyTrainer tasks for 1.6.0.9: +- pytrainer tasks for 1.6.0.9: Added dynamic loading and unloading of plugin menu items (svn rev 344) Removal of decommissioned plugin (garmin301) and addition of new ones (garmingpx). Update of project data (version and url) (svn rev 343) @@ -214,7 +218,7 @@ Updated german translation - bug ID: 2811507 (thanks to Noèl) (svn revs 338, 333) Minor project and license information updated (svn revs 337, 335, 334, 329) -- PyTrainer tasks for 1.6.0.8: +- pytrainer tasks for 1.6.0.8: Rotating log file support added (rev 322, http://sourceforge.net/tracker/?func=detail&aid=2717142&group_id=213157&atid=1024595) Translations reviewed and added script to facilitate them (rev 319-321,323) @@ -223,7 +227,7 @@ Removing redundant calls improving graphical performance (rev 310, linked to http://sourceforge.net/tracker/?func=detail&aid=2717135&group_id=213157&atid=1024592, not yet fully fixed) Optimizing xml files parsing when retrieving data from them (rev 309) -- PyTrainer tasks for 1.6.0.7: +- pytrainer tasks for 1.6.0.7: Removing pytrainer gui minimal window size (svn rev 304) Ordered shutdown of logging stuff (svn rev 303) @@ -237,7 +241,7 @@ Bug #2100647 - Quick entry doesn't work if no gpx file - Fixed (svn rev. 287) FR #2126411 - Package python-sqlite2 not needed anymore: http://www.python.org/doc/2.5.2/lib/module-sqlite3.html (svn rev. 286) -- PyTrainer tasks for 1.6.0.6: +- pytrainer tasks for 1.6.0.6: Close button in "About" dialog now works. Migrating from Glade to GTKBuilder Fixed some properties in pytrainer.desktop (ID#2126616) @@ -245,30 +249,30 @@ Removal of garmin301 plugin Fixed some issues with MySql tables creation (email from Jonas Liljenfeldt) -- PyTrainer tasks for 1.6.0.5: +- pytrainer tasks for 1.6.0.5: mozpytrainer launch script with log level support -> DONE (24.08.2008) MET and extra weight values swapped when adding a new sport -> DONE (22.08.2008) -PyTrainer crashes when adding an activity which sport is not yet in DB -> DONE (31.08.2008) +pytrainer crashes when adding an activity which sport is not yet in DB -> DONE (31.08.2008) Should be enough to check timestamps when adding new activities -> DONE (31.08.2008) Correct initialization of pace and maxpace values -> DONE (31.08.2008) -- PyTrainer tasks for 1.6.0.4: +- pytrainer tasks for 1.6.0.4: Added support for date_time_utc field when importing new tracks via file upload pytrainer/profile.py: fixed logging issue when removing sport from database -- PyTrainer tasks for 1.6.0.3: +- pytrainer tasks for 1.6.0.3: Complete review of migration scripts. Special attention to ~/.pytrainer/conf.xml file -> DONE (31.07.2008) Number output always with two figures to avoid confusion -> DONE (02.08.2008) -- PyTrainer tasks for 1.6.0.2: +- pytrainer tasks for 1.6.0.2: Check paces in DB (maxspeed<->maxpace | average<->pace) -> DONE (19.07.2008) Error when updating records because of new date_time_utc field in DB -> FIXED (20.07.2008) -- PyTrainer tasks for 1.6.0.1: +- pytrainer tasks for 1.6.0.1: Adjust migration scripts Sports saved in ddbb (new column in table sports) -> id_sports in table sports (nothing to do) Modified: pytrainer/trunk/INSTALL =================================================================== --- pytrainer/trunk/INSTALL 2011-10-24 21:30:25 UTC (rev 909) +++ pytrainer/trunk/INSTALL 2011-10-24 22:11:37 UTC (rev 910) @@ -1,13 +1,13 @@ -PyTrainer basic installation +pytrainer basic installation =========================== These are generic installation instructions to use with *.tar.gz files 1.- Dependency Overview -Here you are dependencies for PyTrainer. Of course you must have a working environment with proper shell configuration and typical GNU tools to uncompress (gunzip) and untar (tar) files. +Here you are dependencies for pytrainer. Of course you must have a working environment with proper shell configuration and typical GNU tools to uncompress (gunzip) and untar (tar) files. -1.1.- Packages (Fedora 15 working versions as of 2011.08.28 for 1.9.0) +1.1.- Packages (Fedora 15 working versions as of 2011.08.28 for 1.9.0, package names might change in other distributions) python-2.7.1 python-devel-2.7.1 (to run installation from tarball) @@ -22,13 +22,13 @@ libxml2-2.7.8 libxslt-python-1.1.26 libxslt-1.1.26 -sqlite-3.7.5 (sqlite is preferred as db than mysql, MySQL-python has been reported to be installed if so) +sqlite-3.7.5 (sqlite is preferred to mysql as databas as database, MySQL-python has been reported to be installed if so) python-sqlalchemy-0.6.8 (sqlalchemy >= 0.6.4) python-migrate-0.6 (sqlalchemy-migrate >=0.6.0) - Only needed if correspondent plugin is enabled: gpsbabel-1.3.5 ("Garmin via GPSBabel 1.3.5" aka garmin_hr) - No longer available in official F15 repositories -garmintools-0.10 ("Garmin via garmintools" aka garmintools_full) - No longer available in officia F15 repositories +garmintools-0.10 ("Garmin via garmintools" aka garmintools_full) - No longer available in official F15 repositories 2.- Installation process @@ -43,4 +43,4 @@ 3.- USB access -Currently PyTrainer is using gpsbabel (http://www.gpsbabel.org) to retrieve information from the Garmin device. There are some problems regarding driver to access usb ports, please take a look at http://www.gpsbabel.org/os/Linux_Hotplug.html +pytrainer can use gpsbabel (http://www.gpsbabel.org) to retrieve information from Garmin devices. There are some problems regarding driver to access usb ports, please take a look at http://www.gpsbabel.org/os/Linux_Hotplug.html This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2011-10-24 21:30:32
|
Revision: 909 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=909&view=rev Author: dgranda Date: 2011-10-24 21:30:25 +0000 (Mon, 24 Oct 2011) Log Message: ----------- Fixed issue with unicode strings when adding new sport. Attention: getSportId method is already deprecated Modified Paths: -------------- pytrainer/trunk/pytrainer/record.py Modified: pytrainer/trunk/pytrainer/record.py =================================================================== --- pytrainer/trunk/pytrainer/record.py 2011-10-24 19:09:00 UTC (rev 908) +++ pytrainer/trunk/pytrainer/record.py 2011-10-24 21:30:25 UTC (rev 909) @@ -406,9 +406,9 @@ if sport is None: logging.debug("No sport with name: '%s'", str(sport_name)) if add is not None: - logging.debug("Adding sport '%s'", str(sport)) + logging.debug("Adding sport '%s'", str(sport_name)) new_sport = Sport() - new_sport.name = sport_name + new_sport.name = unicode(sport_name) sport = self._sport_service.store_sport(new_sport) return None if sport is None else sport.id This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2011-10-24 19:09:06
|
Revision: 908 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=908&view=rev Author: dgranda Date: 2011-10-24 19:09:00 +0000 (Mon, 24 Oct 2011) Log Message: ----------- Support for 'resting' intensity lap status in imported activities coming from TCXv2 files Modified Paths: -------------- pytrainer/trunk/pytrainer/gui/windowmain.py Modified: pytrainer/trunk/pytrainer/gui/windowmain.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowmain.py 2011-10-24 19:05:49 UTC (rev 907) +++ pytrainer/trunk/pytrainer/gui/windowmain.py 2011-10-24 19:09:00 UTC (rev 908) @@ -462,6 +462,7 @@ color = { 'active' : '#000000', 'rest' : '#808080', + 'resting' : '#808080', } pic = gtk.gdk.pixbuf_new_from_file(self.data_path+"glade/trigger_%s.png" % lap['laptrigger']) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2011-10-24 19:05:55
|
Revision: 907 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=907&view=rev Author: dgranda Date: 2011-10-24 19:05:49 +0000 (Mon, 24 Oct 2011) Log Message: ----------- Overcome scenario when no lap max_speed value is found, especially for TCXv2 files Modified Paths: -------------- pytrainer/trunk/pytrainer/gui/windowmain.py pytrainer/trunk/pytrainer/lib/gpx.py Modified: pytrainer/trunk/pytrainer/gui/windowmain.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowmain.py 2011-10-23 12:17:22 UTC (rev 906) +++ pytrainer/trunk/pytrainer/gui/windowmain.py 2011-10-24 19:05:49 UTC (rev 907) @@ -454,7 +454,10 @@ max_speed = lap['max_speed'] * 3.6 if s > 0: pace = "%d:%02d" %((3600/s)/60,(3600/s)%60) - max_pace = "%d:%02d" %((3600/max_speed)/60,(3600/max_speed)%60) + if max_speed >0: + max_pace = "%d:%02d" %((3600/max_speed)/60,(3600/max_speed)%60) + else: + max_pace = "0:00" color = { 'active' : '#000000', Modified: pytrainer/trunk/pytrainer/lib/gpx.py =================================================================== --- pytrainer/trunk/pytrainer/lib/gpx.py 2011-10-23 12:17:22 UTC (rev 906) +++ pytrainer/trunk/pytrainer/lib/gpx.py 2011-10-24 19:05:49 UTC (rev 907) @@ -196,6 +196,9 @@ trigger = lap.findtext(triggerTag).lower() summary = lap.find(summaryTag) max_speed = summary.findtext(mainNS.substitute(tag="MaximumSpeed")) + if not max_speed: + max_speed = 0 + logging.info("No max speed found in lap info. Default setting to 0") avg_hr = summary.findtext(mainNS.substitute(tag="AverageHeartRateBpm")) max_hr = summary.findtext(mainNS.substitute(tag="MaximumHeartRateBpm")) logging.debug("Found time: %s, lat: %s lon: %s cal: %s dist: %s " % (elapsedTime, lat, lon, calories, distance)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-10-23 12:17:29
|
Revision: 906 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=906&view=rev Author: ncjones Date: 2011-10-23 12:17:22 +0000 (Sun, 23 Oct 2011) Log Message: ----------- Split "add" and "populate" upgrade operations into separate scripts. ticket:132 Modified Paths: -------------- pytrainer/trunk/pytrainer/upgrade/data.py pytrainer/trunk/pytrainer/upgrade/versions/008_mysql_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/008_sqlite_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/010_default_upgrade.sql Added Paths: ----------- pytrainer/trunk/pytrainer/test/upgrade/versions/version014_test.py pytrainer/trunk/pytrainer/upgrade/versions/006_default_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/007_populate_record_duration.py pytrainer/trunk/pytrainer/upgrade/versions/009_mysql_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/009_sqlite_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/011_populate_lap_details.py pytrainer/trunk/pytrainer/upgrade/versions/012_default_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/013_remove_db_version.py pytrainer/trunk/pytrainer/upgrade/versions/014_clean_sport_data.py pytrainer/trunk/pytrainer/upgrade/versions/version014.py Removed Paths: ------------- pytrainer/trunk/pytrainer/test/upgrade/versions/version012_test.py pytrainer/trunk/pytrainer/upgrade/versions/006_add_record_duration.py pytrainer/trunk/pytrainer/upgrade/versions/007_mysql_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/007_sqlite_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/009_add_lap_details.py pytrainer/trunk/pytrainer/upgrade/versions/011_remove_db_version.py pytrainer/trunk/pytrainer/upgrade/versions/012_clean_sport_data.py pytrainer/trunk/pytrainer/upgrade/versions/version012.py Deleted: pytrainer/trunk/pytrainer/test/upgrade/versions/version012_test.py =================================================================== --- pytrainer/trunk/pytrainer/test/upgrade/versions/version012_test.py 2011-10-23 12:15:59 UTC (rev 905) +++ pytrainer/trunk/pytrainer/test/upgrade/versions/version012_test.py 2011-10-23 12:17:22 UTC (rev 906) @@ -1,81 +0,0 @@ -# -*- coding: iso-8859-1 -*- - -#Copyright (C) Nathan Jones nc...@us... - -#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 unittest -import sqlalchemy -import pytrainer.upgrade.versions.version012 as version012 - -class UpgradeTest(unittest.TestCase): - - def setUp(self): - self._engine = sqlalchemy.create_engine("sqlite:///:memory:") - self._metadata = sqlalchemy.MetaData() - self._metadata.bind = self._engine - self._sports_table = sqlalchemy.Table("sports", self._metadata, - sqlalchemy.Column("id_sports", sqlalchemy.Integer, primary_key=True), - sqlalchemy.Column("name", sqlalchemy.String(100)), - sqlalchemy.Column("weight", sqlalchemy.Float), - sqlalchemy.Column("color", sqlalchemy.String(6)), - sqlalchemy.Column("met", sqlalchemy.Float), - sqlalchemy.Column("max_pace", sqlalchemy.Integer) - ) - self._metadata.drop_all() - self._metadata.create_all() - - def upgradeAndAssert(self, original, expected): - self._engine.execute(sqlalchemy.text("insert into sports (id_sports, name, weight, color, met, max_pace)" - " values (:id, :name, :weight, :color, :met, :max_pace)"), - id= 1, - name= "Test Sport", - weight= original["weight"], - color= original["color"], - met= original["met"], - max_pace= original["max_pace"]) - version012.upgrade(self._engine) - result = self._engine.execute(self._sports_table.select(self._sports_table.c.id_sports==1)) - (_, _, weight, color, met, max_pace) = result.fetchone() - result.close() - self.assertEqual(expected["weight"], weight) - self.assertEqual(expected["color"], color) - self.assertEqual(expected["met"], met) - self.assertEqual(expected["max_pace"], max_pace) - - def testUpgradeFromNullValues(self): - original = { "weight": None, "color": None, "met": None, "max_pace": None } - expected = { "weight": 0.0, "color": "0000ff", "met": None, "max_pace": None } - self.upgradeAndAssert(original, expected) - - def testUpgradeFromZeroValues(self): - original = { "weight": 0, "color": 0, "met": 0, "max_pace": 0 } - expected = { "weight": 0.0, "color": "0", "met": 0, "max_pace": None } - self.upgradeAndAssert(original, expected) - - def testUpgradeFromEmptyValues(self): - original = { "weight": "", "color": "", "met": "", "max_pace": "" } - expected = { "weight": 0.0, "color": "0000ff", "met": None, "max_pace": None } - self.upgradeAndAssert(original, expected) - - def testUpgradeFromNegativeValues(self): - original = { "weight": -1, "color": -1, "met": -1, "max_pace": -1 } - expected = { "weight": 0.0, "color": "-1", "met": None, "max_pace": None } - self.upgradeAndAssert(original, expected) - - def testUpgradeFromValidValues(self): - original = { "weight": 3.4, "color": "abc123", "met": 45.6, "max_pace": 123 } - expected = { "weight": 3.4, "color": "abc123", "met": 45.6, "max_pace": 123 } - self.upgradeAndAssert(original, expected) Copied: pytrainer/trunk/pytrainer/test/upgrade/versions/version014_test.py (from rev 905, pytrainer/trunk/pytrainer/test/upgrade/versions/version012_test.py) =================================================================== --- pytrainer/trunk/pytrainer/test/upgrade/versions/version014_test.py (rev 0) +++ pytrainer/trunk/pytrainer/test/upgrade/versions/version014_test.py 2011-10-23 12:17:22 UTC (rev 906) @@ -0,0 +1,81 @@ +# -*- coding: iso-8859-1 -*- + +#Copyright (C) Nathan Jones nc...@us... + +#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 unittest +import sqlalchemy +import pytrainer.upgrade.versions.version014 as version014 + +class UpgradeTest(unittest.TestCase): + + def setUp(self): + self._engine = sqlalchemy.create_engine("sqlite:///:memory:") + self._metadata = sqlalchemy.MetaData() + self._metadata.bind = self._engine + self._sports_table = sqlalchemy.Table("sports", self._metadata, + sqlalchemy.Column("id_sports", sqlalchemy.Integer, primary_key=True), + sqlalchemy.Column("name", sqlalchemy.String(100)), + sqlalchemy.Column("weight", sqlalchemy.Float), + sqlalchemy.Column("color", sqlalchemy.String(6)), + sqlalchemy.Column("met", sqlalchemy.Float), + sqlalchemy.Column("max_pace", sqlalchemy.Integer) + ) + self._metadata.drop_all() + self._metadata.create_all() + + def upgradeAndAssert(self, original, expected): + self._engine.execute(sqlalchemy.text("insert into sports (id_sports, name, weight, color, met, max_pace)" + " values (:id, :name, :weight, :color, :met, :max_pace)"), + id= 1, + name= "Test Sport", + weight= original["weight"], + color= original["color"], + met= original["met"], + max_pace= original["max_pace"]) + version014.upgrade(self._engine) + result = self._engine.execute(self._sports_table.select(self._sports_table.c.id_sports==1)) + (_, _, weight, color, met, max_pace) = result.fetchone() + result.close() + self.assertEqual(expected["weight"], weight) + self.assertEqual(expected["color"], color) + self.assertEqual(expected["met"], met) + self.assertEqual(expected["max_pace"], max_pace) + + def testUpgradeFromNullValues(self): + original = { "weight": None, "color": None, "met": None, "max_pace": None } + expected = { "weight": 0.0, "color": "0000ff", "met": None, "max_pace": None } + self.upgradeAndAssert(original, expected) + + def testUpgradeFromZeroValues(self): + original = { "weight": 0, "color": 0, "met": 0, "max_pace": 0 } + expected = { "weight": 0.0, "color": "0", "met": 0, "max_pace": None } + self.upgradeAndAssert(original, expected) + + def testUpgradeFromEmptyValues(self): + original = { "weight": "", "color": "", "met": "", "max_pace": "" } + expected = { "weight": 0.0, "color": "0000ff", "met": None, "max_pace": None } + self.upgradeAndAssert(original, expected) + + def testUpgradeFromNegativeValues(self): + original = { "weight": -1, "color": -1, "met": -1, "max_pace": -1 } + expected = { "weight": 0.0, "color": "-1", "met": None, "max_pace": None } + self.upgradeAndAssert(original, expected) + + def testUpgradeFromValidValues(self): + original = { "weight": 3.4, "color": "abc123", "met": 45.6, "max_pace": 123 } + expected = { "weight": 3.4, "color": "abc123", "met": 45.6, "max_pace": 123 } + self.upgradeAndAssert(original, expected) Modified: pytrainer/trunk/pytrainer/upgrade/data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/data.py 2011-10-23 12:15:59 UTC (rev 905) +++ pytrainer/trunk/pytrainer/upgrade/data.py 2011-10-23 12:17:22 UTC (rev 906) @@ -115,13 +115,13 @@ elif legacy_version == 5: # 1.8.0-dev return 5 elif legacy_version == 6: # 1.8.0 - return 8 + return 9 elif legacy_version == 7: # 1.9.0-dev - return 9 + return 10 elif legacy_version == 8: # 1.9.0-dev - return 10 + return 12 elif legacy_version == 9: # 1.9.0-dev - return 10 + return 12 return None def get_available_version(self): Deleted: pytrainer/trunk/pytrainer/upgrade/versions/006_add_record_duration.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/006_add_record_duration.py 2011-10-23 12:15:59 UTC (rev 905) +++ pytrainer/trunk/pytrainer/upgrade/versions/006_add_record_duration.py 2011-10-23 12:17:22 UTC (rev 906) @@ -1,40 +0,0 @@ -from sqlalchemy import MetaData, Table, Column, Integer -from sqlalchemy.sql.expression import text -import logging - -# record duration added in version 1.8.0 - -def upgrade(migrate_engine): - add_duration_column(migrate_engine) - populate_duration_values(migrate_engine) - -def add_duration_column(migrate_engine): - logging.info("Adding records.duration column") - meta = MetaData(migrate_engine) - records_table = Table("records", meta, autoload=True) - duration_column = Column("duration", Integer) - duration_column.create(records_table) - logging.info("Created records.duration column") - -def populate_duration_values(migrate_engine): - logging.info("Populating records.duration column") - records = migrate_engine.execute("select id_record, time from records where duration is null") - for record in records: - record_id = record["id_record"] - record_time = record["time"] - try: - duration = int(record_time) - except: - logging.info("Error parsing time (%s) as int for record_id: %s" % (record_time, record_id)) - duration = 0 - logging.debug("setting record %s duration to %d" , record_id, duration) - migrate_engine.execute(text("update records set duration=:duration where id_record=:record_id"), duration=duration, record_id=record_id) - records.close() - -# work around a migrate bug -try: - import migrate.versioning.exceptions as ex1 - import migrate.changeset.exceptions as ex2 - ex1.MigrateDeprecationWarning = ex2.MigrateDeprecationWarning -except ImportError: - pass Added: pytrainer/trunk/pytrainer/upgrade/versions/006_default_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/006_default_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/006_default_upgrade.sql 2011-10-23 12:17:22 UTC (rev 906) @@ -0,0 +1,2 @@ +-- record duration added in version 1.8.0 +alter table records add duration integer; \ No newline at end of file Deleted: pytrainer/trunk/pytrainer/upgrade/versions/007_mysql_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/007_mysql_upgrade.sql 2011-10-23 12:15:59 UTC (rev 905) +++ pytrainer/trunk/pytrainer/upgrade/versions/007_mysql_upgrade.sql 2011-10-23 12:17:22 UTC (rev 906) @@ -1,4 +0,0 @@ --- record date_time data type changed in version 1.8.0 -alter table records - modify date_time_local varchar(40), - modify date_time_utc varchar(40); \ No newline at end of file Copied: pytrainer/trunk/pytrainer/upgrade/versions/007_populate_record_duration.py (from rev 905, pytrainer/trunk/pytrainer/upgrade/versions/006_add_record_duration.py) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/007_populate_record_duration.py (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/007_populate_record_duration.py 2011-10-23 12:17:22 UTC (rev 906) @@ -0,0 +1,27 @@ +from sqlalchemy.sql.expression import text +import logging + +# record duration added in version 1.8.0 + +def upgrade(migrate_engine): + logging.info("Populating records.duration column") + records = migrate_engine.execute("select id_record, time from records where duration is null") + for record in records: + record_id = record["id_record"] + record_time = record["time"] + try: + duration = int(record_time) + except: + logging.info("Error parsing time (%s) as int for record_id: %s" % (record_time, record_id)) + duration = 0 + logging.debug("setting record %s duration to %d" , record_id, duration) + migrate_engine.execute(text("update records set duration=:duration where id_record=:record_id"), duration=duration, record_id=record_id) + records.close() + +# work around a migrate bug +try: + import migrate.versioning.exceptions as ex1 + import migrate.changeset.exceptions as ex2 + ex1.MigrateDeprecationWarning = ex2.MigrateDeprecationWarning +except ImportError: + pass Deleted: pytrainer/trunk/pytrainer/upgrade/versions/007_sqlite_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/007_sqlite_upgrade.sql 2011-10-23 12:15:59 UTC (rev 905) +++ pytrainer/trunk/pytrainer/upgrade/versions/007_sqlite_upgrade.sql 2011-10-23 12:17:22 UTC (rev 906) @@ -1 +0,0 @@ --- data type change does not affect sqlite schema \ No newline at end of file Modified: pytrainer/trunk/pytrainer/upgrade/versions/008_mysql_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/008_mysql_upgrade.sql 2011-10-23 12:15:59 UTC (rev 905) +++ pytrainer/trunk/pytrainer/upgrade/versions/008_mysql_upgrade.sql 2011-10-23 12:17:22 UTC (rev 906) @@ -1,16 +1,4 @@ --- equipment management added in version 1.8.0 - -create table equipment ( - id integer primary key auto_increment , - description varchar(200), - active boolean, - life_expectancy int, - prior_usage int, - notes text -); - -create table record_equipment ( - id integer primary key auto_increment, - record_id int, - equipment_id int -); +-- record date_time data type changed in version 1.8.0 +alter table records + modify date_time_local varchar(40), + modify date_time_utc varchar(40); \ No newline at end of file Modified: pytrainer/trunk/pytrainer/upgrade/versions/008_sqlite_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/008_sqlite_upgrade.sql 2011-10-23 12:15:59 UTC (rev 905) +++ pytrainer/trunk/pytrainer/upgrade/versions/008_sqlite_upgrade.sql 2011-10-23 12:17:22 UTC (rev 906) @@ -1,16 +1 @@ --- equipment management added in version 1.8.0 - -create table equipment ( - id integer primary key autoincrement , - description varchar(200), - active boolean, - life_expectancy int, - prior_usage int, - notes text -); - -create table record_equipment ( - id integer primary key autoincrement, - record_id int, - equipment_id int -); +-- data type change does not affect sqlite schema \ No newline at end of file Deleted: pytrainer/trunk/pytrainer/upgrade/versions/009_add_lap_details.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/009_add_lap_details.py 2011-10-23 12:15:59 UTC (rev 905) +++ pytrainer/trunk/pytrainer/upgrade/versions/009_add_lap_details.py 2011-10-23 12:17:22 UTC (rev 906) @@ -1,77 +0,0 @@ -from pytrainer.upgrade.context import UPGRADE_CONTEXT -from pytrainer.lib import gpx -from sqlalchemy import MetaData, Table, Column -from sqlalchemy.types import Integer, Text, Float, String -from sqlalchemy.sql.expression import text -import logging -import os.path - -# lap info added in version 1.9.0 -def upgrade(migrate_engine): - add_lap_details_columns(migrate_engine) - populate_lap_details_values(migrate_engine) - -def add_lap_details_columns(migrate_engine): - logging.info("Adding laps details columns") - meta = MetaData(migrate_engine) - laps_table = Table("laps", meta, autoload=True) - create_laps_column(laps_table, "intensity", String(7)) - create_laps_column(laps_table, "laptrigger", String(9)) - create_laps_column(laps_table, "max_speed", Float) - create_laps_column(laps_table, "avg_hr" , Integer) - create_laps_column(laps_table, "max_hr", Integer) - create_laps_column(laps_table, "comments", Text) - logging.info("Created laps details columns") - -def create_laps_column(laps_table, column_name, column_type): - logging.info("Adding column laps.%s" , column_name) - column = Column(column_name, column_type) - laps_table.create(column) - -def populate_lap_details_values(migrate_engine): - logging.info("Populating laps details columns") - resultset = migrate_engine.execute(text("select distinct record from laps where intensity is null")) - record_ids = [] - for row in resultset: - record_ids.append(row["record"]) - resultset.close() - for record_id in record_ids: - gpx_file = UPGRADE_CONTEXT.conf_dir + "/gpx/{0}.gpx".format(record_id) - if os.path.isfile(gpx_file): - gpx_record = gpx.Gpx(filename=gpx_file) - populate_laps_from_gpx(migrate_engine, record_id, gpx_record) - -def populate_laps_from_gpx(migrate_engine, record_id, gpx_record): - resultset = migrate_engine.execute(text("select id_lap from laps where record=:record_id" ), record_id=record_id) - lap_ids = [] - for row in resultset: - lap_ids.append(row["id_lap"]) - resultset.close() - if(len(lap_ids) > 0): - logging.info("Populating laps from GPX for record %s" , record_id) - for lap_id, gpx_lap in zip(lap_ids, gpx_record.getLaps()): - populate_lap_from_gpx(migrate_engine, lap_id, gpx_lap) - -def populate_lap_from_gpx(migrate_engine, lap_id, gpx_lap): - logging.info("Populating lap details from GPX for lap %s" , lap_id) - migrate_engine.execute(text("""update laps set - intensity=:intensity, - avg_hr=:avg_heart_rate, - max_hr=:max_heart_rate, - max_speed=:max_speed, - laptrigger=:lap_trigger - where id_lap=:lap_id"""), - intensity=gpx_lap[7], - avg_heart_rate=gpx_lap[8], - max_heart_rate=gpx_lap[9], - max_speed=float(gpx_lap[10]), - lap_trigger=gpx_lap[11], - lap_id=lap_id) - -# work around a migrate bug -try: - import migrate.versioning.exceptions as ex1 - import migrate.changeset.exceptions as ex2 - ex1.MigrateDeprecationWarning = ex2.MigrateDeprecationWarning -except ImportError: - pass Copied: pytrainer/trunk/pytrainer/upgrade/versions/009_mysql_upgrade.sql (from rev 905, pytrainer/trunk/pytrainer/upgrade/versions/008_mysql_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/009_mysql_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/009_mysql_upgrade.sql 2011-10-23 12:17:22 UTC (rev 906) @@ -0,0 +1,16 @@ +-- equipment management added in version 1.8.0 + +create table equipment ( + id integer primary key auto_increment , + description varchar(200), + active boolean, + life_expectancy int, + prior_usage int, + notes text +); + +create table record_equipment ( + id integer primary key auto_increment, + record_id int, + equipment_id int +); Copied: pytrainer/trunk/pytrainer/upgrade/versions/009_sqlite_upgrade.sql (from rev 905, pytrainer/trunk/pytrainer/upgrade/versions/008_sqlite_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/009_sqlite_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/009_sqlite_upgrade.sql 2011-10-23 12:17:22 UTC (rev 906) @@ -0,0 +1,16 @@ +-- equipment management added in version 1.8.0 + +create table equipment ( + id integer primary key autoincrement , + description varchar(200), + active boolean, + life_expectancy int, + prior_usage int, + notes text +); + +create table record_equipment ( + id integer primary key autoincrement, + record_id int, + equipment_id int +); Modified: pytrainer/trunk/pytrainer/upgrade/versions/010_default_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/010_default_upgrade.sql 2011-10-23 12:15:59 UTC (rev 905) +++ pytrainer/trunk/pytrainer/upgrade/versions/010_default_upgrade.sql 2011-10-23 12:17:22 UTC (rev 906) @@ -1,2 +1,7 @@ --- sport color added in version 1.9.0 -alter table sports add color char(6); \ No newline at end of file +-- lap info added in version 1.9.0 +alter table laps add intensity varchar(7); +alter table laps add laptrigger varchar(9); +alter table laps add max_speed float; +alter table laps add avg_hr int; +alter table laps add max_hr int; +alter table laps add comments text; Copied: pytrainer/trunk/pytrainer/upgrade/versions/011_populate_lap_details.py (from rev 905, pytrainer/trunk/pytrainer/upgrade/versions/009_add_lap_details.py) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/011_populate_lap_details.py (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/011_populate_lap_details.py 2011-10-23 12:17:22 UTC (rev 906) @@ -0,0 +1,54 @@ +from pytrainer.upgrade.context import UPGRADE_CONTEXT +from pytrainer.lib import gpx +from sqlalchemy.sql.expression import text +import logging +import os.path + +# lap info added in version 1.9.0 +def upgrade(migrate_engine): + logging.info("Populating laps details columns") + resultset = migrate_engine.execute(text("select distinct record from laps where intensity is null")) + record_ids = [] + for row in resultset: + record_ids.append(row["record"]) + resultset.close() + for record_id in record_ids: + gpx_file = UPGRADE_CONTEXT.conf_dir + "/gpx/{0}.gpx".format(record_id) + if os.path.isfile(gpx_file): + gpx_record = gpx.Gpx(filename=gpx_file) + populate_laps_from_gpx(migrate_engine, record_id, gpx_record) + +def populate_laps_from_gpx(migrate_engine, record_id, gpx_record): + resultset = migrate_engine.execute(text("select id_lap from laps where record=:record_id" ), record_id=record_id) + lap_ids = [] + for row in resultset: + lap_ids.append(row["id_lap"]) + resultset.close() + if(len(lap_ids) > 0): + logging.info("Populating laps from GPX for record %s" , record_id) + for lap_id, gpx_lap in zip(lap_ids, gpx_record.getLaps()): + populate_lap_from_gpx(migrate_engine, lap_id, gpx_lap) + +def populate_lap_from_gpx(migrate_engine, lap_id, gpx_lap): + logging.info("Populating lap details from GPX for lap %s" , lap_id) + migrate_engine.execute(text("""update laps set + intensity=:intensity, + avg_hr=:avg_heart_rate, + max_hr=:max_heart_rate, + max_speed=:max_speed, + laptrigger=:lap_trigger + where id_lap=:lap_id"""), + intensity=gpx_lap[7], + avg_heart_rate=gpx_lap[8], + max_heart_rate=gpx_lap[9], + max_speed=float(gpx_lap[10]), + lap_trigger=gpx_lap[11], + lap_id=lap_id) + +# work around a migrate bug +try: + import migrate.versioning.exceptions as ex1 + import migrate.changeset.exceptions as ex2 + ex1.MigrateDeprecationWarning = ex2.MigrateDeprecationWarning +except ImportError: + pass Deleted: pytrainer/trunk/pytrainer/upgrade/versions/011_remove_db_version.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/011_remove_db_version.py 2011-10-23 12:15:59 UTC (rev 905) +++ pytrainer/trunk/pytrainer/upgrade/versions/011_remove_db_version.py 2011-10-23 12:17:22 UTC (rev 906) @@ -1,10 +0,0 @@ -from lxml import etree -from pytrainer.upgrade.context import UPGRADE_CONTEXT - -def upgrade(migrate_engine): - config_file = UPGRADE_CONTEXT.conf_dir + "/conf.xml" - parser = etree.XMLParser(encoding="UTF8", recover=True) - xml_tree = etree.parse(config_file, parser=parser) - config_element = xml_tree.getroot() - del config_element.attrib["DB_version"] - xml_tree.write(config_file, xml_declaration=True, encoding="UTF-8") Deleted: pytrainer/trunk/pytrainer/upgrade/versions/012_clean_sport_data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/012_clean_sport_data.py 2011-10-23 12:15:59 UTC (rev 905) +++ pytrainer/trunk/pytrainer/upgrade/versions/012_clean_sport_data.py 2011-10-23 12:17:22 UTC (rev 906) @@ -1,4 +0,0 @@ -import pytrainer.upgrade.versions.version012 as version12 - -def upgrade(migrate_engine): - version12.upgrade(migrate_engine) \ No newline at end of file Copied: pytrainer/trunk/pytrainer/upgrade/versions/012_default_upgrade.sql (from rev 905, pytrainer/trunk/pytrainer/upgrade/versions/010_default_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/012_default_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/012_default_upgrade.sql 2011-10-23 12:17:22 UTC (rev 906) @@ -0,0 +1,2 @@ +-- sport color added in version 1.9.0 +alter table sports add color char(6); \ No newline at end of file Copied: pytrainer/trunk/pytrainer/upgrade/versions/013_remove_db_version.py (from rev 905, pytrainer/trunk/pytrainer/upgrade/versions/011_remove_db_version.py) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/013_remove_db_version.py (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/013_remove_db_version.py 2011-10-23 12:17:22 UTC (rev 906) @@ -0,0 +1,10 @@ +from lxml import etree +from pytrainer.upgrade.context import UPGRADE_CONTEXT + +def upgrade(migrate_engine): + config_file = UPGRADE_CONTEXT.conf_dir + "/conf.xml" + parser = etree.XMLParser(encoding="UTF8", recover=True) + xml_tree = etree.parse(config_file, parser=parser) + config_element = xml_tree.getroot() + del config_element.attrib["DB_version"] + xml_tree.write(config_file, xml_declaration=True, encoding="UTF-8") Added: pytrainer/trunk/pytrainer/upgrade/versions/014_clean_sport_data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/014_clean_sport_data.py (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/014_clean_sport_data.py 2011-10-23 12:17:22 UTC (rev 906) @@ -0,0 +1,4 @@ +import pytrainer.upgrade.versions.version014 as version14 + +def upgrade(migrate_engine): + version14.upgrade(migrate_engine) \ No newline at end of file Deleted: pytrainer/trunk/pytrainer/upgrade/versions/version012.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/version012.py 2011-10-23 12:15:59 UTC (rev 905) +++ pytrainer/trunk/pytrainer/upgrade/versions/version012.py 2011-10-23 12:17:22 UTC (rev 906) @@ -1,91 +0,0 @@ -# -*- coding: iso-8859-1 -*- - -#Copyright (C) Nathan Jones nc...@us... - -#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. - -from sqlalchemy.sql.expression import text -import logging - -class _SportNormalizer(object): - - """A row from the sport DB table that can be "normalized" to have invalid - values replaced with valid defaults.""" - - def __init__(self, id, weight, color, met, max_pace): - self._id = id - self._weight = weight - self._color = color - self._met = met - self._max_pace = max_pace - - def normalize(self, migrate_engine): - self._normalize_weight(migrate_engine) - self._normalize_color(migrate_engine) - self._normalize_met(migrate_engine) - self._normalize_max_pace(migrate_engine) - - def _normalize_weight(self, migrate_engine): - valid = True - try: - weight = float(self._weight) - if weight < 0: - valid = False - except: - valid = False - if not valid: - logging.debug("Sport with id '%s' has invalid weight: '%s'. Replacing with default.", self._id, self._weight) - migrate_engine.execute(text("update sports set weight=:weight where id_sports=:id"), id=self._id, weight=0.0) - - def _normalize_color(self, migrate_engine): - try: - # colors that do not have exactly 6 hexadecimal digits should also - # be invalid, but we do not expect such invalid values to exist. - int(self._color, 16) - except: - logging.debug("Sport with id '%s' has invalid color: '%s'. Replacing with default.", self._id, self._color) - migrate_engine.execute(text("update sports set color=:color where id_sports=:id"), id=self._id, color="0000ff") - - def _normalize_met(self, migrate_engine): - valid = True - if self._met is not None: - try: - met = float(self._met) - if met < 0: - valid = False - except: - valid = False - if not valid: - logging.debug("Sport with id '%s' has invalid MET: '%s'. Replacing with default.", self._id, self._met) - migrate_engine.execute(text("update sports set met=:met where id_sports=:id"), id=self._id, met=None) - - def _normalize_max_pace(self, migrate_engine): - valid = True - if self._max_pace is not None: - try: - max_pace = int(self._max_pace) - if max_pace <= 0: - valid = False - except: - valid = False - if not valid: - logging.debug("Sport with id '%s' has invalid max pace: '%s'. Replacing with default.", self._id, self._max_pace) - migrate_engine.execute(text("update sports set max_pace=:max_pace where id_sports=:id"), id=self._id, max_pace=None) - -def upgrade(migrate_engine): - sport_rows = migrate_engine.execute("select id_sports, weight, color, met, max_pace from sports") - for (id, weight, color, met, max_pace) in sport_rows: - _SportNormalizer(id, weight, color, met, max_pace).normalize(migrate_engine) - sport_rows.close() Copied: pytrainer/trunk/pytrainer/upgrade/versions/version014.py (from rev 905, pytrainer/trunk/pytrainer/upgrade/versions/version012.py) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/version014.py (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/version014.py 2011-10-23 12:17:22 UTC (rev 906) @@ -0,0 +1,91 @@ +# -*- coding: iso-8859-1 -*- + +#Copyright (C) Nathan Jones nc...@us... + +#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. + +from sqlalchemy.sql.expression import text +import logging + +class _SportNormalizer(object): + + """A row from the sport DB table that can be "normalized" to have invalid + values replaced with valid defaults.""" + + def __init__(self, id, weight, color, met, max_pace): + self._id = id + self._weight = weight + self._color = color + self._met = met + self._max_pace = max_pace + + def normalize(self, migrate_engine): + self._normalize_weight(migrate_engine) + self._normalize_color(migrate_engine) + self._normalize_met(migrate_engine) + self._normalize_max_pace(migrate_engine) + + def _normalize_weight(self, migrate_engine): + valid = True + try: + weight = float(self._weight) + if weight < 0: + valid = False + except: + valid = False + if not valid: + logging.debug("Sport with id '%s' has invalid weight: '%s'. Replacing with default.", self._id, self._weight) + migrate_engine.execute(text("update sports set weight=:weight where id_sports=:id"), id=self._id, weight=0.0) + + def _normalize_color(self, migrate_engine): + try: + # colors that do not have exactly 6 hexadecimal digits should also + # be invalid, but we do not expect such invalid values to exist. + int(self._color, 16) + except: + logging.debug("Sport with id '%s' has invalid color: '%s'. Replacing with default.", self._id, self._color) + migrate_engine.execute(text("update sports set color=:color where id_sports=:id"), id=self._id, color="0000ff") + + def _normalize_met(self, migrate_engine): + valid = True + if self._met is not None: + try: + met = float(self._met) + if met < 0: + valid = False + except: + valid = False + if not valid: + logging.debug("Sport with id '%s' has invalid MET: '%s'. Replacing with default.", self._id, self._met) + migrate_engine.execute(text("update sports set met=:met where id_sports=:id"), id=self._id, met=None) + + def _normalize_max_pace(self, migrate_engine): + valid = True + if self._max_pace is not None: + try: + max_pace = int(self._max_pace) + if max_pace <= 0: + valid = False + except: + valid = False + if not valid: + logging.debug("Sport with id '%s' has invalid max pace: '%s'. Replacing with default.", self._id, self._max_pace) + migrate_engine.execute(text("update sports set max_pace=:max_pace where id_sports=:id"), id=self._id, max_pace=None) + +def upgrade(migrate_engine): + sport_rows = migrate_engine.execute("select id_sports, weight, color, met, max_pace from sports") + for (id, weight, color, met, max_pace) in sport_rows: + _SportNormalizer(id, weight, color, met, max_pace).normalize(migrate_engine) + sport_rows.close() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-10-23 12:16:06
|
Revision: 905 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=905&view=rev Author: ncjones Date: 2011-10-23 12:15:59 +0000 (Sun, 23 Oct 2011) Log Message: ----------- Prevent start up with data from unsuported legacy version. ticket:132 Modified Paths: -------------- pytrainer/trunk/pytrainer/test/upgrade/data_test.py Modified: pytrainer/trunk/pytrainer/test/upgrade/data_test.py =================================================================== --- pytrainer/trunk/pytrainer/test/upgrade/data_test.py 2011-10-23 11:32:28 UTC (rev 904) +++ pytrainer/trunk/pytrainer/test/upgrade/data_test.py 2011-10-23 12:15:59 UTC (rev 905) @@ -18,7 +18,7 @@ import unittest from mock import Mock -from pytrainer.upgrade.data import InstalledData, DataState +from pytrainer.upgrade.data import InstalledData, DataState, DataInitializationException import pytrainer.upgrade.context class InstalledDataTest(unittest.TestCase): @@ -70,7 +70,7 @@ self._mock_migratable_db.get_upgrade_version.return_value = 1 try: self._installed_data.get_state() - except ValueError: + except DataInitializationException: pass else: self.fail() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-10-23 11:32:35
|
Revision: 904 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=904&view=rev Author: ncjones Date: 2011-10-23 11:32:28 +0000 (Sun, 23 Oct 2011) Log Message: ----------- Prevent start up with data from unsuported legacy version. ticket:132 Modified Paths: -------------- pytrainer/trunk/pytrainer/upgrade/data.py pytrainer/trunk/pytrainer/upgrade/migratedb.py Modified: pytrainer/trunk/pytrainer/upgrade/data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/data.py 2011-10-23 11:10:12 UTC (rev 903) +++ pytrainer/trunk/pytrainer/upgrade/data.py 2011-10-23 11:32:28 UTC (rev 904) @@ -65,25 +65,37 @@ data_state.update_to_current(self) def get_state(self): + """Get the current state of the installation's data. + + raises DataInitializationException if the existing data is not + compatible and cannot be upgraded. + """ version = self.get_version() available_version= self.get_available_version() if self.is_versioned(): if version == available_version: return DataState.CURRENT elif version > available_version: - raise ValueError("Current version ({0}) is greater than available version ({1}).".format(version, available_version)) + raise DataInitializationException("Existing data version ({0}) is greater than available version ({1}).".format(version, available_version)) else: return DataState.STALE else: if version == None: - return DataState.FRESH + if self.is_fresh(): + return DataState.FRESH + else: + raise DataInitializationException("Existing data version cannot be determined.") else: return DataState.LEGACY + + def is_fresh(self): + """Check if this is a fresh installation.""" + return self._migratable_db.is_empty() def get_version(self): """Get the version number of an installation's data. - If the data is empty then None is returned.""" + If the data version cannot be determined then None is returned.""" if self.is_versioned(): return self._migratable_db.get_version() else: @@ -134,6 +146,11 @@ pytrainer.upgrade.context.UPGRADE_CONTEXT = self._upgrade_context self._migratable_db.upgrade() +class DataInitializationException(Exception): + + def __init__(self, value): + self.value = value + class DataState(object): """The state of an installation's data. Modified: pytrainer/trunk/pytrainer/upgrade/migratedb.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/migratedb.py 2011-10-23 11:10:12 UTC (rev 903) +++ pytrainer/trunk/pytrainer/upgrade/migratedb.py 2011-10-23 11:32:28 UTC (rev 904) @@ -23,8 +23,10 @@ from migrate.exceptions import DatabaseNotControlledError except: from migrate.versioning.exceptions import DatabaseNotControlledError +from sqlalchemy.schema import MetaData import logging import os +import sqlalchemy import sys class MigratableDb(object): @@ -41,6 +43,16 @@ self._repository_path = _get_resource_absolute_path(repository_path) self._db_url = db_url + def is_empty(self): + """Check if the DB schema is empty. + + An empty schema indicates a new uninitialised database.""" + metadata = MetaData() + metadata.bind = sqlalchemy.create_engine(self._db_url) + metadata.reflect() + tables = metadata.tables + return not tables + def is_versioned(self): """ Check if the DB has been initiaized with version metadata.""" try: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-10-23 11:10:18
|
Revision: 903 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=903&view=rev Author: ncjones Date: 2011-10-23 11:10:12 +0000 (Sun, 23 Oct 2011) Log Message: ----------- Remove unnecessary "check DB integrity" function. ticket:132 Modified Paths: -------------- pytrainer/trunk/glade/profile.glade pytrainer/trunk/pytrainer/gui/windowprofile.py pytrainer/trunk/pytrainer/lib/ddbb.py pytrainer/trunk/pytrainer/lib/mysqlUtils.py pytrainer/trunk/pytrainer/lib/sqliteUtils.py pytrainer/trunk/pytrainer/main.py pytrainer/trunk/pytrainer/upgrade/data.py Modified: pytrainer/trunk/glade/profile.glade =================================================================== --- pytrainer/trunk/glade/profile.glade 2011-10-23 11:09:38 UTC (rev 902) +++ pytrainer/trunk/glade/profile.glade 2011-10-23 11:10:12 UTC (rev 903) @@ -1837,51 +1837,6 @@ </packing> </child> <child> - <widget class="GtkLabel" id="labelCheck"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="xpad">5</property> - <property name="ypad">5</property> - <property name="label" translatable="yes">Check</property> - </widget> - <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - </packing> - </child> - <child> - <widget class="GtkCheckButton" id="checkbuttonCheck"> - <property name="label">--check</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="draw_indicator">True</property> - <signal name="toggled" handler="on_checkbuttonCheck_toggled"/> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_padding">10</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="labelCheckDescription"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="xpad">5</property> - <property name="label" translatable="yes"><small>Was a configuration and database check requested?</small></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - </packing> - </child> - <child> <widget class="GtkLabel" id="labelNewGraph"> <property name="visible">True</property> <property name="xalign">0</property> Modified: pytrainer/trunk/pytrainer/gui/windowprofile.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowprofile.py 2011-10-23 11:09:38 UTC (rev 902) +++ pytrainer/trunk/pytrainer/gui/windowprofile.py 2011-10-23 11:10:12 UTC (rev 903) @@ -200,12 +200,6 @@ else: self.checkbuttonValidate.set_active(False) - #Show if database and config check requested - if self.pytrainer_main.startup_options.check: - self.checkbuttonCheck.set_active(True) - else: - self.checkbuttonCheck.set_active(False) - #Show if new graph activated if self.pytrainer_main.startup_options.newgraph: self.checkbuttonNewGraph.set_active(True) @@ -236,18 +230,6 @@ logging.debug("Validate deactivated") self.pytrainer_main.startup_options.validate = False - def on_checkbuttonCheck_toggled(self, widget): - if self.checkbuttonCheck.get_active(): - logging.debug( "Check activated") - if self.pytrainer_main.startup_options.check is not True: - #Need to do sanitycheck - logging.debug("Need to do sanitycheck") - self.pytrainer_main.sanityCheck() - self.pytrainer_main.startup_options.check = True - else: - logging.debug("Check deactivated") - self.pytrainer_main.startup_options.check = False - def on_checkbuttonNewGraph_toggled(self, widget): if self.checkbuttonNewGraph.get_active(): logging.debug("NewGraph activated") Modified: pytrainer/trunk/pytrainer/lib/ddbb.py =================================================================== --- pytrainer/trunk/pytrainer/lib/ddbb.py 2011-10-23 11:09:38 UTC (rev 902) +++ pytrainer/trunk/pytrainer/lib/ddbb.py 2011-10-23 11:10:12 UTC (rev 903) @@ -20,10 +20,7 @@ #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. import logging -import traceback -import commands, os import dateutil -from pytrainer.lib.date import Date #Define the tables and their columns that should be in the database #Obviously, this is not a list but a dict -> TODO: ammend name to avoid confusion!!! @@ -135,9 +132,9 @@ def connect(self): connection_ok, connection_msg = self.ddbbObject.connect() if not connection_ok: - print "ERROR: Unable to connect to database" - print connection_msg - sys.exit(connection_ok) + print "ERROR: Unable to connect to database" + print connection_msg + sys.exit(connection_ok) def disconnect(self): self.ddbbObject.disconnect() @@ -296,95 +293,15 @@ return ret_val[0][0] def create_tables(self): - global tablesList - global tablesDefaultData - logging.debug('>>') - logging.info('Checking PyTrainer database') - #if self.ddbb_type != "sqlite": - # logging.error('Support for MySQL database is decommissioned, please migrate to SQLite. Exiting check') - # exit(-2) - try: - tablesDB = self.ddbbObject.getTableList() - except: - logging.error('Not able to retrieve which tables are in DB. Printing traceback') - traceback.print_exc() - exit(-1) - - logging.debug('Found '+ str(len(tablesDB))+' tables in DB: '+ str(tablesDB)) - - # Create a compressed copy of current DB - try: - self.ddbbObject.createDatabaseBackup() - except: - logging.error('Not able to make a copy of current DB. Printing traceback and exiting') - traceback.print_exc() - exit(-1) - - #Check Tables + """Initialise the database schema from an empty database.""" + logging.info("Creating database tables") for entry in tablesList: - if entry not in tablesDB: - logging.warn('Table '+str(entry)+' does not exist in DB') - self.ddbbObject.createTableDefault(entry,tablesList[entry]) - #Check if this table has default data to add.. - if entry in tablesDefaultData: - logging.debug("Adding default data to %s" % entry) - for data_dict in tablesDefaultData[entry]: - self.insert_dict(entry, data_dict) - else: - self.ddbbObject.checkTable(entry,tablesList[entry]) - - def checkDBIntegrity(self): - '''17.11.2009 - dgranda - Retrieves tables and columns from database, checks current ones and adds something if missed. New in version 1.7.0 - args: none - returns: none''' - self.create_tables() - - #Run any functions to update or correct data - #These functions _must_ be safe to run at any time (i.e. not be version specfic or only safe to run once) - self.populate_date_time_local() - logging.debug('<<') - - def checkDBDataValues(self): - ''' Check all data in DB and report values that do not match the type ''' - global tablesList - - for table in tablesList.keys(): - pass - - def populate_date_time_local(self): - ''' Populate date_time_local and date from date_time_utc - only access records that date_time_local is NULL - using OS timezone to create local_time - - also updates date if date != local_time - - TODO - leaves date_time_local blank for records that have been manually created (as date_time_utc will actually be local time) - ''' - logging.debug('--') - listOfRecords = self.ddbbObject.select("records","id_record,date,date_time_utc,date_time_local", "date_time_local is NULL") - logging.debug("Found %d records in DB without date_time_local field populated" % (len(listOfRecords) ) ) - for record in listOfRecords: - try: - gpxfile = self.configuration.gpxdir+"/%s.gpx"%(record[0]) - dateFromUTC = Date().getDateTime(record[2]) - if os.path.isfile(gpxfile) : #GPX file exists for this record - probably not a manual record - date_time_local = str(dateFromUTC[1]) - dateFromLocal = dateFromUTC[1].strftime("%Y-%m-%d") - if record[1] != dateFromLocal: - #date field incorrect - update it - logging.debug("Updating record id: %s with date: %s and date_time_local: %s" % (record[0], dateFromLocal, date_time_local) ) - self.ddbbObject.update("records","date, date_time_local",[dateFromLocal, date_time_local], "id_record = %d" %record[0]) - else: - #date field OK, just update date_time_local - logging.debug("Updating record id: %s with date_time_local: %s" % (record[0], date_time_local) ) - self.ddbbObject.update("records","date_time_local",[date_time_local], "id_record = %d" %record[0]) - else: #Manual entry? - #For manual entries, the UTC time is the local time - #TODO figure out a way to correct this... - pass - except Exception as e: - print "Error updating record: " + str(record) - print e - logging.debug("Error updating record: " + str(record)) - logging.debug(str(e)) + self.ddbbObject.createTableDefault(entry, tablesList[entry]) + if entry in tablesDefaultData: + logging.debug("Adding default data to %s" % entry) + for data_dict in tablesDefaultData[entry]: + self.insert_dict(entry, data_dict) + + def create_backup(self): + """Create a backup of the current database.""" + self.ddbbObject.createDatabaseBackup() Modified: pytrainer/trunk/pytrainer/lib/mysqlUtils.py =================================================================== --- pytrainer/trunk/pytrainer/lib/mysqlUtils.py 2011-10-23 11:09:38 UTC (rev 902) +++ pytrainer/trunk/pytrainer/lib/mysqlUtils.py 2011-10-23 11:10:12 UTC (rev 903) @@ -168,61 +168,6 @@ sql = "update %s set %s" %(table,string) self.db.query(sql) - def checkTable(self,tableName,columns): - ''' - Checks column names and values from table and adds something if missed. New in version 1.7.0 - args: - tableName - string with name of the table - columns - dictionary containing column names and data types coming from definition - returns: none''' - logging.debug('>>') - logging.info('Inspecting '+str(tableName)+' table') - logging.debug('Columns definition: '+str(columns)) - - # Retrieving data from DB - tableInfo = self.retrieveTableInfo(tableName) - logging.debug('Raw data retrieved from DB '+str(tableName)+': '+str(tableInfo)) - #print('Raw data retrieved from DB '+str(tableName)+': '+str(tableInfo)) - #Raw data retrieved from DB sports: [('met', 'float', 'YES', '', None, ''), ('id_sports', 'int(11)', 'NO', 'PRI', None, 'auto_increment'), ('max_pace', 'int(11)', 'YES', '', None, ''), ('name', 'varchar(100)', 'YES', '', None, ''), ('weight', 'float', 'YES', '', None, '')] - - # Comparing data retrieved from DB with what comes from definition - columnsDB = {} - for field in tableInfo: - newField = {field[0]:field[1]} - columnsDB.update(newField) - logging.debug('Useful data retrieved from '+str(tableName)+' in DB: '+str(columnsDB)) - #print('Useful data retrieved from '+str(tableName)+' in DB: '+str(columnsDB)) - - # http://mail.python.org/pipermail/python-list/2002-May/141458.html - #tempDict = dict(zip(columns,columns)) - tempDict = dict(columns) - #Test for columns that are in DB that shouldn't be - result = [x for x in columnsDB if x not in tempDict] - #Test for columns that are not in the DB that should be - result2 = [x for x in tempDict if x not in columnsDB] - - logging.debug("Columns in DB that shouldnt be: "+str(result)) - logging.debug("Columns missing from DB: "+str(result2)) - - table_ok = True - if len(result) > 0: - logging.debug('Found columns in DB that should not be: '+ str(result)) - table_ok = False - for entry in result: - logging.debug('Column '+ str(entry) +' in DB but not in definition') - print "Column %s in DB but not in definition - please fix manually" % (str(entry)) - print "#TODO need to add auto fix code" - sys.exit(1) - if len(result2) > 0: # may have also different data type - logging.debug('Found columns missed in DB: '+ str(result2)) - table_ok = False - for entry in result2: - logging.debug('Column '+ str(entry) +' not found in DB') - self.addColumn(tableName,str(entry),columns[entry]) - if table_ok: - logging.info('Table '+ str(tableName) +' is OK') - logging.debug('<<') - def retrieveTableInfo(self,tableName): cur = self.db.cursor() sql = "desc %s;" %tableName @@ -245,6 +190,4 @@ traceback.print_exc() def createDatabaseBackup(self): - logging.debug('>>') logging.info("Unable to create backup for MySQL DB") - logging.debug('<<') Modified: pytrainer/trunk/pytrainer/lib/sqliteUtils.py =================================================================== --- pytrainer/trunk/pytrainer/lib/sqliteUtils.py 2011-10-23 11:09:38 UTC (rev 902) +++ pytrainer/trunk/pytrainer/lib/sqliteUtils.py 2011-10-23 11:10:12 UTC (rev 903) @@ -163,60 +163,6 @@ retorno.append(row) return retorno - def checkTable(self,tableName,columns): - '''19.11.2009 - dgranda - Checks column names and values from table and adds something if missed. New in version 1.7.0 - args: - tableName - string with name of the table - columns - dictionary containing column names and data types coming from definition - returns: none''' - logging.debug('>>') - logging.info('Inspecting '+str(tableName)+' table') - logging.debug('Columns definition: '+str(columns)) - - # Retrieving data from DB - tableInfo = self.retrieveTableInfo(tableName) - logging.debug('Raw data retrieved from DB '+str(tableName)+': '+str(tableInfo)) - #Raw data retrieved from DB laps: [(0, u'elapsed_time', u'varchar(20)', 0, None, 0), (1, u'record', u'integer', 0, None, 0), (2, u'end_lon', u'float', 0, None, 0), (3, u'lap_number', u'integer', 0, None, 0), (4, u'end_lat', u'float', 0, None, 0), (5, u'distance', u'float', 0, None, 0), (6, u'start_lon', u'float', 0, None, 0), (7, u'id_lap', u'integer', 0, None, 1), (8, u'calories', u'int', 0, None, 0), (9, u'start_lat', u'float', 0, None, 0)] - - # Comparing data retrieved from DB with what comes from definition - columnsDB = {} - for field in tableInfo: - newField = {field[1]:field[2]} - columnsDB.update(newField) - logging.debug('Useful data retrieved from '+str(tableName)+' in DB: '+str(columnsDB)) - #Useful data retrieved from laps in DB: {u'elapsed_time': u'varchar(20)', u'record': u'integer', u'end_lon': u'float', u'start_lon': u'float', u'end_lat': u'float', u'distance': u'float', u'id_lap': u'integer', u'lap_number': u'integer', u'calories': u'int', u'start_lat': u'float'} - - # http://mail.python.org/pipermail/python-list/2002-May/141458.html - #tempDict = dict(zip(columns,columns)) - tempDict = dict(columns) - #Test for columns that are in DB that shouldn't be - result = [x for x in columnsDB if x not in tempDict] - #Test for columns that are not in the DB that should be - result2 = [x for x in tempDict if x not in columnsDB] - - logging.debug("Columns in DB that shouldnt be: "+str(result)) - logging.debug("Columns missing from DB: "+str(result2)) - - table_ok = True - if len(result) > 0: - logging.debug('Found columns in DB that should not be: '+ str(result)) - table_ok = False - for entry in result: - logging.debug('Column '+ str(entry) +' in DB but not in definition') - print "Column %s in DB but not in definition - please fix manually" % (str(entry)) - print "#TODO need to add auto fix code" - sys.exit(1) - if len(result2) > 0: # may have also different data type - logging.debug('Found columns missed in DB: '+ str(result2)) - table_ok = False - for entry in result2: - logging.debug('Column '+ str(entry) +' not found in DB') - self.addColumn(tableName,str(entry),columns[entry]) - if table_ok: - logging.info('Table '+ str(tableName) +' is OK') - logging.debug('<<') - def retrieveTableInfo(self,tableName): cur = self.db.cursor() sql = "PRAGMA table_info(%s);" %tableName @@ -237,11 +183,9 @@ def createDatabaseBackup(self): - logging.debug('>>') + logging.info("Creating compressed copy of current DB") logging.debug('Database path: '+str(self.ddbb)) result = commands.getstatusoutput('gzip -c '+self.ddbb+' > '+self.ddbb+'_`date +%Y%m%d_%H%M`.gz') if result[0] != 0: raise Exception, "Copying current database does not work, error #"+str(result[0]) - else: - logging.info('Database backup successfully created') - logging.debug('<<') + logging.info('Database backup successfully created') Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2011-10-23 11:09:38 UTC (rev 902) +++ pytrainer/trunk/pytrainer/main.py 2011-10-23 11:10:12 UTC (rev 903) @@ -77,9 +77,6 @@ self.ddbb.connect() initialize_data(self.ddbb, self.environment.conf_dir) - if self.startup_options.check: - logging.debug("Checking DB as per user's request") - self.sanityCheck() self._sport_service = SportService(self.ddbb) self.record = Record(self._sport_service, data_path, self) @@ -119,7 +116,6 @@ parser.add_option("-i", "--info", action="store_const", const=logging.INFO, dest="log_level", help="enable logging at info level") parser.add_option("-w", "--warn", action="store_const", const=logging.WARNING, dest="log_level", help="enable logging at warning level") parser.add_option("--valid", action="store_true", dest="validate", help="enable validation of files imported by plugins (details at info or debug logging level) - note plugin must support validation") - parser.add_option("--check", action="store_true", dest="check", help="triggers database (only sqlite based) and configuration file sanity checks, adding fields if necessary. Backup of database is done before any change. Details at info or debug logging level") parser.add_option("--oldgraph", action="store_false", dest="newgraph", help="Turn off new graphing approach") parser.add_option("--newgraph", action="store_true", dest="newgraph", help="Deprecated Option: Turn on new graphing approach") parser.add_option("--confdir", dest="conf_dir", help="Specify the directory where application configuration will be stored.") @@ -490,13 +486,3 @@ self.activitypool.clear_pool() self.windowmain.setup() logging.debug('<<') - - def sanityCheck(self): - """23.11.2009 - dgranda - Checks database and configuration file - args: none - returns: none""" - logging.debug('>>') - logging.info('Checking database integrity') - self.ddbb.checkDBIntegrity() - logging.debug('<<') Modified: pytrainer/trunk/pytrainer/upgrade/data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/data.py 2011-10-23 11:09:38 UTC (rev 902) +++ pytrainer/trunk/pytrainer/upgrade/data.py 2011-10-23 11:10:12 UTC (rev 903) @@ -130,6 +130,7 @@ def upgrade(self): logging.info("Upgrading data from version '%s' to version '%s'.", self.get_version(), self.get_available_version()) + self._ddbb.create_backup() pytrainer.upgrade.context.UPGRADE_CONTEXT = self._upgrade_context self._migratable_db.upgrade() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-10-23 11:09:44
|
Revision: 902 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=902&view=rev Author: ncjones Date: 2011-10-23 11:09:38 +0000 (Sun, 23 Oct 2011) Log Message: ----------- Incorporate lap data migration into upgrade script. ticket:132 Modified Paths: -------------- pytrainer/trunk/pytrainer/lib/ddbb.py Added Paths: ----------- pytrainer/trunk/pytrainer/upgrade/versions/009_add_lap_details.py Removed Paths: ------------- pytrainer/trunk/pytrainer/upgrade/versions/009_default_upgrade.sql Modified: pytrainer/trunk/pytrainer/lib/ddbb.py =================================================================== --- pytrainer/trunk/pytrainer/lib/ddbb.py 2011-10-23 11:09:12 UTC (rev 901) +++ pytrainer/trunk/pytrainer/lib/ddbb.py 2011-10-23 11:09:38 UTC (rev 902) @@ -23,7 +23,6 @@ import traceback import commands, os import dateutil -import gpx from pytrainer.lib.date import Date #Define the tables and their columns that should be in the database @@ -344,7 +343,6 @@ #Run any functions to update or correct data #These functions _must_ be safe to run at any time (i.e. not be version specfic or only safe to run once) self.populate_date_time_local() - self.add_lap_metadata() logging.debug('<<') def checkDBDataValues(self): @@ -390,21 +388,3 @@ print e logging.debug("Error updating record: " + str(record)) logging.debug(str(e)) - - def add_lap_metadata(self): - logging.debug('--') - record_ids = set([r[0] for r in self.select("laps","record")]) - for record in record_ids: - try: - laps = self.select("laps","id_lap, intensity, avg_hr, max_hr, max_speed, laptrigger", "record = %s" % record) - gpxfile = self.configuration.gpxdir+"/%s.gpx"%(record) - if not laps[0][1] and os.path.isfile(gpxfile) : #GPX file exists for this record - probably not a manual record - gpxrecord = gpx.Gpx(filename=gpxfile) - for lap, gpxlap in zip(laps, gpxrecord.getLaps()): - self.ddbbObject.update("laps", "intensity, avg_hr, max_hr, max_speed, laptrigger", (gpxlap[7], gpxlap[8], gpxlap[9], gpxlap[10], "%s" % gpxlap[11]), "id_lap = %d" % lap[0]) - except Exception as e: - print "Error updating record: " + str(record) - print e - logging.debug("Error updating record: " + str(record)) - logging.debug(str(e)) - Added: pytrainer/trunk/pytrainer/upgrade/versions/009_add_lap_details.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/009_add_lap_details.py (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/009_add_lap_details.py 2011-10-23 11:09:38 UTC (rev 902) @@ -0,0 +1,77 @@ +from pytrainer.upgrade.context import UPGRADE_CONTEXT +from pytrainer.lib import gpx +from sqlalchemy import MetaData, Table, Column +from sqlalchemy.types import Integer, Text, Float, String +from sqlalchemy.sql.expression import text +import logging +import os.path + +# lap info added in version 1.9.0 +def upgrade(migrate_engine): + add_lap_details_columns(migrate_engine) + populate_lap_details_values(migrate_engine) + +def add_lap_details_columns(migrate_engine): + logging.info("Adding laps details columns") + meta = MetaData(migrate_engine) + laps_table = Table("laps", meta, autoload=True) + create_laps_column(laps_table, "intensity", String(7)) + create_laps_column(laps_table, "laptrigger", String(9)) + create_laps_column(laps_table, "max_speed", Float) + create_laps_column(laps_table, "avg_hr" , Integer) + create_laps_column(laps_table, "max_hr", Integer) + create_laps_column(laps_table, "comments", Text) + logging.info("Created laps details columns") + +def create_laps_column(laps_table, column_name, column_type): + logging.info("Adding column laps.%s" , column_name) + column = Column(column_name, column_type) + laps_table.create(column) + +def populate_lap_details_values(migrate_engine): + logging.info("Populating laps details columns") + resultset = migrate_engine.execute(text("select distinct record from laps where intensity is null")) + record_ids = [] + for row in resultset: + record_ids.append(row["record"]) + resultset.close() + for record_id in record_ids: + gpx_file = UPGRADE_CONTEXT.conf_dir + "/gpx/{0}.gpx".format(record_id) + if os.path.isfile(gpx_file): + gpx_record = gpx.Gpx(filename=gpx_file) + populate_laps_from_gpx(migrate_engine, record_id, gpx_record) + +def populate_laps_from_gpx(migrate_engine, record_id, gpx_record): + resultset = migrate_engine.execute(text("select id_lap from laps where record=:record_id" ), record_id=record_id) + lap_ids = [] + for row in resultset: + lap_ids.append(row["id_lap"]) + resultset.close() + if(len(lap_ids) > 0): + logging.info("Populating laps from GPX for record %s" , record_id) + for lap_id, gpx_lap in zip(lap_ids, gpx_record.getLaps()): + populate_lap_from_gpx(migrate_engine, lap_id, gpx_lap) + +def populate_lap_from_gpx(migrate_engine, lap_id, gpx_lap): + logging.info("Populating lap details from GPX for lap %s" , lap_id) + migrate_engine.execute(text("""update laps set + intensity=:intensity, + avg_hr=:avg_heart_rate, + max_hr=:max_heart_rate, + max_speed=:max_speed, + laptrigger=:lap_trigger + where id_lap=:lap_id"""), + intensity=gpx_lap[7], + avg_heart_rate=gpx_lap[8], + max_heart_rate=gpx_lap[9], + max_speed=float(gpx_lap[10]), + lap_trigger=gpx_lap[11], + lap_id=lap_id) + +# work around a migrate bug +try: + import migrate.versioning.exceptions as ex1 + import migrate.changeset.exceptions as ex2 + ex1.MigrateDeprecationWarning = ex2.MigrateDeprecationWarning +except ImportError: + pass Deleted: pytrainer/trunk/pytrainer/upgrade/versions/009_default_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/009_default_upgrade.sql 2011-10-23 11:09:12 UTC (rev 901) +++ pytrainer/trunk/pytrainer/upgrade/versions/009_default_upgrade.sql 2011-10-23 11:09:38 UTC (rev 902) @@ -1,7 +0,0 @@ --- lap info added in version 1.9.0 -alter table laps add intensity varchar(7); -alter table laps add laptrigger varchar(9); -alter table laps add max_speed float; -alter table laps add avg_hr int; -alter table laps add max_hr int; -alter table laps add comments text; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-10-23 11:09:18
|
Revision: 901 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=901&view=rev Author: ncjones Date: 2011-10-23 11:09:12 +0000 (Sun, 23 Oct 2011) Log Message: ----------- Fix calculation of legacy version number. ticket:132 Modified Paths: -------------- pytrainer/trunk/pytrainer/upgrade/data.py pytrainer/trunk/pytrainer/upgrade/versions/001_mysql_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/001_sqlite_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/002_mysql_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/002_sqlite_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/003_default_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/004_default_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/005_mysql_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/005_sqlite_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/006_add_record_duration.py pytrainer/trunk/pytrainer/upgrade/versions/007_mysql_upgrade.sql Modified: pytrainer/trunk/pytrainer/upgrade/data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/data.py 2011-10-22 10:43:44 UTC (rev 900) +++ pytrainer/trunk/pytrainer/upgrade/data.py 2011-10-23 11:09:12 UTC (rev 901) @@ -92,13 +92,23 @@ legacy_version = self._legacy_version_provider.get_legacy_version() if legacy_version is not None: legacy_version = int(legacy_version) - if legacy_version <= 6: - return legacy_version - elif legacy_version == 7: + if legacy_version == 1: # 1.7.1 + return 1 + elif legacy_version == 2: # 1.7.2-dev + return 2 + elif legacy_version == 3: # 1.7.2 + return 3 + elif legacy_version == 4: # 1.8.0-dev + return 4 + elif legacy_version == 5: # 1.8.0-dev + return 5 + elif legacy_version == 6: # 1.8.0 + return 8 + elif legacy_version == 7: # 1.9.0-dev return 9 - elif legacy_version == 8: + elif legacy_version == 8: # 1.9.0-dev return 10 - elif legacy_version == 9: + elif legacy_version == 9: # 1.9.0-dev return 10 return None @@ -166,8 +176,8 @@ self._conf_dir = conf_dir def get_legacy_version(self): - # In versions 1.7 and 1.8 the database version was stored as a property - # in the config file. Versions earlier than 1.7 are not supported for + # In versions 1.7.1-1.8.0 the database version was stored as a property + # in the config file. Versions earlier than 1.7.1 are not supported for # upgrades. config_file = self._conf_dir + "/conf.xml" parser = etree.XMLParser(encoding="UTF8", recover=True) Modified: pytrainer/trunk/pytrainer/upgrade/versions/001_mysql_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/001_mysql_upgrade.sql 2011-10-22 10:43:44 UTC (rev 900) +++ pytrainer/trunk/pytrainer/upgrade/versions/001_mysql_upgrade.sql 2011-10-23 11:09:12 UTC (rev 901) @@ -1,4 +1,4 @@ --- initial schema as of version 1.7.0 +-- initial schema as of version 1.7.1 create table sports ( id_sports integer primary key auto_increment, Modified: pytrainer/trunk/pytrainer/upgrade/versions/001_sqlite_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/001_sqlite_upgrade.sql 2011-10-22 10:43:44 UTC (rev 900) +++ pytrainer/trunk/pytrainer/upgrade/versions/001_sqlite_upgrade.sql 2011-10-23 11:09:12 UTC (rev 901) @@ -1,4 +1,4 @@ --- initial schema as of version 1.7.0 +-- initial schema as of version 1.7.1 create table sports ( id_sports integer primary key autoincrement, Modified: pytrainer/trunk/pytrainer/upgrade/versions/002_mysql_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/002_mysql_upgrade.sql 2011-10-22 10:43:44 UTC (rev 900) +++ pytrainer/trunk/pytrainer/upgrade/versions/002_mysql_upgrade.sql 2011-10-23 11:09:12 UTC (rev 901) @@ -1,4 +1,4 @@ --- laps added in version 1.7.1 +-- laps added in version 1.7.2 create table laps ( id_lap integer primary key auto_increment, record integer, Modified: pytrainer/trunk/pytrainer/upgrade/versions/002_sqlite_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/002_sqlite_upgrade.sql 2011-10-22 10:43:44 UTC (rev 900) +++ pytrainer/trunk/pytrainer/upgrade/versions/002_sqlite_upgrade.sql 2011-10-23 11:09:12 UTC (rev 901) @@ -1,4 +1,4 @@ --- laps added in version 1.7.1 +-- laps added in version 1.7.2 create table laps ( id_lap integer primary key autoincrement, record integer, Modified: pytrainer/trunk/pytrainer/upgrade/versions/003_default_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/003_default_upgrade.sql 2011-10-22 10:43:44 UTC (rev 900) +++ pytrainer/trunk/pytrainer/upgrade/versions/003_default_upgrade.sql 2011-10-23 11:09:12 UTC (rev 901) @@ -1,2 +1,2 @@ --- lap number added in version 1.7.1 +-- lap number added in version 1.7.2 alter table laps add lap_number integer; \ No newline at end of file Modified: pytrainer/trunk/pytrainer/upgrade/versions/004_default_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/004_default_upgrade.sql 2011-10-22 10:43:44 UTC (rev 900) +++ pytrainer/trunk/pytrainer/upgrade/versions/004_default_upgrade.sql 2011-10-23 11:09:12 UTC (rev 901) @@ -1,2 +1,2 @@ --- sport max pace added in version 1.7.2 +-- sport max pace added in version 1.8.0 alter table sports add max_pace integer; \ No newline at end of file Modified: pytrainer/trunk/pytrainer/upgrade/versions/005_mysql_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/005_mysql_upgrade.sql 2011-10-22 10:43:44 UTC (rev 900) +++ pytrainer/trunk/pytrainer/upgrade/versions/005_mysql_upgrade.sql 2011-10-23 11:09:12 UTC (rev 901) @@ -1,4 +1,4 @@ --- athlete stats added in version 1.7.2 +-- athlete stats added in version 1.8.0 create table athletestats ( id_athletestat integer primary key auto_increment, date date, Modified: pytrainer/trunk/pytrainer/upgrade/versions/005_sqlite_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/005_sqlite_upgrade.sql 2011-10-22 10:43:44 UTC (rev 900) +++ pytrainer/trunk/pytrainer/upgrade/versions/005_sqlite_upgrade.sql 2011-10-23 11:09:12 UTC (rev 901) @@ -1,4 +1,4 @@ --- athlete stats added in version 1.7.2 +-- athlete stats added in version 1.8.0 create table athletestats ( id_athletestat integer primary key autoincrement, date date, Modified: pytrainer/trunk/pytrainer/upgrade/versions/006_add_record_duration.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/006_add_record_duration.py 2011-10-22 10:43:44 UTC (rev 900) +++ pytrainer/trunk/pytrainer/upgrade/versions/006_add_record_duration.py 2011-10-23 11:09:12 UTC (rev 901) @@ -2,7 +2,7 @@ from sqlalchemy.sql.expression import text import logging -# record duration added in version 1.7.2 +# record duration added in version 1.8.0 def upgrade(migrate_engine): add_duration_column(migrate_engine) Modified: pytrainer/trunk/pytrainer/upgrade/versions/007_mysql_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/007_mysql_upgrade.sql 2011-10-22 10:43:44 UTC (rev 900) +++ pytrainer/trunk/pytrainer/upgrade/versions/007_mysql_upgrade.sql 2011-10-23 11:09:12 UTC (rev 901) @@ -1,4 +1,4 @@ --- record date_time data type changed in version 1.7.2 +-- record date_time data type changed in version 1.8.0 alter table records modify date_time_local varchar(40), modify date_time_utc varchar(40); \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-10-22 10:43:50
|
Revision: 900 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=900&view=rev Author: ncjones Date: 2011-10-22 10:43:44 +0000 (Sat, 22 Oct 2011) Log Message: ----------- Add support for sqlalchemy-migrate 0.6.1+ ticket:132 Modified Paths: -------------- pytrainer/trunk/INSTALL pytrainer/trunk/pytrainer/upgrade/migratedb.py Modified: pytrainer/trunk/INSTALL =================================================================== --- pytrainer/trunk/INSTALL 2011-10-22 07:41:34 UTC (rev 899) +++ pytrainer/trunk/INSTALL 2011-10-22 10:43:44 UTC (rev 900) @@ -24,7 +24,7 @@ libxslt-1.1.26 sqlite-3.7.5 (sqlite is preferred as db than mysql, MySQL-python has been reported to be installed if so) python-sqlalchemy-0.6.8 (sqlalchemy >= 0.6.4) -python-migrate-0.6 (sqlalchemy-migrate-0.6.0) -- In 0.6.1 migrate.*.exceptions are moved to migrate.exceptions -- +python-migrate-0.6 (sqlalchemy-migrate >=0.6.0) - Only needed if correspondent plugin is enabled: gpsbabel-1.3.5 ("Garmin via GPSBabel 1.3.5" aka garmin_hr) - No longer available in official F15 repositories Modified: pytrainer/trunk/pytrainer/upgrade/migratedb.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/migratedb.py 2011-10-22 07:41:34 UTC (rev 899) +++ pytrainer/trunk/pytrainer/upgrade/migratedb.py 2011-10-22 10:43:44 UTC (rev 900) @@ -17,7 +17,12 @@ #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. from migrate.versioning.api import db_version, upgrade, version, version_control -from migrate.versioning.exceptions import DatabaseNotControlledError +# sqlalchemy-migrate 0.6.1 broke backwards compatibility +# so we need to try importing exceptions from one of two packages +try: + from migrate.exceptions import DatabaseNotControlledError +except: + from migrate.versioning.exceptions import DatabaseNotControlledError import logging import os import sys This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-10-22 07:41:41
|
Revision: 899 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=899&view=rev Author: ncjones Date: 2011-10-22 07:41:34 +0000 (Sat, 22 Oct 2011) Log Message: ----------- Fix data migration from 1.7.1 - 1.7.2 ticket:132 Modified Paths: -------------- pytrainer/trunk/pytrainer/lib/ddbb.py Added Paths: ----------- pytrainer/trunk/pytrainer/upgrade/versions/006_add_record_duration.py Removed Paths: ------------- pytrainer/trunk/pytrainer/upgrade/versions/006_default_upgrade.sql Modified: pytrainer/trunk/pytrainer/lib/ddbb.py =================================================================== --- pytrainer/trunk/pytrainer/lib/ddbb.py 2011-10-21 17:09:03 UTC (rev 898) +++ pytrainer/trunk/pytrainer/lib/ddbb.py 2011-10-22 07:41:34 UTC (rev 899) @@ -344,7 +344,6 @@ #Run any functions to update or correct data #These functions _must_ be safe to run at any time (i.e. not be version specfic or only safe to run once) self.populate_date_time_local() - self.populate_duration_from_time() self.add_lap_metadata() logging.debug('<<') @@ -355,55 +354,6 @@ for table in tablesList.keys(): pass - def populate_duration_from_time(self): - ''' - Populate duration from time field - only for time can be parsed as an int - - also check pace value - ''' - logging.debug('--') - #listOfRecords = self.select_dict("records",('id_record','time'), "duration is NULL") - #logging.debug("Found %d records in DB without date_time_local field populated" % (len(listOfRecords) ) ) - listOfRecords = self.select_dict("records",('id_record','time', 'duration', 'pace', 'average', 'maxspeed', 'maxpace')) - logging.debug("Found %d records in DB" % (len(listOfRecords) ) ) - for record in listOfRecords: - data = {} - try: - duration = int(record['time']) - except Exception as e: - logging.info( "Error parsing time (%s) as int for record_id: %s" % (record['time'], record['id_record'])) - continue - if duration != record['duration']: - logging.debug("setting record %s duration to %d" % (record['id_record'], duration)) - data['duration'] = duration - #Check pace - try: - db_avg_speed = float(record['average']) #km/hr - db_pace = float(record['pace']) #min/km - db_max_speed = float(record['maxspeed']) - db_max_pace = float(record['maxpace']) - calc_pace = 60 / db_avg_speed - calc_max_pace = 60 / db_max_speed - #Update DB if db_pace != calc_pace - if "%.2f" % db_pace != "%.2f" % calc_pace: - print "DB Pace: %.2f, Calc: %.2f" % (db_pace, calc_pace) - #data['pace'] = calc_pace - else: - print "Pace ok: %.2f" % db_pace - #Update DB if db_max_pace != calc_max_pace - if "%.2f" % db_max_pace != "%.2f" % calc_max_pace: - print "DB Max Pace: %.2f, Calc: %.2f" % (db_max_pace, calc_max_pace) - #data['max_pace'] = calc_max_pace - else: - print "Max pace ok: %.2f" % db_max_pace - except Exception as e: - #print type(e), e - logging.debug("Error with converting pace (%s), average speed(%s), max speed (%s), max pace(%s)" % (record['pace'], record['average'], record['maxspeed'], record['maxpace'])) - #Update DB if any changes - if len(data) > 0: - self.update_dict("records",data ,"id_record = %d"%record['id_record']) - def populate_date_time_local(self): ''' Populate date_time_local and date from date_time_utc only access records that date_time_local is NULL Added: pytrainer/trunk/pytrainer/upgrade/versions/006_add_record_duration.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/006_add_record_duration.py (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/006_add_record_duration.py 2011-10-22 07:41:34 UTC (rev 899) @@ -0,0 +1,40 @@ +from sqlalchemy import MetaData, Table, Column, Integer +from sqlalchemy.sql.expression import text +import logging + +# record duration added in version 1.7.2 + +def upgrade(migrate_engine): + add_duration_column(migrate_engine) + populate_duration_values(migrate_engine) + +def add_duration_column(migrate_engine): + logging.info("Adding records.duration column") + meta = MetaData(migrate_engine) + records_table = Table("records", meta, autoload=True) + duration_column = Column("duration", Integer) + duration_column.create(records_table) + logging.info("Created records.duration column") + +def populate_duration_values(migrate_engine): + logging.info("Populating records.duration column") + records = migrate_engine.execute("select id_record, time from records where duration is null") + for record in records: + record_id = record["id_record"] + record_time = record["time"] + try: + duration = int(record_time) + except: + logging.info("Error parsing time (%s) as int for record_id: %s" % (record_time, record_id)) + duration = 0 + logging.debug("setting record %s duration to %d" , record_id, duration) + migrate_engine.execute(text("update records set duration=:duration where id_record=:record_id"), duration=duration, record_id=record_id) + records.close() + +# work around a migrate bug +try: + import migrate.versioning.exceptions as ex1 + import migrate.changeset.exceptions as ex2 + ex1.MigrateDeprecationWarning = ex2.MigrateDeprecationWarning +except ImportError: + pass Deleted: pytrainer/trunk/pytrainer/upgrade/versions/006_default_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/006_default_upgrade.sql 2011-10-21 17:09:03 UTC (rev 898) +++ pytrainer/trunk/pytrainer/upgrade/versions/006_default_upgrade.sql 2011-10-22 07:41:34 UTC (rev 899) @@ -1,2 +0,0 @@ --- record duration added in version 1.7.2 -alter table records add duration integer; \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2011-10-21 17:09:10
|
Revision: 898 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=898&view=rev Author: dgranda Date: 2011-10-21 17:09:03 +0000 (Fri, 21 Oct 2011) Log Message: ----------- Setting proper format for datetime.date objects before executing sql query. MySQL library might have same behavior, not checked - ticket #149 Modified Paths: -------------- pytrainer/trunk/pytrainer/lib/sqliteUtils.py Modified: pytrainer/trunk/pytrainer/lib/sqliteUtils.py =================================================================== --- pytrainer/trunk/pytrainer/lib/sqliteUtils.py 2011-10-20 23:23:33 UTC (rev 897) +++ pytrainer/trunk/pytrainer/lib/sqliteUtils.py 2011-10-21 17:09:03 UTC (rev 898) @@ -109,6 +109,8 @@ return "\"" + value + "\"" elif type(value) == datetime.datetime: return value.strftime("\"%Y-%m-%d %H:%M:%S%z\"") + elif type(value) == datetime.date: + return value.strftime("\"%Y-%m-%d\"") else: return str(value) logging.debug('<<') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2011-10-20 23:23:39
|
Revision: 897 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=897&view=rev Author: dgranda Date: 2011-10-20 23:23:33 +0000 (Thu, 20 Oct 2011) Log Message: ----------- Fixed encoding issue that prevented some days of the week and associated information to be shown in stacked bars graph under week tab Modified Paths: -------------- pytrainer/trunk/pytrainer/weekgraph.py Modified: pytrainer/trunk/pytrainer/weekgraph.py =================================================================== --- pytrainer/trunk/pytrainer/weekgraph.py 2011-10-20 17:41:53 UTC (rev 896) +++ pytrainer/trunk/pytrainer/weekgraph.py 2011-10-20 23:23:33 UTC (rev 897) @@ -43,5 +43,5 @@ def getDays(date_ini): #TODO look at using calendar.day_abbr for this - return [(datetime.datetime.strptime(date_ini, "%Y-%m-%d")+datetime.timedelta(x)).strftime("%a") for x in xrange(0,7)] + return [unicode((datetime.datetime.strptime(date_ini, "%Y-%m-%d")+datetime.timedelta(x)).strftime("%a")) for x in xrange(0,7)] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2011-10-20 17:42:02
|
Revision: 896 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=896&view=rev Author: dgranda Date: 2011-10-20 17:41:53 +0000 (Thu, 20 Oct 2011) Log Message: ----------- Added portuguese localization (thanks to Pedro Ribeiro) Modified Paths: -------------- pytrainer/trunk/pytrainer/gui/aboutdialog.py pytrainer/trunk/setup.py pytrainer/trunk/utils/translator.sh Added Paths: ----------- pytrainer/trunk/locale/pt/ pytrainer/trunk/locale/pt/LC_MESSAGES/ pytrainer/trunk/locale/pt/LC_MESSAGES/Makefile pytrainer/trunk/locale/pt/LC_MESSAGES/pytrainer.mo pytrainer/trunk/locale/pt/LC_MESSAGES/pytrainer_pt.po Added: pytrainer/trunk/locale/pt/LC_MESSAGES/Makefile =================================================================== --- pytrainer/trunk/locale/pt/LC_MESSAGES/Makefile (rev 0) +++ pytrainer/trunk/locale/pt/LC_MESSAGES/Makefile 2011-10-20 17:41:53 UTC (rev 896) @@ -0,0 +1,8 @@ +default: + msgfmt pytrainer_pt.po -o ./pytrainer.mo + +merge: + msgmerge pytrainer_pt.po pytrainer_pt.po_new > pytrainer_pt.po.tmp + mv pytrainer_pt.po.tmp pytrainer_pt.po + rm pytrainer_pt.po_new + Property changes on: pytrainer/trunk/locale/pt/LC_MESSAGES/Makefile ___________________________________________________________________ Added: svn:executable + * Added: pytrainer/trunk/locale/pt/LC_MESSAGES/pytrainer.mo =================================================================== (Binary files differ) Property changes on: pytrainer/trunk/locale/pt/LC_MESSAGES/pytrainer.mo ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: pytrainer/trunk/locale/pt/LC_MESSAGES/pytrainer_pt.po =================================================================== --- pytrainer/trunk/locale/pt/LC_MESSAGES/pytrainer_pt.po (rev 0) +++ pytrainer/trunk/locale/pt/LC_MESSAGES/pytrainer_pt.po 2011-10-20 17:41:53 UTC (rev 896) @@ -0,0 +1,2427 @@ +# Portuguese translation for pytrainer's messages +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the pytrainer package. +# Pedro Ribeiro <p.m...@gm...>, 2011 +# +msgid "" +msgstr "" +"Project-Id-Version: pytrainer 1.9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-10-20 19:14+0200\n" +"PO-Revision-Date: 2011-10-20 19:14+0100\n" +"Last-Translator: Pedro Ribeiro <p.m...@gm...>\n" +"Language-Team: Portuguese <tr...@de...>\n" +"Language: Portuguese\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: glade/calendar.glade:7 +msgid "Calendar" +msgstr "Calendário" + +#: glade/equipment.glade:109 +msgid "<b>Equipment List</b>" +msgstr "<b>Lista de Equipamento</b>" + +#: glade/equipment.glade:149 +#: glade/equipment.glade:406 +#: pytrainer/gui/equipment.py:98 +msgid "Description" +msgstr "Descrição" + +#: glade/equipment.glade:174 +#: glade/equipment.glade:431 +msgid "Life Expectancy" +msgstr "Esperança de Vida" + +#: glade/equipment.glade:211 +#: glade/equipment.glade:467 +msgid "Prior Usage" +msgstr "Utilização Anterior" + +#: glade/equipment.glade:243 +#: glade/equipment.glade:499 +#: pytrainer/gui/equipment.py:102 +msgid "Active" +msgstr "Activo" + +#: glade/equipment.glade:277 +#: glade/equipment.glade:533 +#: pytrainer/gui/windowimportdata.py:353 +msgid "Notes" +msgstr "Notas" + +#: glade/equipment.glade:366 +msgid "<b>Add New Equipment</b>" +msgstr "<b>Acrescentar Novo Equipamento</b>" + +#: glade/equipment.glade:622 +msgid "<b>Edit Equipment</b>" +msgstr "<b>Editar Equipamento</b>" + +#: glade/equipment.glade:651 +msgid "Really delete the equipment item?" +msgstr "De certeza que quer apagar o equipamento?" + +#: glade/equipment.glade:704 +msgid "<b>Delete Equipment</b>" +msgstr "<b>Apagar Equipamento</b>" + +#: glade/extensions.glade:9 +#: glade/pytrainer.glade:163 +msgid "Extensions" +msgstr "Extensões" + +#: glade/extensions.glade:54 +msgid "<b>Extension Details</b>" +msgstr "<b>Detalhes da Extensão</b>" + +#: glade/extensions.glade:67 +msgid "name-entry" +msgstr "nome" + +#: glade/extensions.glade:82 +#: glade/plugins.glade:144 +#: glade/profile.glade:728 +#: glade/pytrainer.glade:5703 +msgid "Name:" +msgstr "Nome:" + +#: glade/extensions.glade:96 +#: glade/plugins.glade:115 +msgid "Status:" +msgstr "Estado:" + +#: glade/extensions.glade:110 +#: glade/plugins.glade:86 +#: glade/pytrainer.glade:6548 +msgid "Description:" +msgstr "Descrição:" + +#: glade/extensions.glade:124 +#: glade/plugins.glade:100 +msgid "status-entry" +msgstr "estado" + +#: glade/extensions.glade:139 +msgid "description-entry" +msgstr "descrição" + +#: glade/importdata.glade:7 +#: glade/importdata.glade:325 +msgid "Import" +msgstr "Importar" + +#: glade/importdata.glade:36 +msgid "" +"Test 1\n" +"Test 2" +msgstr "" +"Teste 1\n" +"Teste 2" + +#: glade/importdata.glade:46 +msgid "<b>Select your GPS device</b>" +msgstr "<b>Seleccione o seu dispositivo GPS</b>" + +#: glade/importdata.glade:64 +msgid "Import from GPS Device is not yet implemented" +msgstr "Importação a partir do Dispositivo GPS ainda não está implementada" + +#: glade/importdata.glade:92 +msgid "<b>Tools</b>" +msgstr "<b>Ferramentas</b>" + +#: glade/importdata.glade:111 +msgid "Rescan" +msgstr "Rescan" + +#: glade/importdata.glade:115 +msgid "Rescan system for available tools" +msgstr "Fazer o rescan do sistema à procura de ferramentas" + +#: glade/importdata.glade:168 +msgid "<b>Import from GPS Device</b>" +msgstr "<b>Importar do Dispositivo GPS</b>" + +#: glade/importdata.glade:221 +msgid "Remove selected files and the associated activities" +msgstr "Remover ficheiros seleccionados e actividades associadas" + +#: glade/importdata.glade:239 +msgid "Add files to import activities from" +msgstr "Acrescentar ficheiros a partir dos quais importar actividades" + +#: glade/importdata.glade:264 +msgid "<b>Add file(s) to import activities from</b>" +msgstr "<b>Acrescentar ficheiro(s) a partir do(s) qual(is) importar actividades" + +#: glade/importdata.glade:307 +msgid "<b>Select activities to import</b>" +msgstr "<b>Seleccionar actividades a importar</b>" + +#: glade/importdata.glade:330 +msgid "Import selected activities" +msgstr "Importar actividades seleccionadas" + +#: glade/importdata.glade:347 +msgid "Close Import dialog" +msgstr "Fechar diálogo de importação" + +#: glade/importdata.glade:387 +msgid "<b>Import from File</b>" +msgstr "<b>Importar a partir de Ficheiro</b>" + +#: glade/importdata.glade:464 +msgid "<b>Plugins</b>" +msgstr "<b>Plugins</b>" + +#: glade/importdata.glade:491 +msgid "Import from GPS Device" +msgstr "Importar a partir do Dispositivo GPS" + +#: glade/importdata.glade:510 +msgid "Import from File" +msgstr "Importar a partir de Ficheiro" + +#: glade/importdata.glade:525 +msgid "Launch 'File Select' on start" +msgstr "Executar o 'Escolher Ficheiro' ao iniciar" + +#: glade/importdata.glade:530 +msgid "Automatically start the file selection dialog" +msgstr "Executar automaticamente o diálogo de selecção de ficheiro" + +#: glade/importdata.glade:546 +#: glade/plugins.glade:9 +msgid "Plugins" +msgstr "Plugins" + +#: glade/importdata.glade:572 +msgid "<b>Default to Tab</b>" +msgstr "<b>Separador predefinido</b>" + +#: glade/importdata.glade:595 +msgid "Reset" +msgstr "Reset" + +#: glade/importdata.glade:611 +msgid "Save" +msgstr "Guardar" + +#: glade/importdata.glade:670 +msgid "<b>Options</b>" +msgstr "<b>Opções</b>" + +#: glade/importdata.glade:702 +msgid "<b>Select file to import from</b>" +msgstr "<b>Escolher ficheiro a partir do qual importar</b>" + +#: glade/importdata.glade:731 +msgid "Tab" +msgstr "Tab" + +#: glade/importdata.glade:746 +msgid "Comma" +msgstr "Vírgula" + +#: glade/importdata.glade:763 +msgid "Other" +msgstr "Outro" + +#: glade/importdata.glade:799 +msgid "Read File" +msgstr "Ler Ficheiro" + +#: glade/importdata.glade:820 +msgid "<b>File delimiter</b>" +msgstr "<b>Delimitador de campos no ficheiro</b>" + +#: glade/importdata.glade:864 +#: pytrainer/gui/windowmain.py:116 +#: pytrainer/gui/windowmain.py:131 +#: pytrainer/gui/windowmain.py:184 +#: pytrainer/gui/windowmain.py:1494 +#: pytrainer/gui/dialogselecttrack.py:40 +msgid "Date" +msgstr "Data" + +#: glade/importdata.glade:877 +#: glade/importdata.glade:918 +#: glade/importdata.glade:933 +#: glade/importdata.glade:1128 +#: glade/importdata.glade:1143 +#: glade/importdata.glade:1158 +#: glade/importdata.glade:1173 +#: glade/importdata.glade:1188 +#: glade/importdata.glade:1203 +#: glade/importdata.glade:1218 +#: glade/importdata.glade:1233 +#: glade/importdata.glade:1248 +#: glade/importdata.glade:1263 +#: glade/importdata.glade:1278 +#: glade/importdata.glade:1293 +msgid "Exclude" +msgstr "Excluir" + +#: glade/importdata.glade:892 +#: pytrainer/recordgraph.py:134 +#: pytrainer/recordgraph.py:136 +#: pytrainer/recordgraph.py:138 +#: pytrainer/recordgraph.py:140 +#: pytrainer/recordgraph.py:142 +#: pytrainer/recordgraph.py:144 +#: pytrainer/recordgraph.py:146 +#: pytrainer/monthgraph.py:26 +#: pytrainer/heartrategraph.py:36 +#: pytrainer/totalgraph.py:24 +#: pytrainer/yeargraph.py:26 +#: pytrainer/daygraph.py:52 +#: pytrainer/daygraph.py:54 +#: pytrainer/daygraph.py:56 +#: pytrainer/weekgraph.py:28 +msgid "Distance (km)" +msgstr "Distância (km)" + +#: glade/importdata.glade:905 +msgid "Duration (sec)" +msgstr "Duração (s)" + +#: glade/importdata.glade:947 +msgid "<b>PyTrainer Field</b>" +msgstr "<b>Campo do PyTrainer</b>" + +#: glade/importdata.glade:958 +msgid "<b>File Column</b>" +msgstr "<b>Coluna no Ficheiro</b>" + +#: glade/importdata.glade:972 +#: pytrainer/gui/windowmain.py:115 +#: pytrainer/gui/windowmain.py:1493 +msgid "Title" +msgstr "Título" + +#: glade/importdata.glade:985 +msgid "Descent (m)" +msgstr "Descida (m)" + +#: glade/importdata.glade:998 +msgid "Accent (m)" +msgstr "Subida (m)" + +#: glade/importdata.glade:1011 +msgid "Calories (kcal)" +msgstr "Calorias (kcal)" + +#: glade/importdata.glade:1024 +msgid "Max Speed (km/h)" +msgstr "Vel Máxima (km/h)" + +#: glade/importdata.glade:1037 +#: pytrainer/monthgraph.py:29 +#: pytrainer/totalgraph.py:27 +#: pytrainer/yeargraph.py:29 +#: pytrainer/weekgraph.py:31 +msgid "Average Speed (km/h)" +msgstr "Vel Média (km/h)" + +#: glade/importdata.glade:1050 +#: glade/pytrainer.glade:277 +#: pytrainer/gui/windowmain.py:110 +#: pytrainer/gui/windowmain.py:118 +#: pytrainer/gui/windowmain.py:140 +#: pytrainer/gui/windowmain.py:1496 +#: pytrainer/gui/windowimportdata.py:353 +#: pytrainer/gui/windowrecord.py:210 +#: pytrainer/gui/windowprofile.py:65 +msgid "Sport" +msgstr "Desporto" + +#: glade/importdata.glade:1063 +msgid "Average Heartrate (bpm)" +msgstr "Ritmo cardíaco médio (ppm)" + +#: glade/importdata.glade:1076 +msgid "Max Heartrate (bpm)" +msgstr "Ritmo cardíaco máx (ppm)" + +#: glade/importdata.glade:1089 +#: pytrainer/recordgraph.py:138 +msgid "Pace (min/km)" +msgstr "Ritmo (min/km)" + +#: glade/importdata.glade:1102 +msgid "Max Pace (min/km)" +msgstr "Ritmo Máximo (min/km)" + +#: glade/importdata.glade:1115 +#: glade/newrecord.glade:1094 +#: pytrainer/gui/windowmain.py:167 +msgid "Comments" +msgstr "Comentários" + +#: glade/importdata.glade:1309 +msgid "Force sport to:" +msgstr "Forçar desporto a:" + +#: glade/importdata.glade:1323 +#: glade/newrecord.glade:404 +msgid " " +msgstr " " + +#: glade/importdata.glade:1394 +msgid "<b>Map Columns</b>" +msgstr "<b>Mapa de Colunas</b>" + +#: glade/importdata.glade:1414 +msgid "" +"<small>This is an experiemental import for delimited files\n" +"1) Select a file\n" +"2) Click 'Read File' to analyse the file\n" +"3) Map columns in the file to pytrainer data elements (Date is required)\n" +"4) Click 'Import Data'</small>" +msgstr "" +"<small>Esta é uma importação experimental para ficheiros delimitados\n" +"1) Escolher um ficheiro\n" +"2) Clicar em 'Ler Ficheiro' para analisar o ficheiro\n" +"3) Mapear colunas do ficheiro para elementos de dados do pytrainer (são\n" +" necessários dados)\n" +"4) Clicar em 'Importar Dados'</small>" + +#: glade/importdata.glade:1427 +msgid "Import Data" +msgstr "Importar Dados" + +#: glade/importdata.glade:1467 +msgid "<b>Import from CSV</b>" +msgstr "<b>Importar a partir do CSV</b>" + +#: glade/newrecord.glade:7 +#: pytrainer/gui/windowmain.py:2160 +msgid "New Entry" +msgstr "Nova Entrada" + +#: glade/newrecord.glade:61 +msgid "Title:" +msgstr "Título:" + +#: glade/newrecord.glade:85 +msgid "GPX File:" +msgstr "Ficheiro GPX:" + +#: glade/newrecord.glade:129 +msgid "Calculate Values" +msgstr "Calcular Valores" + +#: glade/newrecord.glade:149 +msgid "Sport:" +msgstr "Desporto:" + +#: glade/newrecord.glade:184 +msgid "<b>Main</b>" +msgstr "<b>Principal</b>" + +#: glade/newrecord.glade:221 +msgid "Distance (Km):" +msgstr "Distância (Km):" + +#: glade/newrecord.glade:230 +#: glade/newrecord.glade:355 +#: glade/newrecord.glade:558 +#: glade/newrecord.glade:697 +#: glade/newrecord.glade:958 +#: glade/profile.glade:1548 +msgid "Calculate" +msgstr "Calcular" + +#: glade/newrecord.glade:248 +msgid "Duration:" +msgstr "Duração:" + +#: glade/newrecord.glade:279 +#: glade/newrecord.glade:306 +msgid ":" +msgstr ":" + +#: glade/newrecord.glade:376 +msgid "Date:" +msgstr "Data:" + +#: glade/newrecord.glade:445 +msgid "Start Time:" +msgstr "Hora de Início:" + +#: glade/newrecord.glade:461 +msgid "12:00:00" +msgstr "12:00:00" + +#: glade/newrecord.glade:486 +#: glade/profile.glade:1586 +msgid "<b>General</b>" +msgstr "<b>Geral</b>" + +#: glade/newrecord.glade:522 +msgid "Max (km/h):" +msgstr "Máx. (km/h):" + +#: glade/newrecord.glade:547 +msgid "Average (km/h)" +msgstr "Média (km/h)" + +#: glade/newrecord.glade:593 +msgid "<b>Speed</b>" +msgstr "<b>Velocidade</b>" + +#: glade/newrecord.glade:612 +msgid "Quick Entry" +msgstr "Entrada Rápida" + +#: glade/newrecord.glade:644 +msgid "Max (min/km):" +msgstr "Máx. (min/km):" + +#: glade/newrecord.glade:671 +msgid "Pace (min/km):" +msgstr "Ritmo (min/km):" + +#: glade/newrecord.glade:718 +msgid "<b>Pace</b>" +msgstr "<b>Ritmo</b>" + +#: glade/newrecord.glade:754 +msgid "Ascent:" +msgstr "Subida:" + +#: glade/newrecord.glade:780 +msgid "Descent:" +msgstr "Descida:" + +#: glade/newrecord.glade:813 +msgid "<b>Accumulated Altitude Change</b>" +msgstr "<b>Mudança de Altitude Acumulada</b>" + +#: glade/newrecord.glade:850 +msgid "Max (bpm):" +msgstr "Máx (ppm):" + +#: glade/newrecord.glade:862 +msgid "Heart rate:" +msgstr "Ritmo Cardíaco:" + +#: glade/newrecord.glade:902 +#: pytrainer/gui/windowmain.py:122 +#: pytrainer/gui/windowmain.py:165 +#: pytrainer/gui/windowmain.py:1500 +#: pytrainer/monthgraph.py:30 +#: pytrainer/totalgraph.py:28 +#: pytrainer/yeargraph.py:30 +#: pytrainer/weekgraph.py:32 +msgid "Calories" +msgstr "Calorias" + +#: glade/newrecord.glade:931 +msgid "<small><b>Note:</b> In order to calculate the calories you must set the sport MET (in Preferences->Sport) </small>" +msgstr "<small><b>Nota:</b> Para cálculo das calorias deve ser introduzido o MET do desporto (em Preferências->Desporto) </small>" + +#: glade/newrecord.glade:1005 +msgid "<b>Heart Rate</b>" +msgstr "<b>Ritmo Cardíaco</b>" + +#: glade/newrecord.glade:1027 +msgid "Advanced" +msgstr "Avançado" + +#: glade/newrecord.glade:1079 +msgid "<b>Comments</b>" +msgstr "<b>Comentários</b>" + +#: glade/newrecord.glade:1134 +msgid "<i>There are no active equipment items.</i>" +msgstr "<i>Não há items de equipamento activos.</i>" + +#: glade/newrecord.glade:1188 +msgid "<b>Associated Equipment</b>" +msgstr "<b>Equipamento Associado</b>" + +#: glade/newrecord.glade:1203 +#: glade/profile.glade:1446 +msgid "Equipment" +msgstr "Equipamento" + +#: glade/plugins.glade:53 +msgid "<b>Plugin Details</b>" +msgstr "<b>Detalhes do Plugin</b>" + +#: glade/plugins.glade:68 +msgid "description-entry " +msgstr "descrição" + +#: glade/plugins.glade:129 +msgid "nameEntry" +msgstr "nome" + +#: glade/profile.glade:7 +msgid "Preferences" +msgstr "Preferências" + +#: glade/profile.glade:37 +msgid "Metric system" +msgstr "Sistema métrico" + +#: glade/profile.glade:53 +msgid "U.S. customary units" +msgstr "Unidades habituais nos E.U.A." + +#: glade/profile.glade:74 +msgid "<b>System of Measurement</b>" +msgstr "<b>Sistema de Medidas</b>" + +#: glade/profile.glade:103 +#: glade/pytrainer.glade:2111 +msgid "Google" +msgstr "Google" + +#: glade/profile.glade:118 +#: glade/pytrainer.glade:2094 +msgid "Open Street Map" +msgstr "Open Street Map" + +#: glade/profile.glade:140 +msgid "<b>Default Map Viewer</b>" +msgstr "<b>Visualizador de Mapas Predefinido</b>" + +#: glade/profile.glade:176 +msgid "Database type:" +msgstr "Tipo de Base de Dados:" + +#: glade/profile.glade:187 +msgid "Database host:" +msgstr "Servidor de Base de Dados:" + +#: glade/profile.glade:213 +msgid "Database name:" +msgstr "Nome da Base de Dados:" + +#: glade/profile.glade:252 +msgid "Database user:" +msgstr "Utilizador da Base de Dados:" + +#: glade/profile.glade:267 +msgid "Database pass:" +msgstr "Password para a Base de Dados:" + +#: glade/profile.glade:318 +msgid "<b>Database</b>" +msgstr "<b>Base de Dados</b>" + +#: glade/profile.glade:340 +msgid "General" +msgstr "Geral" + +#: glade/profile.glade:369 +msgid "User name:" +msgstr "Nome de Utilizador:" + +#: glade/profile.glade:380 +msgid "Gender:" +msgstr "Sexo:" + +#: glade/profile.glade:407 +#: glade/pytrainer.glade:5728 +msgid "Height:" +msgstr "Altura" + +#: glade/profile.glade:447 +#: glade/pytrainer.glade:5715 +msgid "Date of birth:" +msgstr "Data de Nascimento:" + +#: glade/profile.glade:520 +msgid "Weight:" +msgstr "Peso:" + +#: glade/profile.glade:542 +#: glade/pytrainer.glade:5790 +msgid "<b>Athlete Details</b>" +msgstr "<b>Detalhes do Atleta</b>" + +#: glade/profile.glade:557 +#: glade/pytrainer.glade:5893 +msgid "Athlete" +msgstr "Atleta" + +#: glade/profile.glade:672 +msgid "<b>Sport List</b>" +msgstr "<b>Lista de Desportos</b>" + +#: glade/profile.glade:684 +msgid "llist" +msgstr "llista" + +#: glade/profile.glade:739 +msgid "M.E.T.:" +msgstr "M.E.T.:" + +#: glade/profile.glade:766 +msgid "Extra Weight:" +msgstr "Peso Extra:" + +#: glade/profile.glade:802 +#: glade/profile.glade:1218 +msgid "More information on determining yor M.E.T sport coefficient on Wikipedia" +msgstr "Mais informações para determinar o seu coeficiente desportivo M.E.T. na Wikipédia" + +#: glade/profile.glade:822 +msgid "Maximum Pace:" +msgstr "Ritmo Máximo:" + +#: glade/profile.glade:950 +msgid "<b>Add New Sport</b>" +msgstr "<b>Acrescentar Novo Desporto</b>" + +#: glade/profile.glade:965 +msgid "new" +msgstr "novo" + +#: glade/profile.glade:996 +msgid "" +"Deleting a sport removes associated records.\n" +"Continue?" +msgstr "" +"Apagar um desporto remove registos associados.\n" +"Continuar?" + +#: glade/profile.glade:1078 +msgid "<b>Delete Sport</b>" +msgstr "<b>Apagar Desporto</b>" + +#: glade/profile.glade:1110 +msgid "delete" +msgstr "apagar" + +#: glade/profile.glade:1143 +msgid "Name" +msgstr "Nome" + +#: glade/profile.glade:1166 +msgid "M.E.T." +msgstr "M.E.T." + +#: glade/profile.glade:1193 +#: pytrainer/gui/windowprofile.py:65 +msgid "Extra Weight" +msgstr "Peso Extra" + +#: glade/profile.glade:1238 +#: pytrainer/gui/windowprofile.py:65 +msgid "Maximum Pace" +msgstr "Ritmo Máximo" + +#: glade/profile.glade:1265 +#: pytrainer/gui/windowmain.py:188 +#: pytrainer/gui/windowprofile.py:65 +msgid "Color" +msgstr "Cor" + +#: glade/profile.glade:1375 +msgid "<b>Edit Sport</b>" +msgstr "<b>Editar Desporto</b>" + +#: glade/profile.glade:1386 +msgid "<b>lalaal</b>" +msgstr "<b>lalaal</b>" + +#: glade/profile.glade:1408 +msgid "edit" +msgstr "editar" + +#: glade/profile.glade:1424 +msgid "Sports" +msgstr "Desportos" + +#: glade/profile.glade:1479 +msgid "Maximum heart rate:" +msgstr "Ritmo cardíaco máximo:" + +#: glade/profile.glade:1490 +msgid "Resting heart rate:" +msgstr "Ritmo cardíaco em repouso:" + +#: glade/profile.glade:1535 +msgid "<small><b>Note:</b> Maximum heart rate is calculated by subtracting the number 220 minus your age. </small>" +msgstr "<small><b>Nota:</b> O ritmo cardíaco máximo é calculado pela subtracção de 220 à sua idade. </small>" + +#: glade/profile.glade:1622 +msgid "<small><b>NOTE:</b> in order to use the Karvonen method you must cover the Resting hr field.</small>" +msgstr "<small><b>NOTA:</b> para poder usar o método de Karvonen tem de preencher o campo 'Ritmo cardíaco em repouso'.</small>" + +#: glade/profile.glade:1635 +msgid "Percentages based method" +msgstr "Método baseado em percentagens" + +#: glade/profile.glade:1651 +#: pytrainer/gui/windowmain.py:790 +msgid "Karvonen method" +msgstr "Método de Karvonen" + +#: glade/profile.glade:1672 +msgid "Select how to calculate your heart rate zones." +msgstr "Seleccione o método de cálculo do seu ritmo cardíaco" + +#: glade/profile.glade:1711 +msgid "<b>Heart Rate Zones</b>" +msgstr "<b>Zonas de Ritmo Cardíaco</b>" + +#: glade/profile.glade:1733 +#: pytrainer/recordgraph.py:140 +#: pytrainer/lib/activity.py:443 +#: pytrainer/lib/activity.py:445 +#: pytrainer/lib/activity.py:455 +#: pytrainer/lib/activity.py:525 +#: pytrainer/heartrategraph.py:36 +#: pytrainer/daygraph.py:56 +msgid "Heart Rate" +msgstr "Ritmo Cardíaco" + +#: glade/profile.glade:1759 +msgid "Log Level" +msgstr "Nível de Registo" + +#: glade/profile.glade:1767 +msgid "" +"Error\n" +"Warning\n" +"Info\n" +"Debug" +msgstr "" +"Erro\n" +"Aviso\n" +"Informativo\n" +"Debug" + +#: glade/profile.glade:1785 +msgid "<small>What level of detail is written to the log?</small>" +msgstr "<small>Que nível de informação quer escrever no registo?</small>" + +#: glade/profile.glade:1799 +msgid "Validate" +msgstr "Validar" + +#: glade/profile.glade:1829 +msgid "<small>Do the plugins attempt to validate the input file before processing?</small>" +msgstr "<small>Os plugins tentam validar os ficheiros de input antes do processamento?</small>" + +#: glade/profile.glade:1845 +msgid "Check" +msgstr "Verificar" + +#: glade/profile.glade:1874 +msgid "<small>Was a configuration and database check requested?</small>" +msgstr "<small>Foi pedida uma verificação da configuração e base de dados?</small>" + +#: glade/profile.glade:1890 +msgid "New Graph" +msgstr "Novo Gráfico" + +#: glade/profile.glade:1919 +msgid "<small>Want to use experimental new approach to graphing?</small>" +msgstr "<small>Quer usar a nova abordagem experimental para os gráficos?</small>" + +#: glade/profile.glade:1962 +msgid "<small>This screen shows the state of command line configurable options for pytrainer. These options can be changed here which will affect the current instance of pytrainer, they will not be remembered next time though</small>" +msgstr "<small>Este écran mostra o estado das opções configuráveis pela linha de comando para o pytrainer. Estas opções podem ser alteradas aqui, de modo a afectarem a execução actual do pytrainer. No entanto, estas alterações não serão guardadas para a próxima execução do programa</small>" + +#: glade/profile.glade:1983 +msgid "Startup Parameters" +msgstr "Parâmetros de Arranque" + +#: glade/pytrainer.glade:24 +msgid "_File" +msgstr "_Ficheiro" + +#: glade/pytrainer.glade:39 +msgid "_Import" +msgstr "_Importar" + +#: glade/pytrainer.glade:60 +msgid "_Export as Text Separated by Commas" +msgstr "_Exportar como Texto Separado por Vírgulas (CSV)" + +#: glade/pytrainer.glade:94 +msgid "_Edit" +msgstr "_Editar" + +#: glade/pytrainer.glade:114 +msgid "_View" +msgstr "_Ver" + +#: glade/pytrainer.glade:121 +msgid " _Classic View" +msgstr "Vista _Clássica" + +#: glade/pytrainer.glade:131 +msgid " _List View" +msgstr "Vista em _Lista" + +#: glade/pytrainer.glade:141 +msgid " _Waypoints Editor" +msgstr "Editor de _Pontos de Interesse" + +#: glade/pytrainer.glade:155 +msgid "Tools" +msgstr "Ferramentas" + +#: glade/pytrainer.glade:172 +msgid "GPS Device Plugins" +msgstr "Plugins para Dispositivos GPS" + +#: glade/pytrainer.glade:185 +msgid "_Help" +msgstr "_Ajuda" + +#: glade/pytrainer.glade:290 +#: glade/pytrainer.glade:6324 +msgid "All Sports" +msgstr "Todos os Desportos" + +#: glade/pytrainer.glade:396 +msgid "<b>Sport:</b>" +msgstr "<b>Desporto:</b>" + +#: glade/pytrainer.glade:408 +#: glade/pytrainer.glade:3144 +#: glade/pytrainer.glade:3786 +#: glade/pytrainer.glade:4440 +#: glade/pytrainer.glade:5170 +msgid "<b>Duration:</b>" +msgstr "<b>Duração:</b>" + +#: glade/pytrainer.glade:423 +#: glade/pytrainer.glade:3234 +#: glade/pytrainer.glade:3865 +#: glade/pytrainer.glade:4519 +#: glade/pytrainer.glade:5272 +msgid "<b>Speed:</b>" +msgstr "<b>Velocidade:</b>" + +#: glade/pytrainer.glade:437 +#: glade/pytrainer.glade:3402 +#: glade/pytrainer.glade:4060 +#: glade/pytrainer.glade:4714 +#: glade/pytrainer.glade:5367 +msgid "<b>Pace:</b>" +msgstr "<b>Ritmo:</b>" + +#: glade/pytrainer.glade:451 +msgid "<b>Ascent:</b>" +msgstr "<b>Subida:</b>" + +#: glade/pytrainer.glade:465 +msgid "<b>Calories:</b>" +msgstr "<b>Calorias:</b>" + +#: glade/pytrainer.glade:479 +msgid "<b>Comments:</b>" +msgstr "<b>Comentários:</b>" + +#: glade/pytrainer.glade:614 +msgid "<b>Date:</b>" +msgstr "<b>Data:</b>" + +#: glade/pytrainer.glade:628 +#: glade/pytrainer.glade:3130 +#: glade/pytrainer.glade:3772 +#: glade/pytrainer.glade:4426 +#: glade/pytrainer.glade:5156 +msgid "<b>Distance:</b>" +msgstr "<b>Distância:</b>" + +#: glade/pytrainer.glade:645 +msgid "<b>Max Speed</b>" +msgstr "<b>Vel. Máxima</b>" + +#: glade/pytrainer.glade:661 +#: glade/pytrainer.glade:3432 +#: glade/pytrainer.glade:4074 +#: glade/pytrainer.glade:4728 +#: glade/pytrainer.glade:5382 +msgid "<b>Max Pace:</b>" +msgstr "<b>Ritmo Máx:</b>" + +#: glade/pytrainer.glade:677 +msgid "<b>Descent:</b>" +msgstr "<b>Descida:</b>" + +#: glade/pytrainer.glade:769 +#: glade/pytrainer.glade:3342 +#: glade/pytrainer.glade:3940 +#: glade/pytrainer.glade:4594 +#: glade/pytrainer.glade:5082 +msgid "Cal" +msgstr "Cal" + +#: glade/pytrainer.glade:809 +#: glade/pytrainer.glade:3104 +#: glade/pytrainer.glade:3746 +#: glade/pytrainer.glade:4400 +#: glade/pytrainer.glade:5259 +#: pytrainer/gui/windowmain.py:109 +msgid "Km" +msgstr "Km" + +#: glade/pytrainer.glade:824 +#: glade/pytrainer.glade:3264 +#: glade/pytrainer.glade:3297 +#: glade/pytrainer.glade:3895 +#: glade/pytrainer.glade:3988 +#: glade/pytrainer.glade:4549 +#: glade/pytrainer.glade:4642 +#: glade/pytrainer.glade:5302 +#: glade/pytrainer.glade:5318 +#: pytrainer/gui/windowmain.py:916 +#: pytrainer/gui/windowmain.py:917 +#: pytrainer/gui/windowmain.py:1045 +#: pytrainer/gui/windowmain.py:1046 +#: pytrainer/gui/windowmain.py:1127 +#: pytrainer/gui/windowmain.py:1128 +#: pytrainer/lib/activity.py:203 +msgid "km/h" +msgstr "km/h" + +#: glade/pytrainer.glade:839 +msgid "<b>Equipment:</b>" +msgstr "<b>Equipamento:</b>" + +#: glade/pytrainer.glade:935 +msgid "<b>Active / Rest:</b>" +msgstr "<b>Activo / Em Repouso:</b>" + +#: glade/pytrainer.glade:962 +msgid "h:m:s" +msgstr "h:m:s" + +#: glade/pytrainer.glade:1007 +msgid "<b>Laps</b>" +msgstr "<b>Voltas</b>" + +#: glade/pytrainer.glade:1078 +msgid " <b>Title:</b>" +msgstr "<b>Título:</b>" + +#: glade/pytrainer.glade:1128 +#: pytrainer/gui/windowmain.py:1722 +msgid "Show graph display options" +msgstr "Mostrar opções de gráficos" + +#: glade/pytrainer.glade:1146 +msgid "" +"Profile\n" +"Speed\n" +"Pace\n" +"Heart Rate\n" +"Cadence\n" +"Percentage\n" +"Zone" +msgstr "" +"Perfil\n" +"Velocidade\n" +"Ritmo\n" +"Ritmo Cardíaco\n" +"Cadência\n" +"Percentagem\n" +"Zona" + +#: glade/pytrainer.glade:1163 +#: glade/pytrainer.glade:4311 +#: glade/pytrainer.glade:4965 +#: glade/pytrainer.glade:5618 +#: glade/pytrainer.glade:5984 +msgid "Versus" +msgstr "vs." + +#: glade/pytrainer.glade:1174 +msgid "" +"None\n" +"Profile\n" +"Speed\n" +"Pace\n" +"Heart Rate\n" +"Cadence\n" +msgstr "" +"Nenhum\n" +"Perfil\n" +"Velocidade\n" +"Ritmo\n" +"Ritmo Cardíaco\n" +"Cadência\n" + +#: glade/pytrainer.glade:1320 +msgid "<small>Graph Display Options</small>" +msgstr "<small>Opções de Visualização de Gráficos</small>" + +#: glade/pytrainer.glade:1345 +#: glade/pytrainer.glade:1560 +#: glade/pytrainer.glade:1780 +msgid "<small>Limits</small>" +msgstr "<small>Limites</small>" + +#: glade/pytrainer.glade:1357 +#: glade/pytrainer.glade:1572 +#: glade/pytrainer.glade:1826 +msgid "<small>Min</small>" +msgstr "<small>Mín.</small>" + +#: glade/pytrainer.glade:1369 +#: glade/pytrainer.glade:1584 +#: glade/pytrainer.glade:1838 +msgid "<small>Max</small>" +msgstr "<small>Máx.</small>" + +#: glade/pytrainer.glade:1418 +#: glade/pytrainer.glade:1640 +msgid "<small>Color</small>" +msgstr "<small>Cor</small>" + +#: glade/pytrainer.glade:1449 +#: glade/pytrainer.glade:1653 +msgid "<small>Weight</small>" +msgstr "<small>Peso</small>" + +#: glade/pytrainer.glade:1479 +msgid "Y1" +msgstr "Y1" + +#: glade/pytrainer.glade:1490 +#: glade/pytrainer.glade:1701 +msgid "<small>Smoothing</small>" +msgstr "<small>Suavização</small>" + +#: glade/pytrainer.glade:1630 +msgid "Y2" +msgstr "Y2" + +#: glade/pytrainer.glade:1770 +msgid "X" +msgstr "X" + +#: glade/pytrainer.glade:1851 +msgid "<small>Distance</small>" +msgstr "<small>Distância</small>" + +#: glade/pytrainer.glade:1880 +msgid "<small>Time</small>" +msgstr "<small>Tempo</small>" + +#: glade/pytrainer.glade:1941 +msgid "Show Laps" +msgstr "Mostrar Voltas" + +#: glade/pytrainer.glade:1980 +msgid "Reset Graph" +msgstr "Reset do Gráfico" + +#: glade/pytrainer.glade:2042 +msgid "Redraw Map" +msgstr "Redesenhar Mapa" + +#: glade/pytrainer.glade:2058 +msgid "<small>Show:</small>" +msgstr "<small>Mostrar:</small>" + +#: glade/pytrainer.glade:2069 +msgid "" +"None\n" +"Speed\n" +"Heart rate\n" +"Cadence" +msgstr "" +"Nenhum\n" +"Velocidade\n" +"Ritmo Cardíaco\n" +"Cadência" + +#: glade/pytrainer.glade:2084 +msgid "<small>Display map using:</small>" +msgstr "<small>Mostrar mapa usando:</small>" + +#: glade/pytrainer.glade:2185 +msgid "<b>Beats:</b>" +msgstr "<b>Pulsações:</b>" + +#: glade/pytrainer.glade:2197 +#: glade/pytrainer.glade:3312 +#: glade/pytrainer.glade:3910 +#: glade/pytrainer.glade:4564 +#: glade/pytrainer.glade:5052 +msgid "<b>Calories: </b>" +msgstr "<b>Calorias: </b>" + +#: glade/pytrainer.glade:2211 +#: glade/pytrainer.glade:3464 +#: glade/pytrainer.glade:4138 +#: glade/pytrainer.glade:4792 +#: glade/pytrainer.glade:5430 +msgid "<b>Max Beats:</b>" +msgstr "<b>Máx. de Pulsações:</b>" + +#: glade/pytrainer.glade:2225 +msgid "<b>HR Zones Method:</b>" +msgstr "<b>Método das Zonas HR:</b>" + +#: glade/pytrainer.glade:2240 +msgid "<b>HR Zone5:</b>" +msgstr "<b>Zona5 HR:</b>" + +#: glade/pytrainer.glade:2255 +#: glade/pytrainer.glade:2454 +msgid " bpm" +msgstr " ppm" + +#: glade/pytrainer.glade:2271 +msgid " Cal" +msgstr " Cal" + +#: glade/pytrainer.glade:2329 +msgid "<b>HR Zone4:</b>" +msgstr "<b>Zona4 HR:</b>" + +#: glade/pytrainer.glade:2345 +msgid "<b>HR Zone3:</b>" +msgstr "<b>Zona3 HR:</b>" + +#: glade/pytrainer.glade:2361 +msgid "<b>HR Zone2:</b>" +msgstr "<b>Zona2 HR:</b>" + +#: glade/pytrainer.glade:2377 +msgid "<b>HR Zone1:</b>" +msgstr "<b>Zona1 HR:</b>" + +#: glade/pytrainer.glade:2479 +#: glade/pytrainer.glade:2491 +#: glade/pytrainer.glade:2506 +#: glade/pytrainer.glade:2521 +#: glade/pytrainer.glade:2536 +#: glade/pytrainer.glade:3387 +#: glade/pytrainer.glade:3481 +#: glade/pytrainer.glade:4045 +#: glade/pytrainer.glade:4123 +#: glade/pytrainer.glade:4699 +#: glade/pytrainer.glade:4777 +#: glade/pytrainer.glade:5127 +#: glade/pytrainer.glade:5334 +#: pytrainer/lib/activity.py:445 +#: pytrainer/lib/activity.py:525 +msgid "bpm" +msgstr "ppm" + +#: glade/pytrainer.glade:2581 +msgid " <b>Heart Rate:</b>" +msgstr " <b>Ritmo Cardíaco:</b>" + +#: glade/pytrainer.glade:2769 +msgid "<b>Projected times</b>" +msgstr "<b>Tempos projectados</b>" + +#: glade/pytrainer.glade:2799 +msgid "<i>Rank relative to same-sport activities for distances ± x%:</i>" +msgstr "<i>Classificação relativa para actividades do mesmo desporto para distâncias ± x%:</i>" + +#: glade/pytrainer.glade:2832 +msgid "<b>Range:</b>" +msgstr "<b>Alcance:</b>" + +#: glade/pytrainer.glade:2845 +msgid "<b>Rank:</b>" +msgstr "<b>Classificação:</b>" + +#: glade/pytrainer.glade:2858 +msgid "<b>Speed: </b>" +msgstr "<b>Velocidade: </b>" + +#: glade/pytrainer.glade:2871 +msgid "<b>Avg speed:</b>" +msgstr "<b>Vel. média:</b>" + +#: glade/pytrainer.glade:2884 +msgid "<b>Standard deviation:</b>" +msgstr "<b>Desvio padrão:</b>" + +#: glade/pytrainer.glade:2898 +msgid "<b>Deviation:</b>" +msgstr "<b>Desvio:</b>" + +#: glade/pytrainer.glade:3017 +msgid "<b>Ranking</b>" +msgstr "<b>Classificação</b>" + +#: glade/pytrainer.glade:3043 +msgid "<b>Analytics:</b>" +msgstr "<b>Analítica:</b>" + +#: glade/pytrainer.glade:3071 +msgid "Record" +msgstr "Registo" + +#: glade/pytrainer.glade:3280 +#: glade/pytrainer.glade:3956 +#: glade/pytrainer.glade:4610 +#: glade/pytrainer.glade:5350 +msgid "<b>Max Speed:</b>" +msgstr "<b>Vel. Máxima:</b>" + +#: glade/pytrainer.glade:3357 +#: glade/pytrainer.glade:4015 +#: glade/pytrainer.glade:4669 +#: glade/pytrainer.glade:5097 +msgid "<b>Beats avg:</b>" +msgstr "<b>Média pulsação:</b>" + +#: glade/pytrainer.glade:3417 +#: glade/pytrainer.glade:3449 +#: glade/pytrainer.glade:4091 +#: glade/pytrainer.glade:4107 +#: glade/pytrainer.glade:4745 +#: glade/pytrainer.glade:4761 +#: glade/pytrainer.glade:5399 +#: glade/pytrainer.glade:5415 +#: pytrainer/gui/windowmain.py:918 +#: pytrainer/gui/windowmain.py:919 +#: pytrainer/gui/windowmain.py:1047 +#: pytrainer/gui/windowmain.py:1048 +#: pytrainer/gui/windowmain.py:1129 +#: pytrainer/gui/windowmain.py:1130 +#: pytrainer/lib/activity.py:204 +msgid "min/km" +msgstr "min/km" + +#: glade/pytrainer.glade:3556 +#: glade/pytrainer.glade:4199 +#: glade/pytrainer.glade:4853 +#: glade/pytrainer.glade:5506 +msgid "<b>Total Asc/Desc:</b>" +msgstr "<b>Total Sub/Desc:</b>" + +#: glade/pytrainer.glade:3583 +#: glade/pytrainer.glade:4226 +#: glade/pytrainer.glade:4880 +#: glade/pytrainer.glade:5533 +#: pytrainer/gui/windowmain.py:2066 +#: pytrainer/gui/windowmain.py:2068 +#: pytrainer/lib/activity.py:205 +msgid "m" +msgstr "m" + +#: glade/pytrainer.glade:3602 +msgid " <b>Date:</b>" +msgstr " <b>Data:</b>" + +#: glade/pytrainer.glade:3645 +msgid "Value" +msgstr "Valor" + +#: glade/pytrainer.glade:3656 +msgid "" +"Stage Profile\n" +"Stage Velocity\n" +"Stage Profile/velocity" +msgstr "" +"Definir Perfil\n" +"Definir Velocidade\n" +"Definir Perfil/velocidade" + +#: glade/pytrainer.glade:3712 +msgid "Day" +msgstr "Dia" + +#: glade/pytrainer.glade:4245 +msgid " <b>Week:</b>" +msgstr " <b>Semana:</b>" + +#: glade/pytrainer.glade:4296 +#: glade/pytrainer.glade:4950 +#: glade/pytrainer.glade:5603 +#: glade/pytrainer.glade:5969 +msgid "" +"Distance\n" +"Time\n" +"Average Heart Rate\n" +"Average Speed\n" +"Calories" +msgstr "" +"Distância\n" +"Tempo\n" +"Ritmo Cardíaco Médio\n" +"Velocidade Média\n" +"Calorias" + +#: glade/pytrainer.glade:4322 +#: glade/pytrainer.glade:4976 +#: glade/pytrainer.glade:5629 +#: glade/pytrainer.glade:5995 +msgid "" +"None\n" +"Distance\n" +"Time\n" +"Average Heart Rate\n" +"Average Speed\n" +"Calories" +msgstr "" +"Nenhum\n" +"Distância\n" +"Tempo\n" +"Ritmo Cardíaco Médio\n" +"Velocidade Média\n" +"Calorias" + +#: glade/pytrainer.glade:4366 +msgid "Week" +msgstr "Semana" + +#: glade/pytrainer.glade:4899 +msgid " <b>Month:</b>" +msgstr " <b>Mês:</b>" + +#: glade/pytrainer.glade:5019 +msgid "Month" +msgstr "Mês" + +#: glade/pytrainer.glade:5552 +msgid " <b>Year:</b>" +msgstr " <b>Ano:</b>" + +#: glade/pytrainer.glade:5672 +msgid "Year" +msgstr "Ano" + +#: glade/pytrainer.glade:5826 +msgid "<b>Graph</b>" +msgstr "<b>Gráfico</b>" + +#: glade/pytrainer.glade:5867 +msgid "<b>History</b>" +msgstr "<b>Histórico</b>" + +#: glade/pytrainer.glade:5937 +msgid "<b>Sports</b>" +msgstr "<b>Desportos</b>" + +#: glade/pytrainer.glade:6018 +msgid "Total distance:" +msgstr "Distância total:" + +#: glade/pytrainer.glade:6032 +msgid "Total duration:" +msgstr "Duração total:" + +#: glade/pytrainer.glade:6081 +msgid "Start date:" +msgstr "Data de início:" + +#: glade/pytrainer.glade:6096 +msgid "End date:" +msgstr "Data de fim:" + +#: glade/pytrainer.glade:6182 +msgid "<b>All</b>" +msgstr "<b>Todos</b>" + +#: glade/pytrainer.glade:6208 +msgid "Totals" +msgstr "Totais" + +#: glade/pytrainer.glade:6246 +msgid "<b>Title:</b>" +msgstr "<b>Título:</b>" + +#: glade/pytrainer.glade:6269 +msgid "Search" +msgstr "Pesquisar" + +#: glade/pytrainer.glade:6293 +#: pytrainer/lib/listview.py:3 +#: pytrainer/lib/listview.py:10 +msgid "All Distances" +msgstr "Todas as Distâncias" + +#: glade/pytrainer.glade:6302 +#: pytrainer/lib/listview.py:35 +msgid "All Durations" +msgstr "Todas as durações" + +#: glade/pytrainer.glade:6312 +msgid "" +"All time\n" +"Last 4 weeks\n" +"Last 6 months\n" +"Last 12 months" +msgstr "" +"Todos os registos\n" +"Últimas 4 semanas\n" +"Últimos 6 meses\n" +"Últimos 12 meses" + +#: glade/pytrainer.glade:6349 +msgid "Columns" +msgstr "Colunas" + +#: glade/pytrainer.glade:6477 +msgid "Type:" +msgstr "Tipo:" + +#: glade/pytrainer.glade:6490 +msgid "" +"Font\n" +"Restaurant\n" +"Scenic Area\n" +"Summit" +msgstr "" +"Fonte\n" +"Restaurante\n" +"Paisagem\n" +"Monte" + +#: glade/pytrainer.glade:6506 +msgid "Latitude: " +msgstr "Latitude: " + +#: glade/pytrainer.glade:6520 +msgid " Name:" +msgstr " Nome:" + +#: glade/pytrainer.glade:6532 +msgid "Longitude:" +msgstr "Longitude:" + +#: glade/pytrainer.glade:6624 +msgid "<b> Waypoint: </b>" +msgstr "<b> Ponto de Interesse: </b>" + +#: glade/pytrainer.glade:6808 +msgid "Edit Record" +msgstr "Editar Registo" + +#: glade/pytrainer.glade:6822 +msgid "Show graph in classic view" +msgstr "Mostrar gráfico na vista clássica" + +#: glade/pytrainer.glade:6836 +msgid "Merge tracks" +msgstr "Juntar percursos" + +#: glade/selecttrackdialog.glade:7 +msgid "Select track record" +msgstr "Escolher registo de percurso" + +#: glade/warning.glade:7 +#: glade/warning.glade:38 +msgid "Warning" +msgstr "Aviso" + +#: pytrainer/gui/windowmain.py:107 +msgid "Miles" +msgstr "Milhas" + +#: pytrainer/gui/windowmain.py:110 +#: pytrainer/gui/windowmain.py:114 +#: pytrainer/gui/windowmain.py:127 +#: pytrainer/gui/windowmain.py:130 +#: pytrainer/gui/windowmain.py:139 +#: pytrainer/gui/windowmain.py:173 +#: pytrainer/gui/windowmain.py:182 +msgid "id" +msgstr "id" + +#: pytrainer/gui/windowmain.py:110 +msgid "Start" +msgstr "Início" + +#: pytrainer/gui/windowmain.py:117 +#: pytrainer/gui/windowmain.py:157 +#: pytrainer/gui/windowmain.py:175 +#: pytrainer/gui/windowmain.py:185 +#: pytrainer/gui/windowmain.py:569 +#: pytrainer/gui/windowmain.py:1495 +#: pytrainer/gui/windowimportdata.py:353 +#: pytrainer/gui/windowrecord.py:210 +#: pytrainer/lib/activity.py:323 +#: pytrainer/lib/activity.py:334 +#: pytrainer/lib/activity.py:406 +#: pytrainer/lib/activity.py:417 +#: pytrainer/lib/activity.py:426 +#: pytrainer/lib/activity.py:435 +#: pytrainer/lib/activity.py:444 +#: pytrainer/lib/activity.py:454 +#: pytrainer/lib/activity.py:463 +#: pytrainer/lib/activity.py:524 +#: pytrainer/extensions/googlemaps.py:129 +#: pytrainer/extensions/osm.py:105 +msgid "Distance" +msgstr "Distância" + +#: pytrainer/gui/windowmain.py:119 +#: pytrainer/gui/windowmain.py:158 +#: pytrainer/gui/windowmain.py:176 +#: pytrainer/gui/windowmain.py:186 +#: pytrainer/gui/windowmain.py:570 +#: pytrainer/gui/windowmain.py:1497 +#: pytrainer/extensions/googlemaps.py:129 +#: pytrainer/extensions/osm.py:104 +msgid "Time" +msgstr "Tempo" + +#: pytrainer/gui/windowmain.py:120 +msgid "⌀ HR" +msgstr "⌀ Bat. Card." + +#: pytrainer/gui/windowmain.py:121 +msgid "⌀ Speed" +msgstr "⌀ Vel." + +#: pytrainer/gui/windowmain.py:127 +msgid "Waypoint" +msgstr "Ponto de interesse" + +#: pytrainer/gui/windowmain.py:132 +msgid "Weight" +msgstr "Peso" + +#: pytrainer/gui/windowmain.py:133 +msgid "Body Fat %" +msgstr "% Gordura Corporal" + +#: pytrainer/gui/windowmain.py:134 +msgid "Resting HR" +msgstr "Bat. Card. em Repouso" + +#: pytrainer/gui/windowmain.py:135 +#: pytrainer/gui/windowmain.py:147 +#: pytrainer/gui/windowmain.py:164 +msgid "Max HR" +msgstr "Máx Bat. Card." + +#: pytrainer/gui/windowmain.py:141 +msgid "Records" +msgstr "Registos" + +#: pytrainer/gui/windowmain.py:142 +msgid "Total duration" +msgstr "Duração total" + +#: pytrainer/gui/windowmain.py:143 +msgid "Total distance" +msgstr "Distância total" + +#: pytrainer/gui/windowmain.py:144 +#: pytrainer/gui/windowmain.py:159 +msgid "Avg speed" +msgstr "Vel. Média" + +#: pytrainer/gui/windowmain.py:145 +#: pytrainer/gui/windowmain.py:160 +msgid "Max speed" +msgstr "Vel. Máx." + +#: pytrainer/gui/windowmain.py:146 +#: pytrainer/gui/windowmain.py:163 +msgid "Avg HR" +msgstr "Ritmo Card. Médio" + +#: pytrainer/gui/windowmain.py:148 +msgid "Max duration" +msgstr "Duração Máx." + +#: pytrainer/gui/windowmain.py:149 +msgid "Max distance" +msgstr "Distância Máx." + +#: pytrainer/gui/windowmain.py:155 +msgid "Lap" +msgstr "Volta" + +#: pytrainer/gui/windowmain.py:156 +msgid "Trigger" +msgstr "Gatilho" + +#: pytrainer/gui/windowmain.py:161 +msgid "Avg pace" +msgstr "Ritmo Méd." + +#: pytrainer/gui/windowmain.py:162 +msgid "Max pace" +msgstr "Ritmo Máx." + +#: pytrainer/gui/windowmain.py:166 +msgid "Intensity" +msgstr "Intensidade" + +#: pytrainer/gui/windowmain.py:174 +msgid "Race" +msgstr "Corrida" + +#: pytrainer/gui/windowmain.py:183 +msgid "Rank" +msgstr "Posição" + +#: pytrainer/gui/windowmain.py:187 +#: pytrainer/recordgraph.py:136 +#: pytrainer/lib/activity.py:335 +#: pytrainer/lib/activity.py:425 +#: pytrainer/lib/activity.py:427 +msgid "Speed" +msgstr "Velocidade" + +#: pytrainer/gui/windowmain.py:319 +msgid "d" +msgstr "d" + +#: pytrainer/gui/windowmain.py:559 +msgid "Show on X Axis" +msgstr "Mostrar no eixo X" + +#: pytrainer/gui/windowmain.py:560 +msgid "Show on Y1 Axis" +msgstr "Mostrar no eixo Y1" + +#: pytrainer/gui/windowmain.py:561 +msgid "Show on Y2 Axis" +msgstr "Mostrar no eixo Y2" + +#: pytrainer/gui/windowmain.py:562 +msgid "Axis Limits" +msgstr "Limites do Eixo" + +#: pytrainer/gui/windowmain.py:571 +msgid "Laps" +msgstr "Voltas" + +#: pytrainer/gui/windowmain.py:572 +msgid "Left Axis Grid" +msgstr "Grelha do Eixo Esquerdo" + +#: pytrainer/gui/windowmain.py:573 +msgid "Right Axis Grid" +msgstr "Grelha do Eixo Direito" + +#: pytrainer/gui/windowmain.py:574 +msgid "X Axis Grid" +msgstr "Grelha do Eixo X" + +#: pytrainer/gui/windowmain.py:635 +msgid "Reset Limits" +msgstr "Repor Limites" + +#: pytrainer/gui/windowmain.py:637 +msgid "Set Limits" +msgstr "Definir Limites" + +#: pytrainer/gui/windowmain.py:792 +msgid "Percentages method" +msgstr "Método das percentagens" + +#: pytrainer/gui/windowmain.py:805 +msgid "800 m" +msgstr "800 m" + +#: pytrainer/gui/windowmain.py:806 +msgid "1500 m" +msgstr "1500 m" + +#: pytrainer/gui/windowmain.py:807 +msgid "5K" +msgstr "5K" + +#: pytrainer/gui/windowmain.py:808 +msgid "7K" +msgstr "7K" + +#: pytrainer/gui/windowmain.py:809 +msgid "10K" +msgstr "10K" + +#: pytrainer/gui/windowmain.py:810 +msgid "Half marathon" +msgstr "Meia maratona" + +#: pytrainer/gui/windowmain.py:811 +msgid "Marathon" +msgstr "Maratona" + +#: pytrainer/gui/windowmain.py:812 +msgid "100K" +msgstr "100K" + +#: pytrainer/gui/windowmain.py:909 +#: pytrainer/gui/windowmain.py:1038 +#: pytrainer/gui/windowmain.py:1120 +#: pytrainer/lib/activity.py:197 +msgid "miles" +msgstr "milhas" + +#: pytrainer/gui/windowmain.py:910 +#: pytrainer/gui/windowmain.py:911 +#: pytrainer/gui/windowmain.py:1039 +#: pytrainer/gui/windowmain.py:1040 +#: pytrainer/gui/windowmain.py:1121 +#: pytrainer/gui/windowmain.py:1122 +#: pytrainer/lib/activity.py:198 +msgid "miles/h" +msgstr "milhas/h" + +#: pytrainer/gui/windowmain.py:912 +#: pytrainer/gui/windowmain.py:913 +#: pytrainer/gui/windowmain.py:1041 +#: pytrainer/gui/windowmain.py:1042 +#: pytrainer/gui/windowmain.py:1123 +#: pytrainer/gui/windowmain.py:1124 +#: pytrainer/lib/activity.py:199 +msgid "min/mile" +msgstr "min/milha" + +#: pytrainer/gui/windowmain.py:915 +#: pytrainer/gui/windowmain.py:1044 +#: pytrainer/gui/windowmain.py:1126 +#: pytrainer/lib/activity.py:202 +msgid "km" +msgstr "km" + +#: pytrainer/gui/windowmain.py:1498 +#: pytrainer/recordgraph.py:144 +msgid "Beats" +msgstr "Pulsações" + +#: pytrainer/gui/windowmain.py:1499 +msgid "Average" +msgstr "Média" + +#: pytrainer/gui/windowmain.py:1718 +msgid "Hide graph display options" +msgstr "Esconder opções de visualização de gráficos" + +#: pytrainer/gui/windowmain.py:2056 +msgid "lap" +msgstr "volta" + +#: pytrainer/gui/windowmain.py:2066 +#: pytrainer/gui/drawArea.py:165 +#: pytrainer/extensions/googlemaps.py:127 +#: pytrainer/extensions/osm.py:102 +msgid "h" +msgstr "h" + +#: pytrainer/gui/windowmain.py:2066 +#: pytrainer/gui/windowmain.py:2068 +msgid "s" +msgstr "s" + +#: pytrainer/gui/windowmain.py:2156 +#: pytrainer/record.py:67 +msgid "Edit Entry" +msgstr "Editar Registo" + +#: pytrainer/gui/windowmain.py:2167 +msgid "Delete Entry" +msgstr "Apagar Registo" + +#: pytrainer/gui/windowmain.py:2191 +msgid "Create Athlete Entry" +msgstr "Criar Registo de Atleta" + +#: pytrainer/gui/windowmain.py:2195 +msgid "Edit Athlete Entry" +msgstr "Editar Registo de Atleta" + +#: pytrainer/gui/windowmain.py:2208 +msgid "<b>Date</b>" +msgstr "<b>Data</b>" + +#: pytrainer/gui/windowmain.py:2224 +msgid "<b>Weight</b>" +msgstr "<b>Peso</b>" + +#: pytrainer/gui/windowmain.py:2232 +msgid "<b>Body Fat</b>" +msgstr "<b>Gordura Corporal</b>" + +#: pytrainer/gui/windowmain.py:2240 +msgid "<b>Resting Heart Rate</b>" +msgstr "<b>Ritmo Cardíaco em Repouso</b>" + +#: pytrainer/gui/windowmain.py:2248 +msgid "<b>Max Heart Rate</b>" +msgstr "<b>Ritmo Cardíaco Máximo</b>" + +#: pytrainer/gui/windowmain.py:2276 +#: pytrainer/main.py:451 +msgid "Delete this database entry?" +msgstr "Apagar este registo?" + +#: pytrainer/gui/windowmain.py:2278 +msgid "Are you sure?" +msgstr "De certeza?" + +#: pytrainer/gui/windowimportdata.py:117 +msgid "No file selected" +msgstr "Nenhum ficheiro seleccionado" + +#: pytrainer/gui/windowimportdata.py:162 +msgid "Configure" +msgstr "Configurar" + +#: pytrainer/gui/windowimportdata.py:163 +msgid "Run" +msgstr "Executar" + +#: pytrainer/gui/windowimportdata.py:171 +msgid "Disabled" +msgstr "Desactivado" + +#: pytrainer/gui/windowimportdata.py:173 +msgid "Enabled" +msgstr "Activado" + +#: pytrainer/gui/windowimportdata.py:253 +msgid "GPS device found" +msgstr "Encontrado dispositivo GPS" + +#: pytrainer/gui/windowimportdata.py:256 +msgid "GPS device <b>not</b> found" +msgstr "<b>Não foi</b> encontrado dispositivo GPS" + +#: pytrainer/gui/windowimportdata.py:263 +msgid "This tool was not found on the system" +msgstr "Esta ferramenta não foi encontrada no sistema" + +#: pytrainer/gui/windowimportdata.py:265 +msgid " Homepage" +msgstr " Homepage" + +#: pytrainer/gui/windowimportdata.py:318 +msgid "File" +msgstr "Ficheiro" + +#: pytrainer/gui/windowimportdata.py:318 +msgid "Type" +msgstr "Tipo" + +#: pytrainer/gui/windowimportdata.py:318 +msgid "Activities" +msgstr "Actividades" + +#: pytrainer/gui/windowimportdata.py:353 +#: pytrainer/gui/windowrecord.py:210 +msgid "Start Time" +msgstr "Hora de Início" + +#: pytrainer/gui/windowimportdata.py:353 +#: pytrainer/gui/windowrecord.py:210 +msgid "Duration" +msgstr "Duração" + +#: pytrainer/gui/windowimportdata.py:499 +msgid "Imported into database" +msgstr "Importado para a base de dados" + +#: pytrainer/gui/windowimportdata.py:543 +#: pytrainer/gui/windowextensions.py:81 +#: pytrainer/gui/windowplugins.py:80 +#, python-format +msgid "%s settings" +msgstr "configurações %s" + +#: pytrainer/gui/windowimportdata.py:558 +#: pytrainer/gui/windowextensions.py:70 +#: pytrainer/gui/windowplugins.py:71 +#: pytrainer/gui/windowplugins.py:95 +msgid "Disable" +msgstr "Desligar" + +#: pytrainer/gui/windowimportdata.py:559 +#: pytrainer/gui/windowextensions.py:72 +#: pytrainer/gui/windowplugins.py:69 +#: pytrainer/gui/windowplugins.py:96 +msgid "Enable" +msgstr "Ligar" + +#: pytrainer/gui/windowimportdata.py:566 +#: pytrainer/gui/windowplugins.py:103 +msgid "Ok" +msgstr "Ok" + +#: pytrainer/gui/windowimportdata.py:626 +msgid "Saving options" +msgstr "Opções de gravação" + +#: pytrainer/gui/windowimportdata.py:628 +msgid "Options saved" +msgstr "Opções guardadas" + +#: pytrainer/gui/windowimportdata.py:653 +msgid "Importing one activity" +msgstr "A importar uma actividade" + +#: pytrainer/gui/windowimportdata.py:654 +msgid "Imported one activity" +msgstr "Uma actividade importada" + +#: pytrainer/gui/windowimportdata.py:656 +#, python-format +msgid "Importing %d activities" +msgstr "A importar %d actividades" + +#: pytrainer/gui/windowimportdata.py:657 +#, python-format +msgid "Imported %d activities" +msgstr "%d actividades importadas" + +#: pytrainer/gui/windowimportdata.py:676 +msgid "Choose a file (or files) to import activities from" +msgstr "Escolha um ficheiro (ou ficheiros) para fonte de actividades" + +#: pytrainer/gui/windowimportdata.py:691 +#: pytrainer/gui/windowimportdata.py:692 +#, python-format +msgid "Found file of type: %s" +msgstr "Encontrado ficheiro do tipo: %s" + +#: pytrainer/gui/windowimportdata.py:716 +msgid "Found in database" +msgstr "Encontrado na base de dados" + +#: pytrainer/gui/windowimportdata.py:731 +#: pytrainer/gui/windowimportdata.py:732 +#, python-format +msgid "File %s is of unknown or unsupported file type" +msgstr "O ficheiro %s é de um tipo desconhecido ou não suportado" + +#: pytrainer/gui/windowimportdata.py:805 +#, python-format +msgid "Column %d" +msgstr "Coluna %d" + +#: pytrainer/gui/drawArea.py:166 +#: pytrainer/extensions/googlemaps.py:127 +#: pytrainer/extensions/osm.py:102 +msgid "min" +msgstr "min" + +#: pytrainer/gui/drawArea.py:410 +msgid "rest" +msgstr "repouso" + +#: pytrainer/gui/windowrecord.py:210 +msgid "GPX File" +msgstr "Ficheiro GPX" + +#: pytrainer/gui/windowprofile.py:47 +msgid "Male" +msgstr "Masculino" + +#: pytrainer/gui/windowprofile.py:48 +msgid "Female" +msgstr "Feminino" + +#: pytrainer/gui/windowprofile.py:65 +msgid "MET" +msgstr "MET" + +#: pytrainer/gui/windowprofile.py:314 +msgid "Sport Creation Error" +msgstr "Erro ao Criar Desporto" + +#: pytrainer/gui/equipment.py:101 +msgid "Usage" +msgstr "Utilização" + +#: pytrainer/gui/dialogselecttrack.py:40 +msgid "Track Name" +msgstr "Nome da Pista" + +#: pytrainer/gui/drawGraph.py:170 +msgid "Athlete Data" +msgstr "Dados de Atleta" + +#: pytrainer/gui/windowextensions.py:112 +#: pytrainer/gui/windowextensions.py:125 +msgid "OK" +msgstr "OK" + +#: pytrainer/recordgraph.py:134 +#: pytrainer/daygraph.py:52 +msgid "Height (m)" +msgstr "Altura (m)" + +#: pytrainer/recordgraph.py:134 +#: pytrainer/daygraph.py:52 +msgid "Stage Profile" +msgstr "Definir Perfil" + +#: pytrainer/recordgraph.py:136 +msgid "Speed (Km/h)" +msgstr "Velocidade (Km/h)" + +#: pytrainer/recordgraph.py:138 +#: pytrainer/lib/activity.py:324 +#: pytrainer/lib/activity.py:434 +#: pytrainer/lib/activity.py:436 +msgid "Pace" +msgstr "Ritmo" + +#: pytrainer/recordgraph.py:140 +#: pytrainer/heartrategraph.py:36 +#: pytrainer/daygraph.py:56 +msgid "Beats (bpm)" +msgstr "Pulsações (ppm)" + +#: pytrainer/recordgraph.py:142 +msgid "Cadence (rpm)" +msgstr "Cadência (rpm)" + +#: pytrainer/recordgraph.py:142 +#: pytrainer/lib/activity.py:462 +#: pytrainer/lib/activity.py:464 +msgid "Cadence" +msgstr "Cadência" + +#: pytrainer/recordgraph.py:144 +msgid "Beats (%)" +msgstr "Batidas (%)" + +#: pytrainer/recordgraph.py:146 +msgid "Zone" +msgstr "Zona" + +#: pytrainer/profile.py:114 +msgid "Moderate activity" +msgstr "Actividade moderada" + +#: pytrainer/profile.py:115 +msgid "Weight Control" +msgstr "Controlo de Peso" + +#: pytrainer/profile.py:116 +msgid "Aerobic" +msgstr "Aeróbica" + +#: pytrainer/profile.py:117 +msgid "Anaerobic" +msgstr "Anaeróbica" + +#: pytrainer/profile.py:118 +msgid "VO2 MAX" +msgstr "Máx VO2" + +#: pytrainer/lib/listview.py:32 +msgid "All Time" +msgstr "Desde sempre" + +#: pytrainer/lib/listview.py:32 +msgid "Last 4 Weeks" +msgstr "Últimas 4 Semanas" + +#: pytrainer/lib/listview.py:33 +msgid "Last 6 Months" +msgstr "Últimos 6 Meses" + +#: pytrainer/lib/listview.py:33 +msgid "Last 12 Months" +msgstr "Últimos 12 Meses" + +#: pytrainer/lib/listview.py:36 +msgid "<1 Hour" +msgstr "<1 Hora" + +#: pytrainer/lib/listview.py:37 +msgid "1-2 Hours" +msgstr "1-2 Horas" + +#: pytrainer/lib/listview.py:38 +msgid ">2 Hours" +msgstr ">2 Horas" + +#: pytrainer/lib/gpx.py:129 +msgid "No Name" +msgstr "Sem Nome" + +#: pytrainer/lib/gpx.py:137 +msgid "No Data" +msgstr "Sem Dados" + +#: pytrainer/lib/activity.py:200 +msgid "feet" +msgstr "pés" + +#: pytrainer/lib/activity.py:322 +msgid "Pace by Lap" +msgstr "Ritmo por Volta" + +#: pytrainer/lib/activity.py:328 +#: pytrainer/lib/activity.py:339 +#: pytrainer/lib/activity.py:411 +#: pytrainer/lib/activity.py:421 +#: pytrainer/lib/activity.py:430 +#: pytrainer/lib/activity.py:439 +#: pytrainer/lib/activity.py:448 +#: pytrainer/lib/activity.py:458 +#: pytrainer/lib/activity.py:467 +#: pytrainer/lib/activity.py:529 +msgid "Time (seconds)" +msgstr "Tempo (segundos)" + +#: pytrainer/lib/activity.py:333 +msgid "Speed by Lap" +msgstr "Velocidade por Volta" + +#: pytrainer/lib/activity.py:405 +#: pytrainer/lib/activity.py:407 +msgid "Elevation" +msgstr "Elevação" + +#: pytrainer/lib/activity.py:416 +#: pytrainer/lib/activity.py:418 +msgid "Corrected Elevation" +msgstr "Elevação Corrigida" + +#: pytrainer/lib/activity.py:453 +#, python-format +msgid "Heart Rate (% of max)" +msgstr "Ritmo Cardíaco (% do máx.)" + +#: pytrainer/lib/activity.py:455 +msgid "%" +msgstr "%" + +#: pytrainer/lib/activity.py:464 +msgid "rpm" +msgstr "rpm" + +#: pytrainer/lib/activity.py:523 +msgid "Heart Rate zone" +msgstr "Zona do Ritmo Cardíaco" + +#: pytrainer/monthgraph.py:26 +#: pytrainer/monthgraph.py:27 +#: pytrainer/monthgraph.py:28 +#: pytrainer/monthgraph.py:29 +#: pytrainer/monthgraph.py:30 +msgid "day" +msgstr "dia" + +#: pytrainer/monthgraph.py:26 +#: pytrainer/weekgraph.py:28 +msgid "Daily Distance" +msgstr "Distância Diária" + +#: pytrainer/monthgraph.py:27 +#: pytrainer/totalgraph.py:25 +#: pytrainer/yeargraph.py:27 +#: pytrainer/weekgraph.py:29 +msgid "Time (hours)" +msgstr "Tempo (horas)" + +#: pytrainer/monthgraph.py:27 +#: pytrainer/weekgraph.py:29 +msgid "Daily Time" +msgstr "Tempo Diário" + +#: pytrainer/monthgraph.py:28 +#: pytrainer/totalgraph.py:26 +#: pytrainer/yeargraph.py:28 +#: pytrainer/weekgraph.py:30 +msgid "Average Heart Rate (bpm)" +msgstr "Ritmo Cardíaco Médio (ppm)" + +#: pytrainer/monthgraph.py:28 +#: pytrainer/weekgraph.py:30 +msgid "Daily Average Heart Rate" +msgstr "Ritmo Cardíaco Médio Diário" + +#: pytrainer/monthgraph.py:29 +#: pytrainer/weekgraph.py:31 +msgid "Daily Average Speed" +msgstr "Velocidade Média Diária" + +#: pytrainer/monthgraph.py:30 +#: pytrainer/weekgraph.py:32 +msgid "Daily Calories" +msgstr "Calorias Diárias" + +#: pytrainer/totalgraph.py:24 +#: pytrainer/totalgraph.py:25 +#: pytrainer/totalgraph.py:26 +#: pytrainer/totalgraph.py:27 +#: pytrainer/totalgraph.py:28 +msgid "year" +msgstr "ano" + +#: pytrainer/totalgraph.py:24 +msgid "Annual Distance" +msgstr "Distância Anual" + +#: pytrainer/totalgraph.py:25 +msgid "Annual Time" +msgstr "Tempo anual" + +#: pytrainer/totalgraph.py:26 +msgid "Annual Average Heart Rate" +msgstr "Ritmo Cardíaco Médio Anual" + +#: pytrainer/totalgraph.py:27 +msgid "Annual Average Speed" +msgstr "Velocidade Média Anual" + +#: pytrainer/totalgraph.py:28 +msgid "Annual Calories" +msgstr "Calorias Anuais" + +#: pytrainer/athlete.py:52 +msgid "lb" +msgstr "lb" + +#: pytrainer/athlete.py:54 +msgid "kg" +msgstr "kg" + +#: pytrainer/record.py:56 +msgid "Modify details before importing" +msgstr "Modificar detalhes antes de importar" + +#: pytrainer/record.py:466 +msgid "pyTrainer can't import data from your gpx file" +msgstr "O pyTrainer não pode importar dados do seu ficheiro gpx" + +#: pytrainer/yeargraph.py:26 +#: pytrainer/yeargraph.py:27 +#: pytrainer/yeargraph.py:28 +#: pytrainer/yeargraph.py:29 +#: pytrainer/yeargraph.py:30 +msgid "month" +msgstr "mês" + +#: pytrainer/yeargraph.py:26 +msgid "Monthly Distance" +msgstr "Distância Mensal" + +#: pytrainer/yeargraph.py:27 +msgid "Monthly Time" +msgstr "Tempo Mensal" + +#: pytrainer/yeargraph.py:28 +msgid "Monthly Average Heart Rate" +msgstr "Ritmo Cardíaco Médio Mensal" + +#: pytrainer/yeargraph.py:29 +msgid "Monthly Average Speed" +msgstr "Velocidade Média Mensal" + +#: pytrainer/yeargraph.py:30 +msgid "Monthly Calories" +msgstr "Calorias Médias" + +#: pytrainer/waypoint.py:87 +msgid "The gpx file seems to be a several days records. Perhaps you will need to edit your gpx file" +msgstr "O ficheiro gpx contém aparentemente registos de vários dias. Talvez seja necessário editar o ficheiro gpx" + +#: pytrainer/daygraph.py:54 +msgid "Velocity (Km/h)" +msgstr "Velocidade (Km/h)" + +#: pytrainer/daygraph.py:54 +msgid "Velocity" +msgstr "Velocidade" + +#: pytrainer/main.py:467 +msgid "Delete this waypoint?" +msgstr "Apagar este ponto?" + +#: import/file_gpxplus.py:41 +msgid "GPS eXchange file" +msgstr "Ficheiro GPS eXchange" + +#: import/file_kml20.py:47 +msgid "Geodistance kml version 2.0 file" +msgstr "Ficheiro Geodistance kml versão 2.0" + +#: import/file_garmintcxv1.py:45 +msgid "Garmin training center database file version 1" +msgstr "Ficheiro de base de dados do centro de treino Garmin, versão 1" + +#: import/file_gpxplusNokia.py:41 +msgid "Nokia Export - GPS eXchange file" +msgstr "Nokia Export - ficheiro GPS eXchange" + +#: import/tool_gpsbabel.py:37 +msgid "GPSBabel" +msgstr "GPSBabel" + +#: import/tool_garmintools.py:37 +msgid "Garmintools" +msgstr "Garmintools" + +#: import/tool_gant.py:37 +msgid "Gant" +msgstr "Gant" + +#: import/file_garmintools.py:44 +msgid "Garmin tools dump file" +msgstr "Ficheiro dump de Garmin tools" + +#: import/file_garmintcxv2.py:44 +msgid "Garmin training center database file version 2" +msgstr "Ficheiro de base de dados do centro de treino Garmin, versão 2" + +#: extensions/fixelevation/fixelevation.py:129 +msgid "Elevation Correction Complete" +msgstr "Correcção de Elevações Completa" + +#: extensions/openstreetmap/openstreetmap.py:82 +msgid "" +"Posting GPX trace to Openstreetmap\n" +"\n" +"Please wait this could take several minutes" +msgstr "" +"A enviar percurso GPX para o Openstreetmap\n" +"\n" +"Por favor aguarde, isto pode demorar alguns minutos" + +#: extensions/openstreetmap/openstreetmap.py:84 +msgid "Openstreetmap Extension Processing" +msgstr "A processar Extensão Openstreetmap" + +#: extensions/openstreetmap/openstreetmap.py:102 +msgid "Openstreetmap Extension Upload Complete" +msgstr "Envio da Extensão Openstreetmap completo" + +#: extensions/openstreetmap/openstreetmap.py:107 +msgid "Error while uploading file to OSM: " +msgstr "Erro ao enviar ficheiro para o OSM: " + +#: extensions/openstreetmap/openstreetmap.py:109 +msgid "Openstreetmap Extension Error" +msgstr "Erro na Extensão Openstreetmap" + +#: extensions/openstreetmap/openstreetmap.py:117 +msgid "Please add any additional information for this upload" +msgstr "Por favor, acrescente informações adicionais para este envio" + +#: extensions/openstreetmap/openstreetmap.py:204 +msgid "Error" +msgstr "Erro" + +#: extensions/openstreetmap/openstreetmap.py:247 +msgid "Error while saving extension configuration" +msgstr "Erro ao guardar configuração da extensão" + +#: extensions/wordpress/wordpress.py:46 +msgid "Posting to Wordpress blog" +msgstr "A enviar para blog Wordpress" + +#: extensions/wordpress/wordpress.py:48 +msgid "Wordpress Extension Processing" +msgstr "A processar Extensão Wordpress" + +#: extensions/wordpress/wordpress.py:144 +msgid "Wordpress Extension Upload Complete" +msgstr "Envio da Extensão Wordpress Completo" + Modified: pytrainer/trunk/pytrainer/gui/aboutdialog.py =================================================================== --- pytrainer/trunk/pytrainer/gui/aboutdialog.py 2011-10-16 17:12:12 UTC (rev 895) +++ pytrainer/trunk/pytrainer/gui/aboutdialog.py 2011-10-20 17:41:53 UTC (rev 896) @@ -33,11 +33,11 @@ def run(self): authors = ["Fiz Vázquez <vu...@si...>\nDavid García Granda <dg...@gm...>\nJohn Blance <joh...@gm...>\nArnd Zapletal <a.z...@gm...>\nNathan Jones <na...@nc...>\n\n-Package maintainers:\n\nRedHat/Fedora: Douglas E. Warner <sil...@si...>\nDebian: Noèl Köthe <no...@de...>\nUbuntu: Kevin Dwyer <ke...@ph...>, Alessio Treglia <qua...@ub...>"] - translator_credits = "Euskara: Jabier Santamaria <men...@gm...>\nCatalà: Eloi Crespillo Itchart <el...@ik...>\nČesky: Lobus Pokorny <sp...@se...>\nFrançais: Dj <dj...@dj...>, Pierr... [truncated message content] |
From: <dg...@us...> - 2011-10-16 17:12:20
|
Revision: 895 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=895&view=rev Author: dgranda Date: 2011-10-16 17:12:12 +0000 (Sun, 16 Oct 2011) Log Message: ----------- Updated french localization (thx to Pierre) Modified Paths: -------------- pytrainer/trunk/locale/fr/LC_MESSAGES/pytrainer.mo pytrainer/trunk/locale/fr/LC_MESSAGES/pytrainer_fr.po Modified: pytrainer/trunk/locale/fr/LC_MESSAGES/pytrainer.mo =================================================================== (Binary files differ) Modified: pytrainer/trunk/locale/fr/LC_MESSAGES/pytrainer_fr.po =================================================================== --- pytrainer/trunk/locale/fr/LC_MESSAGES/pytrainer_fr.po 2011-10-12 20:56:07 UTC (rev 894) +++ pytrainer/trunk/locale/fr/LC_MESSAGES/pytrainer_fr.po 2011-10-16 17:12:12 UTC (rev 895) @@ -1,19 +1,19 @@ # translation of pytrainer_fr.po to -# French translations for vud package. -# Copyright (C) 2006 THE vud'S COPYRIGHT HOLDER -# This file is distributed under the same license as the vud package. +# French translations for pytrainer package. +# Copyright (C) 2006 THE pytrainer'S COPYRIGHT HOLDER +# This file is distributed under the same license as the pytrainer package. # # Fiz Vazquez <vu...@si...>, 2006. # dj <dj...@dj...>, 2006. msgid "" msgstr "" -"Project-Id-Version: pytrainer_fr\n" +"Project-Id-Version: pytrainer_fr 1.9.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-09-06 22:08+0200\n" +"POT-Creation-Date: 2011-10-12 22:01+0200\n" "PO-Revision-Date: \n" -"Last-Translator: David Garcia Granda <dg...@gm...>\n" +"Last-Translator: Pierre Gaigé <pg...@fr...>\n" "Language-Team: <fr...@li...>\n" -"Language: \n" +"Language: French\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -85,12 +85,12 @@ #: glade/extensions.glade:67 msgid "name-entry" -msgstr "" +msgstr "name-entry" #: glade/extensions.glade:82 #: glade/plugins.glade:144 #: glade/profile.glade:728 -#: glade/pytrainer.glade:5712 +#: glade/pytrainer.glade:5703 msgid "Name:" msgstr "Nom:" @@ -108,11 +108,11 @@ #: glade/extensions.glade:124 #: glade/plugins.glade:100 msgid "status-entry" -msgstr "" +msgstr "status-entry" #: glade/extensions.glade:139 msgid "description-entry" -msgstr "" +msgstr "description-entry" #: glade/importdata.glade:7 #: glade/importdata.glade:325 @@ -124,6 +124,8 @@ "Test 1\n" "Test 2" msgstr "" +"Test 1\n" +"Test 2" #: glade/importdata.glade:46 msgid "<b>Select your GPS device</b>" @@ -270,6 +272,9 @@ msgstr "Exclure" #: glade/importdata.glade:892 +#: pytrainer/totalgraph.py:24 +#: pytrainer/monthgraph.py:26 +#: pytrainer/heartrategraph.py:36 #: pytrainer/recordgraph.py:134 #: pytrainer/recordgraph.py:136 #: pytrainer/recordgraph.py:138 @@ -277,14 +282,11 @@ #: pytrainer/recordgraph.py:142 #: pytrainer/recordgraph.py:144 #: pytrainer/recordgraph.py:146 -#: pytrainer/monthgraph.py:26 -#: pytrainer/heartrategraph.py:36 -#: pytrainer/totalgraph.py:24 +#: pytrainer/weekgraph.py:28 #: pytrainer/yeargraph.py:26 #: pytrainer/daygraph.py:52 #: pytrainer/daygraph.py:54 #: pytrainer/daygraph.py:56 -#: pytrainer/weekgraph.py:28 msgid "Distance (km)" msgstr "Distance (km) " @@ -323,10 +325,10 @@ msgstr "Vitesse Max (km/h)" #: glade/importdata.glade:1037 -#: pytrainer/monthgraph.py:29 #: pytrainer/totalgraph.py:27 -#: pytrainer/yeargraph.py:29 +#: pytrainer/monthgraph.py:29 #: pytrainer/weekgraph.py:31 +#: pytrainer/yeargraph.py:29 msgid "Average Speed (km/h)" msgstr "Vitesse moyenne (km/h)" @@ -337,8 +339,8 @@ #: pytrainer/gui/windowmain.py:140 #: pytrainer/gui/windowmain.py:1496 #: pytrainer/gui/windowimportdata.py:353 -#: pytrainer/gui/windowrecord.py:210 #: pytrainer/gui/windowprofile.py:65 +#: pytrainer/gui/windowrecord.py:210 msgid "Sport" msgstr "Sport" @@ -457,7 +459,7 @@ #: glade/newrecord.glade:461 msgid "12:00:00" -msgstr "" +msgstr "12:00:00" #: glade/newrecord.glade:486 #: glade/profile.glade:1586 @@ -486,7 +488,7 @@ #: glade/newrecord.glade:671 msgid "Pace (min/km):" -msgstr "Allure (min/km)" +msgstr "Allure (min/km):" #: glade/newrecord.glade:718 msgid "<b>Pace</b>" @@ -513,13 +515,13 @@ msgstr "Fréquence Cardiaque:" #: glade/newrecord.glade:902 +#: pytrainer/totalgraph.py:28 +#: pytrainer/monthgraph.py:30 +#: pytrainer/weekgraph.py:32 #: pytrainer/gui/windowmain.py:122 #: pytrainer/gui/windowmain.py:165 #: pytrainer/gui/windowmain.py:1500 -#: pytrainer/monthgraph.py:30 -#: pytrainer/totalgraph.py:28 #: pytrainer/yeargraph.py:30 -#: pytrainer/weekgraph.py:32 msgid "Calories" msgstr "Calories" @@ -558,11 +560,11 @@ #: glade/plugins.glade:68 msgid "description-entry " -msgstr "" +msgstr "description-entry" #: glade/plugins.glade:129 msgid "nameEntry" -msgstr "" +msgstr "nameEntry" #: glade/profile.glade:7 msgid "Preferences" @@ -581,12 +583,12 @@ msgstr "<b>Système de Mesure</b>" #: glade/profile.glade:103 -#: glade/pytrainer.glade:2120 +#: glade/pytrainer.glade:2111 msgid "Google" -msgstr "" +msgstr "Google" #: glade/profile.glade:118 -#: glade/pytrainer.glade:2103 +#: glade/pytrainer.glade:2094 msgid "Open Street Map" msgstr "Open Street Map" @@ -631,12 +633,12 @@ msgstr "Sexe:" #: glade/profile.glade:407 -#: glade/pytrainer.glade:5737 +#: glade/pytrainer.glade:5728 msgid "Height:" msgstr "Taille:" #: glade/profile.glade:447 -#: glade/pytrainer.glade:5724 +#: glade/pytrainer.glade:5715 msgid "Date of birth:" msgstr "Date de Naissance:" @@ -645,12 +647,12 @@ msgstr "Poids:" #: glade/profile.glade:542 -#: glade/pytrainer.glade:5799 +#: glade/pytrainer.glade:5790 msgid "<b>Athlete Details</b>" msgstr "<b>Détail de l'Athlète</b>" #: glade/profile.glade:557 -#: glade/pytrainer.glade:5902 +#: glade/pytrainer.glade:5893 msgid "Athlete" msgstr "Athlète" @@ -660,7 +662,7 @@ #: glade/profile.glade:684 msgid "llist" -msgstr "" +msgstr "llist" #: glade/profile.glade:739 msgid "M.E.T.:" @@ -777,13 +779,13 @@ msgstr "<b>Zones Cardiaque:</b>" #: glade/profile.glade:1733 -#: pytrainer/recordgraph.py:140 -#: pytrainer/lib/activity.py:439 -#: pytrainer/lib/activity.py:441 -#: pytrainer/lib/activity.py:451 -#: pytrainer/lib/activity.py:521 #: pytrainer/heartrategraph.py:36 +#: pytrainer/recordgraph.py:140 #: pytrainer/daygraph.py:56 +#: pytrainer/lib/activity.py:443 +#: pytrainer/lib/activity.py:445 +#: pytrainer/lib/activity.py:455 +#: pytrainer/lib/activity.py:525 msgid "Heart Rate" msgstr "Fréquence Cardiaque" @@ -893,26 +895,26 @@ msgstr "<b>Sport:</b>" #: glade/pytrainer.glade:408 -#: glade/pytrainer.glade:3153 -#: glade/pytrainer.glade:3795 -#: glade/pytrainer.glade:4449 -#: glade/pytrainer.glade:5179 +#: glade/pytrainer.glade:3144 +#: glade/pytrainer.glade:3786 +#: glade/pytrainer.glade:4440 +#: glade/pytrainer.glade:5170 msgid "<b>Duration:</b>" msgstr "<b>Durée:</b>" #: glade/pytrainer.glade:423 -#: glade/pytrainer.glade:3243 -#: glade/pytrainer.glade:3874 -#: glade/pytrainer.glade:4528 -#: glade/pytrainer.glade:5281 +#: glade/pytrainer.glade:3234 +#: glade/pytrainer.glade:3865 +#: glade/pytrainer.glade:4519 +#: glade/pytrainer.glade:5272 msgid "<b>Speed:</b>" msgstr "<b>Vitesse:</b>" #: glade/pytrainer.glade:437 -#: glade/pytrainer.glade:3411 -#: glade/pytrainer.glade:4069 -#: glade/pytrainer.glade:4723 -#: glade/pytrainer.glade:5376 +#: glade/pytrainer.glade:3402 +#: glade/pytrainer.glade:4060 +#: glade/pytrainer.glade:4714 +#: glade/pytrainer.glade:5367 msgid "<b>Pace:</b>" msgstr "<b>Allure:</b>" @@ -933,10 +935,10 @@ msgstr "<b>Date:</b>" #: glade/pytrainer.glade:628 -#: glade/pytrainer.glade:3139 -#: glade/pytrainer.glade:3781 -#: glade/pytrainer.glade:4435 -#: glade/pytrainer.glade:5165 +#: glade/pytrainer.glade:3130 +#: glade/pytrainer.glade:3772 +#: glade/pytrainer.glade:4426 +#: glade/pytrainer.glade:5156 msgid "<b>Distance:</b>" msgstr "<b>Distance:</b>" @@ -945,10 +947,10 @@ msgstr "<b>Vitesse Max:</b>" #: glade/pytrainer.glade:661 -#: glade/pytrainer.glade:3441 -#: glade/pytrainer.glade:4083 -#: glade/pytrainer.glade:4737 -#: glade/pytrainer.glade:5391 +#: glade/pytrainer.glade:3432 +#: glade/pytrainer.glade:4074 +#: glade/pytrainer.glade:4728 +#: glade/pytrainer.glade:5382 msgid "<b>Max Pace:</b>" msgstr "<b>Allure Max:</b>" @@ -957,31 +959,31 @@ msgstr "<b>Dénivelé Négatif:</b>" #: glade/pytrainer.glade:769 -#: glade/pytrainer.glade:3351 -#: glade/pytrainer.glade:3949 -#: glade/pytrainer.glade:4603 -#: glade/pytrainer.glade:5091 +#: glade/pytrainer.glade:3342 +#: glade/pytrainer.glade:3940 +#: glade/pytrainer.glade:4594 +#: glade/pytrainer.glade:5082 msgid "Cal" msgstr "Cal" #: glade/pytrainer.glade:809 -#: glade/pytrainer.glade:3113 -#: glade/pytrainer.glade:3755 -#: glade/pytrainer.glade:4409 -#: glade/pytrainer.glade:5268 +#: glade/pytrainer.glade:3104 +#: glade/pytrainer.glade:3746 +#: glade/pytrainer.glade:4400 +#: glade/pytrainer.glade:5259 #: pytrainer/gui/windowmain.py:109 msgid "Km" msgstr "km" #: glade/pytrainer.glade:824 -#: glade/pytrainer.glade:3273 -#: glade/pytrainer.glade:3306 -#: glade/pytrainer.glade:3904 -#: glade/pytrainer.glade:3997 -#: glade/pytrainer.glade:4558 -#: glade/pytrainer.glade:4651 -#: glade/pytrainer.glade:5311 -#: glade/pytrainer.glade:5327 +#: glade/pytrainer.glade:3264 +#: glade/pytrainer.glade:3297 +#: glade/pytrainer.glade:3895 +#: glade/pytrainer.glade:3988 +#: glade/pytrainer.glade:4549 +#: glade/pytrainer.glade:4642 +#: glade/pytrainer.glade:5302 +#: glade/pytrainer.glade:5318 #: pytrainer/gui/windowmain.py:916 #: pytrainer/gui/windowmain.py:917 #: pytrainer/gui/windowmain.py:1045 @@ -997,28 +999,27 @@ msgstr "<b>Équipement:</b>" #: glade/pytrainer.glade:935 -#, fuzzy msgid "<b>Active / Rest:</b>" -msgstr "<b>Couru / Reste:</b>" +msgstr "<b>Actif / Repos:</b>" #: glade/pytrainer.glade:962 msgid "h:m:s" -msgstr "" +msgstr "h:m:s" -#: glade/pytrainer.glade:1016 +#: glade/pytrainer.glade:1007 msgid "<b>Laps</b>" msgstr "<b>Tours</b>" -#: glade/pytrainer.glade:1087 +#: glade/pytrainer.glade:1078 msgid " <b>Title:</b>" msgstr " <b>Titre:</b>" -#: glade/pytrainer.glade:1137 +#: glade/pytrainer.glade:1128 #: pytrainer/gui/windowmain.py:1722 msgid "Show graph display options" msgstr "Montrer les réglages du graphe" -#: glade/pytrainer.glade:1155 +#: glade/pytrainer.glade:1146 msgid "" "Profile\n" "Speed\n" @@ -1036,15 +1037,15 @@ "Pourcentage\n" "Zone" -#: glade/pytrainer.glade:1172 -#: glade/pytrainer.glade:4320 -#: glade/pytrainer.glade:4974 -#: glade/pytrainer.glade:5627 +#: glade/pytrainer.glade:1163 +#: glade/pytrainer.glade:4311 +#: glade/pytrainer.glade:4965 +#: glade/pytrainer.glade:5618 #: glade/pytrainer.glade:5984 msgid "Versus" msgstr "Versus" -#: glade/pytrainer.glade:1183 +#: glade/pytrainer.glade:1174 msgid "" "None\n" "Profile\n" @@ -1060,80 +1061,80 @@ "Fréquence Cardiaque\n" "Rythme\n" -#: glade/pytrainer.glade:1329 +#: glade/pytrainer.glade:1320 msgid "<small>Graph Display Options</small>" msgstr "<small>Options d'affichage des graphiques</small>" -#: glade/pytrainer.glade:1354 -#: glade/pytrainer.glade:1569 -#: glade/pytrainer.glade:1789 +#: glade/pytrainer.glade:1345 +#: glade/pytrainer.glade:1560 +#: glade/pytrainer.glade:1780 msgid "<small>Limits</small>" msgstr "<small>Limites</small>" -#: glade/pytrainer.glade:1366 -#: glade/pytrainer.glade:1581 -#: glade/pytrainer.glade:1835 +#: glade/pytrainer.glade:1357 +#: glade/pytrainer.glade:1572 +#: glade/pytrainer.glade:1826 msgid "<small>Min</small>" msgstr "<small>Min</small>" -#: glade/pytrainer.glade:1378 -#: glade/pytrainer.glade:1593 -#: glade/pytrainer.glade:1847 +#: glade/pytrainer.glade:1369 +#: glade/pytrainer.glade:1584 +#: glade/pytrainer.glade:1838 msgid "<small>Max</small>" msgstr "<small>Max</small>" -#: glade/pytrainer.glade:1427 -#: glade/pytrainer.glade:1649 +#: glade/pytrainer.glade:1418 +#: glade/pytrainer.glade:1640 msgid "<small>Color</small>" msgstr "<small>Couleur</small>" -#: glade/pytrainer.glade:1458 -#: glade/pytrainer.glade:1662 +#: glade/pytrainer.glade:1449 +#: glade/pytrainer.glade:1653 msgid "<small>Weight</small>" msgstr "<small>Poids</small>" -#: glade/pytrainer.glade:1488 +#: glade/pytrainer.glade:1479 msgid "Y1" -msgstr "" +msgstr "Y1" -#: glade/pytrainer.glade:1499 -#: glade/pytrainer.glade:1710 +#: glade/pytrainer.glade:1490 +#: glade/pytrainer.glade:1701 msgid "<small>Smoothing</small>" msgstr "<small>Lissage</small>" -#: glade/pytrainer.glade:1639 +#: glade/pytrainer.glade:1630 msgid "Y2" -msgstr "" +msgstr "Y2" -#: glade/pytrainer.glade:1779 +#: glade/pytrainer.glade:1770 msgid "X" -msgstr "" +msgstr "X" -#: glade/pytrainer.glade:1860 +#: glade/pytrainer.glade:1851 msgid "<small>Distance</small>" msgstr "<small>Distance</small>" -#: glade/pytrainer.glade:1889 +#: glade/pytrainer.glade:1880 msgid "<small>Time</small>" msgstr "<small>Temps</small>" -#: glade/pytrainer.glade:1950 +#: glade/pytrainer.glade:1941 msgid "Show Laps" msgstr "Montrer les tours" -#: glade/pytrainer.glade:1989 +#: glade/pytrainer.glade:1980 msgid "Reset Graph" msgstr "Réinitialiser le Graphe" -#: glade/pytrainer.glade:2051 +#: glade/pytrainer.glade:2042 msgid "Redraw Map" msgstr "Redessiner la carte" -#: glade/pytrainer.glade:2067 +#: glade/pytrainer.glade:2058 msgid "<small>Show:</small>" msgstr "<small>Afficher:</small>" -#: glade/pytrainer.glade:2078 +#: glade/pytrainer.glade:2069 msgid "" "None\n" "Speed\n" @@ -1145,160 +1146,151 @@ "Fréquence Cardiaque\n" "Allure" -#: glade/pytrainer.glade:2093 +#: glade/pytrainer.glade:2084 msgid "<small>Display map using:</small>" msgstr "<small>Afficher la carte avec:</small>" -#: glade/pytrainer.glade:2194 +#: glade/pytrainer.glade:2185 msgid "<b>Beats:</b>" msgstr "<b>FC Moy:</b>" -#: glade/pytrainer.glade:2206 -#: glade/pytrainer.glade:3321 -#: glade/pytrainer.glade:3919 -#: glade/pytrainer.glade:4573 -#: glade/pytrainer.glade:5061 +#: glade/pytrainer.glade:2197 +#: glade/pytrainer.glade:3312 +#: glade/pytrainer.glade:3910 +#: glade/pytrainer.glade:4564 +#: glade/pytrainer.glade:5052 msgid "<b>Calories: </b>" msgstr "<b>Calories:</b>" -#: glade/pytrainer.glade:2220 -#: glade/pytrainer.glade:3473 -#: glade/pytrainer.glade:4147 -#: glade/pytrainer.glade:4801 -#: glade/pytrainer.glade:5439 +#: glade/pytrainer.glade:2211 +#: glade/pytrainer.glade:3464 +#: glade/pytrainer.glade:4138 +#: glade/pytrainer.glade:4792 +#: glade/pytrainer.glade:5430 msgid "<b>Max Beats:</b>" msgstr "<b>FC Max:</b>" -#: glade/pytrainer.glade:2234 +#: glade/pytrainer.glade:2225 msgid "<b>HR Zones Method:</b>" msgstr "<b>Calcul des zones de FC :</b>" -#: glade/pytrainer.glade:2249 +#: glade/pytrainer.glade:2240 msgid "<b>HR Zone5:</b>" msgstr "<b>Zone FC5:</b>" -#: glade/pytrainer.glade:2264 -#: glade/pytrainer.glade:2463 +#: glade/pytrainer.glade:2255 +#: glade/pytrainer.glade:2454 msgid " bpm" msgstr " bpm" -#: glade/pytrainer.glade:2280 +#: glade/pytrainer.glade:2271 msgid " Cal" msgstr " Cal" -#: glade/pytrainer.glade:2338 +#: glade/pytrainer.glade:2329 msgid "<b>HR Zone4:</b>" msgstr "<b>Zone FC4:</b>" -#: glade/pytrainer.glade:2354 +#: glade/pytrainer.glade:2345 msgid "<b>HR Zone3:</b>" msgstr "<b>Zone FC3:</b>" -#: glade/pytrainer.glade:2370 +#: glade/pytrainer.glade:2361 msgid "<b>HR Zone2:</b>" msgstr "<b>Zone FC2:</b>" -#: glade/pytrainer.glade:2386 +#: glade/pytrainer.glade:2377 msgid "<b>HR Zone1:</b>" msgstr "<b>Zone FC1:</b>" -#: glade/pytrainer.glade:2488 -#: glade/pytrainer.glade:2500 -#: glade/pytrainer.glade:2515 -#: glade/pytrainer.glade:2530 -#: glade/pytrainer.glade:2545 -#: glade/pytrainer.glade:3396 -#: glade/pytrainer.glade:3490 -#: glade/pytrainer.glade:4054 -#: glade/pytrainer.glade:4132 -#: glade/pytrainer.glade:4708 -#: glade/pytrainer.glade:4786 -#: glade/pytrainer.glade:5136 -#: glade/pytrainer.glade:5343 -#: pytrainer/lib/activity.py:441 -#: pytrainer/lib/activity.py:521 +#: glade/pytrainer.glade:2479 +#: glade/pytrainer.glade:2491 +#: glade/pytrainer.glade:2506 +#: glade/pytrainer.glade:2521 +#: glade/pytrainer.glade:2536 +#: glade/pytrainer.glade:3387 +#: glade/pytrainer.glade:3481 +#: glade/pytrainer.glade:4045 +#: glade/pytrainer.glade:4123 +#: glade/pytrainer.glade:4699 +#: glade/pytrainer.glade:4777 +#: glade/pytrainer.glade:5127 +#: glade/pytrainer.glade:5334 +#: pytrainer/lib/activity.py:445 +#: pytrainer/lib/activity.py:525 msgid "bpm" msgstr "bpm" -#: glade/pytrainer.glade:2590 +#: glade/pytrainer.glade:2581 msgid " <b>Heart Rate:</b>" msgstr " <b>Fréquence Cardiaque:</b>" -#: glade/pytrainer.glade:2778 -#, fuzzy +#: glade/pytrainer.glade:2769 msgid "<b>Projected times</b>" -msgstr "<b>Équipement associé</b>" +msgstr "<b>Temps estimé</b>" -#: glade/pytrainer.glade:2808 +#: glade/pytrainer.glade:2799 msgid "<i>Rank relative to same-sport activities for distances ± x%:</i>" -msgstr "" +msgstr "<i>Classement de l'activité comparativement à une activité de même nature pour une distance de ± x%:</i>" -#: glade/pytrainer.glade:2841 -#, fuzzy +#: glade/pytrainer.glade:2832 msgid "<b>Range:</b>" -msgstr "<b>Allure:</b>" +msgstr "<b>Intervalle:</b>" -#: glade/pytrainer.glade:2854 -#, fuzzy +#: glade/pytrainer.glade:2845 msgid "<b>Rank:</b>" -msgstr "<b>Principal:</b>" +msgstr "<b>Classement:</b>" -#: glade/pytrainer.glade:2867 -#, fuzzy +#: glade/pytrainer.glade:2858 msgid "<b>Speed: </b>" msgstr "<b>Vitesse:</b>" -#: glade/pytrainer.glade:2880 -#, fuzzy +#: glade/pytrainer.glade:2871 msgid "<b>Avg speed:</b>" -msgstr "<b>Vitesse:</b>" +msgstr "<b>Vitesse moy.:</b>" -#: glade/pytrainer.glade:2893 -#, fuzzy +#: glade/pytrainer.glade:2884 msgid "<b>Standard deviation:</b>" -msgstr "<b>Durée:</b>" +msgstr "<b>Écart type:</b>" -#: glade/pytrainer.glade:2907 -#, fuzzy +#: glade/pytrainer.glade:2898 msgid "<b>Deviation:</b>" -msgstr "<b>Durée:</b>" +msgstr "<b>Dispersion:</b>" -#: glade/pytrainer.glade:3026 -#, fuzzy +#: glade/pytrainer.glade:3017 msgid "<b>Ranking</b>" -msgstr "<b>Principal:</b>" +msgstr "<b>Classement:</b>" -#: glade/pytrainer.glade:3052 -#, fuzzy +#: glade/pytrainer.glade:3043 msgid "<b>Analytics:</b>" -msgstr "<b>FC Moy:</b>" +msgstr "<b>Analyse:</b>" -#: glade/pytrainer.glade:3080 +#: glade/pytrainer.glade:3071 msgid "Record" msgstr "Enregistrement" -#: glade/pytrainer.glade:3289 -#: glade/pytrainer.glade:3965 -#: glade/pytrainer.glade:4619 -#: glade/pytrainer.glade:5359 +#: glade/pytrainer.glade:3280 +#: glade/pytrainer.glade:3956 +#: glade/pytrainer.glade:4610 +#: glade/pytrainer.glade:5350 msgid "<b>Max Speed:</b>" msgstr "<b>Vit. Max:</b>" -#: glade/pytrainer.glade:3366 -#: glade/pytrainer.glade:4024 -#: glade/pytrainer.glade:4678 -#: glade/pytrainer.glade:5106 +#: glade/pytrainer.glade:3357 +#: glade/pytrainer.glade:4015 +#: glade/pytrainer.glade:4669 +#: glade/pytrainer.glade:5097 msgid "<b>Beats avg:</b>" msgstr "<b>FC Moy:</b>" -#: glade/pytrainer.glade:3426 -#: glade/pytrainer.glade:3458 -#: glade/pytrainer.glade:4100 -#: glade/pytrainer.glade:4116 -#: glade/pytrainer.glade:4754 -#: glade/pytrainer.glade:4770 -#: glade/pytrainer.glade:5408 -#: glade/pytrainer.glade:5424 +#: glade/pytrainer.glade:3417 +#: glade/pytrainer.glade:3449 +#: glade/pytrainer.glade:4091 +#: glade/pytrainer.glade:4107 +#: glade/pytrainer.glade:4745 +#: glade/pytrainer.glade:4761 +#: glade/pytrainer.glade:5399 +#: glade/pytrainer.glade:5415 #: pytrainer/gui/windowmain.py:918 #: pytrainer/gui/windowmain.py:919 #: pytrainer/gui/windowmain.py:1047 @@ -1309,32 +1301,32 @@ msgid "min/km" msgstr "min/km" -#: glade/pytrainer.glade:3565 -#: glade/pytrainer.glade:4208 -#: glade/pytrainer.glade:4862 -#: glade/pytrainer.glade:5515 +#: glade/pytrainer.glade:3556 +#: glade/pytrainer.glade:4199 +#: glade/pytrainer.glade:4853 +#: glade/pytrainer.glade:5506 msgid "<b>Total Asc/Desc:</b>" -msgstr "<b>Total Asc/Desc:</b>" +msgstr "<b>Dénivelé Total Pos/Neg:</b>" -#: glade/pytrainer.glade:3592 -#: glade/pytrainer.glade:4235 -#: glade/pytrainer.glade:4889 -#: glade/pytrainer.glade:5542 +#: glade/pytrainer.glade:3583 +#: glade/pytrainer.glade:4226 +#: glade/pytrainer.glade:4880 +#: glade/pytrainer.glade:5533 #: pytrainer/gui/windowmain.py:2066 #: pytrainer/gui/windowmain.py:2068 #: pytrainer/lib/activity.py:205 msgid "m" msgstr "m" -#: glade/pytrainer.glade:3611 +#: glade/pytrainer.glade:3602 msgid " <b>Date:</b>" msgstr " <b>Date:</b>" -#: glade/pytrainer.glade:3654 +#: glade/pytrainer.glade:3645 msgid "Value" msgstr "Valeur" -#: glade/pytrainer.glade:3665 +#: glade/pytrainer.glade:3656 msgid "" "Stage Profile\n" "Stage Velocity\n" @@ -1344,17 +1336,17 @@ "Vitesse de la sortie\n" "Profil de la sortie/Vitesse" -#: glade/pytrainer.glade:3721 +#: glade/pytrainer.glade:3712 msgid "Day" msgstr "Jour" -#: glade/pytrainer.glade:4254 +#: glade/pytrainer.glade:4245 msgid " <b>Week:</b>" msgstr "<b>Semaine:</b>" -#: glade/pytrainer.glade:4305 -#: glade/pytrainer.glade:4959 -#: glade/pytrainer.glade:5612 +#: glade/pytrainer.glade:4296 +#: glade/pytrainer.glade:4950 +#: glade/pytrainer.glade:5603 #: glade/pytrainer.glade:5969 msgid "" "Distance\n" @@ -1369,9 +1361,9 @@ "Vitesse moyenne\n" "Calories" -#: glade/pytrainer.glade:4331 -#: glade/pytrainer.glade:4985 -#: glade/pytrainer.glade:5638 +#: glade/pytrainer.glade:4322 +#: glade/pytrainer.glade:4976 +#: glade/pytrainer.glade:5629 #: glade/pytrainer.glade:5995 msgid "" "None\n" @@ -1388,35 +1380,35 @@ "Vitesse moyenne\n" "Calories" -#: glade/pytrainer.glade:4375 +#: glade/pytrainer.glade:4366 msgid "Week" msgstr "Semaine" -#: glade/pytrainer.glade:4908 +#: glade/pytrainer.glade:4899 msgid " <b>Month:</b>" msgstr " <b>Mois:</b>" -#: glade/pytrainer.glade:5028 +#: glade/pytrainer.glade:5019 msgid "Month" msgstr "Mois" -#: glade/pytrainer.glade:5561 +#: glade/pytrainer.glade:5552 msgid " <b>Year:</b>" msgstr " <b>Année:</b>" -#: glade/pytrainer.glade:5681 +#: glade/pytrainer.glade:5672 msgid "Year" msgstr "Année" -#: glade/pytrainer.glade:5835 +#: glade/pytrainer.glade:5826 msgid "<b>Graph</b>" msgstr "<b>Graphe:</b>" -#: glade/pytrainer.glade:5876 +#: glade/pytrainer.glade:5867 msgid "<b>History</b>" msgstr "<b>Historique</b>" -#: glade/pytrainer.glade:5936 +#: glade/pytrainer.glade:5937 msgid "<b>Sports</b>" msgstr "<b>Sports</b>" @@ -1473,7 +1465,7 @@ "Toutes les dates\n" "Les 4 dernières semaines\n" "Les 6 derniers mois\n" -"Les 12 derniers moiss" +"Les 12 derniers mois" #: glade/pytrainer.glade:6349 msgid "Columns" @@ -1532,6 +1524,297 @@ msgid "Warning" msgstr "Attention" +#: import/file_kml20.py:47 +msgid "Geodistance kml version 2.0 file" +msgstr "Fichier Geodistance kml version 2.0" + +#: import/file_gpxplus.py:41 +msgid "GPS eXchange file" +msgstr "Fichier de type GPX" + +#: import/tool_gpsbabel.py:37 +msgid "GPSBabel" +msgstr "GPSBabel" + +#: import/tool_garmintools.py:37 +msgid "Garmintools" +msgstr "Garmintools" + +#: import/file_garmintcxv1.py:45 +msgid "Garmin training center database file version 1" +msgstr "Fichier de base de données Garmin training center version 1" + +#: import/file_gpxplusNokia.py:41 +msgid "Nokia Export - GPS eXchange file" +msgstr "Export Nokia- GPS eXchange file" + +#: import/tool_gant.py:37 +msgid "Gant" +msgstr "Gant" + +#: import/file_garmintools.py:44 +msgid "Garmin tools dump file" +msgstr "Fichier de dump Garmin tools" + +#: import/file_garmintcxv2.py:44 +msgid "Garmin training center database file version 2" +msgstr "Fichier de base de données Garmin training center version 2" + +#: extensions/openstreetmap/openstreetmap.py:82 +msgid "" +"Posting GPX trace to Openstreetmap\n" +"\n" +"Please wait this could take several minutes" +msgstr "" +"Envoi de la trace GPX vers Openstreetmap\n" +"\n" +"Merci d'attendre la fin du processus qui peut prendre quelques minutes" + +#: extensions/openstreetmap/openstreetmap.py:84 +msgid "Openstreetmap Extension Processing" +msgstr "Traitement de l'extension Openstreetmap" + +#: extensions/openstreetmap/openstreetmap.py:102 +msgid "Openstreetmap Extension Upload Complete" +msgstr "Chargement sur Openstreetmap effectué" + +#: extensions/openstreetmap/openstreetmap.py:107 +msgid "Error while uploading file to OSM: " +msgstr "Erreur lors du chargement du fichier ver OSM" + +#: extensions/openstreetmap/openstreetmap.py:109 +msgid "Openstreetmap Extension Error" +msgstr "Erreur d'extension Openstreetmap" + +#: extensions/openstreetmap/openstreetmap.py:117 +msgid "Please add any additional information for this upload" +msgstr "Merci de Compléter les informations pour ce chargement" + +#: extensions/openstreetmap/openstreetmap.py:204 +msgid "Error" +msgstr "Erreur" + +#: extensions/openstreetmap/openstreetmap.py:247 +msgid "Error while saving extension configuration" +msgstr "Erreur lors de la sauvegarde de la configuration de l'extension" + +#: extensions/fixelevation/fixelevation.py:129 +msgid "Elevation Correction Complete" +msgstr "Correction d'élévation terminée" + +#: extensions/wordpress/wordpress.py:46 +msgid "Posting to Wordpress blog" +msgstr "Poster sur le blog Wordpress" + +#: extensions/wordpress/wordpress.py:48 +msgid "Wordpress Extension Processing" +msgstr "Traitement de l'extension Wordpress" + +#: extensions/wordpress/wordpress.py:144 +msgid "Wordpress Extension Upload Complete" +msgstr "Chargement sur Wordpress effectué" + +#: pytrainer/record.py:56 +msgid "Modify details before importing" +msgstr "Modifier les détails avant l'importation" + +#: pytrainer/record.py:67 +#: pytrainer/gui/windowmain.py:2156 +msgid "Edit Entry" +msgstr "Entrée Rapide" + +#: pytrainer/record.py:466 +msgid "pyTrainer can't import data from your gpx file" +msgstr "pyTrainer ne peut pas importer de données depuis le fichier GPX" + +#: pytrainer/totalgraph.py:24 +#: pytrainer/totalgraph.py:25 +#: pytrainer/totalgraph.py:26 +#: pytrainer/totalgraph.py:27 +#: pytrainer/totalgraph.py:28 +msgid "year" +msgstr "année" + +#: pytrainer/totalgraph.py:24 +msgid "Annual Distance" +msgstr "Distance annuelle" + +#: pytrainer/totalgraph.py:25 +#: pytrainer/monthgraph.py:27 +#: pytrainer/weekgraph.py:29 +#: pytrainer/yeargraph.py:27 +msgid "Time (hours)" +msgstr "Durée (Heures)" + +#: pytrainer/totalgraph.py:25 +msgid "Annual Time" +msgstr "Durée annuelle" + +#: pytrainer/totalgraph.py:26 +#: pytrainer/monthgraph.py:28 +#: pytrainer/weekgraph.py:30 +#: pytrainer/yeargraph.py:28 +msgid "Average Heart Rate (bpm)" +msgstr "FC moyenne (bpm)" + +#: pytrainer/totalgraph.py:26 +msgid "Annual Average Heart Rate" +msgstr "FC moyenne annuelle" + +#: pytrainer/totalgraph.py:27 +msgid "Annual Average Speed" +msgstr "Vitesse moyenne annuelle" + +#: pytrainer/totalgraph.py:28 +msgid "Annual Calories" +msgstr "Calories annuelles" + +#: pytrainer/monthgraph.py:26 +#: pytrainer/monthgraph.py:27 +#: pytrainer/monthgraph.py:28 +#: pytrainer/monthgraph.py:29 +#: pytrainer/monthgraph.py:30 +msgid "day" +msgstr "jour" + +#: pytrainer/monthgraph.py:26 +#: pytrainer/weekgraph.py:28 +msgid "Daily Distance" +msgstr "Distance Journalière" + +#: pytrainer/monthgraph.py:27 +#: pytrainer/weekgraph.py:29 +msgid "Daily Time" +msgstr "Durée Journalière" + +#: pytrainer/monthgraph.py:28 +#: pytrainer/weekgraph.py:30 +msgid "Daily Average Heart Rate" +msgstr "FC moyenne Journalière" + +#: pytrainer/monthgraph.py:29 +#: pytrainer/weekgraph.py:31 +msgid "Daily Average Speed" +msgstr "Vitesse moyenne Journalière" + +#: pytrainer/monthgraph.py:30 +#: pytrainer/weekgraph.py:32 +msgid "Daily Calories" +msgstr "Calories Journalière" + +#: pytrainer/heartrategraph.py:36 +#: pytrainer/recordgraph.py:140 +#: pytrainer/daygraph.py:56 +msgid "Beats (bpm)" +msgstr "Pulsations (bpm)" + +#: pytrainer/recordgraph.py:134 +#: pytrainer/daygraph.py:52 +msgid "Height (m)" +msgstr "Altitude (m)" + +#: pytrainer/recordgraph.py:134 +#: pytrainer/daygraph.py:52 +msgid "Stage Profile" +msgstr "Profil de la sortie" + +#: pytrainer/recordgraph.py:136 +msgid "Speed (Km/h)" +msgstr "Vitesse (km/h)" + +#: pytrainer/recordgraph.py:136 +#: pytrainer/gui/windowmain.py:187 +#: pytrainer/lib/activity.py:335 +#: pytrainer/lib/activity.py:425 +#: pytrainer/lib/activity.py:427 +msgid "Speed" +msgstr "Vitesse" + +#: pytrainer/recordgraph.py:138 +#: pytrainer/lib/activity.py:324 +#: pytrainer/lib/activity.py:434 +#: pytrainer/lib/activity.py:436 +msgid "Pace" +msgstr "Allure" + +#: pytrainer/recordgraph.py:142 +msgid "Cadence (rpm)" +msgstr "Rythme (tpm) " + +#: pytrainer/recordgraph.py:142 +#: pytrainer/lib/activity.py:462 +#: pytrainer/lib/activity.py:464 +msgid "Cadence" +msgstr "Rythme" + +#: pytrainer/recordgraph.py:144 +msgid "Beats (%)" +msgstr "Pulsations (%)" + +#: pytrainer/recordgraph.py:144 +#: pytrainer/gui/windowmain.py:1498 +msgid "Beats" +msgstr "Pulsations" + +#: pytrainer/recordgraph.py:146 +msgid "Zone" +msgstr "Zone" + +#: pytrainer/waypoint.py:87 +msgid "The gpx file seems to be a several days records. Perhaps you will need to edit your gpx file" +msgstr "Ce fichier GPX semble contenir plusieurs jours d'enregistrements. Vous devrez peut-être au préalable éditer celui-ci." + +#: pytrainer/extensions/googlemaps.py:127 +#: pytrainer/extensions/osm.py:102 +#: pytrainer/gui/windowmain.py:2066 +#: pytrainer/gui/drawArea.py:165 +msgid "h" +msgstr "h" + +#: pytrainer/extensions/googlemaps.py:127 +#: pytrainer/extensions/osm.py:102 +#: pytrainer/gui/drawArea.py:166 +msgid "min" +msgstr "min" + +#: pytrainer/extensions/googlemaps.py:129 +#: pytrainer/extensions/osm.py:104 +#: pytrainer/gui/windowmain.py:119 +#: pytrainer/gui/windowmain.py:158 +#: pytrainer/gui/windowmain.py:176 +#: pytrainer/gui/windowmain.py:186 +#: pytrainer/gui/windowmain.py:570 +#: pytrainer/gui/windowmain.py:1497 +msgid "Time" +msgstr "Temps" + +#: pytrainer/extensions/googlemaps.py:129 +#: pytrainer/extensions/osm.py:105 +#: pytrainer/gui/windowmain.py:117 +#: pytrainer/gui/windowmain.py:157 +#: pytrainer/gui/windowmain.py:175 +#: pytrainer/gui/windowmain.py:185 +#: pytrainer/gui/windowmain.py:569 +#: pytrainer/gui/windowmain.py:1495 +#: pytrainer/gui/windowimportdata.py:353 +#: pytrainer/gui/windowrecord.py:210 +#: pytrainer/lib/activity.py:323 +#: pytrainer/lib/activity.py:334 +#: pytrainer/lib/activity.py:406 +#: pytrainer/lib/activity.py:417 +#: pytrainer/lib/activity.py:426 +#: pytrainer/lib/activity.py:435 +#: pytrainer/lib/activity.py:444 +#: pytrainer/lib/activity.py:454 +#: pytrainer/lib/activity.py:463 +#: pytrainer/lib/activity.py:524 +msgid "Distance" +msgstr "Distance" + +#: pytrainer/gui/drawGraph.py:170 +msgid "Athlete Data" +msgstr "Données de l'athlète" + #: pytrainer/gui/windowmain.py:107 msgid "Miles" msgstr "Miles" @@ -1550,40 +1833,6 @@ msgid "Start" msgstr "Début" -#: pytrainer/gui/windowmain.py:117 -#: pytrainer/gui/windowmain.py:157 -#: pytrainer/gui/windowmain.py:175 -#: pytrainer/gui/windowmain.py:185 -#: pytrainer/gui/windowmain.py:569 -#: pytrainer/gui/windowmain.py:1495 -#: pytrainer/gui/windowimportdata.py:353 -#: pytrainer/gui/windowrecord.py:210 -#: pytrainer/lib/activity.py:319 -#: pytrainer/lib/activity.py:330 -#: pytrainer/lib/activity.py:402 -#: pytrainer/lib/activity.py:413 -#: pytrainer/lib/activity.py:422 -#: pytrainer/lib/activity.py:431 -#: pytrainer/lib/activity.py:440 -#: pytrainer/lib/activity.py:450 -#: pytrainer/lib/activity.py:459 -#: pytrainer/lib/activity.py:520 -#: pytrainer/extensions/googlemaps.py:129 -#: pytrainer/extensions/osm.py:105 -msgid "Distance" -msgstr "Distance" - -#: pytrainer/gui/windowmain.py:119 -#: pytrainer/gui/windowmain.py:158 -#: pytrainer/gui/windowmain.py:176 -#: pytrainer/gui/windowmain.py:186 -#: pytrainer/gui/windowmain.py:570 -#: pytrainer/gui/windowmain.py:1497 -#: pytrainer/extensions/googlemaps.py:129 -#: pytrainer/extensions/osm.py:104 -msgid "Time" -msgstr "Temps" - #: pytrainer/gui/windowmain.py:120 msgid "⌀ HR" msgstr "FC" @@ -1615,9 +1864,8 @@ msgstr "FC Max" #: pytrainer/gui/windowmain.py:141 -#, fuzzy msgid "Records" -msgstr "Enregistrement" +msgstr "Enregistrements" #: pytrainer/gui/windowmain.py:142 msgid "Total duration" @@ -1656,7 +1904,7 @@ #: pytrainer/gui/windowmain.py:156 msgid "Trigger" -msgstr "" +msgstr "Échantillonage" #: pytrainer/gui/windowmain.py:161 msgid "Avg pace" @@ -1672,41 +1920,31 @@ #: pytrainer/gui/windowmain.py:174 msgid "Race" -msgstr "" +msgstr "Course" #: pytrainer/gui/windowmain.py:183 msgid "Rank" -msgstr "" +msgstr "Place" -#: pytrainer/gui/windowmain.py:187 -#: pytrainer/recordgraph.py:136 -#: pytrainer/lib/activity.py:331 -#: pytrainer/lib/activity.py:421 -#: pytrainer/lib/activity.py:423 -msgid "Speed" -msgstr "Vitesse" - #: pytrainer/gui/windowmain.py:319 -#, fuzzy msgid "d" -msgstr "id" +msgstr "d" #: pytrainer/gui/windowmain.py:559 msgid "Show on X Axis" -msgstr "" +msgstr "Montrer sur l'axe X" #: pytrainer/gui/windowmain.py:560 msgid "Show on Y1 Axis" -msgstr "" +msgstr "Montrer sur l'axe Y1" #: pytrainer/gui/windowmain.py:561 msgid "Show on Y2 Axis" -msgstr "" +msgstr "Montrer sur l'axe Y2" #: pytrainer/gui/windowmain.py:562 -#, fuzzy msgid "Axis Limits" -msgstr "Réinitialiser les limites" +msgstr "Limites des axes" #: pytrainer/gui/windowmain.py:571 msgid "Laps" @@ -1738,35 +1976,35 @@ #: pytrainer/gui/windowmain.py:805 msgid "800 m" -msgstr "" +msgstr "800 m" #: pytrainer/gui/windowmain.py:806 msgid "1500 m" -msgstr "" +msgstr "1500 m" #: pytrainer/gui/windowmain.py:807 msgid "5K" -msgstr "" +msgstr "5K" #: pytrainer/gui/windowmain.py:808 msgid "7K" -msgstr "" +msgstr "7K" #: pytrainer/gui/windowmain.py:809 msgid "10K" -msgstr "" +msgstr "10K" #: pytrainer/gui/windowmain.py:810 msgid "Half marathon" -msgstr "" +msgstr "Semi Marathon" #: pytrainer/gui/windowmain.py:811 msgid "Marathon" -msgstr "" +msgstr "Marathon" #: pytrainer/gui/windowmain.py:812 msgid "100K" -msgstr "" +msgstr "100K" #: pytrainer/gui/windowmain.py:909 #: pytrainer/gui/windowmain.py:1038 @@ -1802,11 +2040,6 @@ msgid "km" msgstr "km" -#: pytrainer/gui/windowmain.py:1498 -#: pytrainer/recordgraph.py:144 -msgid "Beats" -msgstr "Pulsations" - #: pytrainer/gui/windowmain.py:1499 msgid "Average" msgstr "Moyenne" @@ -1820,22 +2053,10 @@ msgstr "tour " #: pytrainer/gui/windowmain.py:2066 -#: pytrainer/gui/drawArea.py:165 -#: pytrainer/extensions/googlemaps.py:127 -#: pytrainer/extensions/osm.py:102 -msgid "h" -msgstr "h" - -#: pytrainer/gui/windowmain.py:2066 #: pytrainer/gui/windowmain.py:2068 msgid "s" msgstr "s" -#: pytrainer/gui/windowmain.py:2156 -#: pytrainer/record.py:67 -msgid "Edit Entry" -msgstr "Entrée Rapide" - #: pytrainer/gui/windowmain.py:2167 msgid "Delete Entry" msgstr "Détruire l'entrée" @@ -1849,29 +2070,24 @@ msgstr "Éditer les données de l'athlète" #: pytrainer/gui/windowmain.py:2208 -#, fuzzy msgid "<b>Date</b>" -msgstr "<b>Date:</b>" +msgstr "<b>Date</b>" #: pytrainer/gui/windowmain.py:2224 -#, fuzzy msgid "<b>Weight</b>" -msgstr "<b>Vitesse</b>" +msgstr "<b>Poids</b>" #: pytrainer/gui/windowmain.py:2232 -#, fuzzy msgid "<b>Body Fat</b>" -msgstr "<b>FC Moy:</b>" +msgstr "<b>Masse grasse</b>" #: pytrainer/gui/windowmain.py:2240 -#, fuzzy msgid "<b>Resting Heart Rate</b>" -msgstr "<b>Fréquence Cardiaque:</b>" +msgstr "<b>Fréquence cardiaque de repos</b>" #: pytrainer/gui/windowmain.py:2248 -#, fuzzy msgid "<b>Max Heart Rate</b>" -msgstr "<b>Fréquence Cardiaque:</b>" +msgstr "<b>Fréquence cardiaque max</b>" #: pytrainer/gui/windowmain.py:2276 #: pytrainer/main.py:451 @@ -1882,6 +2098,32 @@ msgid "Are you sure?" msgstr "Êtes vous sûr?" +#: pytrainer/gui/windowextensions.py:70 +#: pytrainer/gui/windowimportdata.py:558 +#: pytrainer/gui/windowplugins.py:71 +#: pytrainer/gui/windowplugins.py:95 +msgid "Disable" +msgstr "Désactivé" + +#: pytrainer/gui/windowextensions.py:72 +#: pytrainer/gui/windowimportdata.py:559 +#: pytrainer/gui/windowplugins.py:69 +#: pytrainer/gui/windowplugins.py:96 +msgid "Enable" +msgstr "Activé" + +#: pytrainer/gui/windowextensions.py:81 +#: pytrainer/gui/windowimportdata.py:543 +#: pytrainer/gui/windowplugins.py:80 +#, python-format +msgid "%s settings" +msgstr "%s réglages" + +#: pytrainer/gui/windowextensions.py:112 +#: pytrainer/gui/windowextensions.py:125 +msgid "OK" +msgstr "OK" + #: pytrainer/gui/windowimportdata.py:117 msgid "No file selected" msgstr "Pas de fichier sélectionné" @@ -1892,7 +2134,7 @@ #: pytrainer/gui/windowimportdata.py:163 msgid "Run" -msgstr "" +msgstr "Course à pied" #: pytrainer/gui/windowimportdata.py:171 msgid "Disabled" @@ -1944,27 +2186,6 @@ msgid "Imported into database" msgstr "Importé dans la base" -#: pytrainer/gui/windowimportdata.py:543 -#: pytrainer/gui/windowextensions.py:81 -#: pytrainer/gui/windowplugins.py:80 -#, python-format -msgid "%s settings" -msgstr "" - -#: pytrainer/gui/windowimportdata.py:558 -#: pytrainer/gui/windowextensions.py:70 -#: pytrainer/gui/windowplugins.py:71 -#: pytrainer/gui/windowplugins.py:95 -msgid "Disable" -msgstr "Désactivé" - -#: pytrainer/gui/windowimportdata.py:559 -#: pytrainer/gui/windowextensions.py:72 -#: pytrainer/gui/windowplugins.py:69 -#: pytrainer/gui/windowplugins.py:96 -msgid "Enable" -msgstr "Activé" - #: pytrainer/gui/windowimportdata.py:566 #: pytrainer/gui/windowplugins.py:103 msgid "Ok" @@ -2021,20 +2242,6 @@ msgid "Column %d" msgstr "Colonne %d" -#: pytrainer/gui/drawArea.py:166 -#: pytrainer/extensions/googlemaps.py:127 -#: pytrainer/extensions/osm.py:102 -msgid "min" -msgstr "min" - -#: pytrainer/gui/drawArea.py:410 -msgid "rest" -msgstr "repos" - -#: pytrainer/gui/windowrecord.py:210 -msgid "GPX File" -msgstr "Fichier GPX" - #: pytrainer/gui/windowprofile.py:47 msgid "Male" msgstr "Homme" @@ -2049,71 +2256,24 @@ #: pytrainer/gui/windowprofile.py:314 msgid "Sport Creation Error" -msgstr "Sport Creation Erreur" +msgstr "Erreur lors de création du sport" #: pytrainer/gui/equipment.py:101 -#, fuzzy msgid "Usage" -msgstr "Utilisation précédente" +msgstr "Utilisation" +#: pytrainer/gui/drawArea.py:410 +msgid "rest" +msgstr "repos" + +#: pytrainer/gui/windowrecord.py:210 +msgid "GPX File" +msgstr "Fichier GPX" + #: pytrainer/gui/dialogselecttrack.py:40 msgid "Track Name" msgstr "Nom du Circuit" -#: pytrainer/gui/drawGraph.py:170 -msgid "Athlete Data" -msgstr "Données de l'athlète" - -#: pytrainer/gui/windowextensions.py:112 -#: pytrainer/gui/windowextensions.py:125 -msgid "OK" -msgstr "OK" - -#: pytrainer/recordgraph.py:134 -#: pytrainer/daygraph.py:52 -msgid "Height (m)" -msgstr "Altitude (m)" - -#: pytrainer/recordgraph.py:134 -#: pytrainer/daygraph.py:52 -msgid "Stage Profile" -msgstr "Profil de la sortie" - -#: pytrainer/recordgraph.py:136 -msgid "Speed (Km/h)" -msgstr "Vitesse (km/h)" - -#: pytrainer/recordgraph.py:138 -#: pytrainer/lib/activity.py:320 -#: pytrainer/lib/activity.py:430 -#: pytrainer/lib/activity.py:432 -msgid "Pace" -msgstr "Allure" - -#: pytrainer/recordgraph.py:140 -#: pytrainer/heartrategraph.py:36 -#: pytrainer/daygraph.py:56 -msgid "Beats (bpm)" -msgstr "Pulsations (bpm)" - -#: pytrainer/recordgraph.py:142 -msgid "Cadence (rpm)" -msgstr "Rythme (tpm) " - -#: pytrainer/recordgraph.py:142 -#: pytrainer/lib/activity.py:458 -#: pytrainer/lib/activity.py:460 -msgid "Cadence" -msgstr "Rythme" - -#: pytrainer/recordgraph.py:144 -msgid "Beats (%)" -msgstr "Pulsations (%)" - -#: pytrainer/recordgraph.py:146 -msgid "Zone" -msgstr "Zone" - #: pytrainer/profile.py:114 msgid "Moderate activity" msgstr "Activité modérée" @@ -2134,186 +2294,10 @@ msgid "VO2 MAX" msgstr "VO2 Max" -#: pytrainer/lib/listview.py:32 -#, fuzzy -msgid "All Time" -msgstr "Durée annuelle" +#: pytrainer/main.py:467 +msgid "Delete this waypoint?" +msgstr "Détruire ce Point de Localisation" -#: pytrainer/lib/listview.py:32 -msgid "Last 4 Weeks" -msgstr "" - -#: pytrainer/lib/listview.py:33 -msgid "Last 6 Months" -msgstr "" - -#: pytrainer/lib/listview.py:33 -msgid "Last 12 Months" -msgstr "" - -#: pytrainer/lib/listview.py:36 -msgid "<1 Hour" -msgstr "" - -#: pytrainer/lib/listview.py:37 -msgid "1-2 Hours" -msgstr "" - -#: pytrainer/lib/listview.py:38 -msgid ">2 Hours" -msgstr "" - -#: pytrainer/lib/gpx.py:129 -msgid "No Name" -msgstr "Sans Nom" - -#: pytrainer/lib/gpx.py:137 -msgid "No Data" -msgstr "Pas de Valeurs" - -#: pytrainer/lib/activity.py:200 -msgid "feet" -msgstr "pieds" - -#: pytrainer/lib/activity.py:318 -msgid "Pace by Lap" -msgstr "Allure au tour" - -#: pytrainer/lib/activity.py:324 -#: pytrainer/lib/activity.py:335 -#: pytrainer/lib/activity.py:407 -#: pytrainer/lib/activity.py:417 -#: pytrainer/lib/activity.py:426 -#: pytrainer/lib/activity.py:435 -#: pytrainer/lib/activity.py:444 -#: pytrainer/lib/activity.py:454 -#: pytrainer/lib/activity.py:463 -#: pytrainer/lib/activity.py:525 -msgid "Time (seconds)" -msgstr "Durée (s)" - -#: pytrainer/lib/activity.py:329 -msgid "Speed by Lap" -msgstr "Vitesse au tour" - -#: pytrainer/lib/activity.py:401 -#: pytrainer/lib/activity.py:403 -msgid "Elevation" -msgstr "Altitude" - -#: pytrainer/lib/activity.py:412 -#: pytrainer/lib/activity.py:414 -msgid "Corrected Elevation" -msgstr "Altitude corrigée" - -#: pytrainer/lib/activity.py:449 -#, python-format -msgid "Heart Rate (% of max)" -msgstr "Fréquence Cardiaque (% du max)" - -#: pytrainer/lib/activity.py:451 -msgid "%" -msgstr "%" - -#: pytrainer/lib/activity.py:460 -msgid "rpm" -msgstr "tpm" - -#: pytrainer/lib/activity.py:519 -msgid "Heart Rate zone" -msgstr "Zone de Fréquence Cardiaque" - -#: pytrainer/monthgraph.py:26 -#: pytrainer/monthgraph.py:27 -#: pytrainer/monthgraph.py:28 -#: pytrainer/monthgraph.py:29 -#: pytrainer/monthgraph.py:30 -msgid "day" -msgstr "jour" - -#: pytrainer/monthgraph.py:26 -#: pytrainer/weekgraph.py:28 -msgid "Daily Distance" -msgstr "Distance Journalière" - -#: pytrainer/monthgraph.py:27 -#: pytrainer/totalgraph.py:25 -#: pytrainer/yeargraph.py:27 -#: pytrainer/weekgraph.py:29 -msgid "Time (hours)" -msgstr "Durée (Heures)" - -#: pytrainer/monthgraph.py:27 -#: pytrainer/weekgraph.py:29 -msgid "Daily Time" -msgstr "Durée Journalière" - -#: pytrainer/monthgraph.py:28 -#: pytrainer/totalgraph.py:26 -#: pytrainer/yeargraph.py:28 -#: pytrainer/weekgraph.py:30 -msgid "Average Heart Rate (bpm)" -msgstr "FC moyenne (bpm):" - -#: pytrainer/monthgraph.py:28 -#: pytrainer/weekgraph.py:30 -msgid "Daily Average Heart Rate" -msgstr "FC moyenne Journalière" - -#: pytrainer/monthgraph.py:29 -#: pytrainer/weekgraph.py:31 -msgid "Daily Average Speed" -msgstr "Vitesse moyenne Journalière" - -#: pytrainer/monthgraph.py:30 -#: pytrainer/weekgraph.py:32 -msgid "Daily Calories" -msgstr "Calories Journalière" - -#: pytrainer/totalgraph.py:24 -#: pytrainer/totalgraph.py:25 -#: pytrainer/totalgraph.py:26 -#: pytrainer/totalgraph.py:27 -#: pytrainer/totalgraph.py:28 -msgid "year" -msgstr "année" - -#: pytrainer/totalgraph.py:24 -msgid "Annual Distance" -msgstr "Distance annuelle" - -#: pytrainer/totalgraph.py:25 -msgid "Annual Time" -msgstr "Durée annuelle" - -#: pytrainer/totalgraph.py:26 -msgid "Annual Average Heart Rate" -msgstr "FC moyenne annuelle" - -#: pytrainer/totalgraph.py:27 -msgid "Annual Average Speed" -msgstr "Vitesse moyenne annuelle" - -#: pytrainer/totalgraph.py:28 -msgid "Annual Calories" -msgstr "Calories annuelles" - -#: pytrainer/athlete.py:52 -msgid "lb" -msgstr "lb" - -#: pytrainer/athlete.py:54 -msgid "kg" -msgstr "kg" - -#: pytrainer/record.py:56 -msgid "Modify details before importing" -msgstr "" - -#: pytrainer/record.py:465 -msgid "pyTrainer can't import data from your gpx file" -msgstr "pyTrainer ne peut pas importer de données depuis le fichier GPX" - #: pytrainer/yeargraph.py:26 #: pytrainer/yeargraph.py:27 #: pytrainer/yeargraph.py:28 @@ -2342,10 +2326,6 @@ msgid "Monthly Calories" msgstr "Calories Mensuelle" -#: pytrainer/waypoint.py:87 -msgid "The gpx file seems to be a several days records. Perhaps you will need to edit your gpx file" -msgstr "Ce fichier GPX semble contenir plusieurs jours d'enregistrements. Vous devrez peut-être au préalable éditer celui-ci." - #: pytrainer/daygraph.py:54 msgid "Velocity (Km/h)" msgstr "Vitesse (km/h)" @@ -2354,474 +2334,99 @@ msgid "Velocity" msgstr "Vitesse" -#: pytrainer/main.py:467 -msgid "Delete this waypoint?" -msgstr "Détruire ce Point de Localisation" +#: pytrainer/athlete.py:52 +msgid "lb" +msgstr "lb" -#: import/file_gpxplus.py:41 -msgid "GPS eXchange file" -msgstr "Fichier de type GPX" +#: pytrainer/athlete.py:54 +msgid "kg" +msgstr "kg" -#: import/file_kml20.py:47 -msgid "Geodistance kml version 2.0 file" -msgstr "Fichier Geodistance kml version 2.0" +#: pytrainer/lib/listview.py:32 +msgid "All Time" +msgstr "Toutes les dates" -#: import/file_garmintcxv1.py:45 -msgid "Garmin training center database file version 1" -msgstr "Fichier de base de données Garmin training center version 1" +#: pytrainer/lib/listview.py:32 +msgid "Last 4 Weeks" +msgstr "Les 4 dernières semaines" -#: import/file_gpxplusNokia.py:41 -msgid "Nokia Export - GPS eXchange file" -msgstr "Export Nokia- GPS eXchange file" +#: pytrainer/lib/listview.py:33 +msgid "Last 6 Months" +msgstr "Les 6 derniers mois" -#: import/tool_gpsbabel.py:37 -msgid "GPSBabel" -msgstr "GPSBabel" +#: pytrainer/lib/listview.py:33 +msgid "Last 12 Months" +msgstr "Les 12 derniers mois" -#: import/tool_garmintools.py:37 -msgid "Garmintools" -msgstr "Garmintools" +#: pytrainer/lib/listview.py:36 +msgid "<1 Hour" +msgstr "<1 heure" -#: import/tool_gant.py:37 -msgid "Gant" -msgstr "Gant" +#: pytrainer/lib/listview.py:37 +msgid "1-2 Hours" +msgstr "1-2 heures" -#: import/file_garmintools.py:44 -msgid "Garmin tools dump file" -msgstr "Fichier de dump Garmin tools" +#: pytrainer/lib/listview.py:38 +msgid ">2 Hours" +msgstr ">2 heures" -#: import/file_garmintcxv2.py:44 -msgid "Garmin training center database file version 2" -msgstr "Fichier de base de données Garmin training center version 2" +#: pytrainer/lib/activity.py:200 +msgid "feet" +msgstr "pieds" -#: extensions/fixelevation/fixelevation.py:129 -msgid "Elevation Correction Complete" -msgstr "Correction d'élévation terminée" +#: pytrainer/lib/activity.py:322 +msgid "Pace by Lap" +msgstr "Allure au tour" -#: extensions/openstreetmap/openstreetmap.py:82 -msgid "" -"Posting GPX trace to Openstreetmap\n" -"\n" -"Please wait this could take several minutes" -msgstr "" -"Envoi de la trace GPX vers Openstreetmap\n" -"\n" -"Merci d'attendre la fin du processus qui peut prendre quelques minutes" +#: pytrainer/lib/activity.py:328 +#: pytrainer/lib/activity.py:339 +#: pytrainer/lib/activity.py:411 +#: pytrainer/lib/activity.py:421 +#: pytrainer/lib/activity.py:430 +#: pytrainer/lib/activity.py:439 +#: pytrainer/lib/activity.py:448 +#: pytrainer/lib/activity.py:458 +#: pytrainer/lib/activity.py:467 +#: pytrainer/lib/activity.py:529 +msgid "Time (seconds)" +msgstr "Durée (s)" -#: extensions/openstreetmap/openstreetmap.py:84 -msgid "Openstreetmap Extension Processing" -msgstr "Traitement de l'extension Openstreetmap" +#: pytrainer/lib/activity.py:333 +msgid "Speed by Lap" +msgstr "Vitesse au tour" -#: extensions/openstreetmap/openstreetmap.py:102 -msgid "Openstreetmap Extension Upload Complete" -msgstr "Chargement sur Openstreetmap effectué" +#: pytrainer/lib/activity.py:405 +#: pytrainer/lib/activity.py:407 +msgid "Elevation" +msgstr "Altitude" -#: extensions/openstreetmap/openstreetmap.py:107 -msgid "Error while uploading file to OSM: " -msgstr "" +#: pytrainer/lib/activity.py:416 +#: pytrainer/lib/activity.py:418 +msgid "Corrected Elevation" +msgstr "Altitude corrigée" -#: extensions/openstreetmap/openstreetmap.py:109 -msgid "Openstreetmap Extension Error" -msgstr "Erreur d'extension Openstreetmap" +#: pytrainer/lib/activity.py:453 +#, python-format +msgid "Heart Rate (% of max)" +msgstr "Fréquence Cardiaque (% du max)" -#: extensions/openstreetmap/openstreetmap.py:117 -msgid "Please add any additional information for this upload" -msgstr "Merci de Compléter les informations pour ce chargement" +#: pytrainer/lib/activity.py:455 +msgid "%" +msgstr "%" -#: extensions/openstreetmap/openstreetmap.py:204 -msgid "Error" -msgstr "" +#: pytrainer/lib/activity.py:464 +msgid "rpm" +msgstr "tpm" -#: extensions/openstreetmap/openstreetmap.py:247 -msgid "Error while saving extension configuration" -msgstr "" +#: pytrainer/lib/activity.py:523 +msgid "Heart Rate zone" +msgstr "Zone de Fréquence Cardiaque" -#: extensions/wordpress/wordpress.py:46 -msgid "Posting to Wordpress blog" -msgstr "Poster sur le blog Wordpress" +#: pytrainer/lib/gpx.py:129 +msgid "No Name" +msgstr "Sans Nom" -#: extensions/wordpress/wordpress.py:48 -msgid "Wordpress Extension Processing" -msgstr "Traitement de l'extension Wordpress" +#: pytrainer/lib/gpx.py:137 +msgid "No Data" +msgstr "Pas de Valeurs" -#: extensions/wordpress/wordpress.py:144 -msgid "Wordpress Extension Upload Complete" -msgstr "Chargement sur Wordpress effectué" - -#~ msgid "Must have username and password configured" -#~ msgstr "Un nom d'utilisateur et un mot de passe doivent être configurés" - -#~ msgid "Maxiumum Pace" -#~ msgstr "Allure Max" - -#~ msgid "Use this port for internal connections: " -#~ msgstr "Utiliser ce port pour les connexions internes:" - -#~ msgid "" -#~ "<small><b>Note:</b> Change this only if you know what you are doing</" -#~ "small>" -#~ msgstr "" -#~ "<small><b>Note:</b> Changez cette valeur uniquement si vous savez ce que " -#~ "vous faites</small>" - -#~ msgid "<b>Port Connnection</b>" -#~ msgstr "<b>Port de Connexion:</b>" - -#~ msgid "label-2147483648" -#~ msgstr "label-2147483648" - -#~ msgid "<small>Is the Googlemaps API version 3 in use?</small>" -#~ msgstr "<small>Googlemaps utilise t-il l'API version 3?</small>" - -#~ msgid "Unified Import" -#~ msgstr "Import unifié" - -#~ msgid "<small>Is the Unified Importer active?</small>" -#~ msgstr "<small>L'import unifié est-il activé?</small>" - -#~ msgid "" -#~ "<small>* Note Googlemaps API version 3 is on by default, use --gmaps2 to " -#~ "switch it off</small>" -#~ msgstr "" -#~ "<small>* Notez que l'API version 3 de Googlemaps est activée par défaut, " -#~ "utilisez --gmaps2 pour la déactiver</small>" - -#~ msgid "window1" -#~ msgstr "fenêtre1" - -#, fuzzy -#~ msgid "label-2147483647" -#~ msgstr "label-2147483648" - -#~ msgid "label154" -#~ msgstr "label154" - -#~ msgid "label155" -#~ msgstr "label155" - -#~ msgid "label162" -#~ msgstr "label162" - -#~ msgid "label163" -#~ msgstr "label163" - -#~ msgid "Kilometer" -#~ msgstr "Kilomètres" - -#~ msgid "Refresh Graph Display" -#~ msgstr "Rafraîchir l'affichage du graphique" - -#~ msgid "Velocity (km/h)" -#~ msgstr "Vitesse (km/h)" - -#~ msgid "Clear" -#~ msgstr "Effacer" - -#~ msgid "Unknown file type" -#~ msgstr "Fichier de type inconnu" - -#~ msgid "Import Success" -#~ msgstr "Importation réussie" - -#, fuzzy -#~ msgid " " -#~ msgstr " " - -#, fuzzy -#~ msgid "<b>frame1</b>" -#~ msgstr " <b>Nom:</b>" - -#~ msgid "Kilometers" -#~ msgstr "Kilomètres" - -#~ msgid "Daily kilometers" -#~ msgstr "Kilométrage journalier" - -#~ msgid "Beats per Minute" -#~ msgstr "Pulsations par Minute" - -#~ msgid "Daily Beats" -#~ msgstr "FC moy. journalière" - -#~ msgid "Weekly kilometers" -#~ msgstr "Kilométrage hebdomadaire" - -#~ msgid "Weekly Time" -#~ msgstr "Durée hebdomadaire" - -#~ msgid "weekly Beats" -#~ msgstr "FC moy. hebdomadaire" - -#~ msgid "Weekly Speed Averages" -#~ msgstr "Vitesse moy. hebdomadaire" - -#~ msgid "Weekly Calories" -#~ msgstr "Calories hebdomadaire" - -#~ msgid "kilometers" -#~ msgstr "Kilomètres" - -#~ msgid "monthly kilometers" -#~ msgstr "Kilométrage mensuel" - -#~ msgid "time in hours" -#~ msgstr "Temps en heures" - -#~ msgid "beats per minute" -#~ msgstr "pulsations par minute" - -#~ msgid "monthly beats" -#~ msgstr "FC moy. mensuelle" - -#~ msgid "average (hm/h)" -#~ msgstr "Vitesse moy. (km/h)" - -#~ msgid "calories" -#~ msgstr "calories" - -#~ msgid "January" -#~ msgstr "Janvier" - -#~ msgid "Febrary" -#~ msgstr "Février" - -#~ msgid "March" -#~ msgstr "Mars" - -#~ msgid "April" -#~ msgstr "Avril" - -#~ msgid "May" -#~ msgstr "Mai" - -#~ msgid "June" -#~ msgstr "Juin" - -#~ msgid "July" -#~ msgstr "Juillet" - -#~ msgid "August" -#~ msgstr "Août" - -#~ msgid "September" -#~ msgstr "Septembre" - -#~ msgid "October" -#~ msgstr "Octobre" - -#~ msgid "November" -#~ msgstr "Novembre" - -#~ msgid "December" -#~ msgstr "Décembre" - -#~ msgid "" -#~ "Distance\n" -#~ "Time\n" -#~ msgstr "" -#~ "Distance\n" -#~ "Temps\n" - -#~ msgid "" -#~ "<small><b>Note:</b> You can get your M.E.T. sport Coefficient here: " -#~ "http://pytrainer.e-oss.net/met.pdf</small>" -#~ msgstr "" -#~ "<small><b>Note:</b> Vous pouvez consulter l'indice M.E.T. de votre sport " -#~ "à l'adresse suivante: http://pytrainer.e-oss.net/met.pdf</small>" - -#~ msgid "pytrainer" -#~ msgstr "pytrainer" - -#~ msgid "(c) Fiz Vazquez <vu...@si...>" -#~ msgstr "(c) Fiz Vazquez <vu...@si...>" - -#~ msgid "Track sporting activities and performance" -#~ msgstr "Un outil de suivi des activités sportives et des performances" - -#~ msgid "" -#~ "(C) Fiz Vazquez\n" -#~ "\n" -#~ " This program is free software; you can redistribute \n" -#~ " it and/or modify it under the terms of the GNU \n" -#~ " General Public License as published by the Free \n" -#~ " Software Foundation; either version 2 of the License, \n" -#~ " or (at your option) any later version.\n" -#~ "\n" -#~ " This program is distributed in the hope that it will be \n" -#~ " useful, but WITHOUT ANY WARRANTY; without even the\n" -#~ " implied warranty of MERCHANTABILITY or FITNESS FOR \n" -#~ " A PARTICULAR PURPOSE. See the GNU General Public \n" -#~ " License <http://www.opensource.org/gpl-license.html>\n" -#~ " for more details.\n" -#~ "\n" -#~ " You can found the license on Debian systems in the file\n" -#~ " /usr/share/common-licenses/GPL\n" -#~ msgstr "" -#~ "(C) Fiz Vazquez\n" -#~ "\n" -#~ " This program is free software; you can redistribute \n" -#~ " it and/or modify it under the terms of the GNU \n" -#~ " General Public License as published by the Free \n" -#~ " Software Foundation; either version 2 of the License, \n" -#~ " or (at your option) any later version.\n" -#~ "\n" -#~ " This program is distributed in the hope that it will be \n" -#~ " useful, but WITHOUT ANY WARRANTY; without even the\n" -#~ " implied warranty of MERCHANTABILITY or FITNESS FOR \n" -#~ " A PARTICULAR PURPOSE. See the GNU General Public \n" -#~ " License <http://www.opensource.org/gpl-license.html>\n" -#~ " for more details.\n" -#~ "\n" -#~ " You can found the license on Debian systems in the file\n" -#~ " /usr/share/common-licenses/GPL\n" - -#~ msgid "pytrainer.e-oss.net" -#~ msgstr "pytrainer.e-oss.net" - -#~ msgid "" -#~ "Basque: Jabier Santamaria <men...@gm...>\n" -#~ "Catalan: Eloi Crespillo Itchart <el...@ik...>\n" -#~ "Czech: Lobus Pokorny <sp...@se...>\n" -#~ "French: Dj <dj...@dj...>\n" -#~ "French: Pierre Gaigé <pg...@fr...>\n" -#~ "Norwegian: Havard Davidsen <hav...@gm...>\n" -#~ "Polish: Seweryn Kokot <sk...@po...>\n" -#~ "german: Aleks <al...@sc...>\n" -#~ "Spanish: Fiz vazquez <vu...@si...>" -#~ msgstr "" -#~ "Basque: Jabier Santamaria <men...@gm...>\n" -#~ "Catalan: Eloi Crespillo Itchart <el...@ik...>\n" -#~ "Czech: Lobus Pokorny <sp...@se...>\n" -#~ "French: Dj <dj...@dj...>\n" -#~ "French: Pierre Gaigé <pg...@fr...>\n" -#~ "Norwegian: Havard Davidsen <hav...@gm...>\n" -#~ "Polish: Seweryn Kokot <sk...@po...>\n" -#~ "german: Aleks <al...@sc...>\n" -#~ "Spanish: Fiz vazquez <vu...@si...>" - -#~ msgid "No Active Plugins" -#~ msgstr "Aucun plugins actif" - -#~ msgid "No Active Extensions" -#~ msgstr "Aucune extension active" - -#~ msgid " Km" -#~ msgstr " Km" - -#~ msgid "<b>Velocity:</b>" -#~ msgstr "<b>Vitesse:</b>" - -#~ msgid " km/h" -#~ msgstr " km/h" - -#~ msgid " <b>Accumulated Altitude Change:</b> " -#~ msgstr " <b>Dénivelé Cumulé:</b> " - -#~ msgid "<b>Average:</b>" -#~ msgstr "<b>Moyenne:</b>" - -#~ msgid "velocity" -#~ msgstr "vitesse" - -#~ msgid "Calculate Distance" -#~ msgstr "Calculer la Distance" - -#~ msgid "Calculate Time" -#~ msgstr "Calculer la Durée" - -#~ msgid "Calculate Velocity" -#~ msgstr "Calculer la Vitesse" - -#~ msgid "Calculate Pace" -#~ msgstr "Calculer le Rythme" - -#~ msgid "Calculate Calories" -#~ msgstr "Calculer les Calories" - -#~ msgid "Calculate Average" -#~ msgstr "Calcule la Moyenne" - -#~ msgid "" -#~ "You are going to remove a sport. When you delete a \n" -#~ "sport you delete the records asociated. Are you sure \n" -#~ "that you want do it?" -#~ msgstr "" -#~ "Vous êtes en train de supprimer un sport. Quand vous supprimez un sport " -#~ "vous supprimez les résultats associés. Êtes vous sûr de vouloir le faire?" - -#~ msgid "" -#~ "You are going to remove one database entry. Are you sure yo want do it?" -#~ msgstr "" -#~ "Vous êtes en train de supprimer une entrée de la base de données. Êtes " -#~ "vous sûr de vouloir le faire?" - -#~ msgid "You are going to remove one waypoint. Are you sure yo want do it?" -#~ msgstr "" -#~ "Vous êtes en train de supprimer un point de localisation. Êtes vous sûr " -#~ "de vouloir le faire?" - -#~ msgid "" -#~ "The gpx file seems to have several track records. Press cancel to select " -#~ "a track record. Press Ok to load all of them as a single track record." -#~ msgstr "" -#~ "Ce fichier GPX semble contenir plusieurs circuits. Pressez Annuler pour " -#~ "sélectionner un circuit. Pressez Ok pour tous les charger sous un seul et " -#~ "même circuit." - -#~ msgid "<b>Positive:</b>" -#~ msgstr "<b>Positif:</b>" - -#~ msgid "<b>Negative:</b>" -#~ msgstr "<b>Négatif:</b>" - -#~ msgid "Km/day" -#~ msgstr "Km/jour" - -#~ msgid "bpm/day" -#~ msgstr "bpm/jour" - -#~ msgid "km/h/day" -#~ msgstr "km/h/jour" - -#~ msgid "cal/day" -#~ msgstr "cal/jour" - -#~ msgid "time/day" -#~ msgstr "temps/jour" - -#~ msgid " <b>Description:</b>" -#~ msgstr " <b>Description:</b>" - -#~ msgid "Profile" -#~ msgstr "Profil" - -#~ msgid "Age" -#~ msgstr "Age" - -#~ msgid "Database" -#~ msgstr "Base de données" - -#~ msgid "The free sport trainning center" -#~ msgstr "Un outil libre de planification d'entrainements" - -#~ msgid "window2" -#~ msgstr "fenêtre2" - -#~ msgid "The training tool for the gnu people" -#~ msgstr "L'outil d'entrainement pour les gens libres" - -#, fuzzy -#~ msgid "Export " -#~ msgstr "Export" - -#~ msgid "dialog1" -#~ msgstr "dialogue1" - -#~ msgid "Kj" -#~ msgstr "Kj" - -#~ msgid "Kj/day" -#~ msgstr "Kj/jour" - -#~ msgid "Press Here to create the database" -#~ msgstr "Appuyez ici pour créer votre base de données" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2011-10-12 20:56:13
|
Revision: 894 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=894&view=rev Author: dgranda Date: 2011-10-12 20:56:07 +0000 (Wed, 12 Oct 2011) Log Message: ----------- Updating changelog, we are almost there Modified Paths: -------------- pytrainer/trunk/CHANGES Modified: pytrainer/trunk/CHANGES =================================================================== --- pytrainer/trunk/CHANGES 2011-10-12 20:49:00 UTC (rev 893) +++ pytrainer/trunk/CHANGES 2011-10-12 20:56:07 UTC (rev 894) @@ -4,6 +4,8 @@ * New functionality + - Option added in localization script (utils/translator.sh) to generate only .pot file - [888 - 892] + - Galician localization (thanks to Kaptan) - [885 - 887] [893] - Manpage for pytrainer - #125 [872] [874] - Create sport service - #138 [838] [840 - 845] [850] [850 - 856] [875] [880] - Provide means to run all unit tests - #139 [837] @@ -14,7 +16,7 @@ - Assign graph color to sports - #111 [780] - Display laps information on record summary page - #109 #122 [768 - 772] [775] [777] [778] [788] [812] [813] - Coloring Google Maps path by speed/pace - thanks to Jonathan - #107 [765] - - Added swedish localization (thnx to Per) - #98 [756 - 760] + - Added swedish localization (thanks to Per) - #98 [756 - 760] - Add startup option for choosing console or file logging. When "console" is chosen all logging messsages are sent to stdout instead of a log file. [755] * Fixes This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |