From b585787d6180f23581659e01f6f46ae8480f7b58 Mon Sep 17 00:00:00 2001 From: Aleksandr Karpov Date: Sun, 4 Aug 2024 22:16:41 +0700 Subject: [PATCH 1/6] fix: fix bib and card_numbers indexes --- sportorg/gui/dialogs/entry_mass_edit.py | 4 +- sportorg/gui/dialogs/merge_results.py | 4 +- sportorg/gui/dialogs/result_edit.py | 8 +- sportorg/gui/dialogs/settings.py | 1 + sportorg/gui/dialogs/text_io.py | 2 +- sportorg/models/memory.py | 85 +++++++++++++------ sportorg/models/start/relay.py | 2 +- sportorg/models/start/start_preparation.py | 12 +-- sportorg/modules/backup/json.py | 2 + sportorg/modules/iof/iof_xml.py | 10 +-- .../recovery/recovery_orgeo_finish_csv.py | 2 +- .../modules/sportident/result_generation.py | 4 +- sportorg/modules/winorient/wdb.py | 2 +- sportorg/modules/winorient/winorient.py | 4 +- 14 files changed, 91 insertions(+), 51 deletions(-) diff --git a/sportorg/gui/dialogs/entry_mass_edit.py b/sportorg/gui/dialogs/entry_mass_edit.py index a988e865..d1e7bc49 100644 --- a/sportorg/gui/dialogs/entry_mass_edit.py +++ b/sportorg/gui/dialogs/entry_mass_edit.py @@ -201,7 +201,7 @@ def accept(self, *args, **kwargs): cur_person.qual = change_qual if self.bib_checkbox.isChecked(): - cur_person.change_bib(change_bib) + cur_person.bib = change_bib if self.world_code_checkbox.isChecked(): cur_person.world_code = change_world_code @@ -210,7 +210,7 @@ def accept(self, *args, **kwargs): cur_person.national_code = change_national_code if self.card_checkbox.isChecked(): - cur_person.change_card(change_card_number) + cur_person.card_number = change_card_number if self.start_time_checkbox.isChecked(): cur_person.start_time = change_start_time diff --git a/sportorg/gui/dialogs/merge_results.py b/sportorg/gui/dialogs/merge_results.py index 5a6505b3..b697fc87 100644 --- a/sportorg/gui/dialogs/merge_results.py +++ b/sportorg/gui/dialogs/merge_results.py @@ -93,9 +93,9 @@ def apply_changes_impl(self): result_list.sort(key=lambda c: c.finish_time) final_result = ResultSportident() - final_result.change_bib(cur_bib) + final_result.bib = cur_bib final_result.person = result_list[0].person - final_result.change_card(result_list[0].card_number) + final_result.card_number = result_list[0].card_number cur_cp = first_cp for i in result_list: diff --git a/sportorg/gui/dialogs/result_edit.py b/sportorg/gui/dialogs/result_edit.py index c172ce59..035b0294 100644 --- a/sportorg/gui/dialogs/result_edit.py +++ b/sportorg/gui/dialogs/result_edit.py @@ -24,7 +24,7 @@ from sportorg.gui.utils.custom_controls import AdvComboBox, AdvSpinBox, AdvTimeEdit from sportorg.language import translate from sportorg.models.constant import StatusComments -from sportorg.models.memory import Limit, ResultStatus, Split, race +from sportorg.models.memory import Limit, Result, ResultStatus, Split, race from sportorg.models.result.result_calculation import ResultCalculation from sportorg.models.result.result_checker import ResultChecker, ResultCheckerException from sportorg.models.result.split_calculation import GroupSplits @@ -36,7 +36,7 @@ class ResultEditDialog(QDialog): def __init__(self, result, is_new=False): super().__init__(GlobalAccess().get_main_window()) - self.current_object = result + self.current_object: Result = result self.is_new = is_new self.time_format = 'hh:mm:ss' @@ -260,14 +260,14 @@ def apply_changes_impl(self): if new_bib == 0: if result.person and result.is_punch(): if result.person.card_number == result.card_number: - result.person.change_card(0) + result.person.card_number = 0 result.person = None elif cur_bib != new_bib: new_person = race().find_person_by_bib(new_bib) if new_person: if result.person: if result.is_punch(): - result.person.change_card(0) + result.person.card_number = 0 result.person = new_person if result.is_punch(): race().person_card_number(result.person, result.card_number) diff --git a/sportorg/gui/dialogs/settings.py b/sportorg/gui/dialogs/settings.py index c74fc4c1..f3d69aea 100644 --- a/sportorg/gui/dialogs/settings.py +++ b/sportorg/gui/dialogs/settings.py @@ -24,6 +24,7 @@ get_current_race_index, move_down_race, move_up_race, + race, races, set_current_race_index, ) diff --git a/sportorg/gui/dialogs/text_io.py b/sportorg/gui/dialogs/text_io.py index cef2fa13..dbba6c29 100644 --- a/sportorg/gui/dialogs/text_io.py +++ b/sportorg/gui/dialogs/text_io.py @@ -384,7 +384,7 @@ def set_property(person, key, value, **options): elif key == translate('Bib'): if value.isdigit(): new_bib = int(value) - person.change_bib(new_bib) + person.bib = new_bib elif key == translate('Comment'): person.comment = value elif key == translate('IOF id'): diff --git a/sportorg/models/memory.py b/sportorg/models/memory.py index 0a5524ff..bfa669f4 100644 --- a/sportorg/models/memory.py +++ b/sportorg/models/memory.py @@ -1282,8 +1282,8 @@ def __init__(self): self.name = '' self.surname = '' - self.card_number = 0 - self.bib = 0 + self._card_number = 0 + self._bib = 0 self.birth_date: Optional[date] = None self.organization: Optional[Organization] = None @@ -1372,8 +1372,8 @@ def to_dict(self): def update_data(self, data): self.name = str(data['name']) self.surname = str(data['surname']) - self.change_card(data['card_number']) - self.change_bib(int(data['bib'])) + self.card_number = int(data['card_number']) + self.bib = int(data['bib']) self.contact = [] if data['world_code']: self.world_code = str(data['world_code']) @@ -1393,25 +1393,47 @@ def update_data(self, data): elif 'year' in data and data['year']: # back compatibility with v 1.0.0 self.set_year(int(data['year'])) - def change_bib(self, new_bib: int): - if self.bib == new_bib: + @property + def bib(self): + return self._bib + + @bib.setter + def bib(self, new_bib: int): + if self._bib == new_bib: return r = race() - if self.bib in r.person_index_bib: + if self._bib in r.person_index_bib: r.person_index_bib.pop(self.bib) - self.bib = new_bib - r.index_person(self) + if new_bib > 0 and new_bib in r.person_index_bib: + other_person = r.person_index_bib[new_bib] + if not other_person is self: + logging.info( + f'Duplicate bib {new_bib} (do nothing): {self} | {other_person}' + ) + r.person_index_bib[new_bib] = self + self._bib = new_bib + + @property + def card_number(self): + return self._card_number - def change_card(self, new_card: int): - if self.card_number == new_card: + @card_number.setter + def card_number(self, new_card: int): + if self._card_number == new_card: return r = race() - if self.card_number in r.person_index_card: - r.person_index_card.pop(self.card_number) - self.card_number = new_card - r.index_person(self) + if self._card_number in r.person_index_card: + r.person_index_card.pop(self._card_number) + if new_card > 0 and new_card in r.person_index_card: + other_person = r.person_index_card[new_card] + if not other_person is self: + logging.info( + f'Duplicate card {new_card} (do nothing): {self} | {other_person}' + ) + r.person_index_card[new_card] = self + self._card_number = new_card class RaceData(Model): @@ -1714,8 +1736,8 @@ def get_setting(self, setting, nvl_value=None): def get_days(self, date_=None): return self.data.get_days(date_) - def person_card_number(self, person, number=0): - person.change_card(number) + def person_card_number(self, person: Person, number=0): + person.card_number = number for p in self.persons: if p.card_number == number and p != person: p.card_number = 0 @@ -1728,13 +1750,28 @@ def delete_persons(self, indexes): for i in indexes: person = self.persons[i] persons.append(person) - for result in self.results: - if result.person is person: - result.person = None - result.bib = person.bib + self.clear_person_from_caches(person) del self.persons[i] return persons + def clear_person_from_caches(self, person: Person): + for result in self.results: + if result.person is person: + result.person = None + result.bib = person.bib + if ( + person.bib + and person.bib in self.person_index_bib + and self.person_index_bib[person.bib] is person + ): + del self.person_index_bib[person.bib] + if ( + person.card_number + and person.card_number in self.person_index_card + and self.person_index_card[person.card_number] is person + ): + del self.person_index_card[person.card_number] + def delete_results(self, indexes): indexes = sorted(indexes, reverse=True) results = [] @@ -1789,12 +1826,12 @@ def find_person_result(self, person: Person) -> Optional[Result]: return i return None - def find_person_by_bib(self, bib: int): + def find_person_by_bib(self, bib: int) -> Person: if bib in self.person_index_bib: return self.person_index_bib[bib] return None - def find_person_by_card(self, card: int): + def find_person_by_card(self, card: int) -> Person: if card in self.person_index_card: return self.person_index_card[card] return None @@ -2295,7 +2332,7 @@ def is_out_of_competition(self): def set_bib(self): if self.person: - self.person.change_bib(self.get_bib()) + self.person.bib = self.get_bib() def set_person(self, person): self.person = person diff --git a/sportorg/models/start/relay.py b/sportorg/models/start/relay.py index 14e55e9f..3c12fdba 100644 --- a/sportorg/models/start/relay.py +++ b/sportorg/models/start/relay.py @@ -48,7 +48,7 @@ def get_leg_count(): def set_next_relay_number_to_person(person): - person.change_bib(get_next_relay_number_setting()) + person.bib = get_next_relay_number_setting() set_next_relay_number(get_next_relay_number(person.bib)) diff --git a/sportorg/models/start/start_preparation.py b/sportorg/models/start/start_preparation.py index ed7378fa..b61f1663 100644 --- a/sportorg/models/start/start_preparation.py +++ b/sportorg/models/start/start_preparation.py @@ -573,10 +573,10 @@ def set_numbers_by_minute(self, persons, first_number=1): if current_person.start_time: start_time = current_person.start_time delta = (start_time - first_start).to_minute() - current_person.change_bib(int(min_num + delta)) + current_person.bib = int(min_num + delta) max_assigned_num = max(max_assigned_num, current_person.bib) else: - current_person.change_bib(0) + current_person.bib = 0 if max_assigned_num > first_number: return max_assigned_num + 1 @@ -586,7 +586,7 @@ def set_numbers_by_order(self, persons, first_number=1, interval=1): cur_number = first_number if persons and len(persons) > 0: for current_person in persons: - current_person.change_bib(cur_number) + current_person.bib = cur_number cur_number += interval return cur_number @@ -821,14 +821,14 @@ def copy_bib_to_card_number(): obj = race() for person in obj.persons: if person.bib: - person.change_card(person.bib) + person.card_number = person.bib def copy_card_number_to_bib(): obj = race() for person in obj.persons: if person.card_number: - person.change_bib(person.card_number) + person.bib = person.card_number def clone_relay_legs(min_bib, max_bib, increment): @@ -841,6 +841,6 @@ def clone_relay_legs(min_bib, max_bib, increment): if person.bib and min_bib <= person.bib <= max_bib: new_person = copy(person) new_person.id = uuid.uuid4() - new_person.change_bib(person.bib + increment) + new_person.bib = person.bib + increment new_person.card_number = 0 obj.persons.append(new_person) diff --git a/sportorg/modules/backup/json.py b/sportorg/modules/backup/json.py index 194371ef..7896c197 100644 --- a/sportorg/modules/backup/json.py +++ b/sportorg/modules/backup/json.py @@ -43,6 +43,8 @@ def load(file): # while parsing of data index is created in old object, available as race() obj.person_index_card = tmp_obj.person_index_card obj.person_index_bib = tmp_obj.person_index_bib + tmp_obj.person_index_card = {} + tmp_obj.person_index_bib = {} ResultChecker.check_all() ResultCalculation(obj).process_results() diff --git a/sportorg/modules/iof/iof_xml.py b/sportorg/modules/iof/iof_xml.py index 68002088..1a0342d3 100644 --- a/sportorg/modules/iof/iof_xml.py +++ b/sportorg/modules/iof/iof_xml.py @@ -156,14 +156,14 @@ def create_person(person_entry): if 'race_numbers' in person_entry and len(person_entry['race_numbers']): person.comment = 'C:' + ''.join(person_entry['race_numbers']) if 'control_card' in person_entry and person_entry['control_card']: - person.change_card(int(person_entry['control_card'])) + person.card_number = int(person_entry['control_card']) if 'bib' in person_entry['person'] and person_entry['person']['bib']: - person.change_bib(int(person_entry['person']['bib'])) + person.bib = int(person_entry['person']['bib']) elif ( 'bib' in person_entry['person']['extensions'] and person_entry['person']['extensions']['bib'] ): - person.change_bib(int(person_entry['person']['extensions']['bib'])) + person.bib = int(person_entry['person']['extensions']['bib']) if ( 'qual' in person_entry['person']['extensions'] and person_entry['person']['extensions']['qual'] @@ -260,9 +260,9 @@ def import_from_result_list(results) -> None: if card > 0: new_result.card_number = card if person.card_number == 0: - person.change_card(new_result.card_number) + person.card_number = new_result.card_number - person.change_bib(int(bib)) + person.bib = int(bib) person.start_time = start new_result.person = person diff --git a/sportorg/modules/recovery/recovery_orgeo_finish_csv.py b/sportorg/modules/recovery/recovery_orgeo_finish_csv.py index 04ad1c73..f03d79f1 100644 --- a/sportorg/modules/recovery/recovery_orgeo_finish_csv.py +++ b/sportorg/modules/recovery/recovery_orgeo_finish_csv.py @@ -62,7 +62,7 @@ def recovery(file_name: str, race: Race) -> None: person.name = name[spl_pos + 1 :] else: person.name = name - person.change_bib(int(bib)) + person.bib = int(bib) team_name = tokens[POS_TEAM] team = race.find_team(team_name) diff --git a/sportorg/modules/sportident/result_generation.py b/sportorg/modules/sportident/result_generation.py index 5990f5bf..f362629b 100644 --- a/sportorg/modules/sportident/result_generation.py +++ b/sportorg/modules/sportident/result_generation.py @@ -218,12 +218,12 @@ def _add_result(self): def _create_person(self): new_person = Person() - new_person.change_bib(self._get_max_bib() + 1) + new_person.bib = self._get_max_bib() + 1 existing_person = race().find_person_by_card(self._result.card_number) if existing_person: new_person_copy = deepcopy(existing_person) new_person_copy.id = new_person.id - new_person_copy.change_bib(new_person.bib) + new_person_copy.bib = new_person.bib new_person = new_person_copy new_person.card_number = 0 else: diff --git a/sportorg/modules/winorient/wdb.py b/sportorg/modules/winorient/wdb.py index 1f4605b2..989d77aa 100644 --- a/sportorg/modules/winorient/wdb.py +++ b/sportorg/modules/winorient/wdb.py @@ -120,7 +120,7 @@ def create_objects(self): index_of_first_space = str(man.name.strip()).find(' ') if index_of_first_space > 0: new_person.name = man.name.strip()[index_of_first_space + 1 :].strip() - new_person.change_bib(man.number) + new_person.bib = man.number if man.qualification: if man.qualification == 10: man.qualification = Qualification.MSMK.value # Convert ZMS to MSMK diff --git a/sportorg/modules/winorient/winorient.py b/sportorg/modules/winorient/winorient.py index 700b15a3..79754e3c 100644 --- a/sportorg/modules/winorient/winorient.py +++ b/sportorg/modules/winorient/winorient.py @@ -39,9 +39,9 @@ def import_csv(source): person = memory.Person() person.name = person_dict['name'] person.surname = person_dict['surname'] - person.change_bib(person_dict['bib']) + person.bib = int(person_dict['bib']) person.set_year(person_dict['year']) - person.change_card(int(person_dict['sportident_card'])) + person.card_number = int(person_dict['sportident_card']) person.group = memory.find(obj.groups, name=person_dict['group_name']) person.organization = person_org person.qual = Qualification(qual_id) From ff6ce95cc7d835ed3ffecc22969fa31f815a4d41 Mon Sep 17 00:00:00 2001 From: Aleksandr Karpov Date: Tue, 6 Aug 2024 12:13:05 +0700 Subject: [PATCH 2/6] fix: index sportorg files with several days --- sportorg/modules/backup/json.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/sportorg/modules/backup/json.py b/sportorg/modules/backup/json.py index 7896c197..d74bc952 100644 --- a/sportorg/modules/backup/json.py +++ b/sportorg/modules/backup/json.py @@ -40,12 +40,6 @@ def load(file): set_current_race_index(current_race) obj = race() - # while parsing of data index is created in old object, available as race() - obj.person_index_card = tmp_obj.person_index_card - obj.person_index_bib = tmp_obj.person_index_bib - tmp_obj.person_index_card = {} - tmp_obj.person_index_bib = {} - ResultChecker.check_all() ResultCalculation(obj).process_results() RaceSplits(obj).generate() @@ -68,6 +62,8 @@ def get_races_from_file(file): obj = Race() obj.id = uuid.UUID(str(race_dict['id'])) obj.update_data(race_dict) + # while parsing of data index is created in old object, available as race() + move_indexes_to_new_race(obj) event.append(obj) current_race = 0 if 'current_race' in data: @@ -75,6 +71,13 @@ def get_races_from_file(file): return event, current_race +def move_indexes_to_new_race(obj): + obj.person_index_bib = race().person_index_bib + race().person_index_bib = {} + obj.person_index_card = race().person_index_card + race().person_index_card = {} + + def race_migrate(data): for person in data['persons']: if 'sportident_card' in person: From df46930018d9a41ef1d5478863d5428b6f42fa58 Mon Sep 17 00:00:00 2001 From: Aleksandr Karpov Date: Tue, 6 Aug 2024 12:16:19 +0700 Subject: [PATCH 3/6] feat: rebuild indexes on Rechecking (Ctrl+R) action. --- sportorg/gui/menu/actions.py | 1 + sportorg/models/memory.py | 31 +++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/sportorg/gui/menu/actions.py b/sportorg/gui/menu/actions.py index ef0c8a70..a8703a94 100644 --- a/sportorg/gui/menu/actions.py +++ b/sportorg/gui/menu/actions.py @@ -619,6 +619,7 @@ class RecheckingAction(Action, metaclass=ActionFactory): def execute(self): ResultChecker.check_all() ResultCalculation(race()).process_results() + race().rebuild_indexes() self.app.refresh() diff --git a/sportorg/models/memory.py b/sportorg/models/memory.py index bfa669f4..fb71f18f 100644 --- a/sportorg/models/memory.py +++ b/sportorg/models/memory.py @@ -1402,8 +1402,12 @@ def bib(self, new_bib: int): if self._bib == new_bib: return + self._index_bib(new_bib) + self._bib = new_bib + + def _index_bib(self, new_bib: int) -> None: r = race() - if self._bib in r.person_index_bib: + if self._bib != new_bib and self._bib in r.person_index_bib: r.person_index_bib.pop(self.bib) if new_bib > 0 and new_bib in r.person_index_bib: other_person = r.person_index_bib[new_bib] @@ -1412,7 +1416,9 @@ def bib(self, new_bib: int): f'Duplicate bib {new_bib} (do nothing): {self} | {other_person}' ) r.person_index_bib[new_bib] = self - self._bib = new_bib + + def index_bib(self) -> None: + self._index_bib(self.bib) @property def card_number(self): @@ -1423,8 +1429,12 @@ def card_number(self, new_card: int): if self._card_number == new_card: return + self._index_card(new_card) + self._card_number = new_card + + def _index_card(self, new_card): r = race() - if self._card_number in r.person_index_card: + if self._card_number != new_card and self._card_number in r.person_index_card: r.person_index_card.pop(self._card_number) if new_card > 0 and new_card in r.person_index_card: other_person = r.person_index_card[new_card] @@ -1433,7 +1443,9 @@ def card_number(self, new_card: int): f'Duplicate card {new_card} (do nothing): {self} | {other_person}' ) r.person_index_card[new_card] = self - self._card_number = new_card + + def index_card(self): + self._index_card(self._card_number) class RaceData(Model): @@ -1744,17 +1756,24 @@ def person_card_number(self, person: Person, number=0): p.is_rented_card = False return p + def rebuild_indexes(self): + self.person_index_bib = {} + self.person_index_card = {} + for person in self.persons: + person.index_bib() + person.index_card() + def delete_persons(self, indexes): indexes = sorted(indexes, reverse=True) persons = [] for i in indexes: person = self.persons[i] persons.append(person) - self.clear_person_from_caches(person) + self.remove_person_from_indexes(person) del self.persons[i] return persons - def clear_person_from_caches(self, person: Person): + def remove_person_from_indexes(self, person: Person): for result in self.results: if result.person is person: result.person = None From c62302cfd58278b364912c125750c57bf0655a66 Mon Sep 17 00:00:00 2001 From: Aleksandr Karpov Date: Fri, 9 Aug 2024 13:32:59 +0700 Subject: [PATCH 4/6] fix: use set_bib() and set_card_number() instead of property setters --- sportorg/gui/dialogs/entry_mass_edit.py | 4 ++-- sportorg/gui/dialogs/person_edit.py | 21 +++++++++++++++---- sportorg/gui/dialogs/result_edit.py | 4 ++-- sportorg/gui/dialogs/text_io.py | 2 +- sportorg/gui/tabs/memory_model.py | 4 ++-- sportorg/models/memory.py | 17 +++++++++------ sportorg/models/start/relay.py | 2 +- sportorg/models/start/start_preparation.py | 14 ++++++------- sportorg/modules/iof/iof_xml.py | 13 ++++++------ .../recovery/recovery_orgeo_finish_csv.py | 2 +- .../modules/sportident/result_generation.py | 6 +++--- sportorg/modules/winorient/wdb.py | 2 +- sportorg/modules/winorient/winorient.py | 6 +++--- 13 files changed, 57 insertions(+), 40 deletions(-) diff --git a/sportorg/gui/dialogs/entry_mass_edit.py b/sportorg/gui/dialogs/entry_mass_edit.py index d1e7bc49..6738a0b6 100644 --- a/sportorg/gui/dialogs/entry_mass_edit.py +++ b/sportorg/gui/dialogs/entry_mass_edit.py @@ -201,7 +201,7 @@ def accept(self, *args, **kwargs): cur_person.qual = change_qual if self.bib_checkbox.isChecked(): - cur_person.bib = change_bib + cur_person.set_bib(change_bib) if self.world_code_checkbox.isChecked(): cur_person.world_code = change_world_code @@ -210,7 +210,7 @@ def accept(self, *args, **kwargs): cur_person.national_code = change_national_code if self.card_checkbox.isChecked(): - cur_person.card_number = change_card_number + cur_person.set_card_number(change_card_number) if self.start_time_checkbox.isChecked(): cur_person.start_time = change_start_time diff --git a/sportorg/gui/dialogs/person_edit.py b/sportorg/gui/dialogs/person_edit.py index c65e0a65..bfcd6bb7 100644 --- a/sportorg/gui/dialogs/person_edit.py +++ b/sportorg/gui/dialogs/person_edit.py @@ -14,7 +14,14 @@ from sportorg.gui.global_access import GlobalAccess from sportorg.language import translate from sportorg.models.constant import get_names, get_race_groups, get_race_teams -from sportorg.models.memory import Limit, Organization, Qualification, find, race +from sportorg.models.memory import ( + Limit, + Organization, + Person, + Qualification, + find, + race, +) from sportorg.models.result.result_calculation import ResultCalculation from sportorg.modules.configs.configs import Config from sportorg.modules.live.live import live_client @@ -25,11 +32,13 @@ class PersonEditDialog(BaseDialog): GROUP_NAME = '' ORGANIZATION_NAME = '' - def __init__(self, person, is_new=False): + def __init__(self, person: Person, is_new=False): super().__init__(GlobalAccess().get_main_window()) self.current_object = person self.is_new = is_new self.is_item_valid = {} + self.bib = person.bib + self.card_number = person.card_number time_format = 'hh:mm:ss' if race().get_setting('time_accuracy', 0): @@ -91,7 +100,7 @@ def __init__(self, person, is_new=False): ), NumberField( title=translate('Bib'), - object=person, + object=self, key='bib', id='bib', minimum=0, @@ -123,7 +132,7 @@ def __init__(self, person, is_new=False): ), NumberField( title=translate('Punch card #'), - object=person, + object=self, key='card_number', id='card_number', minimum=0, @@ -264,6 +273,10 @@ def on_card_number_changed(self): def apply(self): person = self.current_object + if self.bib != person.bib: + person.set_bib(self.bib) + if self.card_number != person.card_number: + person.set_card_number(self.card_number) if self.is_new: race().add_person(person) diff --git a/sportorg/gui/dialogs/result_edit.py b/sportorg/gui/dialogs/result_edit.py index 035b0294..560a2bc7 100644 --- a/sportorg/gui/dialogs/result_edit.py +++ b/sportorg/gui/dialogs/result_edit.py @@ -260,14 +260,14 @@ def apply_changes_impl(self): if new_bib == 0: if result.person and result.is_punch(): if result.person.card_number == result.card_number: - result.person.card_number = 0 + result.person.set_card_number(0) result.person = None elif cur_bib != new_bib: new_person = race().find_person_by_bib(new_bib) if new_person: if result.person: if result.is_punch(): - result.person.card_number = 0 + result.person.pset_card_number(0) result.person = new_person if result.is_punch(): race().person_card_number(result.person, result.card_number) diff --git a/sportorg/gui/dialogs/text_io.py b/sportorg/gui/dialogs/text_io.py index dbba6c29..ec63b681 100644 --- a/sportorg/gui/dialogs/text_io.py +++ b/sportorg/gui/dialogs/text_io.py @@ -384,7 +384,7 @@ def set_property(person, key, value, **options): elif key == translate('Bib'): if value.isdigit(): new_bib = int(value) - person.bib = new_bib + person.set_bib(new_bib) elif key == translate('Comment'): person.comment = value elif key == translate('IOF id'): diff --git a/sportorg/gui/tabs/memory_model.py b/sportorg/gui/tabs/memory_model.py index 729fa39b..c650657f 100644 --- a/sportorg/gui/tabs/memory_model.py +++ b/sportorg/gui/tabs/memory_model.py @@ -279,8 +279,8 @@ def duplicate(self, position): person = self.race.persons[position] new_person = copy(person) new_person.id = uuid.uuid4() - new_person.bib = 0 - new_person.card_number = 0 + new_person.set_bib(0) + new_person.set_card_number(0) self.race.persons.insert(position, new_person) def get_values_from_object(self, obj): diff --git a/sportorg/models/memory.py b/sportorg/models/memory.py index fb71f18f..e69cd387 100644 --- a/sportorg/models/memory.py +++ b/sportorg/models/memory.py @@ -1372,8 +1372,8 @@ def to_dict(self): def update_data(self, data): self.name = str(data['name']) self.surname = str(data['surname']) - self.card_number = int(data['card_number']) - self.bib = int(data['bib']) + self.set_card_number(int(data['card_number'])) + self.set_bib(int(data['bib'])) self.contact = [] if data['world_code']: self.world_code = str(data['world_code']) @@ -1399,9 +1399,11 @@ def bib(self): @bib.setter def bib(self, new_bib: int): + raise NotImplementedError('Please, use set_bib()') + + def set_bib(self, new_bib: int) -> None: if self._bib == new_bib: return - self._index_bib(new_bib) self._bib = new_bib @@ -1426,6 +1428,9 @@ def card_number(self): @card_number.setter def card_number(self, new_card: int): + raise NotImplementedError('Please, use set_card_number()') + + def set_card_number(self, new_card: int): if self._card_number == new_card: return @@ -1749,10 +1754,10 @@ def get_days(self, date_=None): return self.data.get_days(date_) def person_card_number(self, person: Person, number=0): - person.card_number = number + person.set_card_number(number) for p in self.persons: if p.card_number == number and p != person: - p.card_number = 0 + p.set_card_number(0) p.is_rented_card = False return p @@ -2351,7 +2356,7 @@ def is_out_of_competition(self): def set_bib(self): if self.person: - self.person.bib = self.get_bib() + self.person.set_bib(self.get_bib()) def set_person(self, person): self.person = person diff --git a/sportorg/models/start/relay.py b/sportorg/models/start/relay.py index 3c12fdba..12f86ed9 100644 --- a/sportorg/models/start/relay.py +++ b/sportorg/models/start/relay.py @@ -48,7 +48,7 @@ def get_leg_count(): def set_next_relay_number_to_person(person): - person.bib = get_next_relay_number_setting() + person.set_bib(get_next_relay_number_setting()) set_next_relay_number(get_next_relay_number(person.bib)) diff --git a/sportorg/models/start/start_preparation.py b/sportorg/models/start/start_preparation.py index b61f1663..46c5f0b0 100644 --- a/sportorg/models/start/start_preparation.py +++ b/sportorg/models/start/start_preparation.py @@ -573,10 +573,10 @@ def set_numbers_by_minute(self, persons, first_number=1): if current_person.start_time: start_time = current_person.start_time delta = (start_time - first_start).to_minute() - current_person.bib = int(min_num + delta) + current_person.set_bib(int(min_num + delta)) max_assigned_num = max(max_assigned_num, current_person.bib) else: - current_person.bib = 0 + current_person.set_bib(0) if max_assigned_num > first_number: return max_assigned_num + 1 @@ -586,7 +586,7 @@ def set_numbers_by_order(self, persons, first_number=1, interval=1): cur_number = first_number if persons and len(persons) > 0: for current_person in persons: - current_person.bib = cur_number + current_person.set_bib(cur_number) cur_number += interval return cur_number @@ -821,14 +821,14 @@ def copy_bib_to_card_number(): obj = race() for person in obj.persons: if person.bib: - person.card_number = person.bib + person.set_card_number(person.bib) def copy_card_number_to_bib(): obj = race() for person in obj.persons: if person.card_number: - person.bib = person.card_number + person.set_bib(person.card_number) def clone_relay_legs(min_bib, max_bib, increment): @@ -841,6 +841,6 @@ def clone_relay_legs(min_bib, max_bib, increment): if person.bib and min_bib <= person.bib <= max_bib: new_person = copy(person) new_person.id = uuid.uuid4() - new_person.bib = person.bib + increment - new_person.card_number = 0 + new_person.set_bib(person.bib + increment) + new_person.set_card_number(0) obj.persons.append(new_person) diff --git a/sportorg/modules/iof/iof_xml.py b/sportorg/modules/iof/iof_xml.py index 1a0342d3..d8008842 100644 --- a/sportorg/modules/iof/iof_xml.py +++ b/sportorg/modules/iof/iof_xml.py @@ -156,14 +156,14 @@ def create_person(person_entry): if 'race_numbers' in person_entry and len(person_entry['race_numbers']): person.comment = 'C:' + ''.join(person_entry['race_numbers']) if 'control_card' in person_entry and person_entry['control_card']: - person.card_number = int(person_entry['control_card']) + person.set_card_number(int(person_entry['control_card'])) if 'bib' in person_entry['person'] and person_entry['person']['bib']: - person.bib = int(person_entry['person']['bib']) + person.set_bib(int(person_entry['person']['bib'])) elif ( 'bib' in person_entry['person']['extensions'] and person_entry['person']['extensions']['bib'] ): - person.bib = int(person_entry['person']['extensions']['bib']) + person.set_bib(int(person_entry['person']['extensions']['bib'])) if ( 'qual' in person_entry['person']['extensions'] and person_entry['person']['extensions']['qual'] @@ -199,11 +199,10 @@ def import_from_entry_list(entries) -> None: person.card_number, ) ) - person.card_number = 0 + person.set_card_number(0) if len(persons_dupl_names): logging.info('{}'.format(translate('Duplicate names'))) for person in sorted(persons_dupl_names, key=lambda x: x.full_name): - person.card_number = 0 logging.info( '{} {} {} {}'.format( person.full_name, @@ -260,9 +259,9 @@ def import_from_result_list(results) -> None: if card > 0: new_result.card_number = card if person.card_number == 0: - person.card_number = new_result.card_number + person.set_card_number(new_result.card_number) - person.bib = int(bib) + person.set_bib(int(bib)) person.start_time = start new_result.person = person diff --git a/sportorg/modules/recovery/recovery_orgeo_finish_csv.py b/sportorg/modules/recovery/recovery_orgeo_finish_csv.py index f03d79f1..c444abf2 100644 --- a/sportorg/modules/recovery/recovery_orgeo_finish_csv.py +++ b/sportorg/modules/recovery/recovery_orgeo_finish_csv.py @@ -62,7 +62,7 @@ def recovery(file_name: str, race: Race) -> None: person.name = name[spl_pos + 1 :] else: person.name = name - person.bib = int(bib) + person.set_bib(int(bib)) team_name = tokens[POS_TEAM] team = race.find_team(team_name) diff --git a/sportorg/modules/sportident/result_generation.py b/sportorg/modules/sportident/result_generation.py index f362629b..b2012a91 100644 --- a/sportorg/modules/sportident/result_generation.py +++ b/sportorg/modules/sportident/result_generation.py @@ -218,14 +218,14 @@ def _add_result(self): def _create_person(self): new_person = Person() - new_person.bib = self._get_max_bib() + 1 + new_person.set_bib(self._get_max_bib() + 1) existing_person = race().find_person_by_card(self._result.card_number) if existing_person: new_person_copy = deepcopy(existing_person) new_person_copy.id = new_person.id - new_person_copy.bib = new_person.bib + new_person_copy.set_bib(new_person.bib) new_person = new_person_copy - new_person.card_number = 0 + new_person.set_card_number(0) else: new_person.surname = translate('Competitor') + ' #' + str(new_person.bib) diff --git a/sportorg/modules/winorient/wdb.py b/sportorg/modules/winorient/wdb.py index 989d77aa..46ddde73 100644 --- a/sportorg/modules/winorient/wdb.py +++ b/sportorg/modules/winorient/wdb.py @@ -120,7 +120,7 @@ def create_objects(self): index_of_first_space = str(man.name.strip()).find(' ') if index_of_first_space > 0: new_person.name = man.name.strip()[index_of_first_space + 1 :].strip() - new_person.bib = man.number + new_person.set_bib(man.number) if man.qualification: if man.qualification == 10: man.qualification = Qualification.MSMK.value # Convert ZMS to MSMK diff --git a/sportorg/modules/winorient/winorient.py b/sportorg/modules/winorient/winorient.py index 79754e3c..fedfc572 100644 --- a/sportorg/modules/winorient/winorient.py +++ b/sportorg/modules/winorient/winorient.py @@ -39,9 +39,9 @@ def import_csv(source): person = memory.Person() person.name = person_dict['name'] person.surname = person_dict['surname'] - person.bib = int(person_dict['bib']) + person.set_bib(int(person_dict['bib'])) person.set_year(person_dict['year']) - person.card_number = int(person_dict['sportident_card']) + person.set_card_number(int(person_dict['sportident_card'])) person.group = memory.find(obj.groups, name=person_dict['group_name']) person.organization = person_org person.qual = Qualification(qual_id) @@ -73,7 +73,7 @@ def import_csv(source): person.card_number, ) ) - person.card_number = 0 + person.set_card_number(0) if len(persons_dupl_names): logging.info('{}'.format(translate('Duplicate names'))) for person in sorted(persons_dupl_names, key=lambda x: x.full_name): From a1c10c7593659d82a2128f65a7b206aa3b5c51cb Mon Sep 17 00:00:00 2001 From: Aleksandr Karpov <31531412+alex-karpov@users.noreply.github.com> Date: Fri, 9 Aug 2024 20:57:43 +0700 Subject: [PATCH 5/6] fix: fix typo Co-authored-by: Danil Akhtarov --- sportorg/gui/dialogs/result_edit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sportorg/gui/dialogs/result_edit.py b/sportorg/gui/dialogs/result_edit.py index 560a2bc7..f05a512a 100644 --- a/sportorg/gui/dialogs/result_edit.py +++ b/sportorg/gui/dialogs/result_edit.py @@ -267,7 +267,7 @@ def apply_changes_impl(self): if new_person: if result.person: if result.is_punch(): - result.person.pset_card_number(0) + result.person.set_card_number(0) result.person = new_person if result.is_punch(): race().person_card_number(result.person, result.card_number) From 73a5afc475dc9f47183ceaa5bb4a7d658db13112 Mon Sep 17 00:00:00 2001 From: Aleksandr Karpov Date: Sat, 17 Aug 2024 23:11:58 +0700 Subject: [PATCH 6/6] fix: change string formatting in logger --- sportorg/models/memory.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sportorg/models/memory.py b/sportorg/models/memory.py index e69cd387..c534699a 100644 --- a/sportorg/models/memory.py +++ b/sportorg/models/memory.py @@ -1415,7 +1415,10 @@ def _index_bib(self, new_bib: int) -> None: other_person = r.person_index_bib[new_bib] if not other_person is self: logging.info( - f'Duplicate bib {new_bib} (do nothing): {self} | {other_person}' + 'Duplicate bib %s (do nothing): %s | %s', + new_bib, + self, + other_person, ) r.person_index_bib[new_bib] = self @@ -1445,7 +1448,10 @@ def _index_card(self, new_card): other_person = r.person_index_card[new_card] if not other_person is self: logging.info( - f'Duplicate card {new_card} (do nothing): {self} | {other_person}' + 'Duplicate card %s (do nothing): %s | %s', + new_card, + self, + other_person, ) r.person_index_card[new_card] = self