mirror of
https://code.lenaisten.de/Lenaisten/advent22.git
synced 2024-11-22 15:53:01 +00:00
helpers.EventDays class + basic testing
This commit is contained in:
parent
e9ef7f67e3
commit
97d4d1e136
6 changed files with 206 additions and 1 deletions
5
api/.vscode/settings.json
vendored
5
api/.vscode/settings.json
vendored
|
@ -13,4 +13,9 @@
|
|||
"git.closeDiffOnOperation": true,
|
||||
"python.analysis.typeCheckingMode": "basic",
|
||||
"python.analysis.diagnosticMode": "workspace",
|
||||
"python.testing.pytestArgs": [
|
||||
"test"
|
||||
],
|
||||
"python.testing.unittestEnabled": false,
|
||||
"python.testing.pytestEnabled": true,
|
||||
}
|
11
api/advent22_api/core/__init__.py
Normal file
11
api/advent22_api/core/__init__.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
from . import advent_image, calendar_config, config, depends, helpers, settings, webdav
|
||||
|
||||
__all__ = [
|
||||
"advent_image",
|
||||
"calendar_config",
|
||||
"config",
|
||||
"depends",
|
||||
"helpers",
|
||||
"settings",
|
||||
"webdav",
|
||||
]
|
|
@ -1,11 +1,13 @@
|
|||
import itertools
|
||||
import random
|
||||
import re
|
||||
from datetime import date, datetime, timedelta
|
||||
from io import BytesIO
|
||||
from typing import Any, Self, Sequence, TypeVar
|
||||
|
||||
from fastapi.responses import StreamingResponse
|
||||
from PIL import Image
|
||||
from pydantic import BaseModel
|
||||
|
||||
from .config import get_config
|
||||
from .webdav import WebDAV
|
||||
|
@ -68,3 +70,52 @@ async def api_return_image(img: Image.Image) -> StreamingResponse:
|
|||
media_type="image/jpeg",
|
||||
content=img_buffer,
|
||||
)
|
||||
|
||||
|
||||
class EventDays(BaseModel):
|
||||
first: date
|
||||
next: date | None
|
||||
last: date
|
||||
end: date
|
||||
|
||||
@classmethod
|
||||
def get(
|
||||
cls,
|
||||
*,
|
||||
# current date
|
||||
today: date,
|
||||
# month/day when events begin
|
||||
begin_month: int,
|
||||
begin_day: int,
|
||||
# events: e.g. a 2 means there is an event 2 days after begin
|
||||
# -> assume sorted (asc)
|
||||
events_after: list[int],
|
||||
# countdown to closing begins after last event
|
||||
closing_after: int,
|
||||
) -> Self:
|
||||
"""
|
||||
foo bar
|
||||
"""
|
||||
|
||||
# account for the last event, then add closing period
|
||||
duration = timedelta(days=events_after[-1] + closing_after)
|
||||
|
||||
# the events may begin last year, this year or next year
|
||||
maybe_begin = (
|
||||
datetime(today.year + year_diff, begin_month, begin_day).date()
|
||||
for year_diff in (-1, 0, +1)
|
||||
)
|
||||
|
||||
# find the first begin where the end date is in the future
|
||||
begin = next(begin for begin in maybe_begin if today <= (begin + duration))
|
||||
|
||||
# all event dates
|
||||
events = [begin + timedelta(days=event_after) for event_after in events_after]
|
||||
|
||||
# return relevant event dates
|
||||
return cls(
|
||||
first=events[0],
|
||||
next=next((event for event in events if event > today), None),
|
||||
last=events[-1],
|
||||
end=begin + duration,
|
||||
)
|
||||
|
|
59
api/poetry.lock
generated
59
api/poetry.lock
generated
|
@ -266,6 +266,17 @@ files = [
|
|||
{file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
description = "brain-dead simple config-ini parsing"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
|
||||
{file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lxml"
|
||||
version = "4.9.3"
|
||||
|
@ -418,6 +429,17 @@ files = [
|
|||
{file = "numpy-1.25.2.tar.gz", hash = "sha256:fd608e19c8d7c55021dffd43bfe5492fab8cc105cc8986f813f8c3c048b38760"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "23.1"
|
||||
description = "Core utilities for Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
|
||||
{file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pillow"
|
||||
version = "10.0.0"
|
||||
|
@ -487,6 +509,21 @@ files = [
|
|||
docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"]
|
||||
tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.3.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"},
|
||||
{file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["pre-commit", "tox"]
|
||||
testing = ["pytest", "pytest-benchmark"]
|
||||
|
||||
[[package]]
|
||||
name = "pycodestyle"
|
||||
version = "2.11.0"
|
||||
|
@ -661,6 +698,26 @@ files = [
|
|||
{file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "7.4.2"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"},
|
||||
{file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
iniconfig = "*"
|
||||
packaging = "*"
|
||||
pluggy = ">=0.12,<2.0"
|
||||
|
||||
[package.extras]
|
||||
testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
|
||||
|
||||
[[package]]
|
||||
name = "python-dateutil"
|
||||
version = "2.8.2"
|
||||
|
@ -1047,4 +1104,4 @@ files = [
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.11"
|
||||
content-hash = "c2a27f4ecbc1c234d1368320db111d6c51cd4278986e64e80398cad384037a8c"
|
||||
content-hash = "9039ceba03b4dfdaa6507b4b88d45125f7d33c05438133462d1cb338c5650eed"
|
||||
|
|
|
@ -21,6 +21,7 @@ webdavclient3 = "^3.14.6"
|
|||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
flake8 = "^6.1.0"
|
||||
pytest = "^7.4.2"
|
||||
|
||||
[build-system]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
|
80
api/test/test_helpers.py
Normal file
80
api/test/test_helpers.py
Normal file
|
@ -0,0 +1,80 @@
|
|||
from datetime import datetime
|
||||
|
||||
from advent22_api.core.helpers import EventDays
|
||||
|
||||
|
||||
class TestEventDays:
|
||||
@staticmethod
|
||||
def test_get_before():
|
||||
ed = EventDays.get(
|
||||
today=datetime(2023, 11, 30).date(),
|
||||
begin_month=12,
|
||||
begin_day=1,
|
||||
events_after=list(range(24)),
|
||||
closing_after=5,
|
||||
)
|
||||
|
||||
assert ed.first == datetime(2023, 12, 1).date()
|
||||
assert ed.next == datetime(2023, 12, 1).date()
|
||||
assert ed.last == datetime(2023, 12, 24).date()
|
||||
assert ed.end == datetime(2023, 12, 29).date()
|
||||
|
||||
@staticmethod
|
||||
def test_get_after():
|
||||
ed = EventDays.get(
|
||||
today=datetime(2023, 12, 30).date(),
|
||||
begin_month=12,
|
||||
begin_day=1,
|
||||
events_after=list(range(24)),
|
||||
closing_after=5,
|
||||
)
|
||||
|
||||
assert ed.first == datetime(2024, 12, 1).date()
|
||||
assert ed.next == datetime(2024, 12, 1).date()
|
||||
assert ed.last == datetime(2024, 12, 24).date()
|
||||
assert ed.end == datetime(2024, 12, 29).date()
|
||||
|
||||
@staticmethod
|
||||
def test_get_during_events():
|
||||
ed = EventDays.get(
|
||||
today=datetime(2023, 12, 10).date(),
|
||||
begin_month=12,
|
||||
begin_day=1,
|
||||
events_after=list(range(24)),
|
||||
closing_after=5,
|
||||
)
|
||||
|
||||
assert ed.first == datetime(2023, 12, 1).date()
|
||||
assert ed.next == datetime(2023, 12, 11).date()
|
||||
assert ed.last == datetime(2023, 12, 24).date()
|
||||
assert ed.end == datetime(2023, 12, 29).date()
|
||||
|
||||
@staticmethod
|
||||
def test_get_during_closing():
|
||||
ed = EventDays.get(
|
||||
today=datetime(2023, 12, 29).date(),
|
||||
begin_month=12,
|
||||
begin_day=1,
|
||||
events_after=list(range(24)),
|
||||
closing_after=5,
|
||||
)
|
||||
|
||||
assert ed.first == datetime(2023, 12, 1).date()
|
||||
assert ed.next is None
|
||||
assert ed.last == datetime(2023, 12, 24).date()
|
||||
assert ed.end == datetime(2023, 12, 29).date()
|
||||
|
||||
@staticmethod
|
||||
def test_get_during_wrap():
|
||||
ed = EventDays.get(
|
||||
today=datetime(2024, 1, 1).date(),
|
||||
begin_month=12,
|
||||
begin_day=1,
|
||||
events_after=list(range(24)),
|
||||
closing_after=8,
|
||||
)
|
||||
|
||||
assert ed.first == datetime(2023, 12, 1).date()
|
||||
assert ed.next is None
|
||||
assert ed.last == datetime(2023, 12, 24).date()
|
||||
assert ed.end == datetime(2024, 1, 1).date()
|
Loading…
Reference in a new issue