diff --git a/personal_data/util.py b/personal_data/util.py index ac385d3..4d64b50 100644 --- a/personal_data/util.py +++ b/personal_data/util.py @@ -1,41 +1,44 @@ import csv import datetime import decimal -import inspect import io +import urllib.parse from pathlib import Path import logging -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Iterable, Mapping, Sequence, Callable from decimal import Decimal -import requests -import requests_cache +import typing from frozendict import frozendict -from . import notification, data +from . import data logger = logging.getLogger(__name__) CSV_DIALECT = 'one_true_dialect' csv.register_dialect(CSV_DIALECT, lineterminator='\n', skipinitialspace=True) -def try_value(fn, s: str) -> object: +T = typing.TypeVar('T') + +def try_value(fn: Callable[[str],T], s: str) -> T | None: try: return fn(s) except (ValueError, decimal.InvalidOperation): return None -def to_value(s: str) -> object: +def to_value(s: str) -> str | Decimal | datetime.date | datetime.datetime | urllib.parse.ParseResult | bool | None: s = s.strip() if len(s) == 0: return None - if (v := try_value(Decimal, s)) is not None: - return v - if v := try_value(datetime.date.fromisoformat, s): - return v - if v := try_value(datetime.datetime.fromisoformat, s): - return v + if (v_decimal := try_value(Decimal, s)) is not None: + return v_decimal + if (v_date := try_value(datetime.date.fromisoformat, s)) is not None: + return v_date + if (v_datetime := try_value(datetime.datetime.fromisoformat, s)) is not None: + return v_datetime + if s.startswith(('http://', 'https://')): + return urllib.parse.urlparse(s) if s.lower() == 'false': return False if s.lower() == 'true': diff --git a/personal_data_calendar/__main__.py b/personal_data_calendar/__main__.py index 34c0ac9..62ac194 100644 --- a/personal_data_calendar/__main__.py +++ b/personal_data_calendar/__main__.py @@ -1,6 +1,7 @@ import argparse import logging import icalendar +import urllib.parse import datetime import csv @@ -20,16 +21,29 @@ def generate_calendar(rows: list[dict]) -> icalendar.Calendar: cal.add('version', '2.0') for event_data in rows: - # Select data print(event_data) + # Select data + possible_time_keys = [k for k,v in event_data.items() if isinstance(v, datetime.date)] + possible_name_keys = [k for k,v in event_data.items() if isinstance(v, str)] + possible_image_keys = [k for k,v in event_data.items() if isinstance(v, urllib.parse.ParseResult)] + + date = event_data[possible_time_keys[0]] if possible_time_keys else None + title = event_data[possible_name_keys[0]] + image = event_data[possible_image_keys[0]] if possible_image_keys else None + + if date is None: + continue + # Create event event = icalendar.Event() - event.add('summary', f'Event {i}') - event.add('dtstart', datetime.datetime(2005,4,4,8,0,0,tzinfo=datetime.UTC)) - event.add('dtend', datetime.datetime(2005,4,4,10,0,0,tzinfo=datetime.UTC)) + event.add('summary', title) + event.add('dtstart', date) + event.add('dtend', date) event.add('created', NOW) event.add('dtstamp', NOW) + if image: + event.add('image', image.geturl()) cal.add_component(event) del event