From 81726a4236ee290e508003a5f8e398f709cbbde4 Mon Sep 17 00:00:00 2001 From: Jordan Cook Date: Tue, 5 Dec 2023 22:39:21 -0600 Subject: [PATCH] Don't attempt to fetch observations without a username --- naturtag/client.py | 12 ++++++--- .../controllers/observation_controller.py | 26 +++++++++---------- naturtag/settings.py | 2 +- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/naturtag/client.py b/naturtag/client.py index 1f82d0dd..1b95a9b3 100644 --- a/naturtag/client.py +++ b/naturtag/client.py @@ -84,7 +84,7 @@ def from_ids( logger.debug(f'Fetching remaining {len(remaining_ids)} observations from API') api_results = super().from_ids(*remaining_ids, **params).all() observations.extend(api_results) - save_observations(api_results, self.client.db_path) + self.save(api_results) # Add full taxonomy to observations, if specified if taxonomy: @@ -101,7 +101,7 @@ def count(self, username: str, **params) -> int: def search(self, **params) -> WrapperPaginator[Observation]: """Search observations, and save results to the database (for future reference by ID)""" results = super().search(**params).all() - save_observations(results, self.client.db_path) + self.save(results) return WrapperPaginator(results) def get_user_observations( @@ -135,7 +135,9 @@ def get_user_observations( ) return new_observations[:limit] - # Otherwise get up to `limit` most recent saved observations from the db + # Otherwise get up to `limit` most recent saved observations from the db. This includes ones + # we just fetched and saved; otherwise we can't accurately sort a mix of API results and db + # results by created date in a single query. obs = get_db_observations( self.client.db_path, username=username, @@ -145,6 +147,10 @@ def get_user_observations( ) return list(obs) + def save(self, observations: list[Observation]): + """Save observations to the database""" + save_observations(observations, self.client.db_path) + class TaxonDbController(TaxonController): def from_ids( diff --git a/naturtag/controllers/observation_controller.py b/naturtag/controllers/observation_controller.py index 058eee3e..6d08dd7b 100644 --- a/naturtag/controllers/observation_controller.py +++ b/naturtag/controllers/observation_controller.py @@ -97,6 +97,10 @@ def select_observation(self, observation_id: int): def load_user_observations(self): """Fetch and display a single page of user observations""" + if not self.app.settings.username: + logger.info('Unknown user; skipping observation load') + return + logger.info('Fetching user observations') future = self.app.threadpool.schedule( self.get_user_observations, priority=QThread.LowPriority @@ -131,20 +135,21 @@ def display_observation(self, observation: Observation): @Slot(list) def display_user_observations(self, observations: list[Observation]): """Display a page of observations""" - # Update observation list self.user_observations.set_observations(observations) self.bind_selection(self.user_observations.cards) - - # Update pagination buttons based on current page - self.prev_button.setEnabled(self.page > 1) - self.next_button.setEnabled(self.page < self.total_pages) - self.page_label.setText(f'Page {self.page} / {self.total_pages}') + self.update_pagination_buttons() def bind_selection(self, obs_cards: Iterable[ObservationInfoCard]): """Connect click signal from each observation card""" for obs_card in obs_cards: obs_card.on_click.connect(self.select_observation) + def update_pagination_buttons(self): + """Update pagination buttons based on current page""" + self.prev_button.setEnabled(self.page > 1) + self.next_button.setEnabled(self.page < self.total_pages) + self.page_label.setText(f'Page {self.page} / {self.total_pages}') + # I/O bound functions run from worker threads # ---------------------------------------- @@ -152,12 +157,6 @@ def bind_selection(self, obs_cards: Iterable[ObservationInfoCard]): # TODO: Store a Paginator object instead of page number? def get_user_observations(self) -> list[Observation]: """Fetch a single page of user observations""" - if not self.app.settings.username: - return [] - - updated_since = self.app.settings.last_obs_check - self.app.settings.set_obs_checkpoint() - # TODO: Depending on order of operations, this could be counted from the db instead of API. # Maybe do that except on initial observation load? total_results = self.app.client.observations.count(username=self.app.settings.username) @@ -166,8 +165,9 @@ def get_user_observations(self) -> list[Observation]: observations = self.app.client.observations.get_user_observations( username=self.app.settings.username, - updated_since=updated_since, + updated_since=self.app.settings.last_obs_check, limit=DEFAULT_PAGE_SIZE, page=self.page, ) + self.app.settings.set_obs_checkpoint() return observations diff --git a/naturtag/settings.py b/naturtag/settings.py index a404d388..de5a5b0a 100644 --- a/naturtag/settings.py +++ b/naturtag/settings.py @@ -124,7 +124,7 @@ class Settings(YamlMixin): default=False, doc='Show all available taxonomic rank filters on taxon search page' ) casual_observations: bool = doc_field( - default=True, doc='Include casual observations in searches' + default=True, doc='Include taxa from casual observations in user taxa list' ) locale: str = doc_field(default='en', doc='Locale preference for species common names') preferred_place_id: int = doc_field(