From 965c9b6280b27bb3f3f5a14f0f8b771e94a31780 Mon Sep 17 00:00:00 2001 From: Christian Geier Date: Tue, 31 Oct 2023 01:49:29 +0100 Subject: [PATCH] accept multiple addresses per calendar account --- CHANGELOG.rst | 2 +- khal/cli.py | 2 +- khal/custom_types.py | 2 +- khal/khalendar/event.py | 10 +++++----- khal/khalendar/khalendar.py | 2 +- khal/settings/khal.spec | 7 ++++--- tests/configs/small.conf | 2 +- tests/conftest.py | 4 ++-- tests/event_test.py | 14 +++++++------- tests/settings_test.py | 8 ++++---- 10 files changed, 27 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7ab0a2b84..9f02dcdaf 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -23,7 +23,7 @@ not released yet tentative) * NEW event format option `partstat-symbol` which represents the participation status of an event with a symbol (e.g. `✓` for accepted, `✗` for declined, - `?` for tentative); partication status is shown for the email address + `?` for tentative); partication status is shown for the email addresses configured for the event's calendar 0.11.2 diff --git a/khal/cli.py b/khal/cli.py index b3443e33b..baf8c0090 100644 --- a/khal/cli.py +++ b/khal/cli.py @@ -175,7 +175,7 @@ def build_collection(conf, selection): 'color': cal['color'], 'priority': cal['priority'], 'ctype': cal['type'], - 'address': cal['address'], + 'addresses': cal['addresses'], } collection = khalendar.CalendarCollection( calendars=props, diff --git a/khal/custom_types.py b/khal/custom_types.py index cda30cecf..328ed363c 100644 --- a/khal/custom_types.py +++ b/khal/custom_types.py @@ -12,7 +12,7 @@ class CalendarConfiguration(TypedDict): color: str priority: int ctype: str - address: str + addresses: str class LocaleConfiguration(TypedDict): diff --git a/khal/khalendar/event.py b/khal/khalendar/event.py index d3f38e2c9..3583bc33c 100644 --- a/khal/khalendar/event.py +++ b/khal/khalendar/event.py @@ -68,7 +68,7 @@ def __init__(self, color: Optional[str] = None, start: Optional[dt.datetime] = None, end: Optional[dt.datetime] = None, - address: str = '', + addresses: List[str] = [], ): """ :param start: start datetime of this event instance @@ -88,7 +88,7 @@ def __init__(self, self.color = color self._start: dt.datetime self._end: dt.datetime - self.address = address + self.addresses = addresses if start is None: self._start = self._vevents[self.ref]['DTSTART'].dt @@ -803,9 +803,9 @@ def status(self) -> str: @property def partstat(self) -> Optional[str]: for attendee in self._vevents[self.ref].get('ATTENDEE', []): - print(attendee) - if attendee == 'mailto:' + self.address: - return attendee.params.get('PARTSTAT', '') + for address in self.addresses: + if attendee == 'mailto:' + address: + return attendee.params.get('PARTSTAT', '') class DatetimeEvent(Event): diff --git a/khal/khalendar/khalendar.py b/khal/khalendar/khalendar.py index 4b9820b8b..21c85ae8d 100644 --- a/khal/khalendar/khalendar.py +++ b/khal/khalendar/khalendar.py @@ -284,7 +284,7 @@ def _construct_event(self, ref=ref, color=self._calendars[calendar]['color'], readonly=self._calendars[calendar]['readonly'], - address=self._calendars[calendar]['address'], + addresses=self._calendars[calendar]['addresses'], ) return event diff --git a/khal/settings/khal.spec b/khal/settings/khal.spec index 59d5fa240..70a308a42 100644 --- a/khal/settings/khal.spec +++ b/khal/settings/khal.spec @@ -71,9 +71,10 @@ readonly = boolean(default=False) # *calendars* subsection will be used. type = option('calendar', 'birthdays', 'discover', default='calendar') -# The email address associated with this account. For now it is only used to -# check what participation status ("PARTSTAT") belongs to the user. -address = string(default='') +# All email addresses associated with this account, separated by commas. +# For now it is only used to check what participation status ("PARTSTAT") +# belongs to the user. +addresses = force_list(default='') [sqlite] # khal stores its internal caching database here, by default this will be in the *$XDG_DATA_HOME/khal/khal.db* (this will most likely be *~/.local/share/khal/khal.db*). diff --git a/tests/configs/small.conf b/tests/configs/small.conf index 07a65329a..37271e909 100644 --- a/tests/configs/small.conf +++ b/tests/configs/small.conf @@ -8,4 +8,4 @@ [[work]] path = ~/.calendars/work/ readonly = True - address = user@example.com + addresses = user@example.com diff --git a/tests/conftest.py b/tests/conftest.py index cc23f721d..07b5f1128 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -56,7 +56,7 @@ def coll_vdirs(tmpdir) -> CollVdirType: color='dark blue', priority=10, ctype='calendar', - address='user@example.com', + addresses='user@example.com', ) vdirs[name] = Vdir(path, '.ics') coll = CalendarCollection(calendars=calendars, dbpath=':memory:', locale=LOCALE_BERLIN) @@ -73,7 +73,7 @@ def coll_vdirs_birthday(tmpdir): readonly = True if name == 'a_calendar' else False calendars[name] = {'name': name, 'path': path, 'color': 'dark blue', 'readonly': readonly, 'unicode_symbols': True, 'ctype': 'birthdays', - 'address': 'user@example.com'} + 'addresses': 'user@example.com'} vdirs[name] = Vdir(path, '.vcf') coll = CalendarCollection(calendars=calendars, dbpath=':memory:', locale=LOCALE_BERLIN) coll.default_calendar_name = cal1 diff --git a/tests/event_test.py b/tests/event_test.py index 19a78887e..8a4b34601 100644 --- a/tests/event_test.py +++ b/tests/event_test.py @@ -332,8 +332,8 @@ def test_status_confirmed(): FORMAT_CALENDAR = ('{calendar-color}{status-symbol}{start-end-time-style} ({calendar}) ' '{title} [{location}]{repeat-symbol}') - assert event.format(FORMAT_CALENDAR, dt.date(2014, 4, 9)) == \ - ' ✔09:30-10:30 (foobar) An Event []\x1b[0m' + assert human_formatter(FORMAT_CALENDAR)(event.attributes(dt.date(2014, 4, 9))) == \ + '✔09:30-10:30 (foobar) An Event []\x1b[0m' def test_event_d_long(): event_d_long = _get_text('event_d_long') @@ -696,19 +696,19 @@ def test_partstat(): ) event = Event.fromString( - _get_text('event_dt_partstat'), address='jdoe@example.com', **EVENT_KWARGS) + _get_text('event_dt_partstat'), addresses=['jdoe@example.com'], **EVENT_KWARGS) assert event.partstat == 'ACCEPTED' assert human_formatter(FORMAT_CALENDAR)(event.attributes(dt.date(2014, 4, 9))) == \ '✔09:30-10:30 (foobar) An Event []\x1b[0m' event = Event.fromString( - _get_text('event_dt_partstat'), address='another@example.com', **EVENT_KWARGS) + _get_text('event_dt_partstat'), addresses=['another@example.com'], **EVENT_KWARGS) assert event.partstat == 'DECLINED' assert human_formatter(FORMAT_CALENDAR)(event.attributes(dt.date(2014, 4, 9))) == \ '❌09:30-10:30 (foobar) An Event []\x1b[0m' event = Event.fromString( - _get_text('event_dt_partstat'), address='jqpublic@example.com', **EVENT_KWARGS) + _get_text('event_dt_partstat'), addresses=['jqpublic@example.com'], **EVENT_KWARGS) assert event.partstat == 'ACCEPTED' assert human_formatter(FORMAT_CALENDAR)(event.attributes(dt.date(2014, 4, 9))) == \ '✔09:30-10:30 (foobar) An Event []\x1b[0m' @@ -716,9 +716,9 @@ def test_partstat(): @pytest.mark.xfail def test_partstat_deligated(): event = Event.fromString( - _get_text('event_dt_partstat'), address='hcabot@example.com', **EVENT_KWARGS) + _get_text('event_dt_partstat'), addresses=['hcabot@example.com'], **EVENT_KWARGS) assert event.partstat == 'ACCEPTED' event = Event.fromString( - _get_text('event_dt_partstat'), address='iamboss@example.com', **EVENT_KWARGS) + _get_text('event_dt_partstat'), addresses=['iamboss@example.com'], **EVENT_KWARGS) assert event.partstat == 'ACCEPTED' diff --git a/tests/settings_test.py b/tests/settings_test.py index f30f0eee6..9ae73bae7 100644 --- a/tests/settings_test.py +++ b/tests/settings_test.py @@ -42,11 +42,11 @@ def test_simple_config(self): 'calendars': { 'home': { 'path': os.path.expanduser('~/.calendars/home/'), 'readonly': False, - 'color': None, 'priority': 10, 'type': 'calendar', 'address': '', + 'color': None, 'priority': 10, 'type': 'calendar', 'addresses': [''], }, 'work': { 'path': os.path.expanduser('~/.calendars/work/'), 'readonly': False, - 'color': None, 'priority': 10, 'type': 'calendar', 'address': '', + 'color': None, 'priority': 10, 'type': 'calendar', 'addresses': [''], }, }, 'sqlite': {'path': os.path.expanduser('~/.local/share/khal/khal.db')}, @@ -83,10 +83,10 @@ def test_small(self): 'calendars': { 'home': {'path': os.path.expanduser('~/.calendars/home/'), 'color': 'dark green', 'readonly': False, 'priority': 20, - 'type': 'calendar', 'address': ''}, + 'type': 'calendar', 'addresses': ['']}, 'work': {'path': os.path.expanduser('~/.calendars/work/'), 'readonly': True, 'color': None, 'priority': 10, - 'type': 'calendar', 'address': 'user@example.com'}}, + 'type': 'calendar', 'addresses': ['user@example.com']}}, 'sqlite': {'path': os.path.expanduser('~/.local/share/khal/khal.db')}, 'locale': { 'local_timezone': get_localzone(),