Skip to content

Commit

Permalink
Remove remaining usage of INAT_CLIENT and IMG_SESSION globals
Browse files Browse the repository at this point in the history
  • Loading branch information
JWCook committed Nov 29, 2023
1 parent 159a1eb commit b0905be
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 55 deletions.
5 changes: 0 additions & 5 deletions naturtag/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,3 @@ def get_url_hash(url: str) -> str:
thumbnail_hash = md5(url.encode()).hexdigest()
ext = Photo(url=url).ext
return f'{thumbnail_hash}.{ext}'


# TODO: Refactor to depend on app.client and session objects instead of these module-level globals
INAT_CLIENT = iNatDbClient()
IMG_SESSION = ImageSession()
8 changes: 5 additions & 3 deletions naturtag/controllers/observation_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
ObservationImageWindow,
ObservationPhoto,
VerticalLayout,
set_pixmap_async,
)
from naturtag.widgets.observation_images import GEOPRIVACY_ICONS, QUALITY_GRADE_ICONS

Expand Down Expand Up @@ -119,8 +120,9 @@ def load(self, obs: Observation):
self.group_box.setTitle(obs.taxon.full_name)
self.image.hover_event = True
self.image.observation = obs
self.image.set_pixmap_async(
photo=obs.photos[0], # TODO: add Observation.default_photo in pyinat
set_pixmap_async(
self.image,
photo=Observation.default_photo,
priority=QThread.HighPriority,
)
self._update_nav_buttons()
Expand All @@ -131,7 +133,7 @@ def load(self, obs: Observation):
thumb = ObservationPhoto(observation=obs, idx=i + 1, rounded=True)
thumb.setFixedSize(*SIZE_SM)
thumb.on_click.connect(self.image_window.display_observation_fullscreen)
thumb.set_pixmap_async(photo=photo, size='thumbnail')
set_pixmap_async(thumb, photo=photo, size='thumbnail')
self.thumbnails.addWidget(thumb)

# Load observation details
Expand Down
6 changes: 3 additions & 3 deletions naturtag/controllers/taxon_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@

from naturtag.app.style import fa_icon
from naturtag.constants import SIZE_SM
from naturtag.controllers import get_app
from naturtag.settings import UserTaxa
from naturtag.widgets import (
GridLayout,
HorizontalLayout,
TaxonImageWindow,
TaxonInfoCard,
TaxonList,
set_pixmap_async,
)
from naturtag.widgets.layouts import VerticalLayout
from naturtag.widgets.taxon_images import TaxonPhoto
Expand Down Expand Up @@ -110,7 +110,7 @@ def load(self, taxon: Taxon):
self.group_box.setTitle(taxon.full_name)
self.image.hover_event = True
self.image.taxon = taxon
self.image.set_pixmap_async(photo=taxon.default_photo, priority=QThread.HighPriority)
set_pixmap_async(self.image, photo=taxon.default_photo, priority=QThread.HighPriority)
self._update_nav_buttons()

# Load additional thumbnails
Expand All @@ -119,7 +119,7 @@ def load(self, taxon: Taxon):
thumb = TaxonPhoto(taxon=taxon, idx=i + 1, rounded=True)
thumb.setFixedSize(*SIZE_SM)
thumb.on_click.connect(self.image_window.display_taxon_fullscreen)
thumb.set_pixmap_async(photo=photo, size='thumbnail')
set_pixmap_async(thumb, photo=photo, size='thumbnail')
self.thumbnails.addWidget(thumb)

def prev(self):
Expand Down
6 changes: 3 additions & 3 deletions naturtag/metadata/inat_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from pyinaturalist import Observation, Taxon
from pyinaturalist_convert import to_dwc

from naturtag.client import INAT_CLIENT, iNatDbClient
from naturtag.client import iNatDbClient
from naturtag.constants import COMMON_NAME_IGNORE_TERMS, COMMON_RANKS, PathOrStr
from naturtag.metadata import MetaMetadata
from naturtag.settings import Settings
Expand Down Expand Up @@ -55,8 +55,8 @@ def tag_images(
Returns:
Updated image metadata for each image
"""
client = client or INAT_CLIENT
settings = settings or Settings.read()
client = client or iNatDbClient(settings.db_path)

observation = client.from_ids(observation_id, taxon_id)
if not observation:
Expand Down Expand Up @@ -115,8 +115,8 @@ def refresh_tags(
Returns:
Updated metadata objects for updated images only
"""
client = client or INAT_CLIENT
settings = settings or Settings.read()
client = client or iNatDbClient(settings.db_path)
metadata_objs = [
_refresh_tags(MetaMetadata(image_path), client, settings)
for image_path in get_valid_image_paths(
Expand Down
2 changes: 2 additions & 0 deletions naturtag/widgets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
InfoCardList,
ImageWindow,
PixmapLabel,
set_pixmap,
set_pixmap_async,
)
from naturtag.widgets.inputs import IdInput
from naturtag.widgets.logger import QtRichHandler, init_handler
Expand Down
59 changes: 25 additions & 34 deletions naturtag/widgets/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
from pathlib import Path
from typing import TYPE_CHECKING, Iterator, Optional, TypeAlias, Union

from pyinaturalist import Photo
from PySide6.QtCore import QSize, Qt, QThread, Signal
from PySide6.QtGui import QBrush, QFont, QIcon, QPainter, QPixmap
from PySide6.QtWidgets import QLabel, QLayout, QScrollArea, QSizePolicy, QWidget

from naturtag.app.style import fa_icon
from naturtag.client import IMG_SESSION
from naturtag.constants import SIZE_ICON, SIZE_ICON_SM, SIZE_SM, IconDimensions, IntOrStr, PathOrStr
from naturtag.widgets import StylableWidget, VerticalLayout
from naturtag.widgets.layouts import GridLayout, HorizontalLayout
Expand All @@ -24,6 +22,28 @@
logger = getLogger(__name__)


def set_pixmap_async(
pixmap_label: QLabel,
priority: QThread.Priority = QThread.NormalPriority,
**kwargs,
):
"""Fetch an image from a separate thread, and render it in the main thread when complete"""
from naturtag.controllers import get_app

app = get_app()
future = app.threadpool.schedule(app.img_session.get_pixmap, priority=priority, **kwargs)
future.on_result.connect(pixmap_label.setPixmap)


def set_pixmap(pixmap_label: QLabel, *args, **kwargs):
"""Fetch an image from either a local path or remote URL."""
from naturtag.controllers import get_app

app = get_app()
pixmap = app.img_session.get_pixmap(*args, **kwargs)
pixmap_label.setPixmap(pixmap)


class FAIcon(QLabel):
"""A QLabel for displaying a FontAwesome icon"""

Expand Down Expand Up @@ -129,43 +149,14 @@ def __init__(
self.rounded = rounded
self.scale = scale
self.xform = Qt.SmoothTransformation if resample else Qt.FastTransformation
if path or url:
pixmap = self.get_pixmap(path=path, url=url)
self.setPixmap(pixmap)

# TODO: Need quite a bit of refactoring to not depend on global session object
# Pass app.img_session as a parameter instead
def get_pixmap(self, *args, **kwargs) -> QPixmap:
"""Fetch a pixmap from either a local path or remote URL.
This does not render the image, so it is safe to run from any thread.
"""
return IMG_SESSION.get_pixmap(*args, **kwargs)
if path or url:
set_pixmap(self, path=path, url=url)

def setPixmap(self, pixmap: QPixmap):
self._pixmap = pixmap
super().setPixmap(self.scaledPixmap())

def set_pixmap_async(
self,
priority: QThread.Priority = QThread.NormalPriority,
path: Optional[PathOrStr] = None,
photo: Optional[Photo] = None,
size: str = 'medium',
url: Optional[str] = None,
):
"""Fetch a photo from a separate thread, and render it in the main thread when complete"""
from naturtag.controllers import get_app

future = get_app().threadpool.schedule(
self.get_pixmap,
priority=priority,
path=path,
photo=photo,
url=url,
size=size,
)
future.on_result.connect(self.setPixmap)

def clear(self):
self.setPixmap(QPixmap())

Expand Down Expand Up @@ -392,7 +383,7 @@ def add_card(self, card: InfoCard, thumbnail_url: str, idx: Optional[int] = None
self.root.insertWidget(idx, card)
else:
self.root.addWidget(card)
card.thumbnail.set_pixmap_async(url=thumbnail_url)
set_pixmap_async(card.thumbnail, url=thumbnail_url)

def clear(self):
self.root.clear()
Expand Down
14 changes: 10 additions & 4 deletions naturtag/widgets/observation_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@
from PySide6.QtCore import Qt

from naturtag.constants import SIZE_ICON_SM
from naturtag.widgets.images import HoverPhoto, IconLabel, ImageWindow, InfoCard, InfoCardList
from naturtag.widgets.images import (
HoverPhoto,
IconLabel,
ImageWindow,
InfoCard,
InfoCardList,
set_pixmap,
)
from naturtag.widgets.layouts import HorizontalLayout

logger = getLogger(__name__)
Expand Down Expand Up @@ -41,8 +48,7 @@ def __init__(self, obs: Observation, delayed_load: bool = True):
self.observation = obs

if not delayed_load:
pixmap = self.thumbnail.get_pixmap(url=obs.default_photo.thumbnail_url)
self.thumbnail.setPixmap(pixmap)
set_pixmap(self.thumbnail, url=obs.default_photo.thumbnail_url)

# Title: Taxon name
if obs.taxon:
Expand Down Expand Up @@ -173,7 +179,7 @@ def select_image_idx(self, idx: int):
self.set_photo(self.selected_photo)

def set_photo(self, photo: Photo):
self.image.setPixmap(self.image.get_pixmap(url=photo.original_url))
set_pixmap(self.image, url=photo.original_url)

def remove_image(self):
pass
6 changes: 3 additions & 3 deletions naturtag/widgets/taxon_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
ImageWindow,
InfoCard,
InfoCardList,
set_pixmap,
)

if TYPE_CHECKING:
Expand All @@ -42,8 +43,7 @@ def __init__(self, taxon: Taxon, user_observations_count: int = 0, delayed_load:
self.setFixedHeight(90)
self.taxon = taxon
if not delayed_load:
pixmap = self.thumbnail.get_pixmap(url=taxon.default_photo.thumbnail_url)
self.thumbnail.setPixmap(pixmap)
set_pixmap(self.thumbnail, url=taxon.default_photo.thumbnail_url)

# Details
self.title.setText(f'{taxon.rank.title()}: <i>{taxon.name}</i>')
Expand Down Expand Up @@ -128,7 +128,7 @@ def select_image_idx(self, idx: int):
self.set_photo(self.selected_photo)

def set_photo(self, photo: Photo):
self.image.setPixmap(self.image.get_pixmap(url=photo.original_url))
set_pixmap(self.image, url=photo.original_url)
attribution = (
ATTRIBUTION_STRIP_PATTERN.sub('', photo.attribution or '')
.replace('(c)', '©')
Expand Down

0 comments on commit b0905be

Please sign in to comment.