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: <jb...@us...> - 2010-09-23 10:45:16
|
Revision: 618 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=618&view=rev Author: jblance Date: 2010-09-23 10:45:08 +0000 (Thu, 23 Sep 2010) Log Message: ----------- listview improvements from Arnd Modified Paths: -------------- pytrainer/trunk/pytrainer/gui/windowmain.py pytrainer/trunk/pytrainer/main.py Modified: pytrainer/trunk/pytrainer/gui/windowmain.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowmain.py 2010-09-22 10:23:00 UTC (rev 617) +++ pytrainer/trunk/pytrainer/gui/windowmain.py 2010-09-23 10:45:08 UTC (rev 618) @@ -48,1305 +48,1243 @@ from pytrainer.gui.drawGraph import DrawGraph class Main(SimpleGladeApp): - def __init__(self, data_path = None, parent = None, version = None, gpxDir = None): - def url_hook(dialog, url): - pytrainer.lib.webUtils.open_url_in_browser(url) - # Available in PyGTK 2.6 and above - gtk.about_dialog_set_url_hook(url_hook) - self.version = version - self.parent = parent - self.pytrainer_main = parent - self.data_path = data_path - glade_path="glade/pytrainer.glade" - root = "window1" - domain = None - SimpleGladeApp.__init__(self, self.data_path+glade_path, root, domain) + def __init__(self, data_path = None, parent = None, version = None, gpxDir = None): + def url_hook(dialog, url): + pytrainer.lib.webUtils.open_url_in_browser(url) + # Available in PyGTK 2.6 and above + gtk.about_dialog_set_url_hook(url_hook) + self.version = version + self.parent = parent + self.pytrainer_main = parent + self.data_path = data_path + glade_path="glade/pytrainer.glade" + root = "window1" + domain = None + SimpleGladeApp.__init__(self, self.data_path+glade_path, root, domain) - self.popup = PopupMenu(data_path,self) - self.block = False - self.activeSport = None - self.gpxDir = gpxDir - self.record_list = None - self.laps = None - self.y1_limits = None - self.y1_color = None - self.y1_linewidth = 1 + self.popup = PopupMenu(data_path,self) + self.block = False + self.activeSport = None + self.gpxDir = gpxDir + self.record_list = None + self.laps = None + self.y1_limits = None + self.y1_color = None + self.y1_linewidth = 1 - def new(self): - self.testimport = self.pytrainer_main.startup_options.testimport - self.menublocking = 0 - self.selected_view="day" - self.window1.set_title ("pyTrainer %s" % self.version) - try: - width, height = self.pytrainer_main.profile.getValue("pytraining","window_size").split(',') - self.window1.resize(int(width), int(height)) - except: - pass - self.record_list = [] - #create the columns for the listdayrecord - column_names=[_("id"),_("Start"), _("Sport"),_("Kilometer")] - self.create_treeview(self.recordTreeView,column_names) - #create the columns for the listarea - column_names=[_("id"),_("Title"),_("Date"),_("Distance"),_("Sport"),_("Time"),_("Beats"),_("Average"),("Calories")] - self.create_treeview(self.allRecordTreeView,column_names) - self.create_menulist(column_names) - #create the columns for the waypoints treeview - column_names=[_("id"),_("Waypoint")] - self.create_treeview(self.waypointTreeView,column_names) - #create the columns for the history treeview - column_names=[_("id"),_("Date"),_("Weight"),_("Body Fat %"),_("Resting HR"),_("Max HR")] - self.create_treeview(self.athleteTreeView,column_names) - self.fileconf = self.pytrainer_main.profile.confdir+"/listviewmenu.xml" - if not os.path.isfile(self.fileconf): - self._createXmlListView(self.fileconf) - self.showAllRecordTreeViewColumns() - self.allRecordTreeView.set_search_column(1) - self.notebook.set_current_page(1) + def new(self): + self.testimport = self.pytrainer_main.startup_options.testimport + self.menublocking = 0 + self.selected_view="day" + self.window1.set_title ("pyTrainer %s" % self.version) + try: + width, height = self.pytrainer_main.profile.getValue("pytraining","window_size").split(',') + self.window1.resize(int(width), int(height)) + except: + pass + self.record_list = [] + #create the columns for the listdayrecord + column_names=[_("id"),_("Start"), _("Sport"),_("Kilometer")] + self.create_treeview(self.recordTreeView,column_names) + #create the columns for the listarea + column_names=[_("id"),_("Title"),_("Date"),_("Distance"),_("Sport"),_("Time"),_("Beats"),_("Average"),("Calories")] + self.create_treeview(self.allRecordTreeView,column_names) + self.create_menulist(column_names) + #create the columns for the waypoints treeview + column_names=[_("id"),_("Waypoint")] + self.create_treeview(self.waypointTreeView,column_names) + #create the columns for the history treeview + column_names=[_("id"),_("Date"),_("Weight"),_("Body Fat %"),_("Resting HR"),_("Max HR")] + self.create_treeview(self.athleteTreeView,column_names) + self.fileconf = self.pytrainer_main.profile.confdir+"/listviewmenu.xml" + if not os.path.isfile(self.fileconf): + self._createXmlListView(self.fileconf) + self.showAllRecordTreeViewColumns() + self.allRecordTreeView.set_search_column(1) + self.notebook.set_current_page(1) - #Disable import menu item unless specified on startup - self.set_unified_import(self.testimport) + #Disable import menu item unless specified on startup + self.set_unified_import(self.testimport) - #Set correct map viewer - if self.pytrainer_main.profile.getValue("pytraining","default_viewer") == "1": - self.radiobuttonOSM.set_active(1) - else: - self.radiobuttonGMap.set_active(1) + #Set correct map viewer + if self.pytrainer_main.profile.getValue("pytraining","default_viewer") == "1": + self.radiobuttonOSM.set_active(1) + else: + self.radiobuttonGMap.set_active(1) - def setup(self): - self.createGraphs(RecordGraph,DayGraph,WeekGraph, MonthGraph,YearGraph,HeartRateGraph) - self.createMap(MapViewer,self.pytrainer_main.waypoint) - self.createWaypointEditor(WaypointEditor,self.pytrainer_main.waypoint, parent=self.pytrainer_main) - page = self.notebook.get_current_page() - self.on_page_change(None,None,page) + def setup(self): + self.createGraphs(RecordGraph,DayGraph,WeekGraph, MonthGraph,YearGraph,HeartRateGraph) + self.createMap(MapViewer,self.pytrainer_main.waypoint) + self.createWaypointEditor(WaypointEditor,self.pytrainer_main.waypoint, parent=self.pytrainer_main) + page = self.notebook.get_current_page() + self.on_page_change(None,None,page) - def set_unified_import(self, status=False): - self.menu_importdata.set_sensitive(status) - self.parent.testimport = status + def set_unified_import(self, status=False): + self.menu_importdata.set_sensitive(status) + self.parent.testimport = status - def _createXmlListView(self,file): - menufile = XMLParser(file) - savedOptions = [] - savedOptions.append(("date","True")) - savedOptions.append(("distance","True")) - savedOptions.append(("average","False")) - savedOptions.append(("title","True")) - savedOptions.append(("sport","True")) - savedOptions.append(("id_record","False")) - savedOptions.append(("time","False")) - savedOptions.append(("beats","False")) - savedOptions.append(("calories","False")) - menufile.createXMLFile("listviewmenu",savedOptions) + def _createXmlListView(self,file): + menufile = XMLParser(file) + savedOptions = [] + savedOptions.append(("date","True")) + savedOptions.append(("distance","True")) + savedOptions.append(("average","False")) + savedOptions.append(("title","True")) + savedOptions.append(("sport","True")) + savedOptions.append(("id_record","False")) + savedOptions.append(("time","False")) + savedOptions.append(("beats","False")) + savedOptions.append(("calories","False")) + menufile.createXMLFile("listviewmenu",savedOptions) - def removeImportPlugin(self, plugin): - for widget in self.menuitem1_menu: - if widget.get_name() == plugin[1]: - self.menuitem1_menu.remove(widget) + def removeImportPlugin(self, plugin): + for widget in self.menuitem1_menu: + if widget.get_name() == plugin[1]: + self.menuitem1_menu.remove(widget) - def removeExtension(self, extension): - for widget in self.recordbuttons_hbox: - if widget.get_name() == extension[1]: - logging.debug("Removing extension: %s " % extension[0]) - self.recordbuttons_hbox.remove(widget) + def removeExtension(self, extension): + for widget in self.recordbuttons_hbox: + if widget.get_name() == extension[1]: + logging.debug("Removing extension: %s " % extension[0]) + self.recordbuttons_hbox.remove(widget) - def addImportPlugin(self,plugin): - button = gtk.MenuItem(plugin[0]) - button.set_name(plugin[1]) - button.connect("activate", self.parent.runPlugin, plugin[1]) - self.menuitem1_menu.insert(button,3) - self.menuitem1_menu.show_all() + def addImportPlugin(self,plugin): + button = gtk.MenuItem(plugin[0]) + button.set_name(plugin[1]) + button.connect("activate", self.parent.runPlugin, plugin[1]) + self.menuitem1_menu.insert(button,3) + self.menuitem1_menu.show_all() - def addExtension(self,extension): - #txtbutton,extensioncode,extensiontype = extension - button = gtk.Button(extension[0]) - button.set_name(extension[1]) - button.connect("button_press_event", self.runExtension, extension) - self.recordbuttons_hbox.pack_start(button,False,False,0) - self.recordbuttons_hbox.show_all() + def addExtension(self,extension): + #txtbutton,extensioncode,extensiontype = extension + button = gtk.Button(extension[0]) + button.set_name(extension[1]) + button.connect("button_press_event", self.runExtension, extension) + self.recordbuttons_hbox.pack_start(button,False,False,0) + self.recordbuttons_hbox.show_all() - def runExtension(self,widget,widget2,extension): - #print extension - txtbutton,extensioncode,extensiontype = extension - id = None - if extensiontype=="record": - selected,iter = self.recordTreeView.get_selection().get_selected() - id = selected.get_value(iter,0) - self.parent.runExtension(extension,id) + def runExtension(self,widget,widget2,extension): + #print extension + txtbutton,extensioncode,extensiontype = extension + id = None + if extensiontype=="record": + selected,iter = self.recordTreeView.get_selection().get_selected() + id = selected.get_value(iter,0) + self.parent.runExtension(extension,id) - def createGraphs(self,RecordGraph,DayGraph,WeekGraph, MonthGraph,YearGraph,HeartRateGraph): - self.drawarearecord = RecordGraph(self.record_graph_vbox, self.window1, self.record_combovalue, self.record_combovalue2, self.btnShowLaps, self.tableConfigY1) - self.drawareaheartrate = HeartRateGraph(self.heartrate_vbox, self.window1, self.heartrate_vbox2, pytrainer_main=self.pytrainer_main) - #self.drawareaday = DayGraph(self.day_vbox, self.day_combovalue) - self.day_vbox.hide() - self.drawareaweek = WeekGraph(self.weekview, self.window1, self.week_combovalue, self.week_combovalue2) - self.drawareamonth = MonthGraph(self.month_vbox, self.window1, self.month_combovalue,self.month_combovalue2) - self.drawareayear = YearGraph(self.year_vbox, self.window1, self.year_combovalue,self.year_combovalue2) + def createGraphs(self,RecordGraph,DayGraph,WeekGraph, MonthGraph,YearGraph,HeartRateGraph): + self.drawarearecord = RecordGraph(self.record_graph_vbox, self.window1, self.record_combovalue, self.record_combovalue2, self.btnShowLaps, self.tableConfigY1) + self.drawareaheartrate = HeartRateGraph(self.heartrate_vbox, self.window1, self.heartrate_vbox2, pytrainer_main=self.pytrainer_main) + #self.drawareaday = DayGraph(self.day_vbox, self.day_combovalue) + self.day_vbox.hide() + self.drawareaweek = WeekGraph(self.weekview, self.window1, self.week_combovalue, self.week_combovalue2) + self.drawareamonth = MonthGraph(self.month_vbox, self.window1, self.month_combovalue,self.month_combovalue2) + self.drawareayear = YearGraph(self.year_vbox, self.window1, self.year_combovalue,self.year_combovalue2) - def createMap(self,MapViewer,waypoint): - self.waypoint = waypoint - self.mapviewer = MapViewer(self.data_path, pytrainer_main=self.parent, box=self.map_vbox) - self.mapviewer_fs = MapViewer(self.data_path, pytrainer_main=self.parent, box=self.map_vbox_old) - #self.googlemaps = Googlemaps(self.data_path, self.map_vbox,waypoint, pytrainer_main=self.parent) - #self.osm = Osm(self.data_path, self.map_vbox,waypoint, pytrainer_main=self.parent) - #self.googlemaps_old = Googlemaps(self.data_path, self.map_vbox_old,waypoint, pytrainer_main=self.parent) + def createMap(self,MapViewer,waypoint): + self.waypoint = waypoint + self.mapviewer = MapViewer(self.data_path, pytrainer_main=self.parent, box=self.map_vbox) + self.mapviewer_fs = MapViewer(self.data_path, pytrainer_main=self.parent, box=self.map_vbox_old) + #self.googlemaps = Googlemaps(self.data_path, self.map_vbox,waypoint, pytrainer_main=self.parent) + #self.osm = Osm(self.data_path, self.map_vbox,waypoint, pytrainer_main=self.parent) + #self.googlemaps_old = Googlemaps(self.data_path, self.map_vbox_old,waypoint, pytrainer_main=self.parent) - def updateSportList(self,listSport): - logging.debug(">>") - liststore = self.sportlist.get_model() - if self.sportlist.get_active() is not 0: - self.sportlist.set_active(0) #Set first item active if it isnt - firstEntry = self.sportlist.get_active_text() - liststore.clear() #Delete all items - #Re-add "All Sports" - liststore.append([firstEntry]) - #Re-add all sports in listSport - for i in listSport: - liststore.append([i[0]]) - self.sportlist.set_active(0) - logging.debug("<<") + def updateSportList(self,listSport): + logging.debug(">>") + liststore = self.sportlist.get_model() + if self.sportlist.get_active() is not 0: + self.sportlist.set_active(0) #Set first item active if it isnt + firstEntry = self.sportlist.get_active_text() + liststore.clear() #Delete all items + #Re-add "All Sports" + liststore.append([firstEntry]) + #Re-add all sports in listSport + for i in listSport: + liststore.append([i[0]]) + self.sportlist.set_active(0) + logging.debug("<<") - def create_treeview(self,treeview,column_names): - i=0 - for column_index, column_name in enumerate(column_names): - column = gtk.TreeViewColumn(column_name, gtk.CellRendererText(), text=column_index) - column.set_resizable(True) - if i==0: - column.set_visible(False) - column.set_sort_column_id(i) - treeview.append_column(column) - i+=1 + def create_treeview(self,treeview,column_names): + i=0 + for column_index, column_name in enumerate(column_names): + column = gtk.TreeViewColumn(column_name, gtk.CellRendererText(), text=column_index) + column.set_resizable(True) + if i==0: + column.set_visible(False) + column.set_sort_column_id(i) + treeview.append_column(column) + i+=1 - def actualize_recordview(self,activity): - logging.debug(">>") - if activity.id is None: - self.recordview.set_current_page(0) - self.recordview.set_sensitive(0) - logging.debug("<<") - return - #Set the units for the activity results, e.g. km, km/h etc - self.r_distance_unit.set_text(activity.distance_unit) - self.r_speed_unit.set_text(activity.speed_unit) - self.r_maxspeed_unit.set_text(activity.speed_unit) - self.r_pace_unit.set_text(activity.pace_unit) - self.r_maxpace_unit.set_text(activity.pace_unit) - self.r_ascent_unit.set_text(activity.height_unit) - self.r_descent_unit.set_text(activity.height_unit) + def actualize_recordview(self,activity): + logging.debug(">>") + if activity.id is None: + self.recordview.set_current_page(0) + self.recordview.set_sensitive(0) + logging.debug("<<") + return + #Set the units for the activity results, e.g. km, km/h etc + self.r_distance_unit.set_text(activity.distance_unit) + self.r_speed_unit.set_text(activity.speed_unit) + self.r_maxspeed_unit.set_text(activity.speed_unit) + self.r_pace_unit.set_text(activity.pace_unit) + self.r_maxpace_unit.set_text(activity.pace_unit) + self.r_ascent_unit.set_text(activity.height_unit) + self.r_descent_unit.set_text(activity.height_unit) - if activity.has_data: - self.recordview.set_sensitive(1) + if activity.has_data: + self.recordview.set_sensitive(1) - dateTime = activity.date_time - recordDateTime = dateTime.strftime("%Y-%m-%d %H:%M:%S") - recordDate = dateTime.strftime("%x") - recordTime = dateTime.strftime("%X") - recordDateTimeOffset = dateTime.strftime("%z") + dateTime = activity.date_time + recordDateTime = dateTime.strftime("%Y-%m-%d %H:%M:%S") + recordDate = dateTime.strftime("%x") + recordTime = dateTime.strftime("%X") + recordDateTimeOffset = dateTime.strftime("%z") - self.record_distance.set_text("%0.2f" %activity.distance) - self.record_upositive.set_text("%0.2f" %activity.upositive) - self.record_unegative.set_text("%0.2f" %activity.unegative) - self.record_average.set_text("%0.2f" %activity.average) - self.record_maxspeed.set_text("%0.2f" %activity.maxspeed) - self.record_pace.set_text(Record().pace_from_float(activity.pace)) - self.record_maxpace.set_text(Record().pace_from_float(activity.maxpace)) + self.record_distance.set_text("%0.2f" %activity.distance) + self.record_upositive.set_text("%0.2f" %activity.upositive) + self.record_unegative.set_text("%0.2f" %activity.unegative) + self.record_average.set_text("%0.2f" %activity.average) + self.record_maxspeed.set_text("%0.2f" %activity.maxspeed) + self.record_pace.set_text(Record().pace_from_float(activity.pace)) + self.record_maxpace.set_text(Record().pace_from_float(activity.maxpace)) - self.record_sport.set_text(activity.sport_name) - #self.record_date.set_text(str(date)) - self.record_date.set_text(recordDate) - self.record_time.set_text(recordTime) - hour,min,sec=self.parent.date.second2time(int(activity.time)) - self.record_hour.set_text("%d" %hour) - self.record_minute.set_text("%02d" %min) - self.record_second.set_text("%02d" %sec) - self.record_calories.set_text("%0.0f" %activity.calories) - self.record_title.set_text(activity.title) - buffer = self.record_comments.get_buffer() - start,end = buffer.get_bounds() - buffer.set_text(activity.comments) + self.record_sport.set_text(activity.sport_name) + #self.record_date.set_text(str(date)) + self.record_date.set_text(recordDate) + self.record_time.set_text(recordTime) + hour,min,sec=self.parent.date.second2time(int(activity.time)) + self.record_hour.set_text("%d" %hour) + self.record_minute.set_text("%02d" %min) + self.record_second.set_text("%02d" %sec) + self.record_calories.set_text("%0.0f" %activity.calories) + self.record_title.set_text(activity.title) + buffer = self.record_comments.get_buffer() + start,end = buffer.get_bounds() + buffer.set_text(activity.comments) - else: - self.recordview.set_current_page(0) - self.recordview.set_sensitive(0) - logging.debug("<<") + else: + self.recordview.set_current_page(0) + self.recordview.set_sensitive(0) + logging.debug("<<") - def actualize_recordgraph(self,activity): - logging.debug(">>") - self.record_list = activity.tracks - self.laps = activity.laps - if activity.gpx_file is not None: - if True: - logging.debug("Activity has GPX data") - self.record_vbox.set_sensitive(1) - self.drawarearecord.drawgraph(self.record_list,self.laps) + def actualize_recordgraph(self,activity): + logging.debug(">>") + self.record_list = activity.tracks + self.laps = activity.laps + if self.record_list is not None and len(self.record_list)>0: + self.record_vbox.set_sensitive(1) + self.drawarearecord.drawgraph(self.record_list,self.laps) + else: + #Remove graph + vboxChildren = self.record_vbox.get_children() + logging.debug('Vbox has %d children %s' % (len(vboxChildren), str(vboxChildren) )) + # ToDo: check why vertical container is shared + for child in vboxChildren: + #Remove all FigureCanvasGTK and NavigationToolbar2GTKAgg to stop double ups of graphs + if isinstance(child, matplotlib.backends.backend_gtkagg.FigureCanvasGTK) or isinstance(child, matplotlib.backends.backend_gtkagg.NavigationToolbar2GTKAgg): + logging.debug('Removing child: '+str(child)) + self.record_vbox.remove(child) + self.record_vbox.set_sensitive(0) + logging.debug("<<") - else: #Still just test code - #Create a frame showing data available for graphing - #Remove existing frames - for child in self.graph_data_hbox.get_children(): - self.graph_data_hbox.remove(child) - #Build frames and vboxs to hold checkbuttons - xFrame = gtk.Frame(label="Show on X Axis") - y1Frame = gtk.Frame(label="Show on Y1 Axis") - y2Frame = gtk.Frame(label="Show on Y2 Axis") - xvbox = gtk.VBox() - y1vbox = gtk.VBox() - y2vbox = gtk.VBox() - #Populate X axis data - xdistancebutton = gtk.RadioButton(label="Distance") - xdistancebutton.connect("toggled", self.on_xaxischange, "distance") - xdistancebutton.set_active(True) - xvbox.add(xdistancebutton) - xtimebutton = gtk.RadioButton(group=xdistancebutton, label="Time") - xtimebutton.connect("toggled", self.on_xaxischange, "time") - xvbox.add(xtimebutton) - xFrame.add(xvbox) - #Populate Y axis data - for graphdata in activity.distance_data: - y1button = gtk.CheckButton(label=activity.distance_data[graphdata].title) - y1button.connect("toggled", self.on_y1change, y1vbox, activity.distance_data[graphdata]) - y2button = gtk.CheckButton(label=activity.distance_data[graphdata].title) - y2button.connect("toggled", self.on_y2change, y2vbox) - y1vbox.add(y1button) - y2vbox.add(y2button) - y1Frame.add(y1vbox) - y2Frame.add(y2vbox) - self.graph_data_hbox.pack_start(xFrame, expand=False, fill=True, padding=0) - self.graph_data_hbox.pack_start(y1Frame, expand=False, fill=True, padding=0) - self.graph_data_hbox.pack_start(y2Frame, expand=False, fill=True, padding=0) - self.graph_data_hbox.show_all() - else: - logging.debug("Activity has no GPX data") - #Remove graph - vboxChildren = self.record_graph_vbox.get_children() - logging.debug('Vbox has %d children %s' % (len(vboxChildren), str(vboxChildren) )) - # ToDo: check why vertical container is shared - for child in vboxChildren: - #Remove all FigureCanvasGTK and NavigationToolbar2GTKAgg to stop double ups of graphs - if isinstance(child, matplotlib.backends.backend_gtkagg.FigureCanvasGTK) or isinstance(child, matplotlib.backends.backend_gtkagg.NavigationToolbar2GTKAgg): - logging.debug('Removing child: '+str(child)) - self.record_graph_vbox.remove(child) - self.record_vbox.set_sensitive(0) - logging.debug("<<") + def actualize_heartrategraph(self,activity): + logging.debug(">>") + if activity.tracks is not None and len(activity.tracks)>0: + self.heartrate_vbox_.set_sensitive(1) + self.drawareaheartrate.drawgraph(activity.tracks) + else: + self.heartrate_vbox_.set_sensitive(0) + logging.debug("<<") - def actualize_heartrategraph(self,activity): - logging.debug(">>") - if activity.tracks is not None and len(activity.tracks)>0: - self.heartrate_vbox_.set_sensitive(1) - self.drawareaheartrate.drawgraph(activity.tracks) - else: - self.heartrate_vbox_.set_sensitive(0) - logging.debug("<<") + def actualize_hrview(self,activity): + logging.debug(">>") + zones = self.pytrainer_main.profile.getZones() + record_list = activity.tracks + is_karvonen_method = self.pytrainer_main.profile.getValue("pytraining","prf_hrzones_karvonen") + if record_list is not None and len(record_list)>0: + record_list=record_list[0] + self.record_zone1.set_text("%s-%s" %(zones[4][0],zones[4][1])) + self.record_zone2.set_text("%s-%s" %(zones[3][0],zones[3][1])) + self.record_zone3.set_text("%s-%s" %(zones[2][0],zones[2][1])) + self.record_zone4.set_text("%s-%s" %(zones[1][0],zones[1][1])) + self.record_zone5.set_text("%s-%s" %(zones[0][0],zones[0][1])) + beats = activity.beats + maxbeats = activity.maxbeats + self.record_beats.set_text("%0.2f" %beats) + self.record_maxbeats.set_text("%0.2f" %maxbeats) + self.record_calories2.set_text("%0.0f" %activity.calories) + if is_karvonen_method=="True": + self.record_zonesmethod.set_text(_("Karvonen method")) + else: + self.record_zonesmethod.set_text(_("Percentages method")) + #else: + # self.recordview.set_sensitive(0) + logging.debug("<<") - def actualize_hrview(self,activity): - logging.debug(">>") - zones = self.pytrainer_main.profile.getZones() - record_list = activity.tracks - is_karvonen_method = self.pytrainer_main.profile.getValue("pytraining","prf_hrzones_karvonen") - if record_list is not None and len(record_list)>0: - record_list=record_list[0] - self.record_zone1.set_text("%s-%s" %(zones[4][0],zones[4][1])) - self.record_zone2.set_text("%s-%s" %(zones[3][0],zones[3][1])) - self.record_zone3.set_text("%s-%s" %(zones[2][0],zones[2][1])) - self.record_zone4.set_text("%s-%s" %(zones[1][0],zones[1][1])) - self.record_zone5.set_text("%s-%s" %(zones[0][0],zones[0][1])) - beats = activity.beats - maxbeats = activity.maxbeats - self.record_beats.set_text("%0.2f" %beats) - self.record_maxbeats.set_text("%0.2f" %maxbeats) - self.record_calories2.set_text("%0.0f" %activity.calories) - if is_karvonen_method=="True": - self.record_zonesmethod.set_text(_("Karvonen method")) - else: - self.record_zonesmethod.set_text(_("Percentages method")) - #else: - # self.recordview.set_sensitive(0) - logging.debug("<<") + def actualize_dayview(self,record_list): + logging.debug(">>") + if self.pytrainer_main.profile.getValue("pytraining","prf_us_system") == "True": + self.d_distance_unit.set_text(_("miles")) + self.d_speed_unit.set_text(_("miles/h")) + self.d_maxspeed_unit.set_text(_("miles/h")) + self.d_pace_unit.set_text(_("min/mile")) + self.d_maxpace_unit.set_text(_("min/mile")) + else: + self.d_distance_unit.set_text(_("km")) + self.d_speed_unit.set_text(_("km/h")) + self.d_maxspeed_unit.set_text(_("km/h")) + self.d_pace_unit.set_text(_("min/km")) + self.d_maxpace_unit.set_text(_("min/km")) - def actualize_dayview(self,record_list): - logging.debug(">>") - if self.pytrainer_main.profile.getValue("pytraining","prf_us_system") == "True": - self.d_distance_unit.set_text(_("miles")) - self.d_speed_unit.set_text(_("miles/h")) - self.d_maxspeed_unit.set_text(_("miles/h")) - self.d_pace_unit.set_text(_("min/mile")) - self.d_maxpace_unit.set_text(_("min/mile")) - else: - self.d_distance_unit.set_text(_("km")) - self.d_speed_unit.set_text(_("km/h")) - self.d_maxspeed_unit.set_text(_("km/h")) - self.d_pace_unit.set_text(_("min/km")) - self.d_maxpace_unit.set_text(_("min/km")) + if len(record_list)>0: + tbeats = 0 + distance = 0 + calories = 0 + timeinseconds = 0 + beats = 0 + maxbeats = 0 + maxspeed = 0 + average = 0 + maxpace = "0:00" + pace = "0:00" + for record in record_list: + distance += self.parseFloat(record[2]) + calories += self.parseFloat(record[7]) + timeinseconds += self.parseFloat(record[3]) + beats = self.parseFloat(record[4]) + if float(beats)>0: + tbeats += beats*(self.parseFloat(record[3])/60/60) + if record[9] > maxspeed: + maxspeed = self.parseFloat(record[9]) + if record[10] > maxbeats: + maxbeats = self.parseFloat(record[10]) - if len(record_list)>0: - tbeats = 0 - distance = 0 - calories = 0 - timeinseconds = 0 - beats = 0 - maxbeats = 0 - maxspeed = 0 - average = 0 - maxpace = "0:00" - pace = "0:00" - for record in record_list: - distance += self.parseFloat(record[2]) - calories += self.parseFloat(record[7]) - timeinseconds += self.parseFloat(record[3]) - beats = self.parseFloat(record[4]) - if float(beats)>0: - tbeats += beats*(self.parseFloat(record[3])/60/60) - if record[9] > maxspeed: - maxspeed = self.parseFloat(record[9]) - if record[10] > maxbeats: - maxbeats = self.parseFloat(record[10]) + if self.pytrainer_main.profile.getValue("pytraining","prf_us_system") == "True": + distance = km2miles(distance) + maxspeed = km2miles(maxspeed) - if self.pytrainer_main.profile.getValue("pytraining","prf_us_system") == "True": - distance = km2miles(distance) - maxspeed = km2miles(maxspeed) + if tbeats > 0: + tbeats = tbeats/(timeinseconds/60/60) + if distance > 0: + average = distance/(timeinseconds/60/60) + if maxspeed > 0: + maxpace = "%d:%02d" %((3600/maxspeed)/60,(3600/maxspeed)%60) + if average > 0: + pace = "%d:%02d" %((3600/average)/60,(3600/average)%60) - if tbeats > 0: - tbeats = tbeats/(timeinseconds/60/60) - if distance > 0: - average = distance/(timeinseconds/60/60) - if maxspeed > 0: - maxpace = "%d:%02d" %((3600/maxspeed)/60,(3600/maxspeed)%60) - if average > 0: - pace = "%d:%02d" %((3600/average)/60,(3600/average)%60) + self.dayview.set_sensitive(1) + self.day_distance.set_text("%0.2f" %distance) + hour,min,sec=self.parent.date.second2time(timeinseconds) + self.day_hour.set_text("%d" %hour) + self.day_minute.set_text("%02d" %min) + self.day_second.set_text("%02d" %sec) + self.day_beats.set_text("%0.2f" %tbeats) + self.day_maxbeats.set_text("%0.2f" %maxbeats) + self.day_average.set_text("%0.2f" %average) + self.day_maxspeed.set_text("%0.2f" %maxspeed) + self.day_pace.set_text("%s" %pace) + self.day_maxpace.set_text("%s" %maxpace) + self.day_calories.set_text("%0.0f" %calories) + self.day_topic.set_text(str(record[1])) - self.dayview.set_sensitive(1) - self.day_distance.set_text("%0.2f" %distance) - hour,min,sec=self.parent.date.second2time(timeinseconds) - self.day_hour.set_text("%d" %hour) - self.day_minute.set_text("%02d" %min) - self.day_second.set_text("%02d" %sec) - self.day_beats.set_text("%0.2f" %tbeats) - self.day_maxbeats.set_text("%0.2f" %maxbeats) - self.day_average.set_text("%0.2f" %average) - self.day_maxspeed.set_text("%0.2f" %maxspeed) - self.day_pace.set_text("%s" %pace) - self.day_maxpace.set_text("%s" %maxpace) - self.day_calories.set_text("%0.0f" %calories) - self.day_topic.set_text(str(record[1])) + else: + self.dayview.set_sensitive(0) + logging.debug("<<") + + def actualize_daygraph(self,record_list): + logging.debug(">>") + if len(record_list)>0: + self.day_vbox.set_sensitive(1) + else: + self.day_vbox.set_sensitive(0) + self.drawareaday.drawgraph(record_list) + logging.debug("<<") - else: - self.dayview.set_sensitive(0) - logging.debug("<<") + def actualize_map(self,activity, full_screen=False): + logging.debug(">>") + #Check which type of map viewer to use + if self.radiobuttonOSM.get_active(): + #Use OSM to draw map + logging.debug("Using OSM to draw map....") + htmlfile = Osm(data_path=self.data_path, waypoint=self.waypoint, pytrainer_main=self.parent).drawMap(activity) + elif self.radiobuttonGMap.get_active(): + #Use Google to draw map + logging.debug("Using Google to draw map") + htmlfile = Googlemaps(data_path=self.data_path, waypoint=self.waypoint, pytrainer_main=self.parent).drawMap(activity) + else: + #Unknown map type... + logging.error("Unknown map viewer requested") + htmlfile = self.mapviewer.createErrorHtml() + logging.debug("Displaying htmlfile: %s" % htmlfile) + if full_screen: + logging.debug("Displaying in full screen mode") + self.mapviewer_fs.display_map(htmlfile=htmlfile) + else: + logging.debug("Displaying in embedded mode") + self.mapviewer.display_map(htmlfile=htmlfile) + logging.debug("<<") - def actualize_daygraph(self,record_list): - logging.debug(">>") - if len(record_list)>0: - self.day_vbox.set_sensitive(1) - else: - self.day_vbox.set_sensitive(0) - self.drawareaday.drawgraph(record_list) - logging.debug("<<") + def actualize_weekview(self, record_list, date_ini, date_end): + logging.debug(">>") + date_s = datetime.datetime.strptime(date_ini, "%Y-%m-%d") + date_e = datetime.datetime.strptime(date_end, "%Y-%m-%d") + self.week_date.set_text("%s - %s (%d)" % (datetime.datetime.strftime(date_s, "%a %d %b"), datetime.datetime.strftime(date_e, "%a %d %b"), int(datetime.datetime.strftime(date_e, "%W"))+1) ) - def actualize_map(self,activity, full_screen=False): - logging.debug(">>") - #Check which type of map viewer to use - if self.radiobuttonOSM.get_active(): - #Use OSM to draw map - logging.debug("Using OSM to draw map....") - htmlfile = Osm(data_path=self.data_path, waypoint=self.waypoint, pytrainer_main=self.parent).drawMap(activity) - elif self.radiobuttonGMap.get_active(): - #Use Google to draw map - logging.debug("Using Google to draw map") - htmlfile = Googlemaps(data_path=self.data_path, waypoint=self.waypoint, pytrainer_main=self.parent).drawMap(activity) - else: - #Unknown map type... - logging.error("Unknown map viewer requested") - htmlfile = self.mapviewer.createErrorHtml() - logging.debug("Displaying htmlfile: %s" % htmlfile) - if full_screen: - logging.debug("Displaying in full screen mode") - self.mapviewer_fs.display_map(htmlfile=htmlfile) - else: - logging.debug("Displaying in embedded mode") - self.mapviewer.display_map(htmlfile=htmlfile) - logging.debug("<<") + km = calories = time = average = beats = 0 + num_records = len(record_list) + logging.info("Number of records selected week: "+str(num_records)) + time_in_min = 0 + tbeats = 0 + maxspeed = 0 + pace = "0:00" + maxpace = "0:00" + maxbeats = 0 - def actualize_weekview(self, record_list, date_ini, date_end): - logging.debug(">>") - date_s = datetime.datetime.strptime(date_ini, "%Y-%m-%d") - date_e = datetime.datetime.strptime(date_end, "%Y-%m-%d") - self.week_date.set_text("%s - %s (%d)" % (datetime.datetime.strftime(date_s, "%a %d %b"), datetime.datetime.strftime(date_e, "%a %d %b"), int(datetime.datetime.strftime(date_e, "%W"))+1) ) + if self.pytrainer_main.profile.getValue("pytraining","prf_us_system") == "True": + self.w_distance_unit.set_text(_("miles")) + self.w_speed_unit.set_text(_("miles/h")) + self.w_maxspeed_unit.set_text(_("miles/h")) + self.w_pace_unit.set_text(_("min/mile")) + self.w_maxpace_unit.set_text(_("min/mile")) + else: + self.w_distance_unit.set_text(_("km")) + self.w_speed_unit.set_text(_("km/h")) + self.w_maxspeed_unit.set_text(_("km/h")) + self.w_pace_unit.set_text(_("min/km")) + self.w_maxpace_unit.set_text(_("min/km")) - km = calories = time = average = beats = 0 - num_records = len(record_list) - logging.info("Number of records selected week: "+str(num_records)) - time_in_min = 0 - tbeats = 0 - maxspeed = 0 - pace = "0:00" - maxpace = "0:00" - maxbeats = 0 + if num_records>0: + for record in record_list: + km += self.parseFloat(record[1]) + time += self.parseFloat(record[2]) + average += self.parseFloat(record[5]) + calories += self.parseFloat(record[6]) + beats = self.parseFloat(record[3]) + if float(beats) > 0: + time_in_min += time/60 + tbeats += beats*(time/60) + if record[7] > maxspeed: + maxspeed = self.parseFloat(record[7]) + if record[8] > maxbeats: + maxbeats = self.parseFloat(record[8]) - if self.pytrainer_main.profile.getValue("pytraining","prf_us_system") == "True": - self.w_distance_unit.set_text(_("miles")) - self.w_speed_unit.set_text(_("miles/h")) - self.w_maxspeed_unit.set_text(_("miles/h")) - self.w_pace_unit.set_text(_("min/mile")) - self.w_maxpace_unit.set_text(_("min/mile")) - else: - self.w_distance_unit.set_text(_("km")) - self.w_speed_unit.set_text(_("km/h")) - self.w_maxspeed_unit.set_text(_("km/h")) - self.w_pace_unit.set_text(_("min/km")) - self.w_maxpace_unit.set_text(_("min/km")) + if self.pytrainer_main.profile.getValue("pytraining","prf_us_system") == "True": + km = km2miles(km) + maxspeed = km2miles(maxspeed) - if num_records>0: - for record in record_list: - km += self.parseFloat(record[1]) - time += self.parseFloat(record[2]) - average += self.parseFloat(record[5]) - calories += self.parseFloat(record[6]) - beats = self.parseFloat(record[3]) - if float(beats) > 0: - time_in_min += time/60 - tbeats += beats*(time/60) - if record[7] > maxspeed: - maxspeed = self.parseFloat(record[7]) - if record[8] > maxbeats: - maxbeats = self.parseFloat(record[8]) + if time_in_min > 0: + tbeats = tbeats/time_in_min + else: + tbeats = 0 + if km > 0: + average = (km/(time/3600)) + else: + average = 0 - if self.pytrainer_main.profile.getValue("pytraining","prf_us_system") == "True": - km = km2miles(km) - maxspeed = km2miles(maxspeed) + if maxspeed > 0: + #maxpace = 60/maxspeed + maxpace = "%d:%02d" %((3600/maxspeed)/60,(3600/maxspeed)%60) + if average > 0: + #pace = 60/average + pace = "%d:%02d" %((3600/average)/60,(3600/average)%60) - if time_in_min > 0: - tbeats = tbeats/time_in_min - else: - tbeats = 0 - if km > 0: - average = (km/(time/3600)) - else: - average = 0 + self.weeka_distance.set_text("%0.2f" %km) + hour,min,sec = self.parent.date.second2time(time) + self.weeka_hour.set_text("%d" %hour) + self.weeka_minute.set_text("%02d" %min) + self.weeka_second.set_text("%02d" %sec) + self.weeka_maxbeats.set_text("%0.2f" %(maxbeats)) + self.weeka_beats.set_text("%0.2f" %(tbeats)) + self.weeka_average.set_text("%0.2f" %average) + self.weeka_maxspeed.set_text("%0.2f" %maxspeed) + self.weeka_pace.set_text(pace) + self.weeka_maxpace.set_text(maxpace) + self.weeka_calories.set_text("%0.0f" %calories) + self.weekview.set_sensitive(1) + else: + self.weekview.set_sensitive(0) + self.drawareaweek.drawgraph(record_list, date_ini, date_end) + logging.debug("<<") - if maxspeed > 0: - #maxpace = 60/maxspeed - maxpace = "%d:%02d" %((3600/maxspeed)/60,(3600/maxspeed)%60) - if average > 0: - #pace = 60/average - pace = "%d:%02d" %((3600/average)/60,(3600/average)%60) + def actualize_monthview(self,record_list, nameMonth): + logging.debug(">>") + self.month_date.set_text(nameMonth) + km = calories = time = average = beats = 0 + num_records = len(record_list) + time_in_min = 0 + tbeats = 0 + maxspeed = 0 + pace = "0:00" + maxpace = "0:00" + maxbeats = 0 - self.weeka_distance.set_text("%0.2f" %km) - hour,min,sec = self.parent.date.second2time(time) - self.weeka_hour.set_text("%d" %hour) - self.weeka_minute.set_text("%02d" %min) - self.weeka_second.set_text("%02d" %sec) - self.weeka_maxbeats.set_text("%0.2f" %(maxbeats)) - self.weeka_beats.set_text("%0.2f" %(tbeats)) - self.weeka_average.set_text("%0.2f" %average) - self.weeka_maxspeed.set_text("%0.2f" %maxspeed) - self.weeka_pace.set_text(pace) - self.weeka_maxpace.set_text(maxpace) - self.weeka_calories.set_text("%0.0f" %calories) - self.weekview.set_sensitive(1) - else: - self.weekview.set_sensitive(0) - self.drawareaweek.drawgraph(record_list, date_ini, date_end) - logging.debug("<<") + if self.pytrainer_main.profile.getValue("pytraining","prf_us_system") == "True": + self.m_distance_unit.set_text(_("miles")) + self.m_speed_unit.set_text(_("miles/h")) + self.m_maxspeed_unit.set_text(_("miles/h")) + self.m_pace_unit.set_text(_("min/mile")) + self.m_maxpace_unit.set_text(_("min/mile")) + else: + self.m_distance_unit.set_text(_("km")) + self.m_speed_unit.set_text(_("km/h")) + self.m_maxspeed_unit.set_text(_("km/h")) + self.m_pace_unit.set_text(_("min/km")) + self.m_maxpace_unit.set_text(_("min/km")) - def actualize_monthview(self,record_list, nameMonth): - logging.debug(">>") - self.month_date.set_text(nameMonth) - km = calories = time = average = beats = 0 - num_records = len(record_list) - time_in_min = 0 - tbeats = 0 - maxspeed = 0 - pace = "0:00" - maxpace = "0:00" - maxbeats = 0 + if num_records>0: + for record in record_list: + km += self.parseFloat(record[1]) + time += self.parseFloat(record[2]) + average += self.parseFloat(record[5]) + calories += self.parseFloat(record[6]) + beats = self.parseFloat(record[3]) + if float(beats) > 0: + time_in_min += time/60 + tbeats += beats*(time/60) + if record[7] > maxspeed: + maxspeed = self.parseFloat(record[7]) + if record[8] > maxbeats: + maxbeats = self.parseFloat(record[8]) - if self.pytrainer_main.profile.getValue("pytraining","prf_us_system") == "True": - self.m_distance_unit.set_text(_("miles")) - self.m_speed_unit.set_text(_("miles/h")) - self.m_maxspeed_unit.set_text(_("miles/h")) - self.m_pace_unit.set_text(_("min/mile")) - self.m_maxpace_unit.set_text(_("min/mile")) - else: - self.m_distance_unit.set_text(_("km")) - self.m_speed_unit.set_text(_("km/h")) - self.m_maxspeed_unit.set_text(_("km/h")) - self.m_pace_unit.set_text(_("min/km")) - self.m_maxpace_unit.set_text(_("min/km")) + if self.pytrainer_main.profile.getValue("pytraining","prf_us_system") == "True": + km = km2miles(km) + maxspeed = km2miles(maxspeed) - if num_records>0: - for record in record_list: - km += self.parseFloat(record[1]) - time += self.parseFloat(record[2]) - average += self.parseFloat(record[5]) - calories += self.parseFloat(record[6]) - beats = self.parseFloat(record[3]) - if float(beats) > 0: - time_in_min += time/60 - tbeats += beats*(time/60) - if record[7] > maxspeed: - maxspeed = self.parseFloat(record[7]) - if record[8] > maxbeats: - maxbeats = self.parseFloat(record[8]) + if time_in_min > 0: + tbeats = tbeats/time_in_min + else: + tbeats = 0 + if km > 0: + average = (km/(time/3600)) + else: + average = 0 - if self.pytrainer_main.profile.getValue("pytraining","prf_us_system") == "True": - km = km2miles(km) - maxspeed = km2miles(maxspeed) + if maxspeed > 0: + #maxpace = 60/maxspeed + maxpace = "%d:%02d" %((3600/maxspeed)/60,float(3600/maxspeed)%60) + if average > 0: + #pace = 60/average + pace = "%d:%02d" %((3600/average)/60,float(3600/average)%60) - if time_in_min > 0: - tbeats = tbeats/time_in_min - else: - tbeats = 0 - if km > 0: - average = (km/(time/3600)) - else: - average = 0 + self.montha_distance.set_text("%0.2f" %km) + hour,min,sec = self.parent.date.second2time(time) + self.montha_hour.set_text("%d" %hour) + self.montha_minute.set_text("%02d" %min) + self.montha_second.set_text("%02d" %sec) + self.montha_maxbeats.set_text("%0.2f" %(maxbeats)) + self.montha_beats.set_text("%0.2f" %(tbeats)) + self.montha_average.set_text("%0.2f" %average) + self.montha_maxspeed.set_text("%0.2f" %maxspeed) + self.montha_pace.set_text(pace) + self.montha_maxpace.set_text(maxpace) + self.montha_calories.set_text("%0.0f" %calories) + self.monthview.set_sensitive(1) + else: + self.monthview.set_sensitive(0) + logging.debug("<<") - if maxspeed > 0: - #maxpace = 60/maxspeed - maxpace = "%d:%02d" %((3600/maxspeed)/60,float(3600/maxspeed)%60) - if average > 0: - #pace = 60/average - pace = "%d:%02d" %((3600/average)/60,float(3600/average)%60) + def actualize_monthgraph(self,record_list, daysInMonth): + logging.debug(">>") + self.drawareamonth.drawgraph(record_list, daysInMonth) + logging.debug("<<") - self.montha_distance.set_text("%0.2f" %km) - hour,min,sec = self.parent.date.second2time(time) - self.montha_hour.set_text("%d" %hour) - self.montha_minute.set_text("%02d" %min) - self.montha_second.set_text("%02d" %sec) - self.montha_maxbeats.set_text("%0.2f" %(maxbeats)) - self.montha_beats.set_text("%0.2f" %(tbeats)) - self.montha_average.set_text("%0.2f" %average) - self.montha_maxspeed.set_text("%0.2f" %maxspeed) - self.montha_pace.set_text(pace) - self.montha_maxpace.set_text(maxpace) - self.montha_calories.set_text("%0.0f" %calories) - self.monthview.set_sensitive(1) - else: - self.monthview.set_sensitive(0) - logging.debug("<<") + def actualize_yearview(self,record_list, year): + logging.debug(">>") + self.year_date.set_text("%d" %int(year)) + km = calories = time = average = beats = 0 + num_records = len(record_list) + time_in_min = 0 + tbeats = 0 + maxspeed = 0 + pace = "0:00" + maxpace = "0:00" + maxbeats = 0 + if num_records>0: + for record in record_list: + km += self.parseFloat(record[1]) + time += self.parseFloat(record[2]) + average += self.parseFloat(record[5]) + calories += self.parseFloat(record[6]) + beats = self.parseFloat(record[3]) + if float(beats) > 0: + time_in_min += time/60 + tbeats += beats*(time/60) + if record[7] > maxspeed: + maxspeed = self.parseFloat(record[7]) + if record[8] > maxbeats: + maxbeats = self.parseFloat(record[8]) + if time_in_min > 0: + tbeats = tbeats/time_in_min + else: + tbeats = 0 + if km > 0: + average = (km/(time/3600)) + else: + average = 0 - def actualize_monthgraph(self,record_list, daysInMonth): - logging.debug(">>") - self.drawareamonth.drawgraph(record_list, daysInMonth) - logging.debug("<<") + if maxspeed > 0: + #maxpace = 60/maxspeed + maxpace = "%d:%02d" %((3600/maxspeed)/60,(3600/maxspeed)%60) + if average > 0: + #pace = 60/average + pace = "%d:%02d" %((3600/average)/60,(3600/average)%60) - def actualize_yearview(self,record_list, year): - logging.debug(">>") - self.year_date.set_text("%d" %int(year)) - km = calories = time = average = beats = 0 - num_records = len(record_list) - time_in_min = 0 - tbeats = 0 - maxspeed = 0 - pace = "0:00" - maxpace = "0:00" - maxbeats = 0 - if num_records>0: - for record in record_list: - km += self.parseFloat(record[1]) - time += self.parseFloat(record[2]) - average += self.parseFloat(record[5]) - calories += self.parseFloat(record[6]) - beats = self.parseFloat(record[3]) - if float(beats) > 0: - time_in_min += time/60 - tbeats += beats*(time/60) - if record[7] > maxspeed: - maxspeed = self.parseFloat(record[7]) - if record[8] > maxbeats: - maxbeats = self.parseFloat(record[8]) - if time_in_min > 0: - tbeats = tbeats/time_in_min - else: - tbeats = 0 - if km > 0: - average = (km/(time/3600)) - else: - average = 0 + self.yeara_distance.set_text("%0.2f" %km) + hour,min,sec = self.parent.date.second2time(time) + self.yeara_hour.set_text("%d" %hour) + self.yeara_minute.set_text("%02d" %min) + self.yeara_second.set_text("%02d" %sec) + self.yeara_beats.set_text("%0.2f" %tbeats) + self.yeara_maxbeats.set_text("%0.2f" %(maxbeats)) + self.yeara_average.set_text("%0.2f" %average) + self.yeara_maxspeed.set_text("%0.2f" %maxspeed) + self.yeara_pace.set_text(pace) + self.yeara_maxpace.set_text(maxpace) + self.yeara_calories.set_text("%0.0f" %calories) + self.yearview.set_sensitive(1) + else: + self.yearview.set_sensitive(0) + self.drawareayear.drawgraph([]) + logging.debug("<<") - if maxspeed > 0: - #maxpace = 60/maxspeed - maxpace = "%d:%02d" %((3600/maxspeed)/60,(3600/maxspeed)%60) - if average > 0: - #pace = 60/average - pace = "%d:%02d" %((3600/average)/60,(3600/average)%60) + def actualize_yeargraph(self,record_list): + logging.debug(">>") + self.drawareayear.drawgraph(record_list) + logging.debug("<<") - self.yeara_distance.set_text("%0.2f" %km) - hour,min,sec = self.parent.date.second2time(time) - self.yeara_hour.set_text("%d" %hour) - self.yeara_minute.set_text("%02d" %min) - self.yeara_second.set_text("%02d" %sec) - self.yeara_beats.set_text("%0.2f" %tbeats) - self.yeara_maxbeats.set_text("%0.2f" %(maxbeats)) - self.yeara_average.set_text("%0.2f" %average) - self.yeara_maxspeed.set_text("%0.2f" %maxspeed) - self.yeara_pace.set_text(pace) - self.yeara_maxpace.set_text(maxpace) - self.yeara_calories.set_text("%0.0f" %calories) - self.yearview.set_sensitive(1) - else: - self.yearview.set_sensitive(0) - self.drawareayear.drawgraph([]) - logging.debug("<<") + def actualize_athleteview(self, athletedata): + logging.debug(">>") + self.labelName.set_text(athletedata["prf_name"]) + self.labelDOB.set_text(athletedata["prf_age"]) + self.labelHeight.set_text(athletedata["prf_height"]+" cm") + #Setup graph + self.grapher = DrawGraph(self, self.pytrainer_main) + from pytrainer.lib.graphdata import GraphData + datalist = GraphData(title="Weight", xlabel="Date", ylabel="kg") + #TODO + #Create history treeview + history_store = gtk.ListStore( + gobject.TYPE_INT, #index + gobject.TYPE_STRING, #date + gobject.TYPE_STRING, #weight + gobject.TYPE_STRING, #body fat % + gobject.TYPE_INT, #resting HR + gobject.TYPE_INT #max HR + ) + for data_index, data in enumerate(athletedata['history']): + weight = float(data['Weight']) + date = dateutil.parser.parse(data['Date']).date() - def actualize_yeargraph(self,record_list): - logging.debug(">>") - self.drawareayear.drawgraph(record_list) - logging.debug("<<") + iter = history_store.append() + history_store.set ( + iter, + 0, data_index, + 1, date, #TODO need to sort date graphing... + 2, "%0.2f" % weight, + 3, "%0.2f" % float(data['BF']), + 4, int(data['RestingHR']), + 5, int(data['MaxHR']), + ) + datalist.addPoints(x=date, y=weight) + self.athleteTreeView.set_model(history_store) + self.grapher.drawPlot(datalist=datalist, box=self.boxAthleteGraph) + logging.debug("<<") - def actualize_athleteview(self, athletedata): - logging.debug(">>") - self.labelName.set_text(athletedata["prf_name"]) - self.labelDOB.set_text(athletedata["prf_age"]) - self.labelHeight.set_text(athletedata["prf_height"]+" cm") - #Setup graph - self.grapher = DrawGraph(self, self.pytrainer_main) - from pytrainer.lib.graphdata import GraphData - datalist = GraphData(title="Weight", xlabel="Date", ylabel="kg") - #TODO - #Create history treeview - history_store = gtk.ListStore( - gobject.TYPE_INT, #index - gobject.TYPE_STRING, #date - gobject.TYPE_STRING, #weight - gobject.TYPE_STRING, #body fat % - gobject.TYPE_INT, #resting HR - gobject.TYPE_INT #max HR - ) - for data_index, data in enumerate(athletedata['history']): - weight = float(data['Weight']) - date = dateutil.parser.parse(data['Date']).date() + def actualize_listview(self,record_list): + logging.debug(">>") + #recod list tiene: + #date,distance,average,title,sports.name,id_record,time,beats,caloriesi + #Laas columnas son: + #column_names=[_("id"),_("Title"),_("Date"),_("Distance"),_("Sport"),_("Time"),_("Beats"),_("Average"),("Calories")] - iter = history_store.append() - history_store.set ( - iter, - 0, data_index, - 1, date, #TODO need to sort date graphing... - 2, "%0.2f" % weight, - 3, "%0.2f" % float(data['BF']), - 4, int(data['RestingHR']), - 5, int(data['MaxHR']), - ) - datalist.addPoints(x=date, y=weight) - self.athleteTreeView.set_model(history_store) - self.grapher.drawPlot(datalist=datalist, box=self.boxAthleteGraph) - logging.debug("<<") + date = Date() + store = gtk.ListStore( + gobject.TYPE_INT, + gobject.TYPE_STRING, + gobject.TYPE_STRING, + gobject.TYPE_FLOAT, + gobject.TYPE_STRING, + gobject.TYPE_STRING, + gobject.TYPE_INT, + gobject.TYPE_FLOAT, + gobject.TYPE_INT, + object) + for i in record_list: + hour,min,sec = date.second2time(int(i[6])) + time = "%d:%02d:%02d" %(hour,min,sec) + iter = store.append() + store.set ( + iter, + 0, int(i[5]), # id + 1, str(i[3]), # title + 2, str(i[0]), # date + 3, float(i[1]), # distance + 4, str(i[4]), # sport + 5, time, + 6, round(float(i[7])), # beats + 7, float(i[2]), # average + 8, int(i[8]) # calories + ) + #self.allRecordTreeView.set_headers_clickable(True) + self.allRecordTreeView.set_model(store) + logging.debug("<<") - def actualize_listview(self,record_list): - logging.debug(">>") - #recod list tiene: - #date,distance,average,title,sports.name,id_record,time,beats,caloriesi - #Laas columnas son: - #column_names=[_("id"),_("Title"),_("Date"),_("Distance"),_("Sport"),_("Time"),_("Beats"),_("Average"),("Calories")] + def actualize_waypointview(self,record_list,default_waypoint,redrawmap = 1): + logging.debug(">>") + #redrawmap: indica si tenemos que refrescar tb el mapa. 1 si 0 no + #waypoint list tiene: + #id_waypoint,lat,lon,ele,comment,time,name,sym + #Laas columnas son: + #column_names=[_("id"),_("Waypoint")] - date = Date() - store = gtk.ListStore( - gobject.TYPE_INT, - gobject.TYPE_STRING, - gobject.TYPE_STRING, - gobject.TYPE_FLOAT, - gobject.TYPE_STRING, - gobject.TYPE_STRING, - gobject.TYPE_STRING, - gobject.TYPE_STRING, - gobject.TYPE_STRING, - object) - for i in record_list: - hour,min,sec = date.second2time(int(i[6])) - time = "%d:%d:%d" %(hour,min,sec) - iter = store.append() - store.set ( - iter, - 0, int(i[5]), - 1, str(i[3]), - 2, str(i[0]), - 3, float(i[1]), - 4, str(i[4]), - 5, time, - 6, str(i[7]), - 7, str(i[2]), - 8, str(i[8]) - ) - #self.allRecordTreeView.set_headers_clickable(True) - self.allRecordTreeView.set_model(store) - logging.debug("<<") + store = gtk.ListStore( + gobject.TYPE_INT, + gobject.TYPE_STRING, + object) + iterOne = False + iterDefault = False + counter = 0 + default_id = 0 + for i in record_list: + iter = store.append() + if not iterOne: + iterOne = iter + if int(i[0])==default_waypoint: + iterDefault = iter + default_id = counter + store.set ( + iter, + 0, int(i[0]), + 1, str(i[6]) + ) + counter+=1 - def actualize_waypointview(self,record_list,default_waypoint,redrawmap = 1): - logging.debug(">>") - #redrawmap: indica si tenemos que refrescar tb el mapa. 1 si 0 no - #waypoint list tiene: - #id_waypoint,lat,lon,ele,comment,time,name,sym - #Laas columnas son: - #column_names=[_("id"),_("Waypoint")] + self.waypointTreeView.set_model(store) + if iterDefault: + self.waypointTreeView.get_selection().select_iter(iterDefault) + elif iterOne: + self.waypointTreeView.get_selection().select_iter(iterOne) + if len(record_list) > 0: + self.waypoint_latitude.set_text(str(record_list[default_id][1])) + self.waypoint_longitude.set_text(str(record_list[default_id][2])) + self.waypoint_name.set_text(str(record_list[default_id][6])) + self.waypoint_description.set_text(str(record_list[default_id][4])) + self.set_waypoint_type(str(record_list[default_id][7])) + if redrawmap == 1: + self.waypointeditor.createHtml(default_waypoint) + self.waypointeditor.drawMap() + logging.debug("<<") - store = gtk.ListStore( - gobject.TYPE_INT, - gobject.TYPE_STRING, - object) - iterOne = False - iterDefault = False - counter = 0 - default_id = 0 - for i in record_list: - iter = store.append() - if not iterOne: - iterOne = iter - if int(i[0])==default_waypoint: - iterDefault = iter - default_id = counter - store.set ( - iter, - 0, int(i[0]), - 1, str(i[6]) - ) - counter+=1 + ... [truncated message content] |
From: <jb...@us...> - 2010-09-22 10:23:06
|
Revision: 617 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=617&view=rev Author: jblance Date: 2010-09-22 10:23:00 +0000 (Wed, 22 Sep 2010) Log Message: ----------- Minor changes to test graphing (disabled) Modified Paths: -------------- pytrainer/trunk/pytrainer/gui/windowmain.py pytrainer/trunk/pytrainer/main.py Modified: pytrainer/trunk/pytrainer/gui/windowmain.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowmain.py 2010-09-21 11:35:28 UTC (rev 616) +++ pytrainer/trunk/pytrainer/gui/windowmain.py 2010-09-22 10:23:00 UTC (rev 617) @@ -272,11 +272,16 @@ self.record_list = activity.tracks self.laps = activity.laps if activity.gpx_file is not None: - logging.debug("Activity has GPX data") - self.record_vbox.set_sensitive(1) - self.drawarearecord.drawgraph(self.record_list,self.laps) - #Create a frame showing data available for graphing - if False: #Still just test code + if True: + logging.debug("Activity has GPX data") + self.record_vbox.set_sensitive(1) + self.drawarearecord.drawgraph(self.record_list,self.laps) + + else: #Still just test code + #Create a frame showing data available for graphing + #Remove existing frames + for child in self.graph_data_hbox.get_children(): + self.graph_data_hbox.remove(child) #Build frames and vboxs to hold checkbuttons xFrame = gtk.Frame(label="Show on X Axis") y1Frame = gtk.Frame(label="Show on Y1 Axis") @@ -295,12 +300,12 @@ xFrame.add(xvbox) #Populate Y axis data for graphdata in activity.distance_data: - y1checkbutton = gtk.CheckButton(label=activity.distance_data[graphdata].title) - y1checkbutton.connect("toggled", self.on_y1change, y1vbox) - y2checkbutton = gtk.CheckButton(label=activity.distance_data[graphdata].title) - y2checkbutton.connect("toggled", self.on_y2change, y2vbox) - y1vbox.add(y1checkbutton) - y2vbox.add(y2checkbutton) + y1button = gtk.CheckButton(label=activity.distance_data[graphdata].title) + y1button.connect("toggled", self.on_y1change, y1vbox, activity.distance_data[graphdata]) + y2button = gtk.CheckButton(label=activity.distance_data[graphdata].title) + y2button.connect("toggled", self.on_y2change, y2vbox) + y1vbox.add(y1button) + y2vbox.add(y2button) y1Frame.add(y1vbox) y2Frame.add(y2vbox) self.graph_data_hbox.pack_start(xFrame, expand=False, fill=True, padding=0) @@ -950,13 +955,15 @@ if widget.get_active(): print data - def on_y1change(self, widget, box): + def on_y1change(self, widget, box, data): '''Hander for changes to y1 selection''' - print "Y1 selected: ", + print "Y1 selected: " for child in box.get_children(): if child.get_active(): - print child.get_label(), - print + #This check box is active, so display graph... + #drawgraph to self.record_graph_vbox with data.... + print child.get_label(), data + #print def on_y2change(self, widget, box): '''Hander for changes to y2 selection''' Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-09-21 11:35:28 UTC (rev 616) +++ pytrainer/trunk/pytrainer/main.py 2010-09-22 10:23:00 UTC (rev 617) @@ -49,7 +49,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#616" + self.version ="1.7.2_svn#617" self.DB_version = 3 #Process command line options self.startup_options = self.get_options() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-09-21 11:35:39
|
Revision: 616 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=616&view=rev Author: jblance Date: 2010-09-21 11:35:28 +0000 (Tue, 21 Sep 2010) Log Message: ----------- Some additional (disabled) code for new graphing approach Modified Paths: -------------- pytrainer/trunk/glade/pytrainer.glade pytrainer/trunk/pytrainer/gui/windowmain.py pytrainer/trunk/pytrainer/lib/activity.py pytrainer/trunk/pytrainer/main.py Modified: pytrainer/trunk/glade/pytrainer.glade =================================================================== --- pytrainer/trunk/glade/pytrainer.glade 2010-09-21 10:22:04 UTC (rev 615) +++ pytrainer/trunk/glade/pytrainer.glade 2010-09-21 11:35:28 UTC (rev 616) @@ -1187,6 +1187,25 @@ </packing> </child> <child> + <widget class="GtkHBox" id="graph_data_hbox"> + <property name="visible">True</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> <widget class="GtkHPaned" id="hpaned1"> <property name="visible">True</property> <property name="can_focus">True</property> @@ -1892,7 +1911,7 @@ </child> </widget> <packing> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> </widget> Modified: pytrainer/trunk/pytrainer/gui/windowmain.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowmain.py 2010-09-21 10:22:04 UTC (rev 615) +++ pytrainer/trunk/pytrainer/gui/windowmain.py 2010-09-21 11:35:28 UTC (rev 616) @@ -275,6 +275,38 @@ logging.debug("Activity has GPX data") self.record_vbox.set_sensitive(1) self.drawarearecord.drawgraph(self.record_list,self.laps) + #Create a frame showing data available for graphing + if False: #Still just test code + #Build frames and vboxs to hold checkbuttons + xFrame = gtk.Frame(label="Show on X Axis") + y1Frame = gtk.Frame(label="Show on Y1 Axis") + y2Frame = gtk.Frame(label="Show on Y2 Axis") + xvbox = gtk.VBox() + y1vbox = gtk.VBox() + y2vbox = gtk.VBox() + #Populate X axis data + xdistancebutton = gtk.RadioButton(label="Distance") + xdistancebutton.connect("toggled", self.on_xaxischange, "distance") + xdistancebutton.set_active(True) + xvbox.add(xdistancebutton) + xtimebutton = gtk.RadioButton(group=xdistancebutton, label="Time") + xtimebutton.connect("toggled", self.on_xaxischange, "time") + xvbox.add(xtimebutton) + xFrame.add(xvbox) + #Populate Y axis data + for graphdata in activity.distance_data: + y1checkbutton = gtk.CheckButton(label=activity.distance_data[graphdata].title) + y1checkbutton.connect("toggled", self.on_y1change, y1vbox) + y2checkbutton = gtk.CheckButton(label=activity.distance_data[graphdata].title) + y2checkbutton.connect("toggled", self.on_y2change, y2vbox) + y1vbox.add(y1checkbutton) + y2vbox.add(y2checkbutton) + y1Frame.add(y1vbox) + y2Frame.add(y2vbox) + self.graph_data_hbox.pack_start(xFrame, expand=False, fill=True, padding=0) + self.graph_data_hbox.pack_start(y1Frame, expand=False, fill=True, padding=0) + self.graph_data_hbox.pack_start(y2Frame, expand=False, fill=True, padding=0) + self.graph_data_hbox.show_all() else: logging.debug("Activity has no GPX data") #Remove graph @@ -913,6 +945,27 @@ ## Lista de eventos ## ###################### + def on_xaxischange(self, widget, data=None): + '''Handler for record graph axis selection changes''' + if widget.get_active(): + print data + + def on_y1change(self, widget, box): + '''Hander for changes to y1 selection''' + print "Y1 selected: ", + for child in box.get_children(): + if child.get_active(): + print child.get_label(), + print + + def on_y2change(self, widget, box): + '''Hander for changes to y2 selection''' + print "Y2 selected: ", + for child in box.get_children(): + if child.get_active(): + print child.get_label(), + print + def on_athleteTreeView_button_press_event(self, treeview, event): x = int(event.x) y = int(event.y) Modified: pytrainer/trunk/pytrainer/lib/activity.py =================================================================== --- pytrainer/trunk/pytrainer/lib/activity.py 2010-09-21 10:22:04 UTC (rev 615) +++ pytrainer/trunk/pytrainer/lib/activity.py 2010-09-21 11:35:28 UTC (rev 616) @@ -38,6 +38,8 @@ us_system - (bool) True: imperial measurement False: metric measurement distance_unit - (string) unit to use for distance speed_unit - (string) unit to use for speed + distance_data - (dict of graphdata classes) contains the graph data with x axis distance + time_data - (dict of graphdata classes) contains the graph data with x axis time height_unit - (string) unit to use for height pace_unit - (string) unit to use for pace gpx_file - (string) gpx file name @@ -220,30 +222,30 @@ logging.debug("<<") return #Profile - title=_("Elevation v Distance") + title=_("Elevation") xlabel="%s (%s)" % (_('Distance'), self.distance_unit) ylabel="%s (%s)" % (_('Elevation'), self.height_unit) self.distance_data['elevation'] = GraphData(title=title, xlabel=xlabel, ylabel=ylabel) - title=_("Elevation v Time") + title=_("Elevation") xlabel=_("Time (hours)") self.time_data['elevation'] = GraphData(title=title,xlabel=xlabel, ylabel=ylabel) #Speed - title=_("Speed v Distance") + title=_("Speed") xlabel="%s (%s)" % (_('Distance'), self.distance_unit) ylabel="%s (%s)" % (_('Speed'), self.speed_unit) self.distance_data['speed'] = GraphData(title=title, xlabel=xlabel, ylabel=ylabel) #Pace - title=_("Pace v Distance") + title=_("Pace") xlabel="%s (%s)" % (_('Distance'), self.distance_unit) ylabel="%s (%s)" % (_('Pace'), self.pace_unit) self.distance_data['pace'] = GraphData(title=title, xlabel=xlabel, ylabel=ylabel) #Heartrate - title=_("Heart Rate v Distance") + title=_("Heart Rate") xlabel="%s (%s)" % (_('Distance'), self.distance_unit) ylabel="%s (%s)" % (_('Heart Rate'), _('bpm')) self.distance_data['hr'] = GraphData(title=title, xlabel=xlabel, ylabel=ylabel) #Cadence - title=_("Cadence v Distance") + title=_("Cadence") xlabel="%s (%s)" % (_('Distance'), self.distance_unit) ylabel="%s (%s)" % (_('Cadence'), _('rpm')) self.distance_data['cadence'] = GraphData(title=title, xlabel=xlabel, ylabel=ylabel) @@ -270,11 +272,11 @@ #Remove data with no values for item in self.distance_data.keys(): if len(self.distance_data[item]) == 0: - print "No values for %s. Removing...." % item + logging.debug( "No values for %s. Removing...." % item ) del self.distance_data[item] for item in self.time_data.keys(): if len(self.time_data[item]) == 0: - print "No values for %s. Removing...." % item + logging.debug( "No values for %s. Removing...." % item ) del self.time_data[item] logging.debug("<<") Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-09-21 10:22:04 UTC (rev 615) +++ pytrainer/trunk/pytrainer/main.py 2010-09-21 11:35:28 UTC (rev 616) @@ -49,7 +49,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#615" + self.version ="1.7.2_svn#616" self.DB_version = 3 #Process command line options self.startup_options = self.get_options() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-09-21 10:22:10
|
Revision: 615 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=615&view=rev Author: jblance Date: 2010-09-21 10:22:04 +0000 (Tue, 21 Sep 2010) Log Message: ----------- Small correction to ensure no graph is shown for activities with no gpx data Modified Paths: -------------- pytrainer/trunk/pytrainer/gui/windowmain.py pytrainer/trunk/pytrainer/lib/activity.py pytrainer/trunk/pytrainer/main.py Modified: pytrainer/trunk/pytrainer/gui/windowmain.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowmain.py 2010-09-21 05:00:23 UTC (rev 614) +++ pytrainer/trunk/pytrainer/gui/windowmain.py 2010-09-21 10:22:04 UTC (rev 615) @@ -271,19 +271,21 @@ logging.debug(">>") self.record_list = activity.tracks self.laps = activity.laps - if self.record_list is not None and len(self.record_list)>0: + if activity.gpx_file is not None: + logging.debug("Activity has GPX data") self.record_vbox.set_sensitive(1) self.drawarearecord.drawgraph(self.record_list,self.laps) else: + logging.debug("Activity has no GPX data") #Remove graph - vboxChildren = self.record_vbox.get_children() + vboxChildren = self.record_graph_vbox.get_children() logging.debug('Vbox has %d children %s' % (len(vboxChildren), str(vboxChildren) )) # ToDo: check why vertical container is shared for child in vboxChildren: #Remove all FigureCanvasGTK and NavigationToolbar2GTKAgg to stop double ups of graphs if isinstance(child, matplotlib.backends.backend_gtkagg.FigureCanvasGTK) or isinstance(child, matplotlib.backends.backend_gtkagg.NavigationToolbar2GTKAgg): logging.debug('Removing child: '+str(child)) - self.record_vbox.remove(child) + self.record_graph_vbox.remove(child) self.record_vbox.set_sensitive(0) logging.debug("<<") @@ -390,7 +392,7 @@ else: self.dayview.set_sensitive(0) logging.debug("<<") - + def actualize_daygraph(self,record_list): logging.debug(">>") if len(record_list)>0: @@ -678,7 +680,7 @@ iter = history_store.append() history_store.set ( iter, - 0, data_index, + 0, data_index, 1, date, #TODO need to sort date graphing... 2, "%0.2f" % weight, 3, "%0.2f" % float(data['BF']), @@ -888,7 +890,7 @@ logging.debug("Reseting graph Y axis with ylimits: %s" % str(y1limits) ) self.drawarearecord.drawgraph(self.record_list,self.laps, y1limits=y1limits, y1color=y1color, y1_linewidth=y1_linewidth) logging.debug("<<") - + def update_athlete_item(self, idx, date, weight, bf, restingHR, maxHR): logging.debug(">>") #Prepare vars @@ -910,7 +912,7 @@ ###################### ## Lista de eventos ## ###################### - + def on_athleteTreeView_button_press_event(self, treeview, event): x = int(event.x) y = int(event.y) Modified: pytrainer/trunk/pytrainer/lib/activity.py =================================================================== --- pytrainer/trunk/pytrainer/lib/activity.py 2010-09-21 05:00:23 UTC (rev 614) +++ pytrainer/trunk/pytrainer/lib/activity.py 2010-09-21 10:22:04 UTC (rev 615) @@ -63,7 +63,7 @@ maxspeed - (float) maximum speed obtained during activity maxpace - (float) maxium pace obtained during activity pace - (float) average pace for activity - has_data - (bool) true if gpx processed and instance has data populated + has_data - (bool) true if instance has data populated ''' def __init__(self, pytrainer_main = None, id = None): logging.debug(">>") Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-09-21 05:00:23 UTC (rev 614) +++ pytrainer/trunk/pytrainer/main.py 2010-09-21 10:22:04 UTC (rev 615) @@ -49,7 +49,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#614" + self.version ="1.7.2_svn#615" self.DB_version = 3 #Process command line options self.startup_options = self.get_options() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-09-21 05:00:31
|
Revision: 614 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=614&view=rev Author: jblance Date: 2010-09-21 05:00:23 +0000 (Tue, 21 Sep 2010) Log Message: ----------- Initial checkin of fixelevation code from Arnd - currently in progress. May not function correctly Modified Paths: -------------- pytrainer/trunk/pytrainer/main.py pytrainer/trunk/setup.py Added Paths: ----------- pytrainer/trunk/extensions/fixelevation/ pytrainer/trunk/extensions/fixelevation/README.txt pytrainer/trunk/extensions/fixelevation/conf.xml pytrainer/trunk/extensions/fixelevation/fixelevation.py Added: pytrainer/trunk/extensions/fixelevation/README.txt =================================================================== --- pytrainer/trunk/extensions/fixelevation/README.txt (rev 0) +++ pytrainer/trunk/extensions/fixelevation/README.txt 2010-09-21 05:00:23 UTC (rev 614) @@ -0,0 +1,41 @@ + Fix Elevation pytrainer extension + =============================== + This extension allows you to correct elevations within gpx data. + Code is based on Wojciech Lichota's gpxtools + http://lichota.pl/blog/topics/gpxtools + Elevations are corrected using SRTM data, therefore on first usage the necessary + SRTM tile will be downloaded (large!). Tiles will be cached. + + Extension requires 'GDAL python bindings'. Install e.g. + apt-get install python-gdal + or + yum install gdal-python + + + CONFIG OPTIONS + ============== + n.n. + + USAGE + ===== + Simply submit the fixelevation extension preferences form and then go + to the record tab and press "Fix Elevation". + +--------------------------- + + IMPORTANT + ========= + + - On first use, the extension will download a geo_tif File (about 79mb) for your region, there is no warning dialog or similiar. + - Original gpx data (in '.pytrainer/gpx/') will be overwritten. + - The main record isn't forced to be reloaded at the moment, so restart pytrainer to study the manipulated heights. + + TODO + ==== + (?) Interface to specify source of SRTM data (at the moment hardcoded CGIAR mirror) + (?) Interface to specify where to store SRTM data (at the moment .pytrainer/SRTM_data) + (?) Store original gpx elevation data (gpx extension or whole backup file?); offer revert possibility + (?) Improve Wojciech's border trick. + (?) Offer alternative SRTM/DEM Sources eg http://www.viewfinderpanoramas.org/dem3.html + (?) Offer batch mode to fix bundle of tracks + (?) Higher order of interpolation (ie bicubic) Added: pytrainer/trunk/extensions/fixelevation/conf.xml =================================================================== --- pytrainer/trunk/extensions/fixelevation/conf.xml (rev 0) +++ pytrainer/trunk/extensions/fixelevation/conf.xml 2010-09-21 05:00:23 UTC (rev 614) @@ -0,0 +1,12 @@ +<?xml version="1.0" ?> +<pytrainer-extension + name="Elevation correction" + description="Correct the GPX elevation using GDAL" + extensionbutton="Fix Elevation" + extensioncode="fixelevation" + type="record" + helpfile="README.txt" + executable="fixelevation" +> + +</pytrainer-extension> Added: pytrainer/trunk/extensions/fixelevation/fixelevation.py =================================================================== --- pytrainer/trunk/extensions/fixelevation/fixelevation.py (rev 0) +++ pytrainer/trunk/extensions/fixelevation/fixelevation.py 2010-09-21 05:00:23 UTC (rev 614) @@ -0,0 +1,293 @@ +#!/usr/bin/env python +import os, stat, sys +import logging +import gtk + +import random, re, urllib2, zipfile +from math import floor, ceil +from cStringIO import StringIO +from optparse import OptionParser + +from osgeo import gdal, gdalnumeric +from lxml import etree + + + +# from gpxtools +def bilinear_interpolation(tl, tr, bl, br, a, b): + """ + Based on equation from: + http://en.wikipedia.org/wiki/Bilinear_interpolation + + :Parameters: + tl : int + top-left + tr : int + top-right + bl : int + buttom-left + br : int + bottom-right + a : float + x distance to top-left + b : float + y distance to top-right + + :Returns: (float) + interpolated value + """ + b1 = tl + b2 = bl - tl + b3 = tr - tl + b4 = tl - bl - tr + br + + return b1 + b2 * a + b3 * b + b4 * a * b + +class SrtmTiff(object): + """ + Provides an interface to SRTM elevation data stored in GeoTIFF file. + + Based on code from `eleserver` code by grahamjones139. + http://code.google.com/p/eleserver/ + """ + tile = {} + + def __init__(self, filename): + """ + Reads the GeoTIFF files into memory ready for processing. + """ + self.tile = self.load_tile(filename) + + def load_tile(self, filename): + """ + Loads a GeoTIFF tile from disk and returns a dictionary containing + the file data, plus metadata about the tile. + + The dictionary returned by this function contains the following data: + xsize - the width of the tile in pixels. + ysize - the height of the tile in pixels. + lat_origin - the latitude of the top left pixel in the tile. + lon_origin - the longitude of the top left pixel in the tile. + lat_pixel - the height of one pixel in degrees latitude. + lon_pixel - the width of one pixel in degrees longitude. + N, S, E, W - the bounding box for this tile in degrees. + data - a two dimensional array containing the tile data. + + """ + dataset = gdal.Open(filename) + geotransform = dataset.GetGeoTransform() + xsize = dataset.RasterXSize + ysize = dataset.RasterYSize + lon_origin = geotransform[0] + lat_origin = geotransform[3] + lon_pixel = geotransform[1] + lat_pixel = geotransform[5] + + retdict = { + 'xsize': xsize, + 'ysize': ysize, + 'lat_origin': lat_origin, + 'lon_origin': lon_origin, + 'lon_pixel': lon_pixel, + 'lat_pixel': lat_pixel, + 'N': lat_origin, + 'S': lat_origin + lat_pixel*ysize, + 'E': lon_origin + lon_pixel*xsize, + 'W': lon_origin, + 'dataset': dataset, + } + + return retdict + + def pos_from_lat_lon(self, lat, lon): + """ + Converts coordinates (lat,lon) into the appropriate (row,column) + position in the GeoTIFF tile data stored in td. + """ + td = self.tile + N = td['N'] + S = td['S'] + E = td['E'] + W = td['W'] + lat_pixel = td['lat_pixel'] + lon_pixel = td['lon_pixel'] + xsize = td['xsize'] + ysize = td['ysize'] + + rowno_f = (lat-N)/lat_pixel + colno_f = (lon-W)/lon_pixel + rowno = int(floor(rowno_f)) + colno = int(floor(colno_f)) + + # Error checking to correct any rounding errors. + if (rowno<0): + rowno = 0 + if (rowno>(xsize-1)): + rowno = xsize-1 + if (colno<0): + colno = 0 + if (colno>(ysize-1)): + colno = xsize-1 + + return (rowno, colno, rowno_f, colno_f) + + def get_elevation(self, lat, lon): + """ + Returns the elevation in metres of point (lat, lon). + + Uses bilinar interpolation to interpolate the SRTM data to the + required point. + """ + row, col, row_f, col_f = self.pos_from_lat_lon(lat, lon) + + # NOTE - THIS IS A FIDDLE TO STOP ERRORS AT THE EDGE OF + # TILES - IT IS NO CORRECT - WE SHOULD GET TWO POINTS + # FROM THE NEXT TILE. + if row==5999: row=5998 + if col==5999: col=5998 + + htarr = gdalnumeric.DatasetReadAsArray(self.tile['dataset'], col, row, 2, 2) + height = bilinear_interpolation(htarr[0][0], htarr[0][1], htarr[1][0], htarr[1][1], + row_f-row, col_f-col) + + return height + + +class SrtmLayer(object): + """ + Provides an interface to SRTM elevation data stored in GeoTIFF files. + Files are automaticly downloaded from mirror server and cached. + + Sample usage: + + >>> lat = 52.25 + >>> lon = 16.75 + >>> srtm = SrtmLayer() + >>> ele = srtm.get_elevation(lat, lon) + >>> round(ele, 4) + 63.9979 + + """ + _cache = {} + + def _download_srtm_tiff(self, srtm_filename): + """ + Download and unzip GeoTIFF file. + """ + #msg = _("Downloading SRTM Data from server. This might take some time...") + #md = gtk.MessageDialog(self.pytrainer_main.windowmain.window1, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO, gtk.BUTTONS_NONE, msg) + #md.set_title(_("Downloading SRTM Data")) + #md.set_modal(True) + #md.show() + + logging.info('Downloading SRTM data file, it may take some time ...') + url = 'http://hypersphere.telascience.org/elevation/cgiar_srtm_v4/tiff/zip/%s.ZIP' % srtm_filename[:-4] + print "Attempting to get URL: %s" % url + zobj = StringIO() + zobj.write(urllib2.urlopen(url).read()) + z = zipfile.ZipFile(zobj) + + gpxtools_dir = os.path.expanduser('~/.pytrainer/SRTM_data') + if not os.path.isdir(gpxtools_dir): + os.mkdir(gpxtools_dir) + + srtm_path = os.path.join(gpxtools_dir, srtm_filename) + out_file = open(srtm_path, 'w') + out_file.write(z.read(srtm_filename)) + + z.close() + out_file.close() + #md.destroy() + + + def get_srtm_filename(self, lat, lon): + """ + Filename of GeoTIFF file containing data with given coordinates. + """ + colmin = floor((6000 * (180 + lon)) / 5) + rowmin = floor((6000 * (60 - lat)) / 5) + + ilon = ceil(colmin / 6000.0) + ilat = ceil(rowmin / 6000.0) + + return 'srtm_%02d_%02d.TIF' % (ilon, ilat) + + def get_elevation(self, lat, lon): + """ + Returns the elevation in metres of point (lat, lon). + """ + srtm_filename = self.get_srtm_filename(lat, lon) + if srtm_filename not in self._cache: + srtm_path = os.path.join(os.path.expanduser('~/.pytrainer/SRTM_data'), srtm_filename) + if not os.path.isfile(srtm_path): + self._download_srtm_tiff(srtm_filename) + + self._cache[srtm_filename] = SrtmTiff(srtm_path) + + srtm = self._cache[srtm_filename] + return srtm.get_elevation(lat, lon) + +class fixelevation: + _data = None + _srtm = SrtmLayer() + + def __init__(self, parent = None, pytrainer_main = None, conf_dir = None, options = None): + self.parent = parent + self.pytrainer_main = pytrainer_main + self.options = options + self.conf_dir = conf_dir + + def run(self, id, activity=None): #TODO Convert to use activity... + logging.debug(">>") + gpx_file = "%s/gpx/%s.gpx" % (self.conf_dir, id) + if os.path.isfile(gpx_file): + #GPX file is ok and found, so open it + logging.debug("ELE GPX file: %s found, size: %d" % (gpx_file, os.path.getsize(gpx_file))) + """ + Parse GPX file to ElementTree instance. + """ + self._data = etree.parse(gpx_file) + self._xmlns = self._data.getroot().nsmap[None] + self._trkpt_path = '{%s}trk/{%s}trkseg/{%s}trkpt' % (self._xmlns, self._xmlns, self._xmlns) + + """ + Replace elevation from GPX by data from SRTM. + TODO (Arnd) make a function within class fixelevation out of this for better reuse + """ + for trkpt in self._data.findall(self._trkpt_path): + lat = float(trkpt.attrib['lat']) + lon = float(trkpt.attrib['lon']) + + ele = trkpt.find('{%s}ele' % self._xmlns) + if ele is not None: + ele.text = str(self._srtm.get_elevation(lat, lon)) + else: + ele = etree.Element('ele') + ele.text = str(self._srtm.get_elevation(lat, lon)) + trkpt.append(ele) + """ + write out to original *.gpx. Shall original ele-values backuped/stored somewhere ? + """ + self._data.write( gpx_file, + encoding=self._data.docinfo.encoding, + xml_declaration=True, + pretty_print=False) + + + #print trkpt + res_msg = "Elevation has been fixed." + #Show the user the result + md = gtk.MessageDialog(self.pytrainer_main.windowmain.window1, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, res_msg) + md.set_title(_("Elevation Correction Complete")) + md.set_modal(False) + md.run() + md.destroy() + #TODO reload gpx data in main window + + else: + logging.error("ELE GPX file: %s NOT found!!!" % (gpx_file)) + logging.debug("<<") + + + + Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-09-21 04:23:13 UTC (rev 613) +++ pytrainer/trunk/pytrainer/main.py 2010-09-21 05:00:23 UTC (rev 614) @@ -49,7 +49,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#613" + self.version ="1.7.2_svn#614" self.DB_version = 3 #Process command line options self.startup_options = self.get_options() Modified: pytrainer/trunk/setup.py =================================================================== --- pytrainer/trunk/setup.py 2010-09-21 04:23:13 UTC (rev 613) +++ pytrainer/trunk/setup.py 2010-09-21 05:00:23 UTC (rev 614) @@ -45,6 +45,7 @@ install_plugin("garmintools_full"), install_extension("wordpress"), install_extension("openstreetmap"), + install_extension("fixelevation"), (install_locale("ca")), (install_locale("cs")), (install_locale("da")), This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-09-21 04:23:19
|
Revision: 613 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=613&view=rev Author: jblance Date: 2010-09-21 04:23:13 +0000 (Tue, 21 Sep 2010) Log Message: ----------- Add GUI option to anonymise GPX data in OSM extension Modified Paths: -------------- pytrainer/trunk/extensions/openstreetmap/openstreetmap.py pytrainer/trunk/pytrainer/main.py Modified: pytrainer/trunk/extensions/openstreetmap/openstreetmap.py =================================================================== --- pytrainer/trunk/extensions/openstreetmap/openstreetmap.py 2010-09-20 00:41:08 UTC (rev 612) +++ pytrainer/trunk/extensions/openstreetmap/openstreetmap.py 2010-09-21 04:23:13 UTC (rev 613) @@ -56,6 +56,11 @@ f.close() logging.debug("User abort") return + if self.makeanon: + logging.debug("User requested anonymising of GPX data") + f.close() #Close standard gpxfile + gpx_file = self.make_gpx_private(gpx_file) + f = open(gpx_file, 'r') #Open anonymous gpxfile in readonly mode fields = (("description",self.description), ("tags",self.tags), ("visibility",self.visibility)) logging.debug("Added fields: %s" % str(fields)) #Multipart encode the request @@ -131,6 +136,13 @@ table.attach(combobox,1,2,2,3) self.entryList.append(combobox) table.attach(label,0,1,2,3) + #Add anonymize GPX option + label = gtk.Label("<b>Anonymize GPX Data</b>") + label.set_use_markup(True) + table.attach(label,0,1,3,4) + checkbutton = gtk.CheckButton() + table.attach(checkbutton,1,2,3,4) + self.entryList.append(checkbutton) #Buld dialog and show self.prefwindow.vbox.pack_start(table) self.prefwindow.show_all() @@ -148,7 +160,8 @@ self.description = "Uploaded from pytrainer" self.tags = self.entryList[1].get_text() self.visibility = self.entryList[2].get_active_text() - logging.debug("Description: %s, tags: %s, visibility: %s" % ( self.description, self.tags, self.visibility) ) + self.makeanon = self.entryList[3].get_active() + logging.debug("Description: %s, tags: %s, visibility: %s, makeanon: %s" % ( self.description, self.tags, self.visibility, self.makeanon) ) def multipart_encode(self, fields, files, boundary = None, buffer = None): ''' @@ -182,7 +195,7 @@ wipes out private data from gpx files converts laps to waypoints ''' - + logging.debug(">>") if gpx_file is None: return None @@ -270,6 +283,7 @@ #xmlschema.validate(tree) # write new gpx file - write(anon_gpx_file, pretty_print=False, xml_declaration=True, encoding='UTF-8') + tree.write(anon_gpx_file, pretty_print=False, xml_declaration=True, encoding='UTF-8') + logging.debug("<<") return anon_gpx_file Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-09-20 00:41:08 UTC (rev 612) +++ pytrainer/trunk/pytrainer/main.py 2010-09-21 04:23:13 UTC (rev 613) @@ -49,7 +49,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#612" + self.version ="1.7.2_svn#613" self.DB_version = 3 #Process command line options self.startup_options = self.get_options() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-09-20 00:41:15
|
Revision: 612 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=612&view=rev Author: jblance Date: 2010-09-20 00:41:08 +0000 (Mon, 20 Sep 2010) Log Message: ----------- Some corrections to pace display and calculation as suggested by Arnd Modified Paths: -------------- pytrainer/trunk/pytrainer/activitypool.py pytrainer/trunk/pytrainer/gui/windowmain.py pytrainer/trunk/pytrainer/gui/windowrecord.py pytrainer/trunk/pytrainer/main.py pytrainer/trunk/pytrainer/record.py Modified: pytrainer/trunk/pytrainer/activitypool.py =================================================================== --- pytrainer/trunk/pytrainer/activitypool.py 2010-09-10 03:27:57 UTC (rev 611) +++ pytrainer/trunk/pytrainer/activitypool.py 2010-09-20 00:41:08 UTC (rev 612) @@ -43,7 +43,14 @@ self.pool = {} self.pool_queue = [] logging.debug("<<") - + + def remove_activity(self, id): + sid = str(id) + if sid in self.pool.keys(): + logging.debug("Found activity in pool") + self.pool_queue.remove(sid) + del self.pool[sid] + def get_activity(self, id): sid = str(id) if sid in self.pool.keys(): Modified: pytrainer/trunk/pytrainer/gui/windowmain.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowmain.py 2010-09-10 03:27:57 UTC (rev 611) +++ pytrainer/trunk/pytrainer/gui/windowmain.py 2010-09-20 00:41:08 UTC (rev 612) @@ -28,6 +28,7 @@ from popupmenu import PopupMenu from aboutdialog import About +from pytrainer.record import Record from pytrainer.lib.date import Date from pytrainer.lib.xmlUtils import XMLParser #from pytrainer.lib.gpx import Gpx @@ -244,8 +245,8 @@ self.record_unegative.set_text("%0.2f" %activity.unegative) self.record_average.set_text("%0.2f" %activity.average) self.record_maxspeed.set_text("%0.2f" %activity.maxspeed) - self.record_pace.set_text("%0.2f" %activity.pace) - self.record_maxpace.set_text("%0.2f" %activity.maxpace) + self.record_pace.set_text(Record().pace_from_float(activity.pace)) + self.record_maxpace.set_text(Record().pace_from_float(activity.maxpace)) self.record_sport.set_text(activity.sport_name) #self.record_date.set_text(str(date)) @@ -344,8 +345,8 @@ maxbeats = 0 maxspeed = 0 average = 0 - maxpace = "0.00" - pace = "0.00" + maxpace = "0:00" + pace = "0:00" for record in record_list: distance += self.parseFloat(record[2]) calories += self.parseFloat(record[7]) @@ -367,9 +368,9 @@ if distance > 0: average = distance/(timeinseconds/60/60) if maxspeed > 0: - maxpace = "%d.%02d" %((3600/maxspeed)/60,(3600/maxspeed)%60) + maxpace = "%d:%02d" %((3600/maxspeed)/60,(3600/maxspeed)%60) if average > 0: - pace = "%d.%02d" %((3600/average)/60,(3600/average)%60) + pace = "%d:%02d" %((3600/average)/60,(3600/average)%60) self.dayview.set_sensitive(1) self.day_distance.set_text("%0.2f" %distance) @@ -381,15 +382,15 @@ self.day_maxbeats.set_text("%0.2f" %maxbeats) self.day_average.set_text("%0.2f" %average) self.day_maxspeed.set_text("%0.2f" %maxspeed) - self.day_pace.set_text(pace) - self.day_maxpace.set_text(maxpace) + self.day_pace.set_text("%s" %pace) + self.day_maxpace.set_text("%s" %maxpace) self.day_calories.set_text("%0.0f" %calories) self.day_topic.set_text(str(record[1])) else: self.dayview.set_sensitive(0) logging.debug("<<") - + def actualize_daygraph(self,record_list): logging.debug(">>") if len(record_list)>0: @@ -435,8 +436,8 @@ time_in_min = 0 tbeats = 0 maxspeed = 0 - pace = "0.00" - maxpace = "0.00" + pace = "0:00" + maxpace = "0:00" maxbeats = 0 if self.pytrainer_main.profile.getValue("pytraining","prf_us_system") == "True": @@ -482,10 +483,10 @@ if maxspeed > 0: #maxpace = 60/maxspeed - maxpace = "%d.%02d" %((3600/maxspeed)/60,(3600/maxspeed)%60) + maxpace = "%d:%02d" %((3600/maxspeed)/60,(3600/maxspeed)%60) if average > 0: #pace = 60/average - pace = "%d.%02d" %((3600/average)/60,(3600/average)%60) + pace = "%d:%02d" %((3600/average)/60,(3600/average)%60) self.weeka_distance.set_text("%0.2f" %km) hour,min,sec = self.parent.date.second2time(time) @@ -513,8 +514,8 @@ time_in_min = 0 tbeats = 0 maxspeed = 0 - pace = "0.00" - maxpace = "0.00" + pace = "0:00" + maxpace = "0:00" maxbeats = 0 if self.pytrainer_main.profile.getValue("pytraining","prf_us_system") == "True": @@ -560,10 +561,10 @@ if maxspeed > 0: #maxpace = 60/maxspeed - maxpace = "%d.%02d" %((3600/maxspeed)/60,(3600/maxspeed)%60) + maxpace = "%d:%02d" %((3600/maxspeed)/60,float(3600/maxspeed)%60) if average > 0: #pace = 60/average - pace = "%d.%02d" %((3600/average)/60,(3600/average)%60) + pace = "%d:%02d" %((3600/average)/60,float(3600/average)%60) self.montha_distance.set_text("%0.2f" %km) hour,min,sec = self.parent.date.second2time(time) @@ -595,8 +596,8 @@ time_in_min = 0 tbeats = 0 maxspeed = 0 - pace = "0.00" - maxpace = "0.00" + pace = "0:00" + maxpace = "0:00" maxbeats = 0 if num_records>0: for record in record_list: @@ -623,10 +624,10 @@ if maxspeed > 0: #maxpace = 60/maxspeed - maxpace = "%d.%02d" %((3600/maxspeed)/60,(3600/maxspeed)%60) + maxpace = "%d:%02d" %((3600/maxspeed)/60,(3600/maxspeed)%60) if average > 0: #pace = 60/average - pace = "%d.%02d" %((3600/average)/60,(3600/average)%60) + pace = "%d:%02d" %((3600/average)/60,(3600/average)%60) self.yeara_distance.set_text("%0.2f" %km) hour,min,sec = self.parent.date.second2time(time) Modified: pytrainer/trunk/pytrainer/gui/windowrecord.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowrecord.py 2010-09-10 03:27:57 UTC (rev 611) +++ pytrainer/trunk/pytrainer/gui/windowrecord.py 2010-09-20 00:41:08 UTC (rev 612) @@ -21,6 +21,7 @@ import gtk, gobject from SimpleGladeApp import SimpleGladeApp from windowcalendar import WindowCalendar + from filechooser import FileChooser from pytrainer.lib.date import Date import dateutil.parser @@ -504,8 +505,16 @@ distance = float(self.rcd_distance.get_text()) if distance<1: return False + #Calc Pace average = time_in_min/distance - self.rcd_pace.set_text("%0.2f" %average) + #Tranform pace to mm.ss + min = int(average) + per_min = average - min + sec = float(per_min) * 60 / 100 + dec_pace = min + sec + #Transform pace to mm:ss + pace = self.parent.pace_from_float(dec_pace) + self.rcd_pace.set_text(pace) def on_calccalories_clicked(self,widget): sport = self.rcd_sport.get_active_text() Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-09-10 03:27:57 UTC (rev 611) +++ pytrainer/trunk/pytrainer/main.py 2010-09-20 00:41:08 UTC (rev 612) @@ -49,7 +49,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#611" + self.version ="1.7.2_svn#612" self.DB_version = 3 #Process command line options self.startup_options = self.get_options() Modified: pytrainer/trunk/pytrainer/record.py =================================================================== --- pytrainer/trunk/pytrainer/record.py 2010-09-10 03:27:57 UTC (rev 611) +++ pytrainer/trunk/pytrainer/record.py 2010-09-20 00:41:08 UTC (rev 612) @@ -107,11 +107,29 @@ self.parseFloatRecord(list_options["rcd_unegative"]), self.parseFloatRecord(list_options["rcd_maxvel"]), self.parseFloatRecord(list_options["rcd_maxpace"]), - self.parseFloatRecord(list_options["rcd_pace"]), - self.parseFloatRecord(list_options["rcd_maxbeats"]) + self.pace_to_float(list_options["rcd_pace"]), + self.pace_to_float(list_options["rcd_maxbeats"]) ) logging.debug('<<') return cells,values + + 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 + return value + + def pace_from_float(self, value): + '''Helper to generate mm:ss from float representation mm.ss (or mm,ss?)''' + #Check that value supplied is a float + try: + _value = "%0.2f" % float(value) + except ValueError: + _value = str(value) + return _value.replace('.',':') def _formatRecordNew (self, list_options): """20.07.2008 - dgranda @@ -141,8 +159,8 @@ self.parseFloatRecord(list_options["rcd_upositive"]), self.parseFloatRecord(list_options["rcd_unegative"]), self.parseFloatRecord(list_options["rcd_maxvel"]), - self.parseFloatRecord(list_options["rcd_maxpace"]), - self.parseFloatRecord(list_options["rcd_pace"]), + self.pace_to_float(list_options["rcd_maxpace"]), + self.pace_to_float(list_options["rcd_pace"]), self.parseFloatRecord(list_options["rcd_maxbeats"]), list_options["date_time_utc"], list_options["date_time_local"], @@ -263,6 +281,8 @@ def updateRecord(self, list_options, id_record): logging.debug('>>') + #Remove activity from pool so data is updated + self.pytrainer_main.activitypool.remove_activity(id_record) gpxfile = self.pytrainer_main.profile.gpxdir+"/%d.gpx"%int(id_record) gpxOrig = list_options["rcd_gpxfile"] if os.path.isfile(gpxOrig): @@ -274,7 +294,7 @@ logging.debug('updating bbdd') #ein? cells,values = self._formatRecord(list_options) self.pytrainer_main.ddbb.update("records",cells,values," id_record=%d" %int(id_record)) - self.parent.refreshListView() + self.pytrainer_main.refreshListView() logging.debug('<<') def parseFloatRecord(self,string): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-09-10 03:28:03
|
Revision: 611 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=611&view=rev Author: jblance Date: 2010-09-10 03:27:57 +0000 (Fri, 10 Sep 2010) Log Message: ----------- Initial check-in of OSM anonymising functionality from Arnd Modified Paths: -------------- pytrainer/trunk/extensions/openstreetmap/openstreetmap.py pytrainer/trunk/pytrainer/main.py Modified: pytrainer/trunk/extensions/openstreetmap/openstreetmap.py =================================================================== --- pytrainer/trunk/extensions/openstreetmap/openstreetmap.py 2010-09-10 01:55:13 UTC (rev 610) +++ pytrainer/trunk/extensions/openstreetmap/openstreetmap.py 2010-09-10 03:27:57 UTC (rev 611) @@ -5,6 +5,9 @@ import logging import gtk +import string +from lxml import etree + import httplib, httplib2 import urllib2 import mimetools, mimetypes @@ -38,6 +41,7 @@ logging.debug("GPX file: %s found, size: %d" % (gpx_file, os.path.getsize(gpx_file))) f = open(gpx_file, 'r') file_contents = f.read() + #TODO Fix to use etree functionality..... if file_contents.find("<?xml version='1.0' encoding='ASCII'?>") != -1: logging.debug("GPX file: %s has ASCII encoding - updating to UTF-8 for OSM support" % gpx_file) f.close() #Close readonly file @@ -172,3 +176,100 @@ buffer += '\r\n' + fd.read() + '\r\n' buffer += '--%s--\r\n\r\n' % boundary return boundary, buffer + + def make_gpx_private(self, gpx_file=None): + ''' + wipes out private data from gpx files + converts laps to waypoints + ''' + + if gpx_file is None: + return None + + filen = os.path.basename(gpx_file) + tmpdir = self.pytrainer_main.profile.tmpdir + anon_gpx_file = "%s/%s" % (tmpdir, filen) + + # Filtered home area, example Berlin + # corners NorthEast and SouthWest + #TODO This needs to be a config item.... + NE_LAT = 52.518 + NE_LON = 13.408 + SW_LAT = 52.4 + SW_LON = 13.3 + + # Config parameters, not used yet + FILTER_BOX = True + ERASE_TIME = True + LAP_TO_WAYPOINT = True + + tree = etree.parse(gpx_file) + _xmlns = tree.getroot().nsmap[None] + _trkpt_path = '{%s}trk/{%s}trkseg/{%s}trkpt' % (_xmlns, _xmlns, _xmlns) + # namespace of gpx files + NS = dict(ns='http://www.topografix.com/GPX/1/1') + + myroot = tree.getroot() + gpxdataNS = string.Template(\ + ".//{http://www.cluetrust.com/XML/GPXDATA/1/0}$tag") + lapTag = gpxdataNS.substitute(tag="lap") + endPointTag = gpxdataNS.substitute(tag="endPoint") + triggerTag = gpxdataNS.substitute(tag="trigger") + laps = tree.findall(lapTag) + + #new_waypoints=[] + mygpx = tree.find('gpx') + + for lap in laps: + trigger = lap.find(triggerTag) + # Watch out for manually triggered laps + if trigger.text == 'manual': + endPoint = lap.find(endPointTag) + lat = endPoint.get("lat") + lon = endPoint.get("lon") + print lat,lon + #new_waypoints.append([lat,lon]) + #add waypoint + etree.SubElement(myroot, 'wpt', attrib= {'lat':lat, 'lon':lon}) + + etree.strip_attributes(myroot, 'creator') + + # Wipe out home box + for trkpt in tree.findall(_trkpt_path): + lat = float(trkpt.attrib['lat']) + lon = float(trkpt.attrib['lon']) + #print lat, lon + if (lat < NE_LAT) & (lon < NE_LON) & (lat > SW_LAT) & (lon > SW_LON): + #print lat,lon + par = trkpt.getparent() + par.remove(trkpt) + + + time = tree.xpath('//ns:trkpt/ns:time', namespaces=NS) + for i in time: + i.text = '1970-01-01T00:00:00+00:00' + # osm regards <time> as mandatory. gnaa. + + ext = tree.xpath('//ns:gpx/ns:extensions', namespaces=NS) + for i in ext: + par = i.getparent() + par.remove(i) + meta = tree.xpath('//ns:gpx/ns:metadata', namespaces=NS) + for i in meta: + par = i.getparent() + par.remove(i) + ele = tree.xpath('//ns:trkpt/ns:ele', namespaces=NS) + for i in ele: + par = i.getparent() + par.remove(i) + + # test schema on cleaned xml-tree + # gpx.xsd from http://www.topografix.com/gpx.asp + + #xmlschema = etree.XMLSchema(etree.parse('gpx.xsd')) + #xmlschema.validate(tree) + + # write new gpx file + write(anon_gpx_file, pretty_print=False, xml_declaration=True, encoding='UTF-8') + return anon_gpx_file + Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-09-10 01:55:13 UTC (rev 610) +++ pytrainer/trunk/pytrainer/main.py 2010-09-10 03:27:57 UTC (rev 611) @@ -49,7 +49,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#610" + self.version ="1.7.2_svn#611" self.DB_version = 3 #Process command line options self.startup_options = self.get_options() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-09-10 01:55:19
|
Revision: 610 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=610&view=rev Author: jblance Date: 2010-09-10 01:55:13 +0000 (Fri, 10 Sep 2010) Log Message: ----------- Minor fixes to stop errors when an activity does not have any GPX data associated with it Modified Paths: -------------- pytrainer/trunk/pytrainer/extensions/googlemaps.py pytrainer/trunk/pytrainer/extensions/osm.py pytrainer/trunk/pytrainer/gui/windowmain.py pytrainer/trunk/pytrainer/lib/activity.py pytrainer/trunk/pytrainer/main.py Modified: pytrainer/trunk/pytrainer/extensions/googlemaps.py =================================================================== --- pytrainer/trunk/pytrainer/extensions/googlemaps.py 2010-08-26 03:46:42 UTC (rev 609) +++ pytrainer/trunk/pytrainer/extensions/googlemaps.py 2010-09-10 01:55:13 UTC (rev 610) @@ -49,39 +49,36 @@ polyline = [] list_values = activity.tracks - if list_values != []: - if len(list_values) > 0: - minlat, minlon = float(list_values[0][4]),float(list_values[0][5]) - maxlat=minlat - maxlon=minlon - for i in list_values: - lat, lon = float(i[4]), float(i[5]) - minlat = min(minlat, lat) - maxlat = max(maxlat, lat) - minlon = min(minlon, lon) - maxlon = max(maxlon, lon) - pointlist.append((lat,lon)) - polyline.append("new google.maps.LatLng(%s, %s)" % (lat, lon)) - logging.debug("minlat: %s, maxlat: %s" % (minlat, maxlat)) - logging.debug("minlon: %s, maxlon: %s" % (minlon, maxlon)) - points,levels = Points.encodePoints(pointlist) - points = points.replace("\\","\\\\") - if self.pytrainer_main.startup_options.gm3: - logging.debug("Using Google Maps version 3 API") - laps = activity.laps - timeHours = int(activity.time) / 3600 - timeMin = (float(activity.time) / 3600.0 - timeHours) * 60 - time = "%d%s %02d%s" % (timeHours, _("h"), timeMin, _("min")) - startinfo = "<div class='info_content'>%s: %s</div>" % (activity.sport_name, activity.title) - finishinfo = "<div class='info_content'>%s: %s<br>%s: %s%s</div>" % (_("Time"), time, _("Distance"), activity.distance, activity.distance_unit) - startinfo = startinfo.encode('ascii', 'xmlcharrefreplace') #Encode for html - finishinfo = finishinfo.encode('ascii', 'xmlcharrefreplace') #Encode for html - self.createHtml_api3(polyline, minlat, minlon, maxlat, maxlon, startinfo, finishinfo, laps) - else: - logging.debug("Using Google Maps version 2 API") - self.createHtml(points,levels,pointlist[0]) + if list_values is not None and list_values != [] and len(list_values) > 0: + minlat, minlon = float(list_values[0][4]),float(list_values[0][5]) + maxlat=minlat + maxlon=minlon + for i in list_values: + lat, lon = float(i[4]), float(i[5]) + minlat = min(minlat, lat) + maxlat = max(maxlat, lat) + minlon = min(minlon, lon) + maxlon = max(maxlon, lon) + pointlist.append((lat,lon)) + polyline.append("new google.maps.LatLng(%s, %s)" % (lat, lon)) + logging.debug("minlat: %s, maxlat: %s" % (minlat, maxlat)) + logging.debug("minlon: %s, maxlon: %s" % (minlon, maxlon)) + points,levels = Points.encodePoints(pointlist) + points = points.replace("\\","\\\\") + if self.pytrainer_main.startup_options.gm3: + logging.debug("Using Google Maps version 3 API") + laps = activity.laps + timeHours = int(activity.time) / 3600 + timeMin = (float(activity.time) / 3600.0 - timeHours) * 60 + time = "%d%s %02d%s" % (timeHours, _("h"), timeMin, _("min")) + startinfo = "<div class='info_content'>%s: %s</div>" % (activity.sport_name, activity.title) + finishinfo = "<div class='info_content'>%s: %s<br>%s: %s%s</div>" % (_("Time"), time, _("Distance"), activity.distance, activity.distance_unit) + startinfo = startinfo.encode('ascii', 'xmlcharrefreplace') #Encode for html + finishinfo = finishinfo.encode('ascii', 'xmlcharrefreplace') #Encode for html + self.createHtml_api3(polyline, minlat, minlon, maxlat, maxlon, startinfo, finishinfo, laps) else: - self.createErrorHtml() + logging.debug("Using Google Maps version 2 API") + self.createHtml(points,levels,pointlist[0]) else: self.createErrorHtml() return self.htmlfile Modified: pytrainer/trunk/pytrainer/extensions/osm.py =================================================================== --- pytrainer/trunk/pytrainer/extensions/osm.py 2010-08-26 03:46:42 UTC (rev 609) +++ pytrainer/trunk/pytrainer/extensions/osm.py 2010-09-10 01:55:13 UTC (rev 610) @@ -35,26 +35,23 @@ polyline = [] list_values = activity.tracks - if list_values != []: - if len(list_values) > 0: - for i in list_values: - lat, lon = float(i[4]), float(i[5]) - pointlist.append((lat,lon)) - polyline.append("[%s, %s]" % (lon, lat)) - points,levels = Points.encodePoints(pointlist) - points = points.replace("\\","\\\\") - laps = activity.laps - timeHours = int(activity.time) / 3600 - timeMin = (float(activity.time) / 3600.0 - timeHours) * 60 - time = "%d%s %02d%s" % (timeHours, _("h"), timeMin, _("min")) - startinfo = "<div class='info_content'>%s: %s</div>" % (activity.sport_name, activity.title) - finishinfo = "<div class='info_content'>%s: %s<br>%s: %s%s</div>" % (_("Time"), time, _("Distance"), activity.distance, activity.distance_unit) - startinfo = startinfo.encode('ascii', 'xmlcharrefreplace') #Encode for html - finishinfo = finishinfo.encode('ascii', 'xmlcharrefreplace') #Encode for html + if list_values is not None and list_values != [] and len(list_values) > 0: + for i in list_values: + lat, lon = float(i[4]), float(i[5]) + pointlist.append((lat,lon)) + polyline.append("[%s, %s]" % (lon, lat)) + points,levels = Points.encodePoints(pointlist) + points = points.replace("\\","\\\\") + laps = activity.laps + timeHours = int(activity.time) / 3600 + timeMin = (float(activity.time) / 3600.0 - timeHours) * 60 + time = "%d%s %02d%s" % (timeHours, _("h"), timeMin, _("min")) + startinfo = "<div class='info_content'>%s: %s</div>" % (activity.sport_name, activity.title) + finishinfo = "<div class='info_content'>%s: %s<br>%s: %s%s</div>" % (_("Time"), time, _("Distance"), activity.distance, activity.distance_unit) + startinfo = startinfo.encode('ascii', 'xmlcharrefreplace') #Encode for html + finishinfo = finishinfo.encode('ascii', 'xmlcharrefreplace') #Encode for html - self.createHtml_osm(polyline, startinfo, finishinfo, laps) - else: - self.createErrorHtml() + self.createHtml_osm(polyline, startinfo, finishinfo, laps) else: self.createErrorHtml() return self.htmlfile Modified: pytrainer/trunk/pytrainer/gui/windowmain.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowmain.py 2010-08-26 03:46:42 UTC (rev 609) +++ pytrainer/trunk/pytrainer/gui/windowmain.py 2010-09-10 01:55:13 UTC (rev 610) @@ -270,7 +270,7 @@ logging.debug(">>") self.record_list = activity.tracks self.laps = activity.laps - if len(self.record_list)>0: + if self.record_list is not None and len(self.record_list)>0: self.record_vbox.set_sensitive(1) self.drawarearecord.drawgraph(self.record_list,self.laps) else: @@ -288,7 +288,11 @@ def actualize_heartrategraph(self,activity): logging.debug(">>") - self.drawareaheartrate.drawgraph(activity.tracks) + if activity.tracks is not None and len(activity.tracks)>0: + self.heartrate_vbox_.set_sensitive(1) + self.drawareaheartrate.drawgraph(activity.tracks) + else: + self.heartrate_vbox_.set_sensitive(0) logging.debug("<<") def actualize_hrview(self,activity): @@ -296,7 +300,7 @@ zones = self.pytrainer_main.profile.getZones() record_list = activity.tracks is_karvonen_method = self.pytrainer_main.profile.getValue("pytraining","prf_hrzones_karvonen") - if len(record_list)>0: + if record_list is not None and len(record_list)>0: record_list=record_list[0] self.record_zone1.set_text("%s-%s" %(zones[4][0],zones[4][1])) self.record_zone2.set_text("%s-%s" %(zones[3][0],zones[3][1])) @@ -312,8 +316,8 @@ self.record_zonesmethod.set_text(_("Karvonen method")) else: self.record_zonesmethod.set_text(_("Percentages method")) - else: - self.recordview.set_sensitive(0) + #else: + # self.recordview.set_sensitive(0) logging.debug("<<") def actualize_dayview(self,record_list): @@ -471,7 +475,10 @@ tbeats = tbeats/time_in_min else: tbeats = 0 - average = (km/(time/3600)) + if km > 0: + average = (km/(time/3600)) + else: + average = 0 if maxspeed > 0: #maxpace = 60/maxspeed @@ -546,7 +553,10 @@ tbeats = tbeats/time_in_min else: tbeats = 0 - average = (km/(time/3600)) + if km > 0: + average = (km/(time/3600)) + else: + average = 0 if maxspeed > 0: #maxpace = 60/maxspeed @@ -606,7 +616,10 @@ tbeats = tbeats/time_in_min else: tbeats = 0 - average = (km/(time/3600)) + if km > 0: + average = (km/(time/3600)) + else: + average = 0 if maxspeed > 0: #maxpace = 60/maxspeed Modified: pytrainer/trunk/pytrainer/lib/activity.py =================================================================== --- pytrainer/trunk/pytrainer/lib/activity.py 2010-08-26 03:46:42 UTC (rev 609) +++ pytrainer/trunk/pytrainer/lib/activity.py 2010-09-10 01:55:13 UTC (rev 610) @@ -77,6 +77,7 @@ return self.pytrainer_main = pytrainer_main self.tracks = None + self.tracklist = None self.laps = None self.tree = None self.has_data = False @@ -214,6 +215,10 @@ logging.debug(">>") self.distance_data = {} self.time_data = {} + if self.tracklist is None: + logging.debug("No tracklist in activity") + logging.debug("<<") + return #Profile title=_("Elevation v Distance") xlabel="%s (%s)" % (_('Distance'), self.distance_unit) Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-08-26 03:46:42 UTC (rev 609) +++ pytrainer/trunk/pytrainer/main.py 2010-09-10 01:55:13 UTC (rev 610) @@ -49,7 +49,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#609" + self.version ="1.7.2_svn#610" self.DB_version = 3 #Process command line options self.startup_options = self.get_options() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-08-26 03:46:49
|
Revision: 609 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=609&view=rev Author: jblance Date: 2010-08-26 03:46:42 +0000 (Thu, 26 Aug 2010) Log Message: ----------- Some minor GUI mods for Athlete view Modified Paths: -------------- pytrainer/trunk/glade/pytrainer.glade pytrainer/trunk/pytrainer/gui/drawGraph.py pytrainer/trunk/pytrainer/gui/windowmain.py pytrainer/trunk/pytrainer/lib/graphdata.py pytrainer/trunk/pytrainer/main.py Modified: pytrainer/trunk/glade/pytrainer.glade =================================================================== --- pytrainer/trunk/glade/pytrainer.glade 2010-07-11 04:49:45 UTC (rev 608) +++ pytrainer/trunk/glade/pytrainer.glade 2010-08-26 03:46:42 UTC (rev 609) @@ -5711,7 +5711,205 @@ <widget class="GtkHBox" id="hbox7"> <property name="visible">True</property> <child> - <placeholder/> + <widget class="GtkTable" id="table3"> + <property name="visible">True</property> + <property name="n_rows">6</property> + <property name="n_columns">3</property> + <child> + <widget class="GtkLabel" id="labelAthleteDate"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Date:</property> + </widget> + <packing> + <property name="y_options"></property> + <property name="x_padding">5</property> + <property name="y_padding">5</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="labelAthleteWeight"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Weight:</property> + </widget> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + <property name="x_padding">5</property> + <property name="y_padding">5</property> + </packing> + </child> + <child> + <widget class="GtkButton" id="buttonAlthleteSave"> + <property name="label" translatable="yes">Save</property> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + </widget> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">5</property> + <property name="bottom_attach">6</property> + <property name="x_options">GTK_EXPAND</property> + <property name="y_options"></property> + <property name="x_padding">5</property> + <property name="y_padding">5</property> + </packing> + </child> + <child> + <widget class="GtkEntry" id="entryAthleteDate"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">●</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="x_options">GTK_EXPAND</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <widget class="GtkEntry" id="entryAthleteWeight"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">●</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_EXPAND</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="labelAthleteBF"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Body Fat:</property> + </widget> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options"></property> + <property name="x_padding">5</property> + <property name="y_padding">5</property> + </packing> + </child> + <child> + <widget class="GtkEntry" id="entryAthleteBF"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">●</property> + </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_options">GTK_EXPAND</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <widget class="GtkEntry" id="entryAthleteRestingHR"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">●</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_EXPAND</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="labelRestingHeartRate"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Resting Heart Rate:</property> + </widget> + <packing> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="y_options"></property> + <property name="x_padding">5</property> + <property name="y_padding">5</property> + </packing> + </child> + <child> + <widget class="GtkEntry" id="entryAthleteMaxHR"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">●</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="x_options">GTK_EXPAND</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="labelMaxHeartRate"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Max Heart Rate:</property> + </widget> + <packing> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="y_options"></property> + <property name="x_padding">5</property> + <property name="y_padding">5</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="labelAthleteIdx"> + <property name="visible">True</property> + </widget> + <packing> + <property name="top_attach">5</property> + <property name="bottom_attach">6</property> + <property name="x_options">GTK_EXPAND</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> </child> <child> <widget class="GtkHBox" id="boxAthleteGraph"> @@ -5756,7 +5954,22 @@ <widget class="GtkVBox" id="boxAthleteHistory"> <property name="visible">True</property> <child> - <placeholder/> + <widget class="GtkScrolledWindow" id="scrolledwindow2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">automatic</property> + <property name="vscrollbar_policy">automatic</property> + <child> + <widget class="GtkTreeView" id="athleteTreeView"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <signal name="button_press_event" handler="on_athleteTreeView_button_press_event"/> + </widget> + </child> + </widget> + <packing> + <property name="position">0</property> + </packing> </child> </widget> </child> Modified: pytrainer/trunk/pytrainer/gui/drawGraph.py =================================================================== --- pytrainer/trunk/pytrainer/gui/drawGraph.py 2010-07-11 04:49:45 UTC (rev 608) +++ pytrainer/trunk/pytrainer/gui/drawGraph.py 2010-08-26 03:46:42 UTC (rev 609) @@ -52,20 +52,20 @@ #Debug info - to remove print("drawPlot....") #print datalist - + #Set up drawing area figure = plt.figure() canvas = FigureCanvasGTK(figure) # a gtk.DrawingArea canvas.show() - + #Display title etc + plt.xlabel(datalist.xlabel) + plt.ylabel(datalist.ylabel) + plt.title(datalist.title) #Plot data - data = datalist - plt.plot(data.x_values, data.y_values, linewidth=data.linewidth, color=data.linecolor ) + plt.plot(datalist.x_values, datalist.y_values, linewidth=datalist.linewidth, color=datalist.linecolor ) #Set axis limits - plt.axis([0, data.max_x_value, data.min_y_value, data.max_y_value]) - #Display title etc - plt.xlabel(data.xlabel) - plt.ylabel(data.ylabel) + plt.axis([datalist.min_x_value, datalist.max_x_value, datalist.min_y_value, datalist.max_y_value]) + #axis.set_xlim(0, data.max_x_value) #axis.set_ylim(0, data.max_y_value) Modified: pytrainer/trunk/pytrainer/gui/windowmain.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowmain.py 2010-07-11 04:49:45 UTC (rev 608) +++ pytrainer/trunk/pytrainer/gui/windowmain.py 2010-08-26 03:46:42 UTC (rev 609) @@ -92,6 +92,9 @@ #create the columns for the waypoints treeview column_names=[_("id"),_("Waypoint")] self.create_treeview(self.waypointTreeView,column_names) + #create the columns for the history treeview + column_names=[_("id"),_("Date"),_("Weight"),_("Body Fat %"),_("Resting HR"),_("Max HR")] + self.create_treeview(self.athleteTreeView,column_names) self.fileconf = self.pytrainer_main.profile.confdir+"/listviewmenu.xml" if not os.path.isfile(self.fileconf): self._createXmlListView(self.fileconf) @@ -640,16 +643,37 @@ self.labelName.set_text(athletedata["prf_name"]) self.labelDOB.set_text(athletedata["prf_age"]) self.labelHeight.set_text(athletedata["prf_height"]+" cm") - #TODO + #Setup graph self.grapher = DrawGraph(self, self.pytrainer_main) from pytrainer.lib.graphdata import GraphData datalist = GraphData(title="Weight", xlabel="Date", ylabel="kg") - datalist.addPoints(x=1, y=67) - datalist.addPoints(x=2, y=92) - datalist.addPoints(x=3, y=90) - datalist.addPoints(x=4, y=76) + #TODO + #Create history treeview + history_store = gtk.ListStore( + gobject.TYPE_INT, #index + gobject.TYPE_STRING, #date + gobject.TYPE_STRING, #weight + gobject.TYPE_STRING, #body fat % + gobject.TYPE_INT, #resting HR + gobject.TYPE_INT #max HR + ) + for data_index, data in enumerate(athletedata['history']): + weight = float(data['Weight']) + date = dateutil.parser.parse(data['Date']).date() + + iter = history_store.append() + history_store.set ( + iter, + 0, data_index, + 1, date, #TODO need to sort date graphing... + 2, "%0.2f" % weight, + 3, "%0.2f" % float(data['BF']), + 4, int(data['RestingHR']), + 5, int(data['MaxHR']), + ) + datalist.addPoints(x=date, y=weight) + self.athleteTreeView.set_model(history_store) self.grapher.drawPlot(datalist=datalist, box=self.boxAthleteGraph) - #TODO logging.debug("<<") def actualize_listview(self,record_list): @@ -850,10 +874,47 @@ logging.debug("Reseting graph Y axis with ylimits: %s" % str(y1limits) ) self.drawarearecord.drawgraph(self.record_list,self.laps, y1limits=y1limits, y1color=y1color, y1_linewidth=y1_linewidth) logging.debug("<<") + + def update_athlete_item(self, idx, date, weight, bf, restingHR, maxHR): + logging.debug(">>") + #Prepare vars + idx = str(idx) + date = str(date) + weight = str(weight) + bf = str(bf) + restingHR = str(restingHR) + maxHR = str(maxHR) + #Set vars + self.labelAthleteIdx.set_text(idx) + self.entryAthleteDate.set_text(date) + self.entryAthleteWeight.set_text(weight) + self.entryAthleteBF.set_text(bf) + self.entryAthleteRestingHR.set_text(restingHR) + self.entryAthleteMaxHR.set_text(maxHR) + logging.debug("<<") ###################### ## Lista de eventos ## ###################### + + def on_athleteTreeView_button_press_event(self, treeview, event): + x = int(event.x) + y = int(event.y) + time = event.time + pthinfo = treeview.get_path_at_pos(x, y) + if pthinfo is not None: + path, col, cellx, celly = pthinfo + treeview.grab_focus() + treeview.set_cursor(path, col, 0) + selected,iter = treeview.get_selection().get_selected() + idx = selected.get_value(iter,0) + date = selected.get_value(iter,1) + weight = selected.get_value(iter,2) + bf = selected.get_value(iter,3) + restingHR = selected.get_value(iter,4) + maxHR = selected.get_value(iter,5) + self.update_athlete_item(idx, date, weight, bf, restingHR, maxHR) + #print path, col, cellx, celly def on_window1_configure_event(self, widget, event): #print widget #window widget Modified: pytrainer/trunk/pytrainer/lib/graphdata.py =================================================================== --- pytrainer/trunk/pytrainer/lib/graphdata.py 2010-07-11 04:49:45 UTC (rev 608) +++ pytrainer/trunk/pytrainer/lib/graphdata.py 2010-08-26 03:46:42 UTC (rev 609) @@ -41,6 +41,27 @@ if self.x_values is None: return None return len(self.x_values) + + def __str__(self): + return ''' +Title: %s +ylabel: %s +xlabel: %s +linewidth: %d +linecolor: %s +x min max: %s %s +y min max: %s %s +x values: %s +y values: %s''' % (self.title, + self.ylabel, + self.xlabel, + self.linewidth, + self.linecolor, + str(self.min_x_value), str(self.max_x_value), + str(self.min_y_value), str(self.max_y_value), + str(self.x_values), + str(self.y_values) + ) def addPoints(self, x=None, y=None): if x is None or y is None: @@ -49,11 +70,11 @@ #print('Adding point: %s %s' % (str(x), str(y))) self.x_values.append(x) self.y_values.append(y) - if x > self.max_x_value: + if self.max_x_value is None or x > self.max_x_value: self.max_x_value = x if self.min_x_value is None or x < self.min_x_value: self.min_x_value = x - if y > self.max_y_value: + if self.max_y_value is None or y > self.max_y_value: self.max_y_value = y if self.min_y_value is None or y < self.min_y_value: self.min_y_value = y Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-07-11 04:49:45 UTC (rev 608) +++ pytrainer/trunk/pytrainer/main.py 2010-08-26 03:46:42 UTC (rev 609) @@ -49,7 +49,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#606" + self.version ="1.7.2_svn#609" self.DB_version = 3 #Process command line options self.startup_options = self.get_options() @@ -310,6 +310,14 @@ athletedata['prf_name'] = self.profile.getValue("pytraining","prf_name") athletedata['prf_age'] = self.profile.getValue("pytraining","prf_age") athletedata['prf_height'] = self.profile.getValue("pytraining","prf_height") + athletedata['history'] = ( + {'Date':'2010-01-01', 'Weight':88.8, 'BF':15.0, 'RestingHR':67, 'MaxHR':220}, + {'Date':'2010-02-01', 'Weight':89.8, 'BF':16.0, 'RestingHR':68, 'MaxHR':221}, + {'Date':'2010-03-01', 'Weight':99.1, 'BF':13.0, 'RestingHR':65, 'MaxHR':212}, + {'Date':'2010-04-01', 'Weight':79.5, 'BF':11.0, 'RestingHR':61, 'MaxHR':210}, + {'Date':'2010-05-01', 'Weight':67.2, 'BF':13.0, 'RestingHR':60, 'MaxHR':205}, + {'Date':'2010-06-01', 'Weight':83.8, 'BF':16.0, 'RestingHR':56, 'MaxHR':200}, + ) self.windowmain.actualize_athleteview(athletedata) logging.debug('<<') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-07-11 04:49:52
|
Revision: 608 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=608&view=rev Author: jblance Date: 2010-07-11 04:49:45 +0000 (Sun, 11 Jul 2010) Log Message: ----------- Add cancel button to openstreetmaps extension as per Druzee's patch Modified Paths: -------------- pytrainer/trunk/extensions/openstreetmap/openstreetmap.py Modified: pytrainer/trunk/extensions/openstreetmap/openstreetmap.py =================================================================== --- pytrainer/trunk/extensions/openstreetmap/openstreetmap.py 2010-07-09 19:49:50 UTC (rev 607) +++ pytrainer/trunk/extensions/openstreetmap/openstreetmap.py 2010-07-11 04:49:45 UTC (rev 608) @@ -47,7 +47,11 @@ f.close() #Close f = open(gpx_file, 'r') #Reopen in readonly mode #Get extra info from user - self.display_options_window() + response=self.display_options_window() + if not response==gtk.RESPONSE_ACCEPT: + f.close() + logging.debug("User abort") + return fields = (("description",self.description), ("tags",self.tags), ("visibility",self.visibility)) logging.debug("Added fields: %s" % str(fields)) #Multipart encode the request @@ -93,7 +97,7 @@ logging.debug("<<") def display_options_window(self): - self.prefwindow = gtk.Dialog(title=_("Please add any additional information for this upload"), parent=None, flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) + self.prefwindow = gtk.Dialog(title=_("Please add any additional information for this upload"), parent=None, flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)) self.prefwindow.set_modal(False) table = gtk.Table(1,2) self.entryList = [] @@ -127,10 +131,13 @@ self.prefwindow.vbox.pack_start(table) self.prefwindow.show_all() self.prefwindow.connect("response", self.on_options_ok_clicked) - self.prefwindow.run() + response=self.prefwindow.run() + self.prefwindow.destroy() + return response def on_options_ok_clicked(self, widget, response_id): - widget.destroy() + if not response_id == gtk.RESPONSE_ACCEPT: + return response_id self.description = self.entryList[0].get_text() if self.description == "": logging.debug("A description is required - setting to default") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2010-07-09 19:49:56
|
Revision: 607 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=607&view=rev Author: dgranda Date: 2010-07-09 19:49:50 +0000 (Fri, 09 Jul 2010) Log Message: ----------- Avoid exiting when parsing problem is found, entry skipped Modified Paths: -------------- pytrainer/trunk/plugins/garmintools_full/garmintools_full.py Modified: pytrainer/trunk/plugins/garmintools_full/garmintools_full.py =================================================================== --- pytrainer/trunk/plugins/garmintools_full/garmintools_full.py 2010-07-07 09:56:40 UTC (rev 606) +++ pytrainer/trunk/plugins/garmintools_full/garmintools_full.py 2010-07-09 19:49:50 UTC (rev 607) @@ -146,15 +146,19 @@ xmlString = f.read() fileString = StringIO.StringIO("<root>"+xmlString+"</root>") #parse string as xml - tree = etree.parse(fileString) - #if not self.inDatabase(tree, filename): - if not self.entryExists(tree, filename): - sport = self.getSport(tree) - gpxfile = "%s/garmintools-%d.gpx" % (self.tmpdir, len(importfiles)) - self.createGPXfile(gpxfile, tree) - importfiles.append((gpxfile, sport)) - else: - logging.debug("%s already present. Skipping import." % (filename,) ) + try: + tree = etree.parse(fileString) + #if not self.inDatabase(tree, filename): + if not self.entryExists(tree, filename): + sport = self.getSport(tree) + gpxfile = "%s/garmintools-%d.gpx" % (self.tmpdir, len(importfiles)) + self.createGPXfile(gpxfile, tree) + importfiles.append((gpxfile, sport)) + else: + logging.debug("%s already present. Skipping import." % (filename,) ) + except: + logging.error('Error parsing entry '+ str(filename)) + traceback.print_exc() else: logging.error("File %s failed validation" % (filename)) logging.debug("<<") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-07-07 09:56:47
|
Revision: 606 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=606&view=rev Author: jblance Date: 2010-07-07 09:56:40 +0000 (Wed, 07 Jul 2010) Log Message: ----------- Some initial GUI work for displaying athlete data (e.g. weight) Modified Paths: -------------- pytrainer/trunk/glade/pytrainer.glade pytrainer/trunk/pytrainer/gui/windowmain.py pytrainer/trunk/pytrainer/lib/activity.py pytrainer/trunk/pytrainer/main.py Modified: pytrainer/trunk/glade/pytrainer.glade =================================================================== --- pytrainer/trunk/glade/pytrainer.glade 2010-07-07 08:14:34 UTC (rev 605) +++ pytrainer/trunk/glade/pytrainer.glade 2010-07-07 09:56:40 UTC (rev 606) @@ -135,6 +135,17 @@ </widget> </child> <child> + <widget class="GtkRadioMenuItem" id="athleteview_item"> + <property name="visible">True</property> + <property name="label" translatable="yes"> _Athlete Data</property> + <property name="use_underline">True</property> + <property name="draw_as_radio">True</property> + <property name="group">classicview_item</property> + <signal name="activate" handler="on_athleteview_activate"/> + <accelerator key="a" signal="activate" modifiers="GDK_CONTROL_MASK"/> + </widget> + </child> + <child> <widget class="GtkRadioMenuItem" id="waipointsview_item"> <property name="visible">True</property> <property name="label" translatable="yes"> _Waypoints Editor</property> @@ -5070,7 +5081,6 @@ <child> <widget class="GtkVBox" id="equipview"> <property name="visible">True</property> - <property name="sensitive">True</property> <child> <widget class="GtkHBox" id="hbox6"> <property name="visible">True</property> @@ -5090,7 +5100,6 @@ <child> <widget class="GtkComboBoxEntry" id="record_combovalue1"> <property name="visible">True</property> - <property name="sensitive">True</property> <property name="items" translatable="yes">Running shoes GPS watch T-shirts @@ -5162,12 +5171,8 @@ </widget> </child> <child> - <widget class="GtkLabel" id="label154"> - <property name="visible">True</property> - <property name="label">label154</property> - </widget> + <placeholder/> <packing> - <property name="tab_fill">False</property> <property name="type">tab</property> </packing> </child> @@ -5287,13 +5292,8 @@ </packing> </child> <child> - <widget class="GtkLabel" id="llllll"> - <property name="visible">True</property> - <property name="label">label155</property> - </widget> + <placeholder/> <packing> - <property name="position">1</property> - <property name="tab_fill">False</property> <property name="type">tab</property> </packing> </child> @@ -5570,13 +5570,227 @@ </packing> </child> <child> - <widget class="GtkLabel" id="label-46"> + <placeholder/> + <packing> + <property name="type">tab</property> + </packing> + </child> + <child> + <widget class="GtkHBox" id="athletearea"> <property name="visible">True</property> - <property name="label">label-2147483648</property> + <child> + <widget class="GtkVBox" id="vbox1"> + <property name="visible">True</property> + <child> + <widget class="GtkFrame" id="frame3"> + <property name="visible">True</property> + <property name="label_xalign">0</property> + <child> + <widget class="GtkAlignment" id="alignment9"> + <property name="visible">True</property> + <property name="left_padding">12</property> + <child> + <widget class="GtkTable" id="table2"> + <property name="visible">True</property> + <property name="n_rows">2</property> + <property name="n_columns">4</property> + <child> + <widget class="GtkLabel" id="label21"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Name:</property> + </widget> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="x_padding">5</property> + <property name="y_padding">5</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label22"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Date of birth:</property> + </widget> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="x_padding">5</property> + <property name="y_padding">5</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label23"> + <property name="visible">True</property> + <property name="label" translatable="yes">Height:</property> + </widget> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="x_padding">5</property> + <property name="y_padding">5</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="labelName"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="xpad">5</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="x_padding">10</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="labelDOB"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="xpad">5</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="x_padding">10</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="labelHeight"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="xpad">5</property> + </widget> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="x_padding">10</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label20"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Athlete Details</b></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="type">label_item</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="padding">6</property> + <property name="position">0</property> + </packing> + </child> + <child> + <widget class="GtkFrame" id="frame6"> + <property name="visible">True</property> + <property name="label_xalign">0</property> + <child> + <widget class="GtkAlignment" id="alignment13"> + <property name="visible">True</property> + <property name="left_padding">12</property> + <child> + <widget class="GtkHBox" id="hbox7"> + <property name="visible">True</property> + <child> + <placeholder/> + </child> + <child> + <widget class="GtkHBox" id="boxAthleteGraph"> + <property name="visible">True</property> + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label25"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Detail</b></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="type">label_item</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">5</property> + <property name="position">1</property> + </packing> + </child> + <child> + <widget class="GtkFrame" id="frame5"> + <property name="visible">True</property> + <property name="label_xalign">0</property> + <child> + <widget class="GtkAlignment" id="alignment12"> + <property name="visible">True</property> + <property name="left_padding">12</property> + <child> + <widget class="GtkVBox" id="boxAthleteHistory"> + <property name="visible">True</property> + <child> + <placeholder/> + </child> + </widget> + </child> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label24"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>History</b></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="type">label_item</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">5</property> + <property name="position">2</property> + </packing> + </child> + </widget> + <packing> + <property name="position">0</property> + </packing> + </child> </widget> <packing> - <property name="position">2</property> - <property name="tab_fill">False</property> + <property name="position">3</property> + </packing> + </child> + <child> + <placeholder/> + <packing> <property name="type">tab</property> </packing> </child> @@ -5733,7 +5947,7 @@ <property name="use_stock">False</property> <signal name="activate" handler="on_multiple_merge_ToDo"/> <child internal-child="image"> - <widget class="GtkImage" id="image2"> + <widget class="GtkImage" id="image3"> <property name="visible">True</property> <property name="icon_name">document-properties</property> </widget> Modified: pytrainer/trunk/pytrainer/gui/windowmain.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowmain.py 2010-07-07 08:14:34 UTC (rev 605) +++ pytrainer/trunk/pytrainer/gui/windowmain.py 2010-07-07 09:56:40 UTC (rev 606) @@ -44,6 +44,8 @@ from pytrainer.extensions.mapviewer import MapViewer from pytrainer.extensions.waypointeditor import WaypointEditor +from pytrainer.gui.drawGraph import DrawGraph + class Main(SimpleGladeApp): def __init__(self, data_path = None, parent = None, version = None, gpxDir = None): def url_hook(dialog, url): @@ -633,6 +635,23 @@ self.drawareayear.drawgraph(record_list) logging.debug("<<") + def actualize_athleteview(self, athletedata): + logging.debug(">>") + self.labelName.set_text(athletedata["prf_name"]) + self.labelDOB.set_text(athletedata["prf_age"]) + self.labelHeight.set_text(athletedata["prf_height"]+" cm") + #TODO + self.grapher = DrawGraph(self, self.pytrainer_main) + from pytrainer.lib.graphdata import GraphData + datalist = GraphData(title="Weight", xlabel="Date", ylabel="kg") + datalist.addPoints(x=1, y=67) + datalist.addPoints(x=2, y=92) + datalist.addPoints(x=3, y=90) + datalist.addPoints(x=4, y=76) + self.grapher.drawPlot(datalist=datalist, box=self.boxAthleteGraph) + #TODO + logging.debug("<<") + def actualize_listview(self,record_list): logging.debug(">>") #recod list tiene: @@ -851,7 +870,7 @@ #Hide options self.hpaned1.set_position(0) self.buttonShowOptions.set_tooltip_text(_('Show graph display options') ) - logging.debug('Position: %d' % self.hpaned1.get_position() ) + #logging.debug('Position: %d' % self.hpaned1.get_position() ) logging.debug('Position set: %s' % self.hpaned1.get_property('position-set') ) def on_buttonRedrawMap_clicked(self, widget): @@ -1013,19 +1032,29 @@ def on_classicview_activate(self,widget): self.waypointarea.hide() self.listarea.hide() + self.athletearea.hide() self.selected_view = "record" self.classicarea.show() def on_listview_activate(self,widget): self.waypointarea.hide() self.classicarea.hide() + self.athletearea.hide() self.selected_view = "listview" self.parent.refreshListView() self.listarea.show() + def on_athleteview_activate(self,widget): + self.waypointarea.hide() + self.classicarea.hide() + self.listarea.hide() + self.parent.refreshAthleteView() + self.athletearea.show() + def on_waypointsview_activate(self,widget): self.listarea.hide() self.classicarea.hide() + self.athletearea.hide() self.parent.refreshWaypointView() self.waypointarea.show() Modified: pytrainer/trunk/pytrainer/lib/activity.py =================================================================== --- pytrainer/trunk/pytrainer/lib/activity.py 2010-07-07 08:14:34 UTC (rev 605) +++ pytrainer/trunk/pytrainer/lib/activity.py 2010-07-07 09:56:40 UTC (rev 606) @@ -245,6 +245,7 @@ for track in self.tracklist: try: pace = 60/track['velocity'] + #pace = 0 if pace > 90 else pace except: pace = 0 if self.us_system: Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-07-07 08:14:34 UTC (rev 605) +++ pytrainer/trunk/pytrainer/main.py 2010-07-07 09:56:40 UTC (rev 606) @@ -49,7 +49,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#603" + self.version ="1.7.2_svn#606" self.DB_version = 3 #Process command line options self.startup_options = self.get_options() @@ -304,6 +304,15 @@ self.windowmain.actualize_calendar(record_list) logging.debug('<<') + def refreshAthleteView(self): + logging.debug('>>') + athletedata = {} + athletedata['prf_name'] = self.profile.getValue("pytraining","prf_name") + athletedata['prf_age'] = self.profile.getValue("pytraining","prf_age") + athletedata['prf_height'] = self.profile.getValue("pytraining","prf_height") + self.windowmain.actualize_athleteview(athletedata) + logging.debug('<<') + def refreshListView(self): logging.debug('>>') record_list = self.record.getAllRecordList() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-07-07 08:14:44
|
Revision: 605 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=605&view=rev Author: jblance Date: 2010-07-07 08:14:34 +0000 (Wed, 07 Jul 2010) Log Message: ----------- Update description of garmintools plugin as per Druzee's suggestion Modified Paths: -------------- pytrainer/trunk/plugins/garmintools/conf.xml Modified: pytrainer/trunk/plugins/garmintools/conf.xml =================================================================== --- pytrainer/trunk/plugins/garmintools/conf.xml 2010-07-05 09:43:47 UTC (rev 604) +++ pytrainer/trunk/plugins/garmintools/conf.xml 2010-07-07 08:14:34 UTC (rev 605) @@ -1,10 +1,10 @@ <?xml version="1.0" ?> -<pytrainer-plugin - name="Garmintools dump file import" - description="Import your records from a dump file generated by Garmintools" +<pytrainer-plugin + name="Garmintools dump file import" + description="Import your records from a dump file generated by Garmintools" plugincode="garmintools" - pluginbutton="Import from file: Garmintools dump" - executable="garmintools" + pluginbutton="Import from file: Garmintools dump (.xml)" + executable="garmintools" > <conf-values variable="Force_sport_to" value=""/> </pytrainer-plugin> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-07-05 09:43:53
|
Revision: 604 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=604&view=rev Author: jblance Date: 2010-07-05 09:43:47 +0000 (Mon, 05 Jul 2010) Log Message: ----------- Fix to garmintools_full to make progress bar work - thanks to Druzee Modified Paths: -------------- pytrainer/trunk/plugins/garmintools_full/garmintools_full.py Modified: pytrainer/trunk/plugins/garmintools_full/garmintools_full.py =================================================================== --- pytrainer/trunk/plugins/garmintools_full/garmintools_full.py 2010-07-05 09:42:15 UTC (rev 603) +++ pytrainer/trunk/plugins/garmintools_full/garmintools_full.py 2010-07-05 09:43:47 UTC (rev 604) @@ -80,7 +80,7 @@ numError = self.getDeviceInfo() if numError >= 0: #TODO Remove Zenity below - outgps = commands.getstatusoutput("garmin_save_runs | zenity --progress --pulsate --text='Loading Data' auto-close") + outgps = commands.getstatusoutput("garmin_save_runs -v| zenity --progress --pulsate --text='Loading Data' --auto-close") if outgps[0]==0: # now we should have a lot of gmn (binary) files under $GARMIN_SAVE_RUNS foundFiles = self.searchFiles(self.tmpdir, "gmn") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-07-05 09:42:21
|
Revision: 603 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=603&view=rev Author: jblance Date: 2010-07-05 09:42:15 +0000 (Mon, 05 Jul 2010) Log Message: ----------- Fix for pressing ESC during file open dialog Modified Paths: -------------- pytrainer/trunk/pytrainer/gui/dialogs.py pytrainer/trunk/pytrainer/main.py Modified: pytrainer/trunk/pytrainer/gui/dialogs.py =================================================================== --- pytrainer/trunk/pytrainer/gui/dialogs.py 2010-07-05 09:27:38 UTC (rev 602) +++ pytrainer/trunk/pytrainer/gui/dialogs.py 2010-07-05 09:42:15 UTC (rev 603) @@ -1,6 +1,6 @@ #!/usr/bin/env python -#Copyright (C) +#Copyright (C) #This program is free software; you can redistribute it and/or #modify it under the terms of the GNU General Public License @@ -23,7 +23,8 @@ class fileChooserDialog(): def __init__(self, title = "Choose a file", multiple = False): - dialog = gtk.FileChooserDialog(title, None, gtk.FILE_CHOOSER_ACTION_OPEN,(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) + self.inputfiles = None + dialog = gtk.FileChooserDialog(title, None, gtk.FILE_CHOOSER_ACTION_OPEN,(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) dialog.set_default_response(gtk.RESPONSE_OK) dialog.set_select_multiple(multiple) response = dialog.run() Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-07-05 09:27:38 UTC (rev 602) +++ pytrainer/trunk/pytrainer/main.py 2010-07-05 09:42:15 UTC (rev 603) @@ -49,7 +49,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#601" + self.version ="1.7.2_svn#603" self.DB_version = 3 #Process command line options self.startup_options = self.get_options() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-07-05 09:27:44
|
Revision: 602 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=602&view=rev Author: jblance Date: 2010-07-05 09:27:38 +0000 (Mon, 05 Jul 2010) Log Message: ----------- Remove extra print from wordpress extension Modified Paths: -------------- pytrainer/trunk/extensions/wordpress/wordpress.py Modified: pytrainer/trunk/extensions/wordpress/wordpress.py =================================================================== --- pytrainer/trunk/extensions/wordpress/wordpress.py 2010-07-05 09:21:33 UTC (rev 601) +++ pytrainer/trunk/extensions/wordpress/wordpress.py 2010-07-05 09:27:38 UTC (rev 602) @@ -236,7 +236,6 @@ ''' %( self.sport, self.date, self.distance_unit, self.distance, self.time, self.speed_unit, self.maxspeed, self.speed_unit, self.average, self.pace_unit, self.maxpace,self.pace_unit, self.pace, self.maxbeats, self.beats, self.height_unit, self.upositive, self.height_unit, self.unegative) - print description_table return description_table def createFigureHR(self): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-07-05 09:21:41
|
Revision: 601 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=601&view=rev Author: jblance Date: 2010-07-05 09:21:33 +0000 (Mon, 05 Jul 2010) Log Message: ----------- Update to wordpress extension to publish in US units and data if this preference is selected Modified Paths: -------------- pytrainer/trunk/extensions/openstreetmap/openstreetmap.py pytrainer/trunk/extensions/wordpress/wordpress.py pytrainer/trunk/pytrainer/lib/activity.py pytrainer/trunk/pytrainer/main.py Modified: pytrainer/trunk/extensions/openstreetmap/openstreetmap.py =================================================================== --- pytrainer/trunk/extensions/openstreetmap/openstreetmap.py 2010-07-05 08:36:27 UTC (rev 600) +++ pytrainer/trunk/extensions/openstreetmap/openstreetmap.py 2010-07-05 09:21:33 UTC (rev 601) @@ -19,7 +19,7 @@ self.tags = "" self.visibility = "private" - def run(self, id): + def run(self, id, activity=None): #TODO Convert to use activity... logging.debug(">>") uri = "http://api.openstreetmap.org/api/0.6/gpx/create" #URI for uploading traces to OSM if 'username' not in self.options or self.options['username'] == "" or 'password' not in self.options or self.options['password'] == "": @@ -50,7 +50,7 @@ self.display_options_window() fields = (("description",self.description), ("tags",self.tags), ("visibility",self.visibility)) logging.debug("Added fields: %s" % str(fields)) - #Multipart encode the request + #Multipart encode the request boundary, body = self.multipart_encode(fields=fields, files=(("file", f),)) content_type = 'multipart/form-data; boundary=%s' % boundary #Finished with the file so close it @@ -68,7 +68,7 @@ md.set_title(_("Openstreetmap Extension Processing")) md.set_modal(True) md.show() - while gtk.events_pending(): # This allows the GUI to update + while gtk.events_pending(): # This allows the GUI to update gtk.main_iteration() # before completion of this entire action logging.debug("before request posting") #POST request to OSM @@ -91,44 +91,44 @@ else: logging.error("GPX file: %s NOT found!!!" % (gpx_file)) logging.debug("<<") - + def display_options_window(self): self.prefwindow = gtk.Dialog(title=_("Please add any additional information for this upload"), parent=None, flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) self.prefwindow.set_modal(False) table = gtk.Table(1,2) self.entryList = [] - #Add description + #Add description label = gtk.Label("<b>Description</b>") label.set_use_markup(True) entry = gtk.Entry() self.entryList.append(entry) - table.attach(label,0,1,0,1) + table.attach(label,0,1,0,1) table.attach(entry,1,2,0,1) #Add tags label = gtk.Label("<b>Tags</b>") label.set_use_markup(True) entry = gtk.Entry() - self.entryList.append(entry) + self.entryList.append(entry) table.attach(label,0,1,1,2) table.attach(entry,1,2,1,2) #Add visibility label = gtk.Label("<b>Visibility</b>") label.set_use_markup(True) combobox = gtk.combo_box_new_text() - combobox.append_text("private") + combobox.append_text("private") combobox.append_text("public") - combobox.append_text("trackable") + combobox.append_text("trackable") combobox.append_text("identifiable") combobox.set_active(0) table.attach(combobox,1,2,2,3) - self.entryList.append(combobox) + self.entryList.append(combobox) table.attach(label,0,1,2,3) #Buld dialog and show self.prefwindow.vbox.pack_start(table) self.prefwindow.show_all() self.prefwindow.connect("response", self.on_options_ok_clicked) self.prefwindow.run() - + def on_options_ok_clicked(self, widget, response_id): widget.destroy() self.description = self.entryList[0].get_text() @@ -138,7 +138,7 @@ self.tags = self.entryList[1].get_text() self.visibility = self.entryList[2].get_active_text() logging.debug("Description: %s, tags: %s, visibility: %s" % ( self.description, self.tags, self.visibility) ) - + def multipart_encode(self, fields, files, boundary = None, buffer = None): ''' Multipart encode data for posting Modified: pytrainer/trunk/extensions/wordpress/wordpress.py =================================================================== --- pytrainer/trunk/extensions/wordpress/wordpress.py 2010-07-05 08:36:27 UTC (rev 600) +++ pytrainer/trunk/extensions/wordpress/wordpress.py 2010-07-05 09:21:33 UTC (rev 601) @@ -37,14 +37,14 @@ self.options = options self.conf_dir = conf_dir - def run(self, id): + def run(self, id, activity=None): #Show user something is happening msg = _("Posting to Wordpress blog") md = gtk.MessageDialog(self.pytrainer_main.windowmain.window1, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO, gtk.BUTTONS_NONE, msg) md.set_title(_("Wordpress Extension Processing")) md.set_modal(True) md.show() - while gtk.events_pending(): # This allows the GUI to update + while gtk.events_pending(): # This allows the GUI to update gtk.main_iteration() # before completion of this entire action logging.debug("before request posting") options = self.options @@ -53,11 +53,12 @@ self.password = options["wordpresspass"] self.gpxfile = "%s/gpx/%s.gpx" %(self.conf_dir,id) self.googlekey = options["googlekey"] - self.idrecord = id #options.idrecord + self.idrecord = id + self.activity = activity self.wordpresscategory = options["wordpresscategory"] - debug_msg = "%s, %s, %s, %s, %s, %s" % (self.wordpressurl, self.user, self.gpxfile, self.googlekey, self.idrecord, self.wordpresscategory) + debug_msg = "%s, %s, %s, %s, %s, %s" % (self.wordpressurl, self.user, self.gpxfile, self.googlekey, self.idrecord, self.wordpresscategory) logging.debug(debug_msg) - try: + try: self.wp = wordpresslib.WordPressClient(self.wordpressurl, self.user, self.password) #TODO remove need for wordpresslib?? self.error = False except: @@ -66,58 +67,59 @@ self.loadRecordInfo() if self.title is None: self.title = "No Title" + blog_table = self.createTable() blog_route = self.createRoute() blog_body = self.createBody() - blog_table = self.createTable() + blog_figureHR = self.createFigureHR() blog_figureStage = self.createFigureStage() blog_foot = self.createFoot() - + self.description = "<![CDATA["+blog_body+blog_table+blog_route+blog_figureHR+blog_figureStage+blog_foot+"]]>" - xmlstuff = '''<methodCall> -<methodName>metaWeblog.newPost</methodName> -<params> -<param> -<value> -<string>MyBlog</string> -</value> -</param> -<param> -<value>%s</value> -</param> -<param> -<value> -<string>%s</string> -</value> -</param> -<param> -<struct> -<member> -<name>categories</name> -<value> -<array> + xmlstuff = '''<methodCall> +<methodName>metaWeblog.newPost</methodName> +<params> +<param> +<value> +<string>MyBlog</string> +</value> +</param> +<param> +<value>%s</value> +</param> +<param> +<value> +<string>%s</string> +</value> +</param> +<param> +<struct> +<member> +<name>categories</name> +<value> +<array> <data> -<value>%s</value> -</data> -</array> -</value> -</member> -<member> -<name>description</name> <value>%s</value> -</member> -<member> -<name>title</name> -<value>%s</value> -</member> -</struct> -</param> +</data> +</array> +</value> +</member> +<member> +<name>description</name> +<value>%s</value> +</member> +<member> +<name>title</name> +<value>%s</value> +</member> +</struct> +</param> <param> <value> <boolean>1</boolean> </value> -</param> -</params> +</param> +</params> </methodCall> ''' % (self.user, self.password, self.wordpresscategory, self.description, self.title) @@ -138,7 +140,7 @@ md.set_modal(False) md.run() md.destroy() - + def createRoute(self): gpxpath = "/tmp/gpstrace.gpx.txt" htmlpath = "/tmp/index.html" #TODO fix to use correct tmp dir @@ -150,8 +152,8 @@ #create the html file googlemaps.drawMap(self.gpxfile,self.googlekey,htmlpath) #TODO fix to use main googlemaps and remove extensions copy #create the kml file - os.system("gpsbabel -t -i gpx -f %s -o kml,points=0,line_color=ff0000ff -F %s" %(self.gpxfile,kmlpath)) #TODO fix to remove gpsbabel - + os.system("gpsbabel -t -i gpx -f %s -o kml,points=0,line_color=ff0000ff -F %s" %(self.gpxfile,kmlpath)) #TODO fix to remove gpsbabel + #gfile = self.wp.newMediaObject(self.gpxfile) gfile = self.wp.newMediaObject(gpxpath) hfile = self.wp.newMediaObject(htmlpath) @@ -163,28 +165,33 @@ return description_route def loadRecordInfo(self): - date = Date() - record = self.pytrainer_main.record.getrecordInfo(self.idrecord)[0] + #date = Date() + #record = self.pytrainer_main.record.getrecordInfo(self.idrecord)[0] #"sports.name,date,distance,time,beats,comments,average,calories,id_record,title,upositive,unegative,maxspeed,maxpace,pace,maxbeats,date_time_utc,date_time_local", - self.sport = record[0] - self.date = record[1] - self.distance = record[2] - self.time = date.second2time(float(record[3])) - self.beats = record[4] - self.comments = record[5] - self.average = record[6] - self.calories = record[7] - self.title = record[9] - self.upositive = record[10] - self.unegative = record[11] - self.maxspeed = record[12] - self.maxpace = record[13] - self.pace = record[14] - self.maxbeats = record[15] + self.sport = self.activity.sport_name + self.date = self.activity.date + self.distance = self.activity.distance + self.time = "%d:%02d:%02d" % (self.activity.time_tuple) + print self.time + self.beats = self.activity.beats + self.comments = self.activity.comments + self.average = self.activity.average + self.calories = self.activity.calories + self.title = self.activity.title + self.upositive = self.activity.upositive + self.unegative = self.activity.unegative + self.maxspeed = self.activity.maxspeed + self.maxpace = self.activity.maxpace + self.pace = self.activity.pace + self.maxbeats = self.activity.maxbeats + self.distance_unit = self.activity.distance_unit + self.speed_unit = self.activity.speed_unit + self.pace_unit = self.activity.pace_unit + self.height_unit = self.activity.height_unit def createBody(self): - return '''<b> Description: </b><br/>%s<br/>''' %self.comments - + return '''<b> Description: </b><br/>%s<br/>''' %self.activity.comments + def createTable(self): description_table = ''' <br/> @@ -196,22 +203,22 @@ <td>%s</td> </tr> <tr> - <td><strong>Distance:</strong></td> + <td><strong>Distance (%s):</strong></td> + <td>%.2f</td> + <td><strong>Time (hh:mm:ss):</strong></td> <td>%s</td> - <td><strong>Time (hh, mm, ss):</strong></td> - <td>%s</td> </tr> <tr> - <td><strong>Max speed:</strong></td> - <td>%s</td> - <td><strong>Avg speed (km/h):</strong></td> - <td>%s</td> + <td><strong>Max speed (%s):</strong></td> + <td>%.2f</td> + <td><strong>Avg speed (%s):</strong></td> + <td>%.2f</td> </tr> <tr> - <td><strong>Max pace (min/km):</strong></td> - <td>%s</td> - <td><strong>Avg pace (min/km):</strong></td> - <td>%s</td> + <td><strong>Max pace (%s):</strong></td> + <td>%.2f</td> + <td><strong>Avg pace (%s):</strong></td> + <td>%.2f</td> </tr> <tr> <td><strong>Max pulse:</strong></td> @@ -220,13 +227,16 @@ <td>%s</td> </tr> <tr> - <td><strong>Acc elevation +:</strong></td> - <td>%s</td> - <td><strong>Acc elevation -:</strong></td> - <td>%s</td> + <td><strong>Acc elevation (+%s):</strong></td> + <td>%.2f</td> + <td><strong>Acc elevation (-%s):</strong></td> + <td>%.2f</td> </tr> - </table> - ''' %(self.sport,self.date,self.distance,self.time,self.maxspeed,self.average,self.maxpace,self.pace,self.maxbeats,self.beats,self.upositive,self.unegative) + </table> + ''' %( self.sport, self.date, self.distance_unit, self.distance, self.time, self.speed_unit, self.maxspeed, + self.speed_unit, self.average, self.pace_unit, self.maxpace,self.pace_unit, self.pace, + self.maxbeats, self.beats, self.height_unit, self.upositive, self.height_unit, self.unegative) + print description_table return description_table def createFigureHR(self): @@ -251,13 +261,13 @@ def createFoot(self): return ''' <br/><center>Powered by <a href='http://sourceforge.net/projects/pytrainer/'>Pytrainer</a></center>''' - + def createTitle(self): if self.title==None: self.error = True self.log = "A Title must be defined. Please, configure the record properly" return self.title - + def createCategory(self): if self.wordpresscategory==None: self.error = True Modified: pytrainer/trunk/pytrainer/lib/activity.py =================================================================== --- pytrainer/trunk/pytrainer/lib/activity.py 2010-07-05 08:36:27 UTC (rev 600) +++ pytrainer/trunk/pytrainer/lib/activity.py 2010-07-05 09:21:33 UTC (rev 601) @@ -22,6 +22,7 @@ import dateutil.parser from dateutil.tz import * # for tzutc() +from pytrainer.lib.date import Date from pytrainer.lib.gpx import Gpx from pytrainer.lib.graphdata import GraphData from pytrainer.lib.unitsconversor import * @@ -38,6 +39,7 @@ distance_unit - (string) unit to use for distance speed_unit - (string) unit to use for speed height_unit - (string) unit to use for height + pace_unit - (string) unit to use for pace gpx_file - (string) gpx file name gpx - (Gpx class) actual gpx instance sport_name - (string) sport name @@ -45,6 +47,7 @@ title - (string) title of activity date - (string) date of activity time - (int) activity duration in seconds + time_tuple - (tuple) activity duration as hours, min, secs tuple beats - (int) average heartrate for activity maxbeats - (int) maximum heartrate for activity comments - (string) activity comments @@ -136,6 +139,7 @@ self.title = dict['title'] self.date = dict['date'] self.time = self._int(dict['time']) + self.time_tuple = Date().second2time(self.time) self.beats = self._int(dict['beats']) self.comments = dict['comments'] self.calories = self._int(dict['calories']) Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-07-05 08:36:27 UTC (rev 600) +++ pytrainer/trunk/pytrainer/main.py 2010-07-05 09:21:33 UTC (rev 601) @@ -38,15 +38,7 @@ from importdata import Importdata from plugins import Plugins from profile import Profile -#from recordgraph import RecordGraph -#from daygraph import DayGraph -#from weekgraph import WeekGraph -#from monthgraph import MonthGraph -#from yeargraph import YearGraph -#from heartrategraph import HeartRateGraph -#from extensions.mapviewer import MapViewer -#from extensions.waypointeditor import WaypointEditor from gui.windowimportdata import WindowImportdata from gui.windowmain import Main from gui.warning import Warning @@ -57,7 +49,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#600" + self.version ="1.7.2_svn#601" self.DB_version = 3 #Process command line options self.startup_options = self.get_options() @@ -71,11 +63,6 @@ logging.debug('Checking configuration and profile...') self.profile = Profile(self.data_path,self) self.windowmain = None - - #if self.profile.getValue("pytraining","prf_us_system") == "True": #TODO perhaps move to use dict? - # self.prf_us_system = True - #else: - # self.prf_us_system = False self.ddbb = DDBB(self.profile) logging.debug('connecting to DDBB') self.ddbb.connect() @@ -105,9 +92,6 @@ self.loadPlugins() self.loadExtensions() self.windowmain.setup() - #self.windowmain.createGraphs(RecordGraph,DayGraph,WeekGraph, MonthGraph,YearGraph,HeartRateGraph) - #self.windowmain.createMap(MapViewer,self.waypoint) - #self.windowmain.createWaypointEditor(WaypointEditor,self.waypoint, parent=self) self.windowmain.on_calendar_selected(None) self.refreshMainSportList() self.windowmain.run() @@ -206,9 +190,11 @@ def runExtension(self,extension,id): logging.debug('>>') + print("Extension id: %s" % str(id)) + activity = self.activitypool.get_activity(id) txtbutton,pathExtension,type = extension self.extensionClass = self.extension.importClass(pathExtension) - self.extensionClass.run(id) + self.extensionClass.run(id, activity) #if type == "record": # #Si es record le tenemos que crear el googlemaps, el gpx y darle el id de la bbdd # alert = self.extension.runExtension(pathExtension,id) @@ -469,8 +455,6 @@ logging.debug('>>') logging.info('Checking database integrity') self.ddbb.checkDBIntegrity() - #logging.info('Checking configuration file integrity') - #self.profile.checkProfile() logging.info('Setting DB version to: ' + str(self.DB_version)) self.profile.setValue("pytraining","DB_version", str(self.DB_version)) logging.debug('<<') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-07-05 08:36:33
|
Revision: 600 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=600&view=rev Author: jblance Date: 2010-07-05 08:36:27 +0000 (Mon, 05 Jul 2010) Log Message: ----------- Fixes to units handling to change from metric to US without restart Modified Paths: -------------- pytrainer/trunk/pytrainer/activitypool.py pytrainer/trunk/pytrainer/gui/windowmain.py pytrainer/trunk/pytrainer/lib/graphdata.py pytrainer/trunk/pytrainer/main.py pytrainer/trunk/pytrainer/profile.py Modified: pytrainer/trunk/pytrainer/activitypool.py =================================================================== --- pytrainer/trunk/pytrainer/activitypool.py 2010-06-10 09:42:11 UTC (rev 599) +++ pytrainer/trunk/pytrainer/activitypool.py 2010-07-05 08:36:27 UTC (rev 600) @@ -37,6 +37,13 @@ logging.debug("Initialising ActivityPool to size: %d" % size) logging.debug("<<") + def clear_pool(self): + logging.debug(">>") + logging.debug("Clearing ActivityPool") + self.pool = {} + self.pool_queue = [] + logging.debug("<<") + def get_activity(self, id): sid = str(id) if sid in self.pool.keys(): Modified: pytrainer/trunk/pytrainer/gui/windowmain.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowmain.py 2010-06-10 09:42:11 UTC (rev 599) +++ pytrainer/trunk/pytrainer/gui/windowmain.py 2010-07-05 08:36:27 UTC (rev 600) @@ -35,6 +35,15 @@ from pytrainer.extensions.osm import Osm from pytrainer.lib.unitsconversor import * +from pytrainer.recordgraph import RecordGraph +from pytrainer.daygraph import DayGraph +from pytrainer.weekgraph import WeekGraph +from pytrainer.monthgraph import MonthGraph +from pytrainer.yeargraph import YearGraph +from pytrainer.heartrategraph import HeartRateGraph +from pytrainer.extensions.mapviewer import MapViewer +from pytrainer.extensions.waypointeditor import WaypointEditor + class Main(SimpleGladeApp): def __init__(self, data_path = None, parent = None, version = None, gpxDir = None): def url_hook(dialog, url): @@ -97,6 +106,13 @@ else: self.radiobuttonGMap.set_active(1) + def setup(self): + self.createGraphs(RecordGraph,DayGraph,WeekGraph, MonthGraph,YearGraph,HeartRateGraph) + self.createMap(MapViewer,self.pytrainer_main.waypoint) + self.createWaypointEditor(WaypointEditor,self.pytrainer_main.waypoint, parent=self.pytrainer_main) + page = self.notebook.get_current_page() + self.on_page_change(None,None,page) + def set_unified_import(self, status=False): self.menu_importdata.set_sensitive(status) self.parent.testimport = status Modified: pytrainer/trunk/pytrainer/lib/graphdata.py =================================================================== --- pytrainer/trunk/pytrainer/lib/graphdata.py 2010-06-10 09:42:11 UTC (rev 599) +++ pytrainer/trunk/pytrainer/lib/graphdata.py 2010-07-05 08:36:27 UTC (rev 600) @@ -44,7 +44,7 @@ def addPoints(self, x=None, y=None): if x is None or y is None: - logging.debug("Must supply both x and y data points, got x:'%s' y:'%s'" % (str(x), str(y))) + #logging.debug("Must supply both x and y data points, got x:'%s' y:'%s'" % (str(x), str(y))) return #print('Adding point: %s %s' % (str(x), str(y))) self.x_values.append(x) Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-06-10 09:42:11 UTC (rev 599) +++ pytrainer/trunk/pytrainer/main.py 2010-07-05 08:36:27 UTC (rev 600) @@ -38,15 +38,15 @@ from importdata import Importdata from plugins import Plugins from profile import Profile -from recordgraph import RecordGraph -from daygraph import DayGraph -from weekgraph import WeekGraph -from monthgraph import MonthGraph -from yeargraph import YearGraph -from heartrategraph import HeartRateGraph +#from recordgraph import RecordGraph +#from daygraph import DayGraph +#from weekgraph import WeekGraph +#from monthgraph import MonthGraph +#from yeargraph import YearGraph +#from heartrategraph import HeartRateGraph -from extensions.mapviewer import MapViewer -from extensions.waypointeditor import WaypointEditor +#from extensions.mapviewer import MapViewer +#from extensions.waypointeditor import WaypointEditor from gui.windowimportdata import WindowImportdata from gui.windowmain import Main from gui.warning import Warning @@ -57,7 +57,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#598" + self.version ="1.7.2_svn#600" self.DB_version = 3 #Process command line options self.startup_options = self.get_options() @@ -72,10 +72,10 @@ self.profile = Profile(self.data_path,self) self.windowmain = None - if self.profile.getValue("pytraining","prf_us_system") == "True": #TODO perhaps move to use dict? - self.prf_us_system = True - else: - self.prf_us_system = False + #if self.profile.getValue("pytraining","prf_us_system") == "True": #TODO perhaps move to use dict? + # self.prf_us_system = True + #else: + # self.prf_us_system = False self.ddbb = DDBB(self.profile) logging.debug('connecting to DDBB') self.ddbb.connect() @@ -104,9 +104,10 @@ self.importdata = Importdata(data_path, self, self.profile) self.loadPlugins() self.loadExtensions() - self.windowmain.createGraphs(RecordGraph,DayGraph,WeekGraph, MonthGraph,YearGraph,HeartRateGraph) - self.windowmain.createMap(MapViewer,self.waypoint) - self.windowmain.createWaypointEditor(WaypointEditor,self.waypoint, parent=self) + self.windowmain.setup() + #self.windowmain.createGraphs(RecordGraph,DayGraph,WeekGraph, MonthGraph,YearGraph,HeartRateGraph) + #self.windowmain.createMap(MapViewer,self.waypoint) + #self.windowmain.createWaypointEditor(WaypointEditor,self.waypoint, parent=self) self.windowmain.on_calendar_selected(None) self.refreshMainSportList() self.windowmain.run() @@ -244,7 +245,7 @@ #selected,iter = self.windowmain.recordTreeView.get_selection().get_selected() elif view=="week": logging.debug('week view') - date_ini, date_end = self.date.getWeekInterval(date_selected, self.prf_us_system) + date_ini, date_end = self.date.getWeekInterval(date_selected, self.profile.prf_us_system) sport = self.windowmain.getSportSelected() record_list = self.record.getrecordPeriod(date_ini, date_end, sport) self.windowmain.actualize_weekview(record_list, date_ini, date_end) @@ -456,6 +457,8 @@ def editProfile(self): logging.debug('>>') self.profile.editProfile() + self.activitypool.clear_pool() + self.windowmain.setup() logging.debug('<<') def sanityCheck(self): Modified: pytrainer/trunk/pytrainer/profile.py =================================================================== --- pytrainer/trunk/pytrainer/profile.py 2010-06-10 09:42:11 UTC (rev 599) +++ pytrainer/trunk/pytrainer/profile.py 2010-07-05 08:36:27 UTC (rev 600) @@ -216,6 +216,8 @@ #Added a property, so update config if config_needs_update: self.setProfile(config) + #Set shorthand var for units of measurement + self.prf_us_system = True if config["prf_us_system"] == "True" else False return config except Exception as e: logging.error("Error parsing file: %s. Exiting" % config_file) @@ -325,6 +327,7 @@ logging.debug("setting data values") profilewindow.setValues(self.configuration) profilewindow.run() + self.configuration = self._parse_config_file(self.config_file) logging.debug("<<") def actualize_mainsportlist(self): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jb...@us...> - 2010-06-10 09:42:17
|
Revision: 599 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=599&view=rev Author: jblance Date: 2010-06-10 09:42:11 +0000 (Thu, 10 Jun 2010) Log Message: ----------- New classes for holding and altering data to be graphed Modified Paths: -------------- pytrainer/trunk/pytrainer/lib/activity.py Added Paths: ----------- pytrainer/trunk/pytrainer/gui/drawGraph.py pytrainer/trunk/pytrainer/lib/graphdata.py Added: pytrainer/trunk/pytrainer/gui/drawGraph.py =================================================================== --- pytrainer/trunk/pytrainer/gui/drawGraph.py (rev 0) +++ pytrainer/trunk/pytrainer/gui/drawGraph.py 2010-06-10 09:42:11 UTC (rev 599) @@ -0,0 +1,129 @@ +# -*- coding: iso-8859-1 -*- + +#Copyright (C) Fiz Vazquez vu...@si... + +#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 matplotlib +#matplotlib.use('GTK') +from matplotlib.figure import Figure +from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvasGTK +#from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar +import matplotlib.pyplot as plt +#import pylab +import logging + +class DrawGraph: + def __init__(self, parent = None, pytrainer_main = None): + logging.debug('>>') + self.parent = parent + self.pytrainer_main = pytrainer_main + #self.NEARLY_ZERO = 0.0000000000000000000001 + logging.debug('<<') + + def drawPlot(self, datalist = None, box = None): + ''' + Draw a plot style graph + ''' + #data = {'linewidth':3, 'x':(1,2,3), 'y':(3,9,1)} + logging.debug('>>') + if box is None: + logging.error("Must supply a vbox or hbox to display the graph") + return + #Remove existing plot (if any) + for child in box.get_children(): + logging.debug('Removing box child: '+str(child)) + box.remove(child) + if datalist is None: # or len(datalist) == 0: + logging.debug("drawPlot called with no data") + return + #Debug info - to remove + print("drawPlot....") + #print datalist + + #Set up drawing area + figure = plt.figure() + canvas = FigureCanvasGTK(figure) # a gtk.DrawingArea + canvas.show() + + #Plot data + data = datalist + plt.plot(data.x_values, data.y_values, linewidth=data.linewidth, color=data.linecolor ) + #Set axis limits + plt.axis([0, data.max_x_value, data.min_y_value, data.max_y_value]) + #Display title etc + plt.xlabel(data.xlabel) + plt.ylabel(data.ylabel) + #axis.set_xlim(0, data.max_x_value) + #axis.set_ylim(0, data.max_y_value) + + #Display plot + box.pack_start(canvas, True, True) + + return + #(self,xvalues,yvalues,xlabel,ylabel,title,color,zones=None,xzones=None, ylimits=None, y1_linewidth=None): + logging.debug("Type: plot | title: "+str(title)+" | col: "+str(color)+" | xlabel: "+str(xlabel)+" | ylabel: "+str(ylabel)) + logging.debug('xlabel: '+str(xlabel)+' | ylabel: '+str(ylabel)+' | title: '+str(title)) + #self.removeVboxChildren() + i = 0 + for value in xvalues: + if i<1: + axis = figure.add_subplot(111) + line = axis.plot(xvalues[i],yvalues[i], color=color[i]) + if y1_linewidth is not None: + line[0].set_linewidth(y1_linewidth) + linewidth = line[0].get_linewidth() + + axis.grid(True) + for tl in axis.get_yticklabels(): + tl.set_color('%s' %color[i]) + #Draw zones on graph, eg for each lap + if xzones is not None: + for xzone in xzones: + if xzones.index(xzone) % 2: + zonecolor='b' + else: + zonecolor='g' + axis.axvspan(xzone[0], xzone[1], alpha=0.25, facecolor=zonecolor) + maxX = max(xvalues[i]) + if i>=1: + ax2 = axis.twinx() + ax2.plot(xvalues[i], yvalues[i], color=color[i]) + for tl in ax2.get_yticklabels(): + tl.set_color('%s' %color[i]) + maxXt = max(xvalues[i]) + if maxXt > maxX: + maxX = maxXt + axis.set_xlabel(xlabel[i]) + i+=1 + axis.set_xlim(0, maxX) + + if (len(xvalues)>1): + axis.set_title("%s vs %s" %(ylabel[0],ylabel[1])) + else: + axis.set_title("%s" %(ylabel[0])) + + ylim_min, ylim_max = axis.get_ylim() + if ylimits is not None: + logging.debug("Using ylimits: %s" % str(ylimits)) + if ylimits[0] is not None: + ylim_min = ylimits[0] + if ylimits[1] is not None: + ylim_max = ylimits[1] + axis.set_ylim(ylim_min, ylim_max) + + + logging.debug('<<') + return {'y1_min': ylim_min, 'y1_max': ylim_max, 'y1_linewidth': linewidth} Modified: pytrainer/trunk/pytrainer/lib/activity.py =================================================================== --- pytrainer/trunk/pytrainer/lib/activity.py 2010-06-08 16:58:31 UTC (rev 598) +++ pytrainer/trunk/pytrainer/lib/activity.py 2010-06-10 09:42:11 UTC (rev 599) @@ -23,6 +23,7 @@ from dateutil.tz import * # for tzutc() from pytrainer.lib.gpx import Gpx +from pytrainer.lib.graphdata import GraphData from pytrainer.lib.unitsconversor import * class Activity: @@ -89,6 +90,7 @@ if self.gpx_file is not None: self._init_from_gpx_file() self._init_from_db() + self._init_graph_data() logging.debug("<<") def _set_units(self): @@ -204,6 +206,68 @@ logging.debug("<<") return laps + def _init_graph_data(self): + logging.debug(">>") + self.distance_data = {} + self.time_data = {} + #Profile + title=_("Elevation v Distance") + xlabel="%s (%s)" % (_('Distance'), self.distance_unit) + ylabel="%s (%s)" % (_('Elevation'), self.height_unit) + self.distance_data['elevation'] = GraphData(title=title, xlabel=xlabel, ylabel=ylabel) + title=_("Elevation v Time") + xlabel=_("Time (hours)") + self.time_data['elevation'] = GraphData(title=title,xlabel=xlabel, ylabel=ylabel) + #Speed + title=_("Speed v Distance") + xlabel="%s (%s)" % (_('Distance'), self.distance_unit) + ylabel="%s (%s)" % (_('Speed'), self.speed_unit) + self.distance_data['speed'] = GraphData(title=title, xlabel=xlabel, ylabel=ylabel) + #Pace + title=_("Pace v Distance") + xlabel="%s (%s)" % (_('Distance'), self.distance_unit) + ylabel="%s (%s)" % (_('Pace'), self.pace_unit) + self.distance_data['pace'] = GraphData(title=title, xlabel=xlabel, ylabel=ylabel) + #Heartrate + title=_("Heart Rate v Distance") + xlabel="%s (%s)" % (_('Distance'), self.distance_unit) + ylabel="%s (%s)" % (_('Heart Rate'), _('bpm')) + self.distance_data['hr'] = GraphData(title=title, xlabel=xlabel, ylabel=ylabel) + #Cadence + title=_("Cadence v Distance") + xlabel="%s (%s)" % (_('Distance'), self.distance_unit) + ylabel="%s (%s)" % (_('Cadence'), _('rpm')) + self.distance_data['cadence'] = GraphData(title=title, xlabel=xlabel, ylabel=ylabel) + for track in self.tracklist: + try: + pace = 60/track['velocity'] + except: + pace = 0 + if self.us_system: + self.distance_data['elevation'].addPoints(x=km2miles(track['elapsed_distance']), y=m2feet(track['ele'])) + self.distance_data['speed'].addPoints(x=km2miles(track['elapsed_distance']), y=km2miles(track['velocity'])) + self.distance_data['pace'].addPoints(x=km2miles(track['elapsed_distance']), y=pacekm2miles(pace)) + self.distance_data['hr'].addPoints(x=km2miles(track['elapsed_distance']), y=track['hr']) + self.distance_data['cadence'].addPoints(x=km2miles(track['elapsed_distance']), y=track['cadence']) + self.time_data['elevation'].addPoints(x=track['time_elapsed'], y=m2feet(track['ele'])) + else: + self.distance_data['elevation'].addPoints(x=track['elapsed_distance'], y=track['ele']) + self.distance_data['speed'].addPoints(x=track['elapsed_distance'], y=track['velocity']) + self.distance_data['pace'].addPoints(x=track['elapsed_distance'], y=pace) + self.distance_data['hr'].addPoints(x=track['elapsed_distance'], y=track['hr']) + self.distance_data['cadence'].addPoints(x=track['elapsed_distance'], y=track['cadence']) + self.time_data['elevation'].addPoints(x=track['time_elapsed'], y=track['ele']) + #Remove data with no values + for item in self.distance_data.keys(): + if len(self.distance_data[item]) == 0: + print "No values for %s. Removing...." % item + del self.distance_data[item] + for item in self.time_data.keys(): + if len(self.time_data[item]) == 0: + print "No values for %s. Removing...." % item + del self.time_data[item] + logging.debug("<<") + def _float(self, value): try: result = float(value) Added: pytrainer/trunk/pytrainer/lib/graphdata.py =================================================================== --- pytrainer/trunk/pytrainer/lib/graphdata.py (rev 0) +++ pytrainer/trunk/pytrainer/lib/graphdata.py 2010-06-10 09:42:11 UTC (rev 599) @@ -0,0 +1,63 @@ +# -*- coding: iso-8859-1 -*- + +#Copyright (C) Fiz Vazquez vu...@si... + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public License +#as published by the Free Software Foundation; either version 2 +#of the License, or (at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +import logging + +class GraphData: + ''' + Class to hold data and formating for graphing via matplotlib + ''' + def __init__(self, title=None, ylabel=None, xlabel=None): + logging.debug('>>') + self.title = title + self.ylabel = ylabel + self.xlabel = xlabel + self.x_values = [] + self.y_values = [] + self.linewidth = 1 + self.linecolor = '#ff0000' + self.max_x_value = None + self.min_x_value = None + self.max_y_value = None + self.min_y_value = None + logging.debug('<<') + + def __len__(self): + if self.x_values is None: + return None + return len(self.x_values) + + def addPoints(self, x=None, y=None): + if x is None or y is None: + logging.debug("Must supply both x and y data points, got x:'%s' y:'%s'" % (str(x), str(y))) + return + #print('Adding point: %s %s' % (str(x), str(y))) + self.x_values.append(x) + self.y_values.append(y) + if x > self.max_x_value: + self.max_x_value = x + if self.min_x_value is None or x < self.min_x_value: + self.min_x_value = x + if y > self.max_y_value: + self.max_y_value = y + if self.min_y_value is None or y < self.min_y_value: + self.min_y_value = y + + + + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2010-06-08 16:58:37
|
Revision: 598 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=598&view=rev Author: dgranda Date: 2010-06-08 16:58:31 +0000 (Tue, 08 Jun 2010) Log Message: ----------- Added some structure for equipment view Modified Paths: -------------- pytrainer/trunk/glade/pytrainer.glade pytrainer/trunk/pytrainer/main.py Modified: pytrainer/trunk/glade/pytrainer.glade =================================================================== --- pytrainer/trunk/glade/pytrainer.glade 2010-06-07 17:30:56 UTC (rev 597) +++ pytrainer/trunk/glade/pytrainer.glade 2010-06-08 16:58:31 UTC (rev 598) @@ -5070,10 +5070,69 @@ <child> <widget class="GtkVBox" id="equipview"> <property name="visible">True</property> - <property name="sensitive">False</property> + <property name="sensitive">True</property> <child> + <widget class="GtkHBox" id="hbox6"> + <property name="visible">True</property> + <property name="border_width">5</property> + <property name="spacing">8</property> + <child> + <widget class="GtkLabel" id="label19"> + <property name="visible">True</property> + <property name="label" translatable="yes">Category:</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <widget class="GtkComboBoxEntry" id="record_combovalue1"> + <property name="visible">True</property> + <property name="sensitive">True</property> + <property name="items" translatable="yes">Running shoes +GPS watch +T-shirts +Tyres +Socks</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <placeholder/> + </child> + <child> + <widget class="GtkButton" id="button3"> + <property name="label" translatable="yes">New equipment</property> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="image_position">right</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">3</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> <placeholder/> </child> + <child> + <placeholder/> + </child> </widget> <packing> <property name="position">5</property> @@ -5081,7 +5140,7 @@ </child> <child> <widget class="GtkLabel" id="label15"> - <property name="sensitive">False</property> + <property name="visible">True</property> <property name="label" translatable="yes">Equipment</property> </widget> <packing> Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-06-07 17:30:56 UTC (rev 597) +++ pytrainer/trunk/pytrainer/main.py 2010-06-08 16:58:31 UTC (rev 598) @@ -57,7 +57,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#596" + self.version ="1.7.2_svn#598" self.DB_version = 3 #Process command line options self.startup_options = self.get_options() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2010-06-07 17:31:03
|
Revision: 597 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=597&view=rev Author: dgranda Date: 2010-06-07 17:30:56 +0000 (Mon, 07 Jun 2010) Log Message: ----------- Adding not operative yet 'merge tracks' option in popup menu as for #49 Modified Paths: -------------- pytrainer/trunk/glade/pytrainer.glade Modified: pytrainer/trunk/glade/pytrainer.glade =================================================================== --- pytrainer/trunk/glade/pytrainer.glade 2010-05-27 08:14:50 UTC (rev 596) +++ pytrainer/trunk/glade/pytrainer.glade 2010-06-07 17:30:56 UTC (rev 597) @@ -244,6 +244,7 @@ <widget class="GtkTreeView" id="recordTreeView"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="rubber_banding">True</property> <signal name="button_press_event" handler="on_allRecordTreeView_button_press"/> <signal name="row_activated" handler="on_recordTree_clicked"/> </widget> @@ -5653,7 +5654,7 @@ </child> <child> <widget class="GtkImageMenuItem" id="show_in_classic_view1"> - <property name="label">Show graph in classic view</property> + <property name="label" translatable="yes">Show graph in classic view</property> <property name="visible">True</property> <property name="use_stock">False</property> <signal name="activate" handler="on_showclassic_activate"/> @@ -5666,6 +5667,21 @@ </widget> </child> <child> + <widget class="GtkImageMenuItem" id="merge_tracks"> + <property name="label" translatable="yes">Merge tracks</property> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="use_stock">False</property> + <signal name="activate" handler="on_multiple_merge_ToDo"/> + <child internal-child="image"> + <widget class="GtkImage" id="image2"> + <property name="visible">True</property> + <property name="icon_name">document-properties</property> + </widget> + </child> + </widget> + </child> + <child> <widget class="GtkSeparatorMenuItem" id="separador2"> <property name="visible">True</property> </widget> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2010-05-27 08:14:57
|
Revision: 596 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=596&view=rev Author: dgranda Date: 2010-05-27 08:14:50 +0000 (Thu, 27 May 2010) Log Message: ----------- Changed default colors for profile and cadence in record graph as they were the same that for heartrate Modified Paths: -------------- pytrainer/trunk/pytrainer/main.py pytrainer/trunk/pytrainer/recordgraph.py Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2010-05-26 16:26:52 UTC (rev 595) +++ pytrainer/trunk/pytrainer/main.py 2010-05-27 08:14:50 UTC (rev 596) @@ -57,7 +57,7 @@ class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants - self.version ="1.7.2_svn#593" + self.version ="1.7.2_svn#596" self.DB_version = 3 #Process command line options self.startup_options = self.get_options() Modified: pytrainer/trunk/pytrainer/recordgraph.py =================================================================== --- pytrainer/trunk/pytrainer/recordgraph.py 2010-05-26 16:26:52 UTC (rev 595) +++ pytrainer/trunk/pytrainer/recordgraph.py 2010-05-27 08:14:50 UTC (rev 596) @@ -129,7 +129,7 @@ def get_value_params(self,value): if value == 0: - return _("Distance (km)"),_("Height (m)"),_("Stage Profile"),"#ff0000" + return _("Distance (km)"),_("Height (m)"),_("Stage Profile"),"#000000" if value == 1: return _("Distance (km)"),_("Speed (Km/h)"),_("Speed"),"#00ff00" if value == 2: @@ -137,7 +137,7 @@ if value == 3: return _("Distance (km)"),_("Beats (bpm)"),_("Heart Rate"),"#ff0000" if value == 4: - return _("Distance (km)"),_("Cadence (rpm)"),_("Cadence"),"#ff0000" + return _("Distance (km)"),_("Cadence (rpm)"),_("Cadence"),"#7B3F00" def get_values(self,values, value_selected): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2010-05-26 16:26:58
|
Revision: 595 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=595&view=rev Author: dgranda Date: 2010-05-26 16:26:52 +0000 (Wed, 26 May 2010) Log Message: ----------- Updated ES localization Modified Paths: -------------- pytrainer/trunk/locale/es/LC_MESSAGES/pytrainer.mo pytrainer/trunk/locale/es/LC_MESSAGES/pytrainer_es.po Modified: pytrainer/trunk/locale/es/LC_MESSAGES/pytrainer.mo =================================================================== (Binary files differ) Modified: pytrainer/trunk/locale/es/LC_MESSAGES/pytrainer_es.po =================================================================== --- pytrainer/trunk/locale/es/LC_MESSAGES/pytrainer_es.po 2010-05-26 16:26:17 UTC (rev 594) +++ pytrainer/trunk/locale/es/LC_MESSAGES/pytrainer_es.po 2010-05-26 16:26:52 UTC (rev 595) @@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: pytrainer 1.7.2\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-05-22 10:05+0200\n" -"PO-Revision-Date: 2010-05-22 10:14+0100\n" +"POT-Creation-Date: 2010-05-26 18:18+0200\n" +"PO-Revision-Date: 2010-05-26 18:19+0100\n" "Last-Translator: David Garcia Granda <dg...@gm...>\n" "Language-Team: Spanish <es...@li...>\n" "MIME-Version: 1.0\n" @@ -191,7 +191,7 @@ #: glade/newrecord.glade:223 msgid "Distance (Km):" -msgstr "Distancia (Km):" +msgstr "Distancia (km):" #: glade/newrecord.glade:232 #: glade/newrecord.glade:357 @@ -234,7 +234,7 @@ #: glade/newrecord.glade:524 msgid "Max (km/h):" -msgstr "Punta (Km/h)" +msgstr "Punta (km/h)" #: glade/newrecord.glade:549 msgid "Average (km/h)" @@ -281,7 +281,7 @@ msgstr "Pulsaciones" #: glade/newrecord.glade:903 -#: pytrainer/gui/windowmain.py:744 +#: pytrainer/gui/windowmain.py:745 #: pytrainer/monthgraph.py:77 #: pytrainer/yeargraph.py:78 #: pytrainer/weekgraph.py:123 @@ -513,7 +513,7 @@ msgstr "Basado en porcentajes" #: glade/profile.glade:1562 -#: pytrainer/gui/windowmain.py:290 +#: pytrainer/gui/windowmain.py:291 msgid "Karvonen method" msgstr "Karvonen" @@ -643,7 +643,7 @@ #: glade/pytrainer.glade:275 #: pytrainer/gui/windowmain.py:75 #: pytrainer/gui/windowmain.py:78 -#: pytrainer/gui/windowmain.py:740 +#: pytrainer/gui/windowmain.py:741 #: pytrainer/gui/windowimportdata.py:333 #: pytrainer/gui/windowrecord.py:147 #: pytrainer/gui/windowprofile.py:56 @@ -747,22 +747,22 @@ #: glade/pytrainer.glade:4093 #: glade/pytrainer.glade:4722 #: glade/pytrainer.glade:4738 -#: pytrainer/gui/windowmain.py:307 #: pytrainer/gui/windowmain.py:308 -#: pytrainer/gui/windowmain.py:424 +#: pytrainer/gui/windowmain.py:309 #: pytrainer/gui/windowmain.py:425 -#: pytrainer/gui/windowmain.py:499 +#: pytrainer/gui/windowmain.py:426 #: pytrainer/gui/windowmain.py:500 -#: pytrainer/lib/activity.py:70 +#: pytrainer/gui/windowmain.py:501 +#: pytrainer/lib/activity.py:102 msgid "km/h" -msgstr "Km/h" +msgstr "km/h" #: glade/pytrainer.glade:1039 msgid " <b>Title:</b>" msgstr "<b>Título:</b>" #: glade/pytrainer.glade:1089 -#: pytrainer/gui/windowmain.py:836 +#: pytrainer/gui/windowmain.py:837 msgid "Show graph display options" msgstr "Mostrar opciones del gráfico" @@ -868,7 +868,7 @@ #: glade/pytrainer.glade:1910 msgid "Redraw Map" -msgstr "Mapa original" +msgstr "Restaurar" #: glade/pytrainer.glade:1926 msgid "<small>Display map using:</small>" @@ -973,13 +973,13 @@ #: glade/pytrainer.glade:4212 #: glade/pytrainer.glade:4819 #: glade/pytrainer.glade:4835 -#: pytrainer/gui/windowmain.py:309 #: pytrainer/gui/windowmain.py:310 -#: pytrainer/gui/windowmain.py:426 +#: pytrainer/gui/windowmain.py:311 #: pytrainer/gui/windowmain.py:427 -#: pytrainer/gui/windowmain.py:501 +#: pytrainer/gui/windowmain.py:428 #: pytrainer/gui/windowmain.py:502 -#: pytrainer/lib/activity.py:71 +#: pytrainer/gui/windowmain.py:503 +#: pytrainer/lib/activity.py:103 msgid "min/km" msgstr "min/km" @@ -1135,18 +1135,18 @@ msgstr "Kilómetros" #: pytrainer/gui/windowmain.py:78 -#: pytrainer/gui/windowmain.py:737 +#: pytrainer/gui/windowmain.py:738 msgid "Title" msgstr "Título" #: pytrainer/gui/windowmain.py:78 -#: pytrainer/gui/windowmain.py:738 +#: pytrainer/gui/windowmain.py:739 #: pytrainer/gui/dialogselecttrack.py:40 msgid "Date" msgstr "Fecha" #: pytrainer/gui/windowmain.py:78 -#: pytrainer/gui/windowmain.py:739 +#: pytrainer/gui/windowmain.py:740 #: pytrainer/gui/windowimportdata.py:333 #: pytrainer/gui/windowrecord.py:147 #: pytrainer/extensions/googlemaps.py:76 @@ -1155,19 +1155,19 @@ msgstr "Distancia" #: pytrainer/gui/windowmain.py:78 -#: pytrainer/gui/windowmain.py:741 +#: pytrainer/gui/windowmain.py:742 #: pytrainer/extensions/googlemaps.py:76 #: pytrainer/extensions/osm.py:51 msgid "Time" msgstr "Tiempo" #: pytrainer/gui/windowmain.py:78 -#: pytrainer/gui/windowmain.py:742 +#: pytrainer/gui/windowmain.py:743 msgid "Beats" msgstr "Pulsaciones" #: pytrainer/gui/windowmain.py:78 -#: pytrainer/gui/windowmain.py:743 +#: pytrainer/gui/windowmain.py:744 msgid "Average" msgstr "Media" @@ -1175,67 +1175,67 @@ msgid "Waypoint" msgstr "Waypoint" -#: pytrainer/gui/windowmain.py:292 +#: pytrainer/gui/windowmain.py:293 msgid "Percentages method" msgstr "basado en porcentajes" -#: pytrainer/gui/windowmain.py:300 -#: pytrainer/gui/windowmain.py:417 -#: pytrainer/gui/windowmain.py:492 -#: pytrainer/lib/activity.py:64 +#: pytrainer/gui/windowmain.py:301 +#: pytrainer/gui/windowmain.py:418 +#: pytrainer/gui/windowmain.py:493 +#: pytrainer/lib/activity.py:96 msgid "miles" msgstr "millas" -#: pytrainer/gui/windowmain.py:301 #: pytrainer/gui/windowmain.py:302 -#: pytrainer/gui/windowmain.py:418 +#: pytrainer/gui/windowmain.py:303 #: pytrainer/gui/windowmain.py:419 -#: pytrainer/gui/windowmain.py:493 +#: pytrainer/gui/windowmain.py:420 #: pytrainer/gui/windowmain.py:494 -#: pytrainer/lib/activity.py:65 +#: pytrainer/gui/windowmain.py:495 +#: pytrainer/lib/activity.py:97 msgid "miles/h" msgstr "millas/h" -#: pytrainer/gui/windowmain.py:303 #: pytrainer/gui/windowmain.py:304 -#: pytrainer/gui/windowmain.py:420 +#: pytrainer/gui/windowmain.py:305 #: pytrainer/gui/windowmain.py:421 -#: pytrainer/gui/windowmain.py:495 +#: pytrainer/gui/windowmain.py:422 #: pytrainer/gui/windowmain.py:496 -#: pytrainer/lib/activity.py:66 +#: pytrainer/gui/windowmain.py:497 +#: pytrainer/lib/activity.py:98 msgid "min/mile" msgstr "min/milla" -#: pytrainer/gui/windowmain.py:306 -#: pytrainer/gui/windowmain.py:423 -#: pytrainer/gui/windowmain.py:498 -#: pytrainer/lib/activity.py:69 +#: pytrainer/gui/windowmain.py:307 +#: pytrainer/gui/windowmain.py:424 +#: pytrainer/gui/windowmain.py:499 +#: pytrainer/lib/activity.py:101 msgid "km" -msgstr "Km" +msgstr "km" -#: pytrainer/gui/windowmain.py:832 +#: pytrainer/gui/windowmain.py:833 msgid "Hide graph display options" msgstr "Ocultar configuración de visualización gráfica" -#: pytrainer/gui/windowmain.py:1081 +#: pytrainer/gui/windowmain.py:1082 msgid "lap" msgstr "vuelta" -#: pytrainer/gui/windowmain.py:1087 +#: pytrainer/gui/windowmain.py:1088 #: pytrainer/gui/drawArea.py:143 #: pytrainer/extensions/googlemaps.py:74 #: pytrainer/extensions/osm.py:49 msgid "h" msgstr "h" -#: pytrainer/gui/windowmain.py:1087 -#: pytrainer/gui/windowmain.py:1089 -#: pytrainer/lib/activity.py:72 +#: pytrainer/gui/windowmain.py:1088 +#: pytrainer/gui/windowmain.py:1090 +#: pytrainer/lib/activity.py:104 msgid "m" msgstr "m" -#: pytrainer/gui/windowmain.py:1087 -#: pytrainer/gui/windowmain.py:1089 +#: pytrainer/gui/windowmain.py:1088 +#: pytrainer/gui/windowmain.py:1090 msgid "s" msgstr "s" @@ -1421,7 +1421,7 @@ #: pytrainer/daygraph.py:56 #: pytrainer/weekgraph.py:115 msgid "Distance (km)" -msgstr "Distancia (Km)" +msgstr "Distancia (km)" #: pytrainer/recordgraph.py:132 #: pytrainer/daygraph.py:52 @@ -1463,35 +1463,35 @@ msgid "Cadence" msgstr "Cadence" -#: pytrainer/profile.py:167 +#: pytrainer/profile.py:168 msgid "Moderate activity" msgstr "Actividad moderada" -#: pytrainer/profile.py:168 +#: pytrainer/profile.py:169 msgid "Weight Control" msgstr "Control de peso" -#: pytrainer/profile.py:169 +#: pytrainer/profile.py:170 msgid "Aerobic" msgstr "Aeróbico" -#: pytrainer/profile.py:170 +#: pytrainer/profile.py:171 msgid "Anaerobic" msgstr "Anaeróbico" -#: pytrainer/profile.py:171 +#: pytrainer/profile.py:172 msgid "VO2 MAX" msgstr "VO2 máximo" -#: pytrainer/lib/gpx.py:117 +#: pytrainer/lib/gpx.py:119 msgid "No Name" msgstr "Sin nombre" -#: pytrainer/lib/gpx.py:124 +#: pytrainer/lib/gpx.py:126 msgid "No Data" msgstr "Sin datos" -#: pytrainer/lib/activity.py:67 +#: pytrainer/lib/activity.py:99 msgid "feet" msgstr "pies" @@ -1594,11 +1594,11 @@ msgid "Velocity" msgstr "Velocidad" -#: pytrainer/main.py:425 +#: pytrainer/main.py:422 msgid "Delete this database entry?" msgstr "¿Borrar esta entrada de la base de datos?" -#: pytrainer/main.py:439 +#: pytrainer/main.py:436 msgid "Delete this waypoint?" msgstr "¿Borrar este waypoint?" @@ -1676,41 +1676,3 @@ msgid "Wordpress Extension Upload Complete" msgstr "Envío completo a Wordpress" -#~ msgid "label-2147483648" -#~ msgstr " " - -#~ msgid "--valid" -#~ msgstr "--valid" - -#~ msgid "--check" -#~ msgstr "--check" - -#~ msgid "--gmaps2*" -#~ msgstr "--gmaps2*" - -#~ msgid "--testimport" -#~ msgstr "--testimport" - -#~ msgid "window1" -#~ msgstr "Ventana1" - -#~ msgid "00" -#~ msgstr "00" - -#~ msgid "label-2147483647" -#~ msgstr " " - -#~ msgid "000" -#~ msgstr "000" - -#~ msgid "label154" -#~ msgstr " " - -#~ msgid "label155" -#~ msgstr " " - -#~ msgid "label162" -#~ msgstr " " - -#~ msgid "label163" -#~ msgstr " " This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2010-05-26 16:26:26
|
Revision: 594 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=594&view=rev Author: dgranda Date: 2010-05-26 16:26:17 +0000 (Wed, 26 May 2010) Log Message: ----------- Closing empty head tag, thnx to Druzee Modified Paths: -------------- pytrainer/trunk/pytrainer/extensions/googlemaps.py Modified: pytrainer/trunk/pytrainer/extensions/googlemaps.py =================================================================== --- pytrainer/trunk/pytrainer/extensions/googlemaps.py 2010-05-26 07:59:27 UTC (rev 593) +++ pytrainer/trunk/pytrainer/extensions/googlemaps.py 2010-05-26 16:26:17 UTC (rev 594) @@ -336,6 +336,7 @@ content = '''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml"> <head> +</head> <body> No Gpx Data </body> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |