Jellyfin(8096), OrbStack(8097) 포트 충돌으로 변경. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
59 lines
2.1 KiB
Python
59 lines
2.1 KiB
Python
"""Utility functions for icalendar-searcher."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import Iterable, Iterator
|
|
from datetime import date, datetime
|
|
from itertools import tee
|
|
|
|
from icalendar.prop import TypesFactory
|
|
|
|
## We need an instance of the icalendar.prop.TypesFactory class.
|
|
## We'll make a global instance rather than instantiate it for
|
|
## every loop iteration
|
|
types_factory = TypesFactory()
|
|
|
|
|
|
## Helper to normalize date/datetime for comparison
|
|
## (I feel this one is duplicated over many projects ...)
|
|
def _normalize_dt(dt_value: date | datetime) -> datetime:
|
|
"""Convert date to datetime for comparison, or return datetime as-is with timezone."""
|
|
if dt_value is None:
|
|
return None
|
|
## If it's a date (not datetime), convert to datetime at midnight
|
|
if hasattr(dt_value, "year") and not hasattr(dt_value, "hour"):
|
|
from datetime import time
|
|
|
|
return datetime.combine(dt_value, time.min).astimezone()
|
|
## TODO: we should probably do some research on the default calendar timezone,
|
|
## which may not be the same as the local timezone ... uh ... timezones are
|
|
## difficult.
|
|
return dt_value.astimezone()
|
|
|
|
|
|
## Helper - generators are generally more neat than lists,
|
|
## but bool(x) will always return True. I'd like to verify
|
|
## that a generator is not empty, without side effects.
|
|
def _iterable_or_false(g: Iterable, _debug_print_peek: bool = False) -> bool | Iterable:
|
|
"""This method will return False if it's not possible to get an
|
|
item from the iterable (which can only be done by utilizing
|
|
`next`). It will then return a new iterator that behaves like
|
|
the original iterator (like if `next` wasn't used).
|
|
|
|
Uses itertools.tee to create two independent iterators: one for
|
|
checking if the iterator is empty, and one to return.
|
|
"""
|
|
if not isinstance(g, Iterator):
|
|
return bool(g) and g
|
|
|
|
# Create two independent iterators from the input
|
|
check_it, result_it = tee(g)
|
|
|
|
try:
|
|
my_value = next(check_it)
|
|
if _debug_print_peek:
|
|
print(my_value)
|
|
return result_it # Return the untouched iterator
|
|
except StopIteration:
|
|
return False
|