Esempio n. 1
0
    def parse_open(self, response):
        soup = bs4.BeautifulSoup(response.text)
        tds = soup.select('tr > td')
        data = []

        for td in tds:
            str_td = str(td)
            athlete_match = re.search(self.ATHLETE_ID_REGEX, str_td)
            rank_and_score = re.search(self.RANK_AND_SCORE_REGEX, str_td)
            event_id = re.search(self.EVENT_ID_REGEX, str_td)

            if athlete_match:
                athlete_id = athlete_match.group("athlete_id")
                athlete = Athlete(athlete_id)
            elif self.has_rank_score_and_event(rank_and_score, event_id):
                event_id = event_id.group("event_id")
                rank = rank_and_score.group("rank")
                score = rank_and_score.group("score")
                athlete.set_event(event_id, rank, score)
                if self.verbose:
                    print("Getting event " + event_id + " for " + athlete_id + "\n")

            if event_id == "5":
                data.append(athlete)

        return data
Esempio n. 2
0
    def parse_athlete(self, athlete_id, response):
        soup = bs4.BeautifulSoup(response.text)
        trs = soup.select('tr')
        dl = soup.select('.profile-details dl')
        athlete = Athlete(athlete_id)

        for tr in trs:
            contents = tr.contents
            if len(tr.contents) < 2:
                continue

            exercise = contents[0].getText()
            value = contents[1].getText()

            athlete.set_stat(exercise, value)

        counter = 0
        for content in dl[0].contents:
            counter += 1
            if counter % 2 == 0:
                value = content.getText()
                athlete.set_personal(label, value)
            else:
                label = content.getText()[:-1]

        return athlete
Esempio n. 3
0
def add_athlete(athlete_id, division):
    if Division(division).add_athlete(athlete_id):
        athlete = Athlete(athlete_id)

        return json.dumps(athlete.get())
    else:
        return 'Incorrect gender for Division'
Esempio n. 4
0
    def parse_open(self, response):
        soup = bs4.BeautifulSoup(response.text)
        tds = soup.select('tr > td')
        data = []

        for td in tds:
            str_td = str(td)
            athlete_match = re.search(self.ATHLETE_ID_REGEX, str_td)
            rank_and_score = re.search(self.RANK_AND_SCORE_REGEX, str_td)
            event_id = re.search(self.EVENT_ID_REGEX, str_td)

            if athlete_match:
                athlete_id = athlete_match.group("athlete_id")
                athlete = Athlete(athlete_id)
            elif self.has_rank_score_and_event(rank_and_score, event_id):
                event_id = event_id.group("event_id")
                rank = rank_and_score.group("rank")
                score = rank_and_score.group("score")
                athlete.set_event(event_id, rank, score)
                if self.verbose:
                    print("Getting event " + event_id + " for " + athlete_id +
                          "\n")

            if event_id == "5":
                data.append(athlete)

        return data
Esempio n. 5
0
 def __init__(self):
     self.actions = [
         Actions.up, Actions.down, Actions.right, Actions.left,
         Actions.stick
     ]
     self.initial_state = Soccer_Field(
         Athlete(coordinates=(2, 0), has_possession=False, ID=1),
         Athlete(coordinates=(1, 0), has_possession=True, ID=2))
     self.Nash = defaultdict(lambda: 1)
Esempio n. 6
0
    def __init__(self, filename=None, data_path=None):
        # Based in Django's approach -> http://code.djangoproject.com/svn/django/trunk/django/__init__.py
        self.version = __import__('pytrainer').get_version()
        #Process command line options
        self.startup_options = self.get_options()
        #Setup logging
        self.environment = Environment(platform.get_platform(),
                                       self.startup_options.conf_dir)
        self.environment.create_directories()
        self.set_logging(self.startup_options.log_level,
                         self.startup_options.log_type)
        logging.debug('>>')
        logging.debug("pytrainer version %s" % (self.version))
        self.data_path = data_path
        self.date = Date()
        self.ddbb = None
        # Checking profile
        logging.debug('Checking configuration and profile...')
        self.profile = Profile(self.environment, self.data_path, self)
        self.uc = UC()
        self.windowmain = None
        self.ddbb = DDBB(self.profile, self)
        logging.debug('connecting to DDBB')
        self.ddbb.connect()

        initialize_data(self.ddbb, self.environment.conf_dir)

        self._sport_service = SportService(self.ddbb)
        self.record = Record(self._sport_service, data_path, self)
        self.athlete = Athlete(data_path, self)
        self.stats = Stats(self._sport_service, self)
        pool_size = self.profile.getIntValue("pytraining",
                                             "activitypool_size",
                                             default=1)
        self.activitypool = ActivityPool(self, size=pool_size)
        #preparamos la ventana principal
        self.windowmain = Main(self._sport_service,
                               data_path,
                               self,
                               self.version,
                               gpxDir=self.profile.gpxdir)
        self.date = Date(self.windowmain.calendar)
        self.waypoint = Waypoint(data_path, self)
        self.extension = Extension(data_path, self)
        self.plugins = Plugins(data_path, self)
        self.importdata = Importdata(self._sport_service, data_path, self,
                                     self.profile)
        self.loadPlugins()
        self.loadExtensions()
        self.windowmain.setup()
        self.windowmain.on_calendar_selected(None)
        self.refreshMainSportList()
        self.windowmain.run()
        logging.debug('<<')
Esempio n. 7
0
    def field_state_a2_first(self, athlete1_action, athlete2_action):

        a1_new_position = self.get_new_coordinates(self.athlete1,
                                                   athlete1_action)
        a2_new_position = self.get_new_coordinates(self.athlete2,
                                                   athlete2_action)

        if a1_new_position == a2_new_position:
            both_new_actions_are_the_same = True
        else:
            both_new_actions_are_the_same = False

        # What the field would look like if athlete 2 moved first
        if a2_new_position != self.athlete1.coordinates:
            if self.athlete2.has_possession:
                a2_state_if_a2_first = Athlete(coordinates=a2_new_position,
                                               has_possession=True,
                                               ID=2)
                if both_new_actions_are_the_same:
                    a1_state_if_a2_first = Athlete(
                        coordinates=self.athlete1.coordinates,
                        has_possession=False,
                        ID=1)
                else:
                    a1_state_if_a2_first = Athlete(coordinates=a1_new_position,
                                                   has_possession=False,
                                                   ID=1)
            else:
                if both_new_actions_are_the_same:
                    a2_state_if_a2_first = Athlete(coordinates=a2_new_position,
                                                   has_possession=True,
                                                   ID=2)
                    a1_state_if_a2_first = Athlete(
                        coordinates=self.athlete1.coordinates,
                        has_possession=False,
                        ID=1)
                else:
                    a2_state_if_a2_first = Athlete(coordinates=a2_new_position,
                                                   has_possession=False,
                                                   ID=2)
                    a1_state_if_a2_first = Athlete(coordinates=a1_new_position,
                                                   has_possession=True,
                                                   ID=1)
        else:  #if a2 moves to a1's coordinates..
            a2_state_if_a2_first = Athlete(
                coordinates=self.athlete2.coordinates,
                has_possession=False,
                ID=2)
            a1_state_if_a2_first = Athlete(
                coordinates=self.athlete1.coordinates,
                has_possession=True,
                ID=1)

        new_soccer_field = Soccer_Field(a1_state_if_a2_first,
                                        a2_state_if_a2_first)
        return new_soccer_field
Esempio n. 8
0
    def add_athlete(self, athlete_id):
        athlete = Athlete(athlete_id).get()

        # if 'sex' not in athlete and (athlete['sex'] == self.division_object['sex'] or athlete['sex'] == 'None'):
        Division.remove_athlete_from_all_divisions(athlete_id)
        redisclient.sadd('%s_members' % self.division_id, athlete_id)

        return True
Esempio n. 9
0
def get_coach_data(filename):
    try:
        with open(filename) as f:
            data = f.readline()
            templ = data.strip().split(',')
        return (Athlete(templ.pop(0), templ.pop(0), templ))
    except IOError as ierr:
        print('file error:' + str(ioerr))
        return None
Esempio n. 10
0
def get_coach_data(filename):
    try:
        with open(filename) as player_score:
            data = player_score.readline().strip().split(',')
            result = Athlete(data.pop(0), data.pop(0), data)
            return (result)
    except IOError as err:
        print('IOErroe: ' + str(err))
        return (None)
Esempio n. 11
0
    def parse_athlete(self, athlete_id, response):
        soup = bs4.BeautifulSoup(response.text)
        trs = soup.select('tr')
        dl = soup.select('.profile-details dl')
        athlete = Athlete(athlete_id)

        for tr in trs:
            contents = tr.contents
            if len(tr.contents) < 2:
                continue

            exercise = contents[0].getText()
            value = contents[1].getText()

            athlete.set_stat(exercise, value)

        counter = 0
        for content in dl[0].contents:
            counter += 1
            if counter % 2 == 0:
                value = content.getText()
                athlete.set_personal(label, value)
            else:
                label = content.getText()[:-1]

        return athlete
Esempio n. 12
0
def get_coach_data(filename):
    """
    将指定文件去除不需要的空白符并返回列表。
    参数"filename“,将要转换为列表的文件路径。
    """
    try:
        with open(filename) as fl:
            data = fl.readline().strip().split(',')

        return Athlete(data.pop(0), data.pop(0), data)
    except IOError as err:
        print('File Error\n\t' + str(err))
        return None
Esempio n. 13
0
    def test_Athlete_whenCalledWithAthleteIdInRedis_returnsAthleteRecordFromRedis(
            self):
        with mock.patch('webrequest.getjsonfromurl') as mock_geturl:
            self.setupTestData()
            mock_geturl.return_value = self.test_data['members'][1338208]

            athlete = Athlete('1338208').get()

            mock_geturl.assert_not_called()

            self.assertEqual(athlete['firstname'], 'Brett')
            self.assertEqual(athlete['lastname'], 'J ARCC')
            self.assertEqual(athlete['sex'], 'M')
Esempio n. 14
0
    def get_all(get_athletes=False):
        divisions = {}
        division_list = Division.get_list()

        for division_id in division_list:
            division = Division(division_id).get()

            if get_athletes:
                for member in division['members']:
                    division['members'][member] = Athlete(member).get()

            divisions[division_id] = division

        return divisions
Esempio n. 15
0
 def __init__(self,filename = None, data_path = None):
     #Version constants
     self.version ="1.10.0-dev"
     #Process command line options
     self.startup_options = self.get_options()
     #Setup logging
     self.environment = Environment(platform.get_platform(), self.startup_options.conf_dir)
     self.environment.create_directories()
     self.set_logging(self.startup_options.log_level, self.startup_options.log_type)
     logging.debug('>>')
     logging.debug("PyTrainer version %s" % (self.version))
     self.data_path = data_path
     self.date = Date()
     self.ddbb = None
     # Checking profile
     logging.debug('Checking configuration and profile...')
     self.profile = Profile(self.environment, self.data_path,self)
     self.uc = UC()
     self.windowmain = None
     self.ddbb = DDBB(self.profile, self)
     logging.debug('connecting to DDBB')
     self.ddbb.connect()
     
     initialize_data(self.ddbb, self.environment.conf_dir)
         
     self._sport_service = SportService(self.ddbb)
     self.record = Record(self._sport_service, data_path, self)
     self.athlete = Athlete(data_path,self)
     self.stats = Stats(self._sport_service, self)
     pool_size = self.profile.getIntValue("pytraining","activitypool_size", default=1)
     self.activitypool = ActivityPool(self, size=pool_size)
     #preparamos la ventana principal
     self.windowmain = Main(self._sport_service, data_path,self,self.version, gpxDir=self.profile.gpxdir)
     self.date = Date(self.windowmain.calendar)
     self.waypoint = Waypoint(data_path,self)
     self.extension = Extension(data_path, self)
     self.plugins = Plugins(data_path, self)
     self.importdata = Importdata(self._sport_service, data_path, self, self.profile)
     self.loadPlugins()
     self.loadExtensions()
     self.windowmain.setup()
     self.windowmain.on_calendar_selected(None)
     self.refreshMainSportList()
     self.windowmain.run()
     logging.debug('<<')
Esempio n. 16
0
def token_exchange():
    code = request.args.get('code')

    client_id = redisclient.hget('api', 'client_id')
    client_secret = redisclient.hget('api', 'client_token')

    exch_uri = 'https://www.strava.com/oauth/token'
    data = urlencode({
        'client_id': client_id,
        'client_secret': client_secret,
        'code': code
    }).encode()

    with closing(urlopen(exch_uri, data)) as response:
        user_profile = json.loads(response.read().decode())

        athlete = Athlete(user_profile['athlete']['id']).get()

        return render_template('connected.html', athlete=athlete)
Esempio n. 17
0
    try:
        with open(filename) as fl:
            data = fl.readline().strip().split(',')

        return Athlete(data.pop(0), data.pop(0), data)
    except IOError as err:
        print('File Error\n\t' + str(err))
        return None


james = get_coach_data('.//chapter6//james2.txt')
julie = get_coach_data('.//chapter6//julie2.txt')
mikey = get_coach_data('.//chapter6//mikey2.txt')
sarah = get_coach_data('.//chapter6//sarah2.txt')
print(james.name + "'s fastest times are: " + str(james.top3()))
print(julie.name + "'s fastest times are: " + str(julie.top3()))
print(mikey.name + "'s fastest times are: " + str(mikey.top3()))
print(sarah.name + "'s fastest times are: " + str(sarah.top3()))
# print(james.times)
# james.add_time('0:3')
# print(james.name + "'s fastest times are: " + str(james.top3()))
# print(james.times)
# james.add_times(['3.2', '1:2', '0-1'])
# print(james.name + "'s fastest times are: " + str(james.top3()))
# print(james.times)
vera = Athlete('Vera Vi')
vera.append('1.31')
print(vera.top3())
vera.extend(['2.22', '1-21', '2:22'])
print(vera.top3())
Esempio n. 18
0
    def compile_league(self, league_name, effort_list):
        members = redisclient.smembers(league_name + '_members')
        times = []
        efforts = {}

        # Compile dict of best efforts for each athlete in this league
        for effort in effort_list:
            athlete_id = effort['athlete']['id']

            if str(athlete_id) in members:
                if athlete_id in efforts:
                    if effort['elapsed_time'] >= efforts[athlete_id][
                            'elapsed_time']:
                        continue

                efforts[athlete_id] = effort

        # Enrich with athlete details, and collect list of times for ranking
        for athlete_id, effort in efforts.items():
            athlete = Athlete(athlete_id).get()

            for k, v in athlete.items():
                effort['athlete'][k] = v

            corrected_time = effort['elapsed_time']

            neutralised_times = []
            for key, value in effort['neutralised'].items():
                corrected_time = corrected_time - value
                neutralised_times.append(str(value))

            effort['neutralised_times_formatted'] = ', '.join(
                neutralised_times)

            minutes = int(effort['elapsed_time'] / 60)
            seconds = effort['elapsed_time'] % 60
            effort['elapsed_time_formatted'] = "%d.%02d" % (minutes, seconds)

            minutes = corrected_time / 60
            seconds = corrected_time % 60
            effort['corrected_time'] = corrected_time
            effort['corrected_time_formatted'] = "%d.%02d" % (minutes, seconds)

            start_time_formatted = datetime.strptime(
                effort['start_date_local'], "%Y-%m-%dT%H:%M:%SZ")
            effort['start_time_formatted'] = start_time_formatted.strftime(
                '%a %d/%m, %H:%M')

            times.append(corrected_time)

        times = list(set(times))
        times.sort()
        rank = 1

        # Assign a rank to each effort
        for time in times:
            joint = 0

            for athlete_id, effort in efforts.items():
                if effort['corrected_time'] == time:
                    effort['rank'] = rank
                    effort['points'] = max(11 - rank, 0)
                    joint = joint + 1

            rank = rank + max(joint, 1)

        # s = OrderedDict(sorted(efforts.items(), key=lambda t: t[1]['rank']))

        return efforts
Esempio n. 19
0
    def compile_league(self, league_name, effort_list):
        members = redisclient.smembers(league_name + '_members')
        times = []
        efforts = {}

        # Compile dict of best efforts for each athlete in this league
        for effort in effort_list:
            athlete_id = effort['athlete']['id']

            if str(athlete_id) in members:
                if athlete_id in efforts:
                    if effort['elapsed_time'] >= efforts[athlete_id]['elapsed_time']:
                        continue

                efforts[athlete_id] = effort

        # Enrich with athlete details, and collect list of times for ranking
        for athlete_id, effort in efforts.items():
            athlete = Athlete(athlete_id).get()

            for k, v in athlete.items():
                effort['athlete'][k] = v

            corrected_time = effort['elapsed_time']

            neutralised_times = []
            for key, value in effort['neutralised'].items():
                corrected_time = corrected_time - value
                neutralised_times.append(str(value))

            effort['neutralised_times_formatted'] = ', '.join(neutralised_times)

            minutes = int(effort['elapsed_time'] / 60)
            seconds = effort['elapsed_time'] % 60
            effort['elapsed_time_formatted'] = "%d.%02d" % (minutes, seconds)

            minutes = corrected_time / 60
            seconds = corrected_time % 60
            effort['corrected_time'] = corrected_time
            effort['corrected_time_formatted'] = "%d.%02d" % (minutes, seconds)

            start_time_formatted = datetime.strptime(effort['start_date_local'], "%Y-%m-%dT%H:%M:%SZ")
            effort['start_time_formatted'] = start_time_formatted.strftime('%a %d/%m, %H:%M')

            times.append(corrected_time)

        times = list(set(times))
        times.sort()
        rank = 1

        # Assign a rank to each effort
        for time in times:
            joint = 0

            for athlete_id, effort in efforts.items():
                if effort['corrected_time'] == time:
                    effort['rank'] = rank
                    effort['points'] = max(11 - rank, 0)
                    joint = joint + 1

            rank = rank + max(joint, 1)

        # s = OrderedDict(sorted(efforts.items(), key=lambda t: t[1]['rank']))

        return efforts
Esempio n. 20
0
def createAthlete(data):
    athleteJson = json.loads(data)
    return Athlete(athleteJson.get('id'), athleteJson.get('firstName'),
                   athleteJson.get('secondName'), athleteJson.get('age'),
                   athleteJson.get('disc'), athleteJson.get('club'),
                   athleteJson.get('nationality'))
Esempio n. 21
0
 def test_athlete_male(self):
     male = Athlete("male", birth_year=2000, birth_month=2,
                    weight=50, height=195)
     exam = male.examine(exam_year=2014, exam_month=10)
     self.assertEqual(exam.calendar_age, 176)
     self.assertAlmostEqual(exam.bio_age, 11.752, places=3)
Esempio n. 22
0
    def field_state_a1_first(self, athlete1_action, athlete2_action):

        # update the soccer field if athlete 1 goes first
        a1_new_position = self.get_new_coordinates(self.athlete1,
                                                   athlete1_action)
        a2_new_position = self.get_new_coordinates(self.athlete2,
                                                   athlete2_action)

        if a1_new_position == a2_new_position:
            both_new_actions_are_the_same = True
        else:
            both_new_actions_are_the_same = False

        # What the field would look like if athlete 1 moved first
        '''if the player without the ball moves into the player with the ball, attempting to steal 
        the ball, he cannot.'''
        if a1_new_position != self.athlete2.coordinates:  #if a1's new move is NOT where a2 is...
            if self.athlete1.has_possession:  #AND a1 has possession...
                a1_state_if_a1_first = Athlete(
                    coordinates=a1_new_position, has_possession=True,
                    ID=1)  #then a1 can move anywhere
                if both_new_actions_are_the_same:
                    a2_state_if_a1_first = Athlete(
                        coordinates=self.athlete2.coordinates,
                        has_possession=False,
                        ID=2
                    )  #a2 cannot move where a1 is because no possession
                else:
                    a2_state_if_a1_first = Athlete(
                        coordinates=a2_new_position,
                        has_possession=False,
                        ID=2
                    )  #a2 can go anywhere as long as it's not where a1 is

            else:  #if a1 doesn't have the ball
                if both_new_actions_are_the_same:  #and both actions are the same...
                    a1_state_if_a1_first = Athlete(coordinates=a1_new_position,
                                                   has_possession=True,
                                                   ID=1)  #a1 gets the ball
                    a2_state_if_a1_first = Athlete(
                        coordinates=self.athlete2.coordinates,
                        has_possession=False,
                        ID=2)  #a2 loses the ball
                else:
                    a1_state_if_a1_first = Athlete(coordinates=a1_new_position,
                                                   has_possession=False,
                                                   ID=1)
                    a2_state_if_a1_first = Athlete(coordinates=a2_new_position,
                                                   has_possession=True,
                                                   ID=2)
        #If the player with the ball moves into the player without it, the former loses the ball to the latter
        else:
            a1_state_if_a1_first = Athlete(
                coordinates=self.athlete1.coordinates,
                has_possession=False,
                ID=1)
            a2_state_if_a1_first = Athlete(
                coordinates=self.athlete2.coordinates,
                has_possession=True,
                ID=2)

        new_soccer_field = Soccer_Field(a1_state_if_a1_first,
                                        a2_state_if_a1_first)
        return new_soccer_field
Esempio n. 23
0
class pyTrainer:
    def __init__(self, filename=None, data_path=None):
        # Based on Django's approach -> http://code.djangoproject.com/svn/django/trunk/django/__init__.py
        self.version = __import__('pytrainer').get_version()
        #Process command line options
        self.startup_options = self.get_options()
        #Setup logging
        self.environment = Environment(self.startup_options.conf_dir,
                                       data_path)
        self.environment.create_directories()
        self.environment.clear_temp_dir()
        self.set_logging(self.startup_options.log_level,
                         self.startup_options.log_type)
        logging.debug('>>')
        logging.info("pytrainer version %s" % (self.version))
        self.data_path = data_path

        # Checking profile
        logging.debug('Checking configuration and profile...')
        self.profile = Profile()
        # Write the default config to disk
        self.profile.saveProfile()
        self.uc = UC()
        self.profilewindow = None
        self.ddbb = DDBB(self.profile.sqlalchemy_url)
        logging.debug('connecting to DDBB')
        self.ddbb.connect()

        logging.info('Checking if some upgrade action is needed...')
        initialize_data(self.ddbb, self.environment.conf_dir)

        # Loading shared services
        logging.debug('Loading sport service...')
        self._sport_service = SportService(self.ddbb)
        logging.debug('Loading record service...')
        self.record = Record(self._sport_service, data_path, self)
        logging.debug('Loading athlete service...')
        self.athlete = Athlete(data_path, self)
        logging.debug('Loading stats service...')
        self.stats = Stats(self)
        logging.debug('Initializing activity pool...')
        pool_size = self.profile.getIntValue("pytraining",
                                             "activitypool_size",
                                             default=1)
        self.activitypool = ActivityService(self, size=pool_size)

        #Loading main window
        self.windowmain = None
        logging.debug('Loading main window...')
        self.windowmain = Main(self._sport_service,
                               data_path,
                               self,
                               self.version,
                               gpxDir=self.profile.gpxdir)

        # Select initial date depending on user's preference
        self.selectInitialDate()

        logging.debug('Loading waypoint service...')
        self.waypoint = WaypointService(data_path, self)
        logging.debug('Loading extension service...')
        self.extension = Extension(data_path, self)
        logging.debug('Loading plugins service...')
        self.plugins = Plugins(data_path, self)
        self.importdata = Importdata(self._sport_service, data_path, self,
                                     self.profile)
        logging.debug('Loading plugins...')
        self.loadPlugins()
        logging.debug('Loading extensions...')
        self.loadExtensions()
        logging.debug('Setting values for graphs, maps and waypoint editor...')
        self.windowmain.setup()
        self.windowmain.on_calendar_selected(None)
        logging.debug('Refreshing sport list... is this needed?')
        self.refreshMainSportList()
        logging.debug('Launching main window...')
        self.windowmain.run()
        logging.debug('<<')

    def get_options(self):
        '''
        Define usage and accepted options for command line startup

        returns: options - dict with option: value pairs
        '''
        usage = '''usage: %prog [options]

        For more help on valid options try:
           %prog -h '''
        parser = OptionParser(usage=usage)
        parser.set_defaults(log_level=logging.WARNING,
                            validate=False,
                            equip=False,
                            newgraph=True,
                            conf_dir=None,
                            log_type="file")
        parser.add_option("-d",
                          "--debug",
                          action="store_const",
                          const=logging.DEBUG,
                          dest="log_level",
                          help="enable logging at debug level")
        parser.add_option("-i",
                          "--info",
                          action="store_const",
                          const=logging.INFO,
                          dest="log_level",
                          help="enable logging at info level")
        parser.add_option("-w",
                          "--warn",
                          action="store_const",
                          const=logging.WARNING,
                          dest="log_level",
                          help="enable logging at warning level")
        parser.add_option("--error",
                          action="store_const",
                          const=logging.ERROR,
                          dest="log_level",
                          help="enable logging at error level")
        parser.add_option(
            "--valid",
            action="store_true",
            dest="validate",
            help=
            "enable validation of files imported by plugins (details at info or debug logging level) - note plugin must support validation"
        )
        parser.add_option("--oldgraph",
                          action="store_false",
                          dest="newgraph",
                          help="Turn off new graphing approach")
        parser.add_option(
            "--newgraph",
            action="store_true",
            dest="newgraph",
            help="Deprecated Option: Turn on new graphing approach")
        parser.add_option(
            "--confdir",
            dest="conf_dir",
            help=
            "Specify the directory where application configuration will be stored."
        )
        parser.add_option(
            "--logtype",
            dest="log_type",
            metavar="TYPE",
            type="choice",
            choices=["file", "console"],
            help=
            "Specify where logging should be output to. TYPE is one of 'file' (default), or 'console'."
        )
        (options, args) = parser.parse_args()
        return options

    def set_logging(self, level, log_type):
        '''Setup rotating log file with customized format'''
        if ("console" == log_type):
            handler = logging.StreamHandler(sys.stdout)
        else:
            handler = logging.handlers.RotatingFileHandler(
                self.environment.log_file, maxBytes=100000, backupCount=5)
        formatter = logging.Formatter(
            '%(asctime)s|%(levelname)s|%(module)s|%(funcName)s|%(message)s')
        handler.setFormatter(formatter)
        logging.getLogger('').addHandler(handler)
        self.set_logging_level(self.startup_options.log_level)

    def set_logging_level(self, level):
        '''Set level of information written to log'''
        logging.debug("Setting logger to level: " + str(level))
        logging.getLogger('').setLevel(level)
        logging.getLogger('sqlalchemy.engine').setLevel(level)

    def quit(self):
        logging.debug('--')
        logging.info("Exit!")
        #self.webservice.stop()
        self.windowmain.gtk_main_quit()
        logging.shutdown()
        sys.exit(
        )  # Any nonzero value is considered "abnormal termination" by shells and the like

    def selectInitialDate(self):
        logging.debug('>>')
        # self.windowmain.calendar comes from SimpleGladeApp initialisation, not really sure how... :?
        self.date = Date(self.windowmain.calendar)
        if self.profile.getValue("pytraining",
                                 "prf_startscreen") == "last_entry":
            logging.info(
                "User selection is to display last entry in start screen")
            last_entry_date = self.record.getLastRecordDateString()
            try:
                logging.info("Last activity found on %s" % last_entry_date)
                self.date.setDate(last_entry_date)
            except:
                logging.error(
                    "No data available regarding last activity date. Default date will be today"
                )
                logging.debug("Traceback: %s" % traceback.format_exc())
        else:
            logging.info(
                "User selection is to display current day in start screen")
        logging.debug('Setting date to %s' %
                      self.date.getDate().strftime("%Y-%m-%d"))
        logging.debug('<<')

    def loadPlugins(self):
        logging.debug('>>')
        activeplugins = self.plugins.getActivePlugins()
        if (len(activeplugins) < 1):
            logging.info("No active plugins")
        else:
            for plugin in activeplugins:
                # From version 1.10 on all file imports are managed via File -> import wizard
                # Only showing garmintools_full and garmin-hr in 'File' dropdown
                plugin_name = os.path.basename(plugin)
                if (plugin_name == "garmintools_full"
                        or plugin_name == "garmin-hr"):
                    txtbutton = self.plugins.loadPlugin(plugin)
                    self.windowmain.addImportPlugin(txtbutton)
                else:
                    logging.debug(
                        'From version 1.10 on, file import plugins are managed via File -> Import. Not displaying plugin '
                        + plugin_name)
        logging.debug('<<')

    def loadExtensions(self):
        logging.debug('>>')
        activeextensions = self.extension.getActiveExtensions()
        if (len(activeextensions) < 1):
            logging.info("No active extensions")
        else:
            for extension in activeextensions:
                txtbutton = self.extension.loadExtension(extension)
                self.windowmain.addExtension(txtbutton)
        logging.debug('<<')

    def runPlugin(self, widget, pathPlugin):
        logging.debug('>>')
        self.pluginClass = self.plugins.importClass(pathPlugin)
        pluginFiles = self.pluginClass.run()
        if pluginFiles is not None:
            logging.debug("Plugin returned %d files" % (len(pluginFiles)))
            #process returned GPX files
            for (pluginFile, sport) in pluginFiles:
                if os.path.isfile(pluginFile):
                    logging.info('File exists. Size: %d. Sport: %s' %
                                 (os.path.getsize(pluginFile), sport))
                    if self.record.importFromGPX(pluginFile, sport) is None:
                        logging.error("Error importing file " + pluginFile)
                else:
                    logging.error('File ' + pluginFile + ' not valid')
        else:
            logging.debug("No files returned from Plugin")
        self.refreshListRecords()
        self.refreshGraphView("day")
        logging.debug('<<')

    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, 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)

        logging.debug('<<')

    def refreshMainSportList(self):
        logging.debug('>>')
        sports = self._sport_service.get_all_sports()
        self.windowmain.updateSportList(sports)
        logging.debug('<<')

    def refreshGraphView(self, view, sport=None):
        logging.debug('>>')
        if self.windowmain is None:
            logging.debug("First call to refreshGraphView")
            logging.debug('<<')
            return
        date_selected = self.date.getDate()
        if view == "record":
            logging.debug('record view')
            if self.windowmain.recordview.get_current_page() == 0:
                self.refreshRecordGraphView("info")
            elif self.windowmain.recordview.get_current_page() == 1:
                self.refreshRecordGraphView("graphs")
            elif self.windowmain.recordview.get_current_page() == 2:
                self.refreshRecordGraphView("map")
            elif self.windowmain.recordview.get_current_page() == 3:
                self.refreshRecordGraphView("heartrate")
            elif self.windowmain.recordview.get_current_page() == 4:
                self.refreshRecordGraphView("analytics")
        elif view == "day":
            logging.debug('day view')
            self.windowmain.actualize_dayview(date_selected)
        elif view == "week":
            logging.debug('week view')
            date_range = DateRange.for_week_containing(date_selected)
            self.windowmain.actualize_weekview(date_range)
        elif view == "month":
            logging.debug('month view')
            date_range = DateRange.for_month_containing(date_selected)
            nameMonth, daysInMonth = getNameMonth(date_selected)
            self.windowmain.actualize_monthview(date_range, nameMonth,
                                                daysInMonth)
        elif view == "year":
            logging.debug('year view')
            date_range = DateRange.for_year_containing(date_selected)
            self.windowmain.actualize_yearview(date_range, date_selected.year)
        elif view == "listview":
            logging.debug('list view')
            self.refreshListView()
        elif view == "athlete":
            logging.debug('athlete view')
            self.windowmain.on_athleteview_activate()
        elif view == "stats":
            logging.debug('stats view')
            self.windowmain.on_statsview_activate()
        else:
            print "Unknown view %s" % view
        logging.debug('<<')

    def refreshRecordGraphView(self, view, id_record=None):
        logging.debug('>>')
        logging.info('Working on ' + view + ' graph')
        if id_record is not None:
            #Refresh called for a specific record
            #Select correct record in treeview
            model = self.windowmain.recordTreeView.get_model()
            #Loop through all records in treeview looking for the correct one to highlight
            for i, row in enumerate(model):
                if row[0] == id_record:
                    self.windowmain.recordTreeView.set_cursor(i)
        else:
            selected, iter = self.windowmain.recordTreeView.get_selection(
            ).get_selected()
            if iter:
                id_record = selected.get_value(iter, 0)
            else:
                id_record = None
                view = "info"
        activity = self.activitypool.get_activity(id_record)
        if view == "info":
            self.windowmain.actualize_recordview(activity)
        if view == "graphs":
            self.windowmain.actualize_recordgraph(activity)
        if view == "map":
            self.refreshMapView()
        if view == "heartrate":
            self.windowmain.actualize_heartrategraph(activity)
            self.windowmain.actualize_hrview(activity)
        if view == "analytics":
            self.windowmain.actualize_analytics(activity)
        logging.debug('<<')

    def refreshMapView(self, full_screen=False):
        logging.debug('>>')
        if self.windowmain is None:
            logging.debug('Called before windowmain initialisation')
            logging.debug('<<')
            return
        selected, iter = self.windowmain.recordTreeView.get_selection(
        ).get_selected()
        id_record = selected.get_value(iter, 0)
        activity = self.activitypool.get_activity(id_record)
        logging.debug('Trying to show map for record ' + str(id_record))
        self.windowmain.actualize_map(activity, full_screen)
        logging.debug('<<')

    def refreshListRecords(self):
        logging.debug('>>')
        #Refresh list records
        date = self.date.getDate()
        if self.windowmain.activeSport:
            sport = self._sport_service.get_sport_by_name(
                self.windowmain.activeSport)
        else:
            sport = None
        self.windowmain.actualize_recordTreeView(date)
        #Mark the monthly calendar to show which days have activity?
        record_list = self.record.getRecordDayList(date, sport)
        self.windowmain.actualize_calendar(record_list)
        logging.debug('<<')

    def refreshAthleteView(self):
        logging.debug('>>')
        self.athlete.refresh()
        self.windowmain.actualize_athleteview(self.athlete)
        logging.debug('<<')

    def refreshStatsView(self):
        logging.debug('>>')
        self.stats.refresh()
        self.windowmain.actualize_statsview(
            self.stats, self.activitypool.get_all_activities())
        logging.debug('<<')

    def refreshListView(self, condition=None):
        logging.debug('>>')
        record_list = self.record.getRecordListByCondition(condition)
        self.windowmain.actualize_listview(record_list)
        logging.debug('<<')

    def refreshWaypointView(self, default_waypoint=None, redrawmap=1):
        logging.debug('>>')
        waypoint_list = self.waypoint.getAllWaypoints()
        self.windowmain.actualize_waypointview(waypoint_list, default_waypoint,
                                               redrawmap)
        logging.debug('<<')

    def editExtensions(self):
        logging.debug('>>')
        before = self.extension.getActiveExtensions()
        self.extension.manageExtensions()
        after = self.extension.getActiveExtensions()
        self.setExtensions(before, after)
        logging.debug('<<')

    def importData(self):
        logging.debug('>>')
        activeplugins_before = self.plugins.getActivePlugins()
        self.importdata.runImportdata()
        activeplugins_after = self.plugins.getActivePlugins()
        #Need to check for plugins that have been disabled (were active and now are not)
        self.setMenuPlugins(activeplugins_before, activeplugins_after)
        self.refreshListRecords()
        self.refreshGraphView(self.windowmain.selected_view)
        logging.debug('<<')

    def editGpsPlugins(self):
        logging.debug('>>')
        activeplugins_before = self.plugins.getActivePlugins()
        self.plugins.managePlugins()
        activeplugins_after = self.plugins.getActivePlugins()
        #Need to check for plugins that have been disabled (were active and now are not)
        self.setMenuPlugins(activeplugins_before, activeplugins_after)
        logging.debug('<<')

    def setMenuPlugins(self, activeplugins_before, activeplugins_after):
        logging.debug('>>')
        #Need to check for plugins that have been disabled (were active and now are not)
        for plugin in activeplugins_before:
            if plugin not in activeplugins_after:
                #disabled plugin -> need to unload plugin
                txtbutton = self.plugins.loadPlugin(plugin)
                self.windowmain.removeImportPlugin(txtbutton)
        #Need to check for plugins that have been enabled (were not active and now are)
        for plugin in activeplugins_after:
            if plugin not in activeplugins_before:
                #new active plugin -> need to load plugin
                plugin_name = os.path.basename(plugin)
                if (plugin_name == "garmintools_full"
                        or plugin_name == "garmin-hr"):
                    txtbutton = self.plugins.loadPlugin(plugin)
                    self.windowmain.addImportPlugin(txtbutton)
                else:
                    logging.debug(
                        'From version 1.10 on file import plugins are managed via File -> Import. Not displaying plugin '
                        + plugin_name)
        logging.debug('<<')

    def setExtensions(self, before, after):
        logging.debug('>>')
        #Need to check for extensions that have been disabled (were active and now are not)
        for extension in before:
            if extension not in after:
                #disabled extension -> need to unload extension
                print "Need to disable extension %s " % extension
                txtbutton = self.extension.loadExtension(extension)
                self.windowmain.removeExtension(txtbutton)
        #Need to check for plugins that have been enabled (were not active and now are)
        for extension in after:
            if extension not in before:
                #new active extension -> need to load extension
                logging.debug("Enabling extension %s " % extension)
                txtbutton = self.extension.loadExtension(extension)
                self.windowmain.addExtension(txtbutton)
        logging.debug('<<')

    def newRecord(self,
                  title=None,
                  distance=None,
                  time=None,
                  upositive=None,
                  unegative=None,
                  bpm=None,
                  calories=None,
                  comment=None,
                  view=None):
        logging.debug('>>')
        date = self.date.getDate()
        self.record.newRecord(date, title, distance, time, upositive,
                              unegative, bpm, calories, comment)
        self.refreshListRecords()
        if view is not None:
            self.refreshGraphView(view)
        logging.debug('<<')

    def editRecord(self, id_record, view=None):
        logging.debug("Editing record with id: '%s'", id_record)
        self.record.editRecord(id_record)
        self.refreshListRecords()
        if view is not None:
            self.refreshGraphView(view)
        logging.debug('<<')

    def removeRecord(self, id_record, confirm=False, view=None):
        logging.debug('>>')
        if confirm:
            activity = self.activitypool.get_activity(id_record)
            self.activitypool.remove_activity_from_db(activity)
        else:
            msg = _("Delete this database entry?")
            params = [id_record, True]
            warning = Warning(self.data_path, self.removeRecord, params)
            warning.set_text(msg)
            warning.run()
        self.refreshListRecords()
        if view is not None:
            self.refreshGraphView(view)
        logging.debug('<<')

    def removeWaypoint(self, id_waypoint, confirm=False):
        logging.debug('>>')
        if confirm:
            self.waypoint.removeWaypoint(id_waypoint)
            self.refreshWaypointView()
        else:
            msg = _("Delete this waypoint?")
            params = [id_waypoint, True]
            warning = Warning(self.data_path, self.removeWaypoint, params)
            warning.set_text(msg)
            warning.run()
        logging.debug('<<')

    def updateWaypoint(self, id_waypoint, lat, lon, name, desc, sym):
        logging.debug('>>')
        self.waypoint.updateWaypoint(id_waypoint, lat, lon, name, desc, sym)
        self.refreshWaypointView(id_waypoint)
        logging.debug('<<')

    def exportCsv(self):
        logging.debug('>>')
        from save import Save
        save = Save(self.data_path, self.record)
        save.run()
        logging.debug('<<')

    def editProfile(self):
        logging.debug('>>')
        from gui.windowprofile import WindowProfile
        self.profile.refreshConfiguration()
        if self.profilewindow is None:
            self.profilewindow = WindowProfile(self._sport_service,
                                               self.data_path,
                                               self.profile,
                                               pytrainer_main=self)
            logging.debug("setting data values")
            self.profilewindow.setValues(self.profile.configuration)
            self.profilewindow.run()
            self.profilewindow = None
        else:
            self.profilewindow.setValues(self.profile.configuration)
            self.profilewindow.present()
        self.profile.refreshConfiguration()

        self.activitypool.clear_pool()
        self.windowmain.setup()
        logging.debug('<<')
Esempio n. 24
0
    def __init__(self, filename=None, data_path=None):
        # Based on Django's approach -> http://code.djangoproject.com/svn/django/trunk/django/__init__.py
        self.version = __import__('pytrainer').get_version()
        #Process command line options
        self.startup_options = self.get_options()
        #Setup logging
        self.environment = Environment(self.startup_options.conf_dir,
                                       data_path)
        self.environment.create_directories()
        self.environment.clear_temp_dir()
        self.set_logging(self.startup_options.log_level,
                         self.startup_options.log_type)
        logging.debug('>>')
        logging.info("pytrainer version %s" % (self.version))
        self.data_path = data_path

        # Checking profile
        logging.debug('Checking configuration and profile...')
        self.profile = Profile()
        # Write the default config to disk
        self.profile.saveProfile()
        self.uc = UC()
        self.profilewindow = None
        self.ddbb = DDBB(self.profile.sqlalchemy_url)
        logging.debug('connecting to DDBB')
        self.ddbb.connect()

        logging.info('Checking if some upgrade action is needed...')
        initialize_data(self.ddbb, self.environment.conf_dir)

        # Loading shared services
        logging.debug('Loading sport service...')
        self._sport_service = SportService(self.ddbb)
        logging.debug('Loading record service...')
        self.record = Record(self._sport_service, data_path, self)
        logging.debug('Loading athlete service...')
        self.athlete = Athlete(data_path, self)
        logging.debug('Loading stats service...')
        self.stats = Stats(self)
        logging.debug('Initializing activity pool...')
        pool_size = self.profile.getIntValue("pytraining",
                                             "activitypool_size",
                                             default=1)
        self.activitypool = ActivityService(self, size=pool_size)

        #Loading main window
        self.windowmain = None
        logging.debug('Loading main window...')
        self.windowmain = Main(self._sport_service,
                               data_path,
                               self,
                               self.version,
                               gpxDir=self.profile.gpxdir)

        # Select initial date depending on user's preference
        self.selectInitialDate()

        logging.debug('Loading waypoint service...')
        self.waypoint = WaypointService(data_path, self)
        logging.debug('Loading extension service...')
        self.extension = Extension(data_path, self)
        logging.debug('Loading plugins service...')
        self.plugins = Plugins(data_path, self)
        self.importdata = Importdata(self._sport_service, data_path, self,
                                     self.profile)
        logging.debug('Loading plugins...')
        self.loadPlugins()
        logging.debug('Loading extensions...')
        self.loadExtensions()
        logging.debug('Setting values for graphs, maps and waypoint editor...')
        self.windowmain.setup()
        self.windowmain.on_calendar_selected(None)
        logging.debug('Refreshing sport list... is this needed?')
        self.refreshMainSportList()
        logging.debug('Launching main window...')
        self.windowmain.run()
        logging.debug('<<')
Esempio n. 25
0
class pyTrainer:
    def __init__(self,filename = None, data_path = None):
        #Version constants
        self.version ="1.10.0-dev"
        #Process command line options
        self.startup_options = self.get_options()
        #Setup logging
        self.environment = Environment(platform.get_platform(), self.startup_options.conf_dir)
        self.environment.create_directories()
        self.set_logging(self.startup_options.log_level, self.startup_options.log_type)
        logging.debug('>>')
        logging.debug("PyTrainer version %s" % (self.version))
        self.data_path = data_path
        self.date = Date()
        self.ddbb = None
        # Checking profile
        logging.debug('Checking configuration and profile...')
        self.profile = Profile(self.environment, self.data_path,self)
        self.uc = UC()
        self.windowmain = None
        self.ddbb = DDBB(self.profile, self)
        logging.debug('connecting to DDBB')
        self.ddbb.connect()
        
        initialize_data(self.ddbb, self.environment.conf_dir)
            
        self._sport_service = SportService(self.ddbb)
        self.record = Record(self._sport_service, data_path, self)
        self.athlete = Athlete(data_path,self)
        self.stats = Stats(self._sport_service, self)
        pool_size = self.profile.getIntValue("pytraining","activitypool_size", default=1)
        self.activitypool = ActivityPool(self, size=pool_size)
        #preparamos la ventana principal
        self.windowmain = Main(self._sport_service, data_path,self,self.version, gpxDir=self.profile.gpxdir)
        self.date = Date(self.windowmain.calendar)
        self.waypoint = Waypoint(data_path,self)
        self.extension = Extension(data_path, self)
        self.plugins = Plugins(data_path, self)
        self.importdata = Importdata(self._sport_service, data_path, self, self.profile)
        self.loadPlugins()
        self.loadExtensions()
        self.windowmain.setup()
        self.windowmain.on_calendar_selected(None)
        self.refreshMainSportList()
        self.windowmain.run()
        logging.debug('<<')


    def get_options(self):
        '''
        Define usage and accepted options for command line startup

        returns: options - dict with option: value pairs
        '''
        usage = '''usage: %prog [options]

        For more help on valid options try:
           %prog -h '''
        parser = OptionParser(usage=usage)
        parser.set_defaults(log_level=logging.ERROR, validate=False, equip=False, newgraph=True, conf_dir=None, log_type="file")
        parser.add_option("-d", "--debug", action="store_const", const=logging.DEBUG, dest="log_level", help="enable logging at debug level")
        parser.add_option("-i", "--info", action="store_const", const=logging.INFO, dest="log_level", help="enable logging at info level")
        parser.add_option("-w", "--warn", action="store_const", const=logging.WARNING, dest="log_level", help="enable logging at warning level")
        parser.add_option("--valid", action="store_true", dest="validate", help="enable validation of files imported by plugins (details at info or debug logging level) - note plugin must support validation")
        parser.add_option("--oldgraph", action="store_false", dest="newgraph", help="Turn off new graphing approach")
        parser.add_option("--newgraph", action="store_true", dest="newgraph", help="Deprecated Option: Turn on new graphing approach")
        parser.add_option("--confdir", dest="conf_dir", help="Specify the directory where application configuration will be stored.")
        parser.add_option("--logtype", dest="log_type", metavar="TYPE",  type="choice" , choices=["file", "console"], help="Specify where logging should be output to. TYPE is one of 'file' (default), or 'console'.")
        (options, args) = parser.parse_args()
        return options

    def set_logging(self, level, log_type):
        '''Setup rotating log file with customized format'''
        if("console" == log_type):
            handler = logging.StreamHandler(sys.stdout)
        else:
            handler = logging.handlers.RotatingFileHandler(self.environment.log_file, maxBytes=100000, backupCount=5)
        formatter = logging.Formatter('%(asctime)s|%(levelname)s|%(module)s|%(funcName)s|%(message)s')
        handler.setFormatter(formatter)
        logging.getLogger('').addHandler(handler)
        self.set_logging_level(self.startup_options.log_level)

    def set_logging_level(self, level):
        '''Set level of information written to log'''
        logging.debug("Setting logger to level: "+ str(level))
        logging.getLogger('').setLevel(level)

    def quit(self):
        logging.debug('--')
        logging.info("Exit!")
        #self.webservice.stop()
        self.windowmain.gtk_main_quit()
        logging.shutdown()
        sys.exit() # Any nonzero value is considered "abnormal termination" by shells and the like

    def loadPlugins(self):
        logging.debug('>>')
        activeplugins = self.plugins.getActivePlugins()
        if (len(activeplugins)<1):
             logging.info("No active plugins")
        else:
             for plugin in activeplugins:
                txtbutton = self.plugins.loadPlugin(plugin)
                self.windowmain.addImportPlugin(txtbutton)
        logging.debug('<<')

    def loadExtensions(self):
        logging.debug('>>')
        activeextensions = self.extension.getActiveExtensions()
        if (len(activeextensions)<1):
             logging.info("No active extensions")
        else:
             for extension in activeextensions:
                txtbutton = self.extension.loadExtension(extension)
                self.windowmain.addExtension(txtbutton)
        logging.debug('<<')

    def runPlugin(self,widget,pathPlugin):
        logging.debug('>>')
        self.pluginClass = self.plugins.importClass(pathPlugin)
        pluginFiles = self.pluginClass.run()
        if pluginFiles is not None:
            logging.debug("Plugin returned %d files" % (len(pluginFiles)) )
            #process returned GPX files
            for (pluginFile, sport) in pluginFiles:
                if os.path.isfile(pluginFile):
                    logging.info('File exists. Size: %d. Sport: %s' % (os.path.getsize(pluginFile), sport))
                    if self.record.importFromGPX(pluginFile, sport) is None:
                        logging.error("Error importing file "+pluginFile)
                else:
                    logging.error('File '+pluginFile+' not valid')
        else:
            logging.debug("No files returned from Plugin")
        self.refreshListRecords()
        self.refreshGraphView("day")
        logging.debug('<<')

    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, 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)

        logging.debug('<<')

    def refreshMainSportList(self):
        logging.debug('>>')
        sports = self._sport_service.get_all_sports()
        self.windowmain.updateSportList(sports)
        logging.debug('<<')

    def refreshGraphView(self, view, sport=None):
        logging.debug('>>')
        if self.windowmain is None:
            logging.debug("First call to refreshGraphView")
            logging.debug('<<')
            return
        date_selected = self.date.getDate()
        if view=="record":
             logging.debug('record view')
             if self.windowmain.recordview.get_current_page()==0:
                self.refreshRecordGraphView("info")
             elif self.windowmain.recordview.get_current_page()==1:
                self.refreshRecordGraphView("graphs")
             elif self.windowmain.recordview.get_current_page()==2:
                self.refreshRecordGraphView("map")
             elif self.windowmain.recordview.get_current_page()==3:
                self.refreshRecordGraphView("heartrate")
             elif self.windowmain.recordview.get_current_page()==4:
                self.refreshRecordGraphView("analytics")
        elif view=="day":
             logging.debug('day view')
             sport = self.windowmain.activeSport
             sport_id = self.record.getSportId(sport)
             record_list = self.record.getrecordList(date_selected, sport_id)
             self.windowmain.actualize_dayview(record_list=record_list)
             #selected,iter = self.windowmain.recordTreeView.get_selection().get_selected()
        elif view=="week":
             logging.debug('week view')
             date_range = DateRange.for_week_containing(date_selected)
             sport = self.windowmain.activeSport
             sport_id = self.record.getSportId(sport)
             record_list = self.record.getrecordPeriod(date_range, sport_id)
             self.windowmain.actualize_weekview(record_list, date_range)
        elif view=="month":
             logging.debug('month view')
             date_range = DateRange.for_month_containing(date_selected)
             sport = self.windowmain.activeSport
             sport_id = self.record.getSportId(sport)
             record_list = self.record.getrecordPeriod(date_range, sport_id)
             nameMonth, daysInMonth = self.date.getNameMonth(date_selected)
             self.windowmain.actualize_monthview(record_list, nameMonth)
             self.windowmain.actualize_monthgraph(record_list, daysInMonth)
        elif view=="year":
             logging.debug('year view')
             date_range = DateRange.for_year_containing(date_selected)
             sport = self.windowmain.activeSport
             sport_id = self.record.getSportId(sport)
             record_list = self.record.getrecordPeriod(date_range, sport_id)
             self.windowmain.actualize_yearview(record_list, date_selected.year)
             self.windowmain.actualize_yeargraph(record_list)
        elif view=="listview":
            logging.debug('list view')
            self.refreshListView()
        elif view=="athlete":
            logging.debug('athlete view')
            self.windowmain.on_athleteview_activate()
        elif view=="stats":
            logging.debug('stats view')
            self.windowmain.on_statsview_activate()
        else:
            print "Unknown view %s" % view
        logging.debug('<<')
        
    def refreshRecordGraphView(self, view, id_record=None):
        logging.debug('>>')
        logging.info('Working on '+view+' graph')
        if id_record is not None:
			#Refresh called for a specific record
            #Select correct record in treeview
            model = self.windowmain.recordTreeView.get_model()
            #Loop through all records in treeview looking for the correct one to highlight
            for i,row in enumerate(model):
				if row[0] == id_record:
					self.windowmain.recordTreeView.set_cursor(i)
        else:
            selected,iter = self.windowmain.recordTreeView.get_selection().get_selected()
            if iter:
                id_record = selected.get_value(iter,0)
            else:
                id_record = None
                view="info"
        activity = self.activitypool.get_activity(id_record)
        if view=="info":
            self.windowmain.actualize_recordview(activity)
        if view=="graphs":
            self.windowmain.actualize_recordgraph(activity)
        if view=="map":
             self.refreshMapView()
        if view=="heartrate":
             self.windowmain.actualize_heartrategraph(activity)
             self.windowmain.actualize_hrview(activity)
        if view=="analytics":
             self.windowmain.actualize_analytics(activity)
        logging.debug('<<')

    def refreshMapView(self, full_screen=False):
        logging.debug('>>')
        if self.windowmain is None:
            logging.debug('Called before windowmain initialisation')
            logging.debug('<<')
            return
        selected,iter = self.windowmain.recordTreeView.get_selection().get_selected()
        id_record = selected.get_value(iter,0)
        activity = self.activitypool.get_activity(id_record)
        logging.debug('Trying to show map for record '+str(id_record))
        self.windowmain.actualize_map(activity, full_screen)
        logging.debug('<<')

    def refreshListRecords(self):
        logging.debug('>>')
        #Refresh list view
        #self.refreshListView() # old variant
        self.refreshListView(self.windowmain.listsearch.condition)
        #Refresh list records
        date = self.date.getDate()
        sport = self.windowmain.activeSport
        id_sport = self.record.getSportId(sport)
        record_ids = self.record.getrecordList(date, id_sport)
        self.windowmain.actualize_recordTreeView(record_ids)
        #Mark the monthly calendar to show which days have activity?
        record_list = self.record.getRecordDayList(date, id_sport)
        self.windowmain.actualize_calendar(record_list)
        logging.debug('<<')

    def refreshAthleteView(self):
        logging.debug('>>')
        self.athlete.refresh()
        self.windowmain.actualize_athleteview(self.athlete)
        logging.debug('<<')

    def refreshStatsView(self):
        logging.debug('>>')
        self.stats.refresh()
        self.windowmain.actualize_statsview(self.stats, self.record.getAllRecordList())
        logging.debug('<<')

    def refreshListView(self,condition=None):
        logging.debug('>>')
        record_list = self.record.getRecordListByCondition(condition)
        self.windowmain.actualize_listview(record_list)
        logging.debug('<<')

    def refreshWaypointView(self,default_waypoint=None,redrawmap=1):
        logging.debug('>>')
        waypoint_list = self.waypoint.getAllWaypoints()
        self.windowmain.actualize_waypointview(waypoint_list,default_waypoint,redrawmap)
        logging.debug('<<')

    def editExtensions(self):
        logging.debug('>>')
        before = self.extension.getActiveExtensions()
        self.extension.manageExtensions()
        after = self.extension.getActiveExtensions()
        self.setExtensions(before, after)
        logging.debug('<<')

    def importData(self):
        logging.debug('>>')
        activeplugins_before = self.plugins.getActivePlugins()
        self.importdata.runImportdata()
        activeplugins_after = self.plugins.getActivePlugins()
        #Need to check for plugins that have been disabled (were active and now are not)
        self.setMenuPlugins(activeplugins_before, activeplugins_after)
        self.refreshListRecords()
        self.refreshGraphView(self.windowmain.selected_view)
        logging.debug('<<')

    def editGpsPlugins(self):
        logging.debug('>>')
        activeplugins_before = self.plugins.getActivePlugins()
        self.plugins.managePlugins()
        activeplugins_after = self.plugins.getActivePlugins()
        #Need to check for plugins that have been disabled (were active and now are not)
        self.setMenuPlugins(activeplugins_before, activeplugins_after)
        logging.debug('<<')

    def setMenuPlugins(self, activeplugins_before, activeplugins_after):
        logging.debug('>>')
        #Need to check for plugins that have been disabled (were active and now are not)
        for plugin in activeplugins_before:
            if plugin not in activeplugins_after:
                #disabled plugin -> need to unload plugin
                txtbutton = self.plugins.loadPlugin(plugin)
                self.windowmain.removeImportPlugin(txtbutton)
        #Need to check for plugins that have been enabled (were not active and now are)
        for plugin in activeplugins_after:
            if plugin not in activeplugins_before:
                #new active plugin -> need to load plugin
                txtbutton = self.plugins.loadPlugin(plugin)
                self.windowmain.addImportPlugin(txtbutton)
        logging.debug('<<')

    def setExtensions(self, before, after):
        logging.debug('>>')
        #Need to check for extensions that have been disabled (were active and now are not)
        for extension in before:
            if extension not in after:
                #disabled extension -> need to unload extension
                print "Need to disable extension %s " % extension
                txtbutton = self.extension.loadExtension(extension)
                self.windowmain.removeExtension(txtbutton)
        #Need to check for plugins that have been enabled (were not active and now are)
        for extension in after:
            if extension not in before:
                #new active extension -> need to load extension
                logging.debug("Enabling extension %s " % extension)
                txtbutton = self.extension.loadExtension(extension)
                self.windowmain.addExtension(txtbutton)
        logging.debug('<<')

    def newRecord(self,title=None,distance=None,time=None,upositive=None,unegative=None,bpm=None,calories=None,comment=None,view=None):
        logging.debug('>>')
        date = self.date.getDate()
        self.record.newRecord(date, title, distance, time, upositive, unegative, bpm, calories, comment)
        self.refreshListRecords()
        if view is not None:
            self.refreshGraphView(view)
        logging.debug('<<')

    def editRecord(self, id_record, view=None):
        logging.debug("Editing record with id: '%s'", id_record)
        self.record.editRecord(id_record)
        self.refreshListRecords()
        if view is not None:
            self.refreshGraphView(view)
        logging.debug('<<')

    def removeRecord(self, id_record, confirm = False, view=None):
        logging.debug('>>')
        if confirm:
             self.record.removeRecord(id_record)
        else:
             msg = _("Delete this database entry?")
             params = [id_record,True]
             warning = Warning(self.data_path,self.removeRecord,params)
             warning.set_text(msg)
             warning.run()
        self.refreshListRecords()
        if view is not None:
            self.refreshGraphView(view)
        logging.debug('<<')

    def removeWaypoint(self,id_waypoint, confirm = False):
        logging.debug('>>')
        if confirm:
             self.waypoint.removeWaypoint(id_waypoint)
             self.refreshWaypointView()
        else:
             msg = _("Delete this waypoint?")
             params = [id_waypoint,True]
             warning = Warning(self.data_path,self.removeWaypoint,params)
             warning.set_text(msg)
             warning.run()
        logging.debug('<<')

    def updateWaypoint(self,id_waypoint,lat,lon,name,desc,sym):
        logging.debug('>>')
        self.waypoint.updateWaypoint(id_waypoint,lat,lon,name,desc,sym)
        self.refreshWaypointView(id_waypoint)
        logging.debug('<<')

    def exportCsv(self):
        logging.debug('>>')
        from save import Save
        save = Save(self.data_path, self.record)
        save.run()
        logging.debug('<<')

    def editProfile(self):
        logging.debug('>>')
        self.profile.editProfile(self._sport_service)
        self.activitypool.clear_pool()
        self.windowmain.setup()
        logging.debug('<<')