From a57156ccc98781fd32b2774432d37d53f43a9d7a Mon Sep 17 00:00:00 2001 From: Christian Geier Date: Sat, 17 Jun 2023 17:53:18 +0200 Subject: [PATCH 1/5] support for status-symbol --- CHANGELOG.rst | 3 +++ doc/source/usage.rst | 3 +++ khal/khalendar/event.py | 23 +++++++++++++++++++++-- tests/event_test.py | 9 +++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e54148826..a7e4ee974 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -22,6 +22,9 @@ not released yet * NEW Add default alarms configuration option * FIX defaults for `default_event_duration` and `default_dayevent_duration` where mixed up, `default_dayevent_duration` is the default for all-day events +* NEW event format option `status-symbol` which represents the status of an + event with a symbol (e.g. `✓` for confirmed, `✗` for cancelled, `?` for + tentative) 0.11.2 ====== diff --git a/doc/source/usage.rst b/doc/source/usage.rst index dfac789bc..c72c49727 100644 --- a/doc/source/usage.rst +++ b/doc/source/usage.rst @@ -150,6 +150,9 @@ Several options are common to almost all of :program:`khal`'s commands The status of the event (if this event has one), something like `CONFIRMED` or `CANCELLED`. + status-symbol + The status of the event as a symbol, `✓` or `✗` or `?`. + cancelled The string `CANCELLED` (plus one blank) if the event's status is cancelled, otherwise nothing. diff --git a/khal/khalendar/event.py b/khal/khalendar/event.py index e1258e278..674f51383 100644 --- a/khal/khalendar/event.py +++ b/khal/khalendar/event.py @@ -286,7 +286,10 @@ def symbol_strings(self) -> Dict[str, str]: 'range': '\N{Left right arrow}', 'range_end': '\N{Rightwards arrow to bar}', 'range_start': '\N{Rightwards arrow from bar}', - 'right_arrow': '\N{Rightwards arrow}' + 'right_arrow': '\N{Rightwards arrow}', + 'cancelled': '\N{Cross mark}', + 'confirmed': '\N{Heavy check mark}', + 'tentative': '\N{White question mark ornament}', } else: return { @@ -295,7 +298,10 @@ def symbol_strings(self) -> Dict[str, str]: 'range': '<->', 'range_end': '->|', 'range_start': '|->', - 'right_arrow': '->' + 'right_arrow': '->', + 'cancelled': 'X', + 'confirmed': 'V', + 'tentative': '?', } @property @@ -554,6 +560,18 @@ def _alarm_str(self) -> str: alarmstr = '' return alarmstr + @property + def _status_str(self) -> str: + if self.status == 'CANCELLED': + statusstr = ' ' + self.symbol_strings['cancelled'] + elif self.status == 'TENTATIVE': + statusstr = ' ' + self.symbol_strings['tentative'] + elif self.status == 'CONFIRMED': + statusstr = ' ' + self.symbol_strings['confirmed'] + else: + statusstr = '' + return statusstr + def attributes( self, relative_to: Union[Tuple[dt.date, dt.date], dt.date], @@ -684,6 +702,7 @@ def attributes( attributes["repeat-symbol"] = self._recur_str attributes["repeat-pattern"] = self.recurpattern attributes["alarm-symbol"] = self._alarm_str + attributes["status-symbol"] = self._status_str attributes["title"] = self.summary attributes["organizer"] = self.organizer.strip() attributes["description"] = self.description.strip() diff --git a/tests/event_test.py b/tests/event_test.py index 6dad949ca..4a6b7c75b 100644 --- a/tests/event_test.py +++ b/tests/event_test.py @@ -326,6 +326,15 @@ def test_event_rd(): assert event.recurring is True +def test_status_confirmed(): + event = Event.fromString(_get_text('event_dt_status_confirmed'), **EVENT_KWARGS) + assert event.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' + def test_event_d_long(): event_d_long = _get_text('event_d_long') event = Event.fromString(event_d_long, **EVENT_KWARGS) From f94551dbbdbbe1373e0296cdb8cb7957c2d0da1f Mon Sep 17 00:00:00 2001 From: Christian Geier Date: Sat, 17 Jun 2023 17:53:18 +0200 Subject: [PATCH 2/5] config: accept email address for each calendar --- khal/settings/khal.spec | 4 ++++ tests/configs/small.conf | 1 + tests/settings_test.py | 8 ++++---- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/khal/settings/khal.spec b/khal/settings/khal.spec index dc9ae1a2c..8bc5d2f87 100644 --- a/khal/settings/khal.spec +++ b/khal/settings/khal.spec @@ -71,6 +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='') + [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*). path = expand_db_path(default=None) diff --git a/tests/configs/small.conf b/tests/configs/small.conf index 9981df2fe..07a65329a 100644 --- a/tests/configs/small.conf +++ b/tests/configs/small.conf @@ -8,3 +8,4 @@ [[work]] path = ~/.calendars/work/ readonly = True + address = user@example.com diff --git a/tests/settings_test.py b/tests/settings_test.py index 290f1aeff..3428ebfe4 100644 --- a/tests/settings_test.py +++ b/tests/settings_test.py @@ -41,9 +41,9 @@ def test_simple_config(self): comp_config = { 'calendars': { 'home': {'path': os.path.expanduser('~/.calendars/home/'), - 'readonly': False, 'color': None, 'priority': 10, 'type': 'calendar'}, + 'readonly': False, 'color': None, 'priority': 10, 'type': 'calendar', 'address': ''}, 'work': {'path': os.path.expanduser('~/.calendars/work/'), - 'readonly': False, 'color': None, 'priority': 10, 'type': 'calendar'}, + 'readonly': False, 'color': None, 'priority': 10, 'type': 'calendar', 'address': ''}, }, 'sqlite': {'path': os.path.expanduser('~/.local/share/khal/khal.db')}, 'locale': LOCALE_BERLIN, @@ -81,10 +81,10 @@ def test_small(self): 'calendars': { 'home': {'path': os.path.expanduser('~/.calendars/home/'), 'color': 'dark green', 'readonly': False, 'priority': 20, - 'type': 'calendar'}, + 'type': 'calendar', 'address': ''}, 'work': {'path': os.path.expanduser('~/.calendars/work/'), 'readonly': True, 'color': None, 'priority': 10, - 'type': 'calendar'}}, + 'type': 'calendar', 'address': 'user@example.com'}}, 'sqlite': {'path': os.path.expanduser('~/.local/share/khal/khal.db')}, 'locale': { 'local_timezone': get_localzone(), From e0bd70b2fcf8c647050aed509e9b6e3b5967bfbf Mon Sep 17 00:00:00 2001 From: Christian Geier Date: Sat, 17 Jun 2023 17:53:18 +0200 Subject: [PATCH 3/5] show partstat status for calendar's address --- CHANGELOG.rst | 4 +++ doc/source/usage.rst | 3 +++ khal/cli.py | 1 + khal/custom_types.py | 1 + khal/khalendar/event.py | 35 ++++++++++++++++++++++--- khal/khalendar/khalendar.py | 1 + tests/conftest.py | 4 ++- tests/event_test.py | 34 ++++++++++++++++++++++++ tests/ics/event_dt_partstat.ics | 22 ++++++++++++++++ tests/ics/event_dt_status_confirmed.ics | 12 +++++++++ tests/settings_test.py | 12 ++++++--- 11 files changed, 120 insertions(+), 9 deletions(-) create mode 100644 tests/ics/event_dt_partstat.ics create mode 100644 tests/ics/event_dt_status_confirmed.ics diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a7e4ee974..25efebf74 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -25,6 +25,10 @@ not released yet * NEW event format option `status-symbol` which represents the status of an event with a symbol (e.g. `✓` for confirmed, `✗` for cancelled, `?` for 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 + configured for the event's calendar 0.11.2 ====== diff --git a/doc/source/usage.rst b/doc/source/usage.rst index c72c49727..c07ddf390 100644 --- a/doc/source/usage.rst +++ b/doc/source/usage.rst @@ -153,6 +153,9 @@ Several options are common to almost all of :program:`khal`'s commands status-symbol The status of the event as a symbol, `✓` or `✗` or `?`. + partstat-symbol + The participation status of the event as a symbol, `✓` or `✗` or `?`. + cancelled The string `CANCELLED` (plus one blank) if the event's status is cancelled, otherwise nothing. diff --git a/khal/cli.py b/khal/cli.py index ec6cbac94..b3443e33b 100644 --- a/khal/cli.py +++ b/khal/cli.py @@ -175,6 +175,7 @@ def build_collection(conf, selection): 'color': cal['color'], 'priority': cal['priority'], 'ctype': cal['type'], + 'address': cal['address'], } collection = khalendar.CalendarCollection( calendars=props, diff --git a/khal/custom_types.py b/khal/custom_types.py index 97000076e..cda30cecf 100644 --- a/khal/custom_types.py +++ b/khal/custom_types.py @@ -12,6 +12,7 @@ class CalendarConfiguration(TypedDict): color: str priority: int ctype: str + address: str class LocaleConfiguration(TypedDict): diff --git a/khal/khalendar/event.py b/khal/khalendar/event.py index 674f51383..2a9b05192 100644 --- a/khal/khalendar/event.py +++ b/khal/khalendar/event.py @@ -68,7 +68,8 @@ def __init__(self, color: Optional[str] = None, start: Optional[dt.datetime] = None, end: Optional[dt.datetime] = None, - ) -> None: + address: str = '', + ): """ :param start: start datetime of this event instance :param end: end datetime of this event instance @@ -87,6 +88,7 @@ def __init__(self, self.color = color self._start: dt.datetime self._end: dt.datetime + self.address = address if start is None: self._start = self._vevents[self.ref]['DTSTART'].dt @@ -290,6 +292,8 @@ def symbol_strings(self) -> Dict[str, str]: 'cancelled': '\N{Cross mark}', 'confirmed': '\N{Heavy check mark}', 'tentative': '\N{White question mark ornament}', + 'declined': '\N{Cross mark}', + 'accepted': '\N{Heavy check mark}', } else: return { @@ -302,6 +306,8 @@ def symbol_strings(self) -> Dict[str, str]: 'cancelled': 'X', 'confirmed': 'V', 'tentative': '?', + 'declined': 'X', + 'accepted': 'V', } @property @@ -563,15 +569,28 @@ def _alarm_str(self) -> str: @property def _status_str(self) -> str: if self.status == 'CANCELLED': - statusstr = ' ' + self.symbol_strings['cancelled'] + statusstr = self.symbol_strings['cancelled'] elif self.status == 'TENTATIVE': - statusstr = ' ' + self.symbol_strings['tentative'] + statusstr = self.symbol_strings['tentative'] elif self.status == 'CONFIRMED': - statusstr = ' ' + self.symbol_strings['confirmed'] + statusstr = self.symbol_strings['confirmed'] else: statusstr = '' return statusstr + @property + def _partstat_str(self) -> str: + partstat = self.partstat + if partstat == 'ACCEPTED': + partstatstr = self.symbol_strings['accepted'] + elif partstat == 'TENTATIVE': + partstatstr = self.symbol_strings['tentative'] + elif partstat == 'DECLINED': + partstatstr = self.symbol_strings['declined'] + else: + partstatstr = '' + return partstatstr + def attributes( self, relative_to: Union[Tuple[dt.date, dt.date], dt.date], @@ -703,6 +722,7 @@ def attributes( attributes["repeat-pattern"] = self.recurpattern attributes["alarm-symbol"] = self._alarm_str attributes["status-symbol"] = self._status_str + attributes["partstat-symbol"] = self._partstat_str attributes["title"] = self.summary attributes["organizer"] = self.organizer.strip() attributes["description"] = self.description.strip() @@ -785,6 +805,13 @@ def delete_instance(self, instance: dt.datetime) -> None: def status(self) -> str: return self._vevents[self.ref].get('STATUS', '') + @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', '') + class DatetimeEvent(Event): pass diff --git a/khal/khalendar/khalendar.py b/khal/khalendar/khalendar.py index fc22f28b0..4b9820b8b 100644 --- a/khal/khalendar/khalendar.py +++ b/khal/khalendar/khalendar.py @@ -284,6 +284,7 @@ def _construct_event(self, ref=ref, color=self._calendars[calendar]['color'], readonly=self._calendars[calendar]['readonly'], + address=self._calendars[calendar]['address'], ) return event diff --git a/tests/conftest.py b/tests/conftest.py index 10bc52bbe..cc23f721d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -56,6 +56,7 @@ def coll_vdirs(tmpdir) -> CollVdirType: color='dark blue', priority=10, ctype='calendar', + address='user@example.com', ) vdirs[name] = Vdir(path, '.ics') coll = CalendarCollection(calendars=calendars, dbpath=':memory:', locale=LOCALE_BERLIN) @@ -71,7 +72,8 @@ def coll_vdirs_birthday(tmpdir): os.makedirs(path, mode=0o770) readonly = True if name == 'a_calendar' else False calendars[name] = {'name': name, 'path': path, 'color': 'dark blue', - 'readonly': readonly, 'unicode_symbols': True, 'ctype': 'birthdays'} + 'readonly': readonly, 'unicode_symbols': True, 'ctype': 'birthdays', + 'address': '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 4a6b7c75b..94d606ff1 100644 --- a/tests/event_test.py +++ b/tests/event_test.py @@ -695,3 +695,37 @@ def test_parameters_description(): assert event.description == ( 'Hey, \n\nJust setting aside some dedicated time to talk about redacted.' ) + +def test_partstat(): + FORMAT_CALENDAR = ( + '{calendar-color}{partstat-symbol}{status-symbol}{start-end-time-style} ({calendar}) ' + '{title} [{location}]{repeat-symbol}' + ) + + event = Event.fromString( + _get_text('event_dt_partstat'), address='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) + 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) + 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' + +@pytest.mark.xfail +def test_partstat_deligated(): + event = Event.fromString( + _get_text('event_dt_partstat'), address='hcabot@example.com', **EVENT_KWARGS) + assert event.partstat == 'ACCEPTED' + + event = Event.fromString( + _get_text('event_dt_partstat'), address='iamboss@example.com', **EVENT_KWARGS) + assert event.partstat == 'ACCEPTED' diff --git a/tests/ics/event_dt_partstat.ics b/tests/ics/event_dt_partstat.ics new file mode 100644 index 000000000..617f1c063 --- /dev/null +++ b/tests/ics/event_dt_partstat.ics @@ -0,0 +1,22 @@ +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//PIMUTILS.ORG//NONSGML khal / icalendar //EN +BEGIN:VEVENT +SUMMARY:An Event +DTSTART;TZID=Europe/Berlin:20140409T093000 +DTEND;TZID=Europe/Berlin:20140409T103000 +DTSTAMP:20140401T234817Z +UID:V042MJ8B3SJNFXQOJL6P53OFMHJE8Z3VZWOU +ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=TENTATIVE;DELEGATED-FROM= + "mailto:iamboss@example.com";CN=Henry Cabot:mailto:hcabot@ + example.com +ATTENDEE;ROLE=NON-PARTICIPANT;PARTSTAT=DELEGATED;DELEGATED-TO= + "mailto:hcabot@example.com";CN=The Big Cheese:mailto:iamboss + @example.com +ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Jane Doe + :mailto:jdoe@example.com +ATTENDEE;PARTSTAT=ACCEPTED:mailto:jqpublic@example.com +ATTENDEE;PARTSTAT=DECLINED:mailto:another@example.com +ATTENDEE;PARTSTAT=TENTATIVE:mailto:tent@example.com +END:VEVENT +END:VCALENDAR diff --git a/tests/ics/event_dt_status_confirmed.ics b/tests/ics/event_dt_status_confirmed.ics new file mode 100644 index 000000000..0fddc316a --- /dev/null +++ b/tests/ics/event_dt_status_confirmed.ics @@ -0,0 +1,12 @@ +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//PIMUTILS.ORG//NONSGML khal / icalendar //EN +BEGIN:VEVENT +SUMMARY:An Event +DTSTART;TZID=Europe/Berlin:20140409T093000 +DTEND;TZID=Europe/Berlin:20140409T103000 +DTSTAMP:20140401T234817Z +UID:V042MJ8B3SJNFXQOJL6P53OFMHJE8Z3VZWOU +STATUS:CONFIRMED +END:VEVENT +END:VCALENDAR diff --git a/tests/settings_test.py b/tests/settings_test.py index 3428ebfe4..8da73132c 100644 --- a/tests/settings_test.py +++ b/tests/settings_test.py @@ -40,10 +40,14 @@ def test_simple_config(self): ) comp_config = { 'calendars': { - 'home': {'path': os.path.expanduser('~/.calendars/home/'), - 'readonly': False, 'color': None, 'priority': 10, 'type': 'calendar', 'address': ''}, - 'work': {'path': os.path.expanduser('~/.calendars/work/'), - 'readonly': False, 'color': None, 'priority': 10, 'type': 'calendar', 'address': ''}, + 'home': { + 'path': os.path.expanduser('~/.calendars/home/'), 'readonly': False, + 'color': None, 'priority': 10, 'type': 'calendar', 'address': '', + }, + 'work': { + 'path': os.path.expanduser('~/.calendars/work/'), 'readonly': False, + 'color': None, 'priority': 10, 'type': 'calendar', 'address': '', + }, }, 'sqlite': {'path': os.path.expanduser('~/.local/share/khal/khal.db')}, 'locale': LOCALE_BERLIN, From d508e18142de72d0cb6a2ac0f5ea322f7e73b0ae Mon Sep 17 00:00:00 2001 From: Christian Geier Date: Tue, 31 Oct 2023 01:49:29 +0100 Subject: [PATCH 4/5] accept multiple addresses per calendar account --- CHANGELOG.rst | 2 +- khal/cli.py | 2 +- khal/custom_types.py | 2 +- khal/khalendar/event.py | 11 ++++++----- 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, 28 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 25efebf74..5ea3a1586 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -27,7 +27,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 2a9b05192..84425461c 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: Optional[List[str]] =None, ): """ :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 addresses else [] if start is None: self._start = self._vevents[self.ref]['DTSTART'].dt @@ -808,9 +808,10 @@ 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', '') + return None 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 8bc5d2f87..676d51032 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 94d606ff1..d20b90e5f 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') @@ -703,19 +703,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' @@ -723,9 +723,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 8da73132c..a1d6799c7 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')}, @@ -85,10 +85,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(), From 765bae2f64f1c8b20eb2e3cf176d0cef9f84cd23 Mon Sep 17 00:00:00 2001 From: Christian Geier Date: Wed, 15 Nov 2023 21:07:42 +0100 Subject: [PATCH 5/5] use standard ? as status for tentative --- khal/khalendar/event.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/khal/khalendar/event.py b/khal/khalendar/event.py index 84425461c..9f7339521 100644 --- a/khal/khalendar/event.py +++ b/khal/khalendar/event.py @@ -291,7 +291,7 @@ def symbol_strings(self) -> Dict[str, str]: 'right_arrow': '\N{Rightwards arrow}', 'cancelled': '\N{Cross mark}', 'confirmed': '\N{Heavy check mark}', - 'tentative': '\N{White question mark ornament}', + 'tentative': '?', 'declined': '\N{Cross mark}', 'accepted': '\N{Heavy check mark}', }