From c4daba0dbf0ea3af83d1b7f815b0263c8cc886fd Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 27 Dec 2021 11:41:02 -0600 Subject: [PATCH] continued work on sync engine still left to do: create benchcoachobjects when needed. --- benchcoach/utils/teamsnap_sync_engine.py | 176 ++++++++++++++++++----- benchcoach/utils/test_sync.py | 6 +- 2 files changed, 149 insertions(+), 33 deletions(-) diff --git a/benchcoach/utils/teamsnap_sync_engine.py b/benchcoach/utils/teamsnap_sync_engine.py index 4833bd9..4d2e7a6 100644 --- a/benchcoach/utils/teamsnap_sync_engine.py +++ b/benchcoach/utils/teamsnap_sync_engine.py @@ -7,27 +7,107 @@ import teamsnap.models from benchcoach.utils.sync_engine import AbstractSyncEngine class TeamsnapSyncEngine(AbstractSyncEngine): - models = [Availability, Player, Team, Positioning, Event, Venue] + models = [ + Availability, + Player, + Team, + # Positioning, # Not Implemented + Event, + Venue + ] def __init__(self, managed_team_teamsnap_id, teamsnap_token): self.managed_teamsnap_team_id = managed_team_teamsnap_id self.client = TeamSnap(token=teamsnap_token) - model_map = { - Availability: teamsnap.models.Availability, - Player: teamsnap.models.Member, - Team: teamsnap.models.Team, - Positioning: teamsnap.models.LineupEntry, - Event: teamsnap.models.Event, - Venue: teamsnap.models.Location - } - def _update_teamsnapdb_from_teamsnapapi(self, teamsnap_instance): + ApiObject = { + teamsnap.models.Availability:teamsnap.teamsnap.api.Availability, + teamsnap.models.Member:teamsnap.teamsnap.api.Member, + teamsnap.models.Team:teamsnap.teamsnap.api.Team, + teamsnap.models.Opponent:teamsnap.teamsnap.api.Opponent, + # teamsnap.models.LineupEntry # Not Implemented + teamsnap.models.Event:teamsnap.teamsnap.api.Event, + teamsnap.models.Location:teamsnap.teamsnap.api.Location + }.get(teamsnap_instance._meta.model) teamsnap_model = teamsnap_instance._meta.model - new_data = teamsnap_instance.ApiObject.get(client=self.client, id=teamsnap_instance.id).data - obj, created = teamsnap_model.update_or_create_from_teamsnap_api(new_data) + new_data = ApiObject.get(client=self.client, id=teamsnap_instance.id).data + obj, created = self._update_or_create_from_teamsnapapi(teamsnap_model, new_data) return [(obj, created)] + def _update_or_create_from_teamsnapapi(self, teamsnap_model, teamsnap_data, create_benchcoach_object = False): + related_objects = {} + fields = ['id', 'created_at', 'updated_at'] + if teamsnap_model == teamsnap.models.Event: + fields += [ + 'label', + 'start_date', + 'formatted_title', + 'points_for_opponent', + 'points_for_team', + 'is_game', + 'game_type' + ] + if teamsnap_data.get('location_id'): + related_objects['location'] = self._update_or_create_from_teamsnapapi( + teamsnap.models.Location, + {'id':teamsnap_data['location_id']} + ) + if teamsnap_data.get('opponent_id'): + related_objects['opponent'] = self._update_or_create_from_teamsnapapi( + teamsnap.models.Opponent, + {'id':teamsnap_data['opponent_id']} + ) + + elif teamsnap_model == teamsnap.models.Opponent: + fields += ['name'] + + elif teamsnap_model == teamsnap.models.Team: + fields += ['name'] + + elif teamsnap_model == teamsnap.models.Location: + fields += ['name'] + + elif teamsnap_model == teamsnap.models.Member: + fields += [ + 'first_name', + 'last_name', + 'jersey_number', + 'is_non_player' + ] + elif teamsnap_model == teamsnap.models.Availability: + fields += ['status_code'] + + related_objects['member'] = self._update_or_create_from_teamsnapapi( + teamsnap.models.Member, + {'id': teamsnap_data['member_id']} + ) + + related_objects['event'] = self._update_or_create_from_teamsnapapi( + teamsnap.models.Event, + {'id': teamsnap_data['event_id']} + ) + + else: + raise ValueError + + if teamsnap_data.get('team_id'): + related_objects['team'] = self._update_or_create_from_teamsnapapi(teamsnap.models.Team, + {"id":teamsnap_data['team_id']}) + + data = {field: teamsnap_data[field] for field in fields if teamsnap_data.get(field) != None} + id = data.pop('id') + instance, created = teamsnap_model.objects.update_or_create(id=id, defaults=data) + r_related_objects = [] + for related_object_name, related_objectcreated_list in related_objects.items(): + related_object, created = related_objectcreated_list[0] #FIXME This can't be right, do we need a list for related? + setattr(instance, related_object_name, related_object) + r_related_objects.append((related_object, created)) + instance.save() + # if create_benchcoach_object: + # ben + return [(instance, created)] + r_related_objects + def _update_teamsnapdb_to_benchcoachdb(self, benchcoach_instance, teamsnap_instance, create_if_doesnt_exist: bool = False) -> List[Tuple[django.db.models.Model, bool]]: ''' Function to update from a teamsnap object to Benchcoach object. @@ -217,26 +297,58 @@ class TeamsnapSyncEngine(AbstractSyncEngine): return r def import_items(self, object_name): - Object = { - obj.__name__.lower(): obj - for obj in - [ - teamsnap.models.Availability, - teamsnap.models.Event, - teamsnap.models.LineupEntry, - teamsnap.models.Location, - teamsnap.models.Member, - teamsnap.models.Opponent, - teamsnap.models.Team, - teamsnap.models.User - ] - }.get(object_name) - if not Object: raise KeyError(f"key {object_name} not found.") - r = [] - for Obj in [Object]: - a = Obj.ApiObject.search(self.client, team_id=self.managed_teamsnap_team_id) + object_names = [] + if object_name == 'team': + object_names += ['opponent', 'team'] + elif object_name == 'player': + object_names = ['member'] + elif object_name == 'venue': + object_name == ['location'] + elif object_name in [model.__name__.lower() for model in self.models]: + object_names += [object_name] + + if len(object_names) == 0: + raise ValueError('no valid keyword provided') + + for object_name in object_names: + Object = { + obj.__name__.lower(): obj + for obj in + [ + teamsnap.models.Availability, + teamsnap.models.Event, + # teamsnap.models.LineupEntry, + teamsnap.models.Location, + teamsnap.models.Member, + teamsnap.models.Opponent, + teamsnap.models.Team, + # teamsnap.models.User + ] + }.get(object_name) + + ApiObject = { + apiobj.__name__.lower(): apiobj + for apiobj in + [ + teamsnap.teamsnap.api.Availability, + teamsnap.teamsnap.api.Event, + # teamsnap.teamsnap.api.LineupEntry, + teamsnap.teamsnap.api.Location, + teamsnap.teamsnap.api.Member, + teamsnap.teamsnap.api.Opponent, + teamsnap.teamsnap.api.Team, + # teamsnap.teamsnap.api.User + ] + }.get(object_name) + + pass + + if not Object: raise KeyError(f"key {object_name} not found.") + r = [] + + a = ApiObject.search(self.client, team_id=self.managed_teamsnap_team_id) for _a in a: - obj, created = Obj.update_or_create_from_teamsnap_api(_a.data) - r += [(obj, created)] + response = self._update_or_create_from_teamsnapapi(Object, _a.data) + r += response return r \ No newline at end of file diff --git a/benchcoach/utils/test_sync.py b/benchcoach/utils/test_sync.py index aad951d..b1ccf50 100644 --- a/benchcoach/utils/test_sync.py +++ b/benchcoach/utils/test_sync.py @@ -8,6 +8,10 @@ import benchcoach.models TEAMSNAP_TOKEN = os.environ['TEAMSNAP_TOKEN'] TEAM_TEAMSNAP_ID = os.environ['TEAM_TEAMSNAP_ID'] +syncengine = TeamsnapSyncEngine(managed_team_teamsnap_id=TEAM_TEAMSNAP_ID, teamsnap_token=TEAMSNAP_TOKEN) +r=syncengine.import_items('event') +pass + class TestEventModel(TestCase): fixtures = ['minimal'] @@ -17,5 +21,5 @@ class TestEventModel(TestCase): def test_all_models(self): for Model in self.syncengine.models: with self.subTest(): - + self.syncengine.import_items(Model.__name__.lower()) pass \ No newline at end of file