diff options
| author | Daniel Schadt <kingdread@gmx.de> | 2026-09-25 09:39:14 +0200 |
|---|---|---|
| committer | Daniel Schadt <kingdread@gmx.de> | 2026-09-25 09:39:14 +0200 |
| commit | 3a5187c118aba5eac93e85c9394346fc49fed604 (patch) | |
| tree | 98ba3b5c130a98b1dd7618b7ffe87f45141415ce | |
| parent | ff56efd935d3c68fb9db1921819bef43020b9212 (diff) | |
| download | fietsboek-3a5187c118aba5eac93e85c9394346fc49fed604.tar.gz fietsboek-3a5187c118aba5eac93e85c9394346fc49fed604.tar.bz2 fietsboek-3a5187c118aba5eac93e85c9394346fc49fed604.zip | |
add climb modelclimbs
| -rw-r--r-- | fietsboek/models/__init__.py | 1 | ||||
| -rw-r--r-- | fietsboek/models/climb.py | 64 | ||||
| -rw-r--r-- | fietsboek/models/track.py | 8 |
3 files changed, 73 insertions, 0 deletions
diff --git a/fietsboek/models/__init__.py b/fietsboek/models/__init__.py index 004ed8e..4d4fcaf 100644 --- a/fietsboek/models/__init__.py +++ b/fietsboek/models/__init__.py @@ -9,6 +9,7 @@ from sqlalchemy import engine_from_config, event from sqlalchemy.orm import configure_mappers, sessionmaker from .badge import Badge # flake8: noqa +from .climb import Climb # flake8: noqa from .comment import Comment # flake8: noqa from .image import ImageMetadata # flake8: noqa from .journey import Journey diff --git a/fietsboek/models/climb.py b/fietsboek/models/climb.py new file mode 100644 index 0000000..3dd8d17 --- /dev/null +++ b/fietsboek/models/climb.py @@ -0,0 +1,64 @@ +"""The Climb model.""" + +from typing import TYPE_CHECKING + +from pyramid.httpexceptions import HTTPNotFound +from pyramid.request import Request +from sqlalchemy import ForeignKey, Integer, LargeBinary, Text, select +from sqlalchemy.orm import Mapped, mapped_column, relationship + +from .meta import Base +from ..geo import Path + +if TYPE_CHECKING: + from .track import Track + + +class Climb(Base): + + # pylint: disable=too-few-public-methods + __tablename__ = "climbs" + id: Mapped[int] = mapped_column(Integer, primary_key=True) + track_id: Mapped[int] = mapped_column(Integer, ForeignKey("tracks.id"), nullable=False) + automatic_name: Mapped[str | None] = mapped_column(Text) + given_name: Mapped[str | None] = mapped_column(Text) + image: Mapped[bytes] = mapped_column(LargeBinary) + + start_index: Mapped[int] = mapped_column(Integer, nullable=False) + end_index: Mapped[int] = mapped_column(Integer, nullable=False) + + track: Mapped[Track] = relationship("Track", back_populates="climbs") + + @classmethod + def factory(cls, request: Request) -> "Climb": + """Factory method to pass to a route definition. + + This factory retrieves the climb based on the ``climb_id`` matched + route parameter, and returns the climb. If the climb is not found, + ``HTTPNotFound`` is raised. + + :raises pyramid.httpexception.NotFound: If the climb is not found. + :param request: The pyramid request. + :return: The climb. + """ + query = select(cls).filter_by(id=request.matchdict["climb_id"]) + climb_object = request.dbsession.execute(query).scalar_one_or_none() + if climb_object is None: + raise HTTPNotFound() + return climb_object + + def __acl__(self): + # Delegate all access handling to the track this climb belongs to + return self.track.__acl__() + + def path(self) -> Path: + """Returns the path of this climb.""" + path = self.track.path() + return Path(path.points[self.start_index:self.end_index]) + + def display_name(self) -> str: + if self.given_name: + return self.given_name + return self.automatic_name + +__all__ = ["Climb"] diff --git a/fietsboek/models/track.py b/fietsboek/models/track.py index 95e341f..361cc12 100644 --- a/fietsboek/models/track.py +++ b/fietsboek/models/track.py @@ -309,6 +309,9 @@ class Track(Base): cache: Mapped[Optional["TrackCache"]] = relationship( "TrackCache", back_populates="track", uselist=False, cascade="all, delete-orphan" ) + climbs: Mapped[list["models.Climb"]] = relationship( + "Climb", back_populates="track", cascade="all, delete-orphan" + ) tagged_people: Mapped[list["models.User"]] = relationship( "User", secondary=track_people_assoc, back_populates="tagged_tracks" ) @@ -854,6 +857,11 @@ class TrackWithMetadata: return self.track.badges[:] @property + def climbs(self) -> list["models.Climb"]: + """Climbs of the underlying track.""" + return self.track.climbs[:] + + @property def tags(self) -> list["models.Tag"]: """Tags of the underlying track.""" return self.track.tags[:] |
