def loadRecordInfo(self): date = Date() record = self.webserviceserver.getRecordInfo(self.idrecord) self.sport = record["sport"] self.date = record["date"] self.distance = record["distance"] self.time = date.second2time(float(record["time"])) self.heure = self.time[0] self.minute = self.time[1] self.seconde = self.time[2] self.beats = record["beats"] self.comments = record["comments"] self.average = record["average"] self.calories = record["calories"] self.title = record["title"] self.upositive = record["upositive"] self.unegative = record["unegative"]
def loadRecordInfo(self): date = Date() record = self.webserviceserver.getRecordInfo(self.idrecord) self.sport = record["sport"] self.date = record["date"] self.distance = record["distance"] self.time = date.second2time(float(record["time"])) self.heure = self.time[0] self.minute = self.time[1] self.seconde = self.time[2] self.beats = record["beats"] self.comments = record["comments"] self.average = record["average"] self.calories = record["calories"] self.title = record["title"] self.upositive = record["upositive"] self.unegative = record["unegative"]
def test_getDate_should_return_valid_date_if_date_is_valid(self): mock_calendar = Mock() start_date = datetime.date(2019, 1, 1) # list of every day in 2019 (non-leap year) and 2020 (leap year) date_list = [start_date + datetime.timedelta(days=x) for x in range(0, 731)] end_date = datetime.date(2019, 12, 31) # test every day in the list for date in date_list: # python3 way : with self.subTest(date=date): try : mock_calendar = Mock() # act as gtk calendar where months are numbered from 0 to 11 attrs = {'get_date.return_value': (date.year, date.month - 1, date.day)} mock_calendar.configure_mock(**attrs) self.assertEqual((datetime.date(date.year, date.month, date.day)), Date(mock_calendar).getDate()) except : self.fail("Failed with date %s-%s-%s" % (date.year, date.month, date.day))
def getDateTime(self, time_): return Date().getDateTime(time_)
def _init_from_db(self): ''' Get activity information from the DB ''' logging.debug(">>") #Get base information cols = ("sports.name", "id_sports", "date", "distance", "time", "beats", "comments", "average", "calories", "id_record", "title", "upositive", "unegative", "maxspeed", "maxpace", "pace", "maxbeats", "date_time_utc", "date_time_local", "sports.max_pace") # outer join on sport id to workaround bug where sport reference is null on records from GPX import db_result = self.pytrainer_main.ddbb.select( "records left outer join sports on records.sport=sports.id_sports", ", ".join(cols), "id_record=\"%s\" " % self.id) if len(db_result) == 1: row = db_result[0] self.sport_name = row[cols.index('sports.name')] if self.sport_name == None: self.sport_name = "" self.sport_id = row[cols.index('id_sports')] self.pace_limit = row[cols.index('sports.max_pace')] if self.pace_limit == 0 or self.pace_limit == "": self.pace_limit = None self.title = row[cols.index('title')] if self.title is None: self.title = "" self.date = row[cols.index('date')] self.time = self._int(row[cols.index('time')]) self.time_tuple = Date().second2time(self.time) self.beats = self._int(row[cols.index('beats')]) self.comments = row[cols.index('comments')] if self.comments is None: self.comments = "" self.calories = self._int(row[cols.index('calories')]) self.id_record = row[cols.index('id_record')] self.maxbeats = self._int(row[cols.index('maxbeats')]) #Sort time.... # ... use local time if available otherwise use date_time_utc and create a local datetime... self.date_time_local = row[cols.index('date_time_local')] self.date_time_utc = row[cols.index('date_time_utc')] if self.date_time_local is not None: #Have a local time stored in DB self.date_time = dateutil.parser.parse(self.date_time_local) self.starttime = self.date_time.strftime("%X") else: #No local time in DB tmpDateTime = dateutil.parser.parse(self.date_time_utc) self.date_time = tmpDateTime.astimezone(tzlocal( )) #datetime with localtime offset (using value from OS) self.starttime = self.date_time.strftime("%X") #Sort data that changes for the US etc #if self.us_system: # self.distance = km2miles(self._float(row[cols.index('distance')])) # self.average = km2miles(self._float(row[cols.index('average')])) # self.upositive = m2feet(self._float(row[cols.index('upositive')])) # self.unegative = m2feet(self._float(row[cols.index('unegative')])) # self.maxspeed = km2miles(self._float(row[cols.index('maxspeed')])) # self.maxpace = pacekm2miles(self._float(row[cols.index('maxpace')])) # self.pace = pacekm2miles(self._float(row[cols.index('pace')])) #else: self.distance = self._float(row[cols.index('distance')]) if not self.distance: self.distance = self.gpx_distance self.average = self._float(row[cols.index('average')]) self.upositive = self._float(row[cols.index('upositive')]) self.unegative = self._float(row[cols.index('unegative')]) self.maxspeed = self._float(row[cols.index('maxspeed')]) self.maxpace = self._float(row[cols.index('maxpace')]) self.pace = self._float(row[cols.index('pace')]) self.has_data = True else: raise Exception("Error - multiple results from DB for id: %s" % self.id) #Get lap information laps = self.pytrainer_main.ddbb.select_dict( "laps", ("id_lap", "record", "elapsed_time", "distance", "start_lat", "start_lon", "end_lat", "end_lon", "calories", "lap_number", "intensity", "avg_hr", "max_hr", "max_speed", "laptrigger", "comments"), "record=\"%s\"" % self.id) if laps is None or laps == [] or len(laps) < 1: #No laps found logging.debug("No laps in DB for record %d" % self.id) if self.gpx_file is not None: laps = self._get_laps_from_gpx() self.laps = laps logging.debug("<<")
def show_treeviewEntries_row(self, row): ''' Show details of treeview entry TODO need to maintain any changes and display those.... ''' logging.debug(">>") self.active_row = row #Get details from stored data #set sport sport = self.activity_data[row]["rcd_sport"] sportPosition = self.getSportPositionByName(sport) if sportPosition is not None: self.rcd_sport.set_active(sportPosition) #Set gpx file name gpx_file = self.activity_data[row]["rcd_gpxfile"] self.setValue("rcd_gpxfile", gpx_file, "%s") #set duration time = Date().time2second( self.activity_data[row] ["rcd_time"]) #TODO Fix to use timeinseconds!! self.setTime(time) #TODO Fix to use timeinseconds!! #Set distance self.setValue("rcd_distance", self.activity_data[row]["rcd_distance"], "%s") #Set comments buffer = self.rcd_comments.get_buffer() start, end = buffer.get_bounds() if "rcd_comments" not in self.activity_data[row]: self.activity_data[row]["rcd_comments"] = "" buffer.set_text(self.activity_data[row]["rcd_comments"]) while gtk.events_pending(): # This allows the GUI to update gtk.main_iteration() # before completion of this entire action if self.activity_data[row]["complete"] is False: #Haven't processed GPX file yet #Blank values not yet known self.setValue("rcd_date", "", "%s") self.setValue("rcd_starttime", "", "%s") self.setValue("rcd_average", "", "%s") self.setValue("rcd_calories", "", "%s") self.setValue("rcd_beats", "", "%s") self.setValue("rcd_upositive", "", "%s") self.setValue("rcd_unegative", "", "%s") self.setValue("rcd_maxvel", "", "%s") self.rcd_maxpace.set_text("") self.rcd_pace.set_text("") self.setValue("rcd_maxbeats", "", "%s") while gtk.events_pending(): # This allows the GUI to update gtk.main_iteration() # before completion of this entire action #Get some info from gpx file self.update_activity_data(row, gpx_file, sport) self.setValue("rcd_distance", self.activity_data[row]["rcd_distance"], "%s") time = Date().time2second(self.activity_data[row]["rcd_time"]) self.setTime(time) self.setValue("rcd_date", self.activity_data[row]["rcd_date"], "%s") self.setValue("rcd_starttime", self.activity_data[row]["rcd_starttime"], "%s") self.setValue("rcd_average", self.activity_data[row]["rcd_average"]) self.setValue("rcd_calories", self.activity_data[row]["rcd_calories"], "%s") self.setValue("rcd_beats", self.activity_data[row]["rcd_beats"], "%s") self.setValue("rcd_upositive", self.activity_data[row]["rcd_upositive"], "%s") self.setValue("rcd_unegative", self.activity_data[row]["rcd_unegative"], "%s") self.setValue("rcd_maxvel", self.activity_data[row]["rcd_maxvel"]) self.rcd_maxpace.set_text(self.activity_data[row]["rcd_maxpace"]) self.rcd_pace.set_text(self.activity_data[row]["rcd_pace"]) self.setValue("rcd_maxbeats", self.activity_data[row]["rcd_maxbeats"], "%s") self.rcd_title.set_text(self.activity_data[row]["rcd_title"]) logging.debug("<<")
def on_accept_clicked(self, widget): logging.debug(">>") if self.mode == "multiple_activities": logging.debug("multiple_activities") #Check for edited data in comments if self.active_row is not None: buffer = self.rcd_comments.get_buffer() start, end = buffer.get_bounds() comments = buffer.get_text(start, end, True).replace("\"", "'") self.activity_data[self.active_row]["rcd_comments"] = comments #Advanced tab items self.activity_data[self.active_row][ "rcd_maxpace"] = self.rcd_maxpace.get_text() self.activity_data[ self.active_row]["rcd_pace"] = self.rcd_pace.get_text() self.activity_data[self.active_row][ "rcd_upositive"] = self.rcd_upositive.get_text() self.activity_data[self.active_row][ "rcd_unegative"] = self.rcd_unegative.get_text() self.activity_data[self.active_row][ "rcd_maxbeats"] = self.rcd_maxbeats.get_text() self.activity_data[ self.active_row]["rcd_beats"] = self.rcd_beats.get_text() self.activity_data[self.active_row][ "rcd_calories"] = self.rcd_calories.get_text() row = 0 for activity in self.activity_data: index = self.activity_data.index(activity) if activity["complete"] is False: #Did not view or modify this record - need to get all the details print "Activity incomplete.. " + activity["rcd_gpxfile"] self.update_activity_data(row, activity["rcd_gpxfile"], activity["rcd_sport"]) activity["rcd_title"] = activity["rcd_title"].replace( "\"", "'") #Add activity to DB etc laps = activity.pop("laps", ()) selected_equipment_ids = self._get_selected_equipment_ids() self.activity_data[index]["db_id"] = self.parent.insertRecord( activity, laps, equipment=selected_equipment_ids) row += 1 logging.debug("Processed %d rows of activity data" % row) else: logging.debug("Single activity") list_options = {} trackSummary = {} list_options["rcd_date"] = self.rcd_date.get_text() list_options["rcd_sport"] = self.rcd_sport.get_active_text() list_options["rcd_distance"] = self.uc.usr2sys_str( 'distance', self.rcd_distance.get_text()) list_options["rcd_beats"] = self.rcd_beats.get_text() list_options["rcd_average"] = self.uc.usr2sys_str( 'speed', self.rcd_average.get_text()) list_options["rcd_calories"] = self.rcd_calories.get_text() list_options["rcd_title"] = self.rcd_title.get_text().replace( "\"", "'") list_options["rcd_gpxfile"] = self.rcd_gpxfile.get_text() list_options["rcd_upositive"] = self.uc.usr2sys_str( 'height', self.rcd_upositive.get_text()) list_options["rcd_unegative"] = self.uc.usr2sys_str( 'height', self.rcd_unegative.get_text()) list_options["rcd_maxbeats"] = self.rcd_maxbeats.get_text() # 2011.11.05 - dgranda # Pace is shown to user in mm:ss format # But pace in database is stored in a mixed way: 4.30 for 4:30 (4.5 in 'decimal'). This needs to be changed!! list_options["rcd_pace"] = self.uc.usr2sys_str( 'pace', self.rcd_pace.get_text().replace(":", ".")) list_options["rcd_maxpace"] = self.uc.usr2sys_str( 'pace', self.rcd_maxpace.get_text().replace(":", ".")) list_options["rcd_maxvel"] = self.uc.usr2sys_str( 'speed', self.rcd_maxvel.get_text()) list_options["rcd_time"] = [ self.rcd_hour.get_value_as_int(), self.rcd_min.get_value_as_int(), self.rcd_second.get_value_as_int() ] buffer = self.rcd_comments.get_buffer() start, end = buffer.get_bounds() comment = buffer.get_text(start, end, True) list_options["rcd_comments"] = comment.replace("\"", "'") selected_equipment_ids = self._get_selected_equipment_ids() # Added to change start time, only activities without GPX+ source file - dgranda 2011/06/10 record_time = self.rcd_starttime.get_text() record_date = self.rcd_date.get_text() localtz = Date().getLocalTZ() date = dateutil.parser.parse(record_date + " " + record_time + " " + localtz) local_date = str(date) utc_date = date.astimezone(tzutc()).strftime("%Y-%m-%dT%H:%M:%SZ") list_options["date_time_utc"] = utc_date list_options["date_time_local"] = local_date if self.mode == "newrecord": logging.debug('Track data: ' + str(list_options)) if list_options["rcd_gpxfile"] != "": logging.info('Adding new activity based on GPX file') self.parent.insertRecord(list_options, None, selected_equipment_ids) else: logging.info('Adding new activity based on provided data') #Manual entry, calculate time info record_time = self.rcd_starttime.get_text() record_date = self.rcd_date.get_text() localtz = Date().getLocalTZ() date = dateutil.parser.parse(record_date + " " + record_time + " " + localtz) local_date = str(date) utc_date = date.astimezone( tzutc()).strftime("%Y-%m-%dT%H:%M:%SZ") list_options["date_time_utc"] = utc_date list_options["date_time_local"] = local_date self.parent.insertRecord(list_options, equipment=selected_equipment_ids) elif self.mode == "editrecord": self.parent.updateRecord(list_options, self.id_record, equipment=selected_equipment_ids) logging.debug("<<") self.close_window()
def on_buttonCSVImport_clicked(self, widget): logging.debug('>>') #Determine values dateCol = self.cbCSVDate.get_active() distanceCol = self.cbCSVDistance.get_active() durationCol = self.cbCSVDuration.get_active() titleCol = self.cbCSVTitle.get_active() sportCol = self.cbCSVSport.get_active() avgspeedCol = self.cbCSVAvgSpeed.get_active() maxspeedCol = self.cbCSVMaxSpeed.get_active() calCol = self.cbCSVCal.get_active() accCol = self.cbCSVAccent.get_active() desCol = self.cbCSVDescent.get_active() hrCol = self.cbCSVHR.get_active() maxHRCol = self.cbCSVMaxHR.get_active() paceCol = self.cbCSVPace.get_active() maxPaceCol = self.cbCSVMaxPace.get_active() commentsCol = self.cbCSVComments.get_active() if dateCol == 0: #Error need to have at least a date self.updateStatusbar(self.statusbarCSVImport, _("ERROR: Must define at least a date column")) return #Import... #Get selected file if not os.path.isfile(self.CSVfilename): return #Read as delimited file csvfile = open(self.CSVfilename, 'rb') reader = csv.reader(csvfile, delimiter=self.delimiter) #Process File for i, row in enumerate(reader): if self.has_header and i==0: #Ignore first row continue if not row: continue data = {} #Determine dates _date = Date().getDateTime(row[dateCol-1]) #year, month, day = date.split("-") date = _date[1].strftime("%Y-%m-%d") zuluDateTime = _date[0].strftime("%Y-%m-%dT%H:%M:%SZ") localDateTime = str(_date[1]) data['date'] = date data['date_time_utc'] = zuluDateTime data['date_time_local'] = localDateTime if distanceCol: try: data['distance'] = locale.atof(row[distanceCol-1]) except: data['distance'] = 0 else: data['distance'] = 0 if durationCol: #calculate duration in sec... try: _duration = row[durationCol-1] except: _duration = 0 if _duration.count(':') == 2: #Have 00:00:00 duration h, m, s = _duration.split(':') try: durationSec = int(h)*3600 + int(m)*60 + int(s) except: logging.debug("Error calculating duration for '%s'" % _duration) durationSec = None else: try: durationSec = locale.atoi(_duration) except: #Unknown duration logging.debug("Could not determine duration for '%s'" % _duration) durationSec = None if durationSec is not None: data['duration'] = durationSec data['time'] = str(durationSec) if titleCol: try: data['title'] = row[titleCol-1] except: pass if self.checkbCSVForceSport.get_active(): sport_id = self.pytrainer_main.record.getSportId(self.comboCSVForceSport.get_active_text(),add=True) data['sport'] = sport_id elif sportCol: #retrieving sport id (adding sport if it doesn't exist yet) sport_id = self.pytrainer_main.record.getSportId(row[sportCol-1],add=True) data['sport'] = sport_id else: self.comboCSVForceSport.set_active(0) sport_id = self.pytrainer_main.record.getSportId(self.comboCSVForceSport.get_active_text(),add=True) data['sport'] = sport_id if avgspeedCol: # try: data['average'] = locale.atof(row[avgspeedCol-1]) except: pass if maxspeedCol: try: data['maxspeed'] = locale.atof(row[maxspeedCol-1]) except: pass if calCol: try: data['calories'] = locale.atoi(row[calCol-1]) except: pass if accCol: try: data['upositive'] = locale.atof(row[accCol-1]) except: pass if desCol: try: data['unegative'] = locale.atof(row[desCol-1]) except: pass if hrCol: try: data['beats'] = locale.atof(row[hrCol-1]) except: pass if maxHRCol: try: data['maxbeats'] = locale.atof(row[maxHRCol-1]) except: pass if paceCol: try: data['pace'] = locale.atof(row[paceCol-1]) except: pass if maxPaceCol: try: data['maxpace'] = locale.atof(row[maxPaceCol-1]) except: pass if commentsCol: try: data['comments'] = row[commentsCol--1] except: pass #Insert into DB logging.debug("Data", data) self.pytrainer_main.ddbb.insert_dict('records', data) #Display message.... self.updateStatusbar(self.statusbarCSVImport, _("Import completed. %d rows processed") % i) #Disable import button self.buttonCSVImport.set_sensitive(0) logging.debug('<<')
def test_getDate_should_raise_ValueError_if_day_is_before_first(self): mock_calendar = Mock() attrs = {'get_date.return_value': (2019, 1, 0)} # 2019-02-00 mock_calendar.configure_mock(**attrs) with self.assertRaises(ValueError): Date(mock_calendar).getDate()
def test_getDate_should_return_valid_date_if_day_is_too_large(self): mock_calendar = Mock() attrs = {'get_date.return_value': (2019, 1, 31)} # 2019-02-31 mock_calendar.configure_mock(**attrs) self.assertEqual(datetime.date(2019,2,28), Date(mock_calendar).getDate())