diff --git a/AUTHORS.txt b/AUTHORS.txt index 04c93b866..42d95d3b5 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -34,3 +34,4 @@ August Lindberg Thomas Kluyver - thomas [at] kluyver [dot] me [dot] uk Tobias Brummer - hallo [at] t0bybr.de - https://t0bybr.de Amanda Hickman - amanda [at] velociraptor [dot] info +Raef Coles - raefcoles [at] gmail [dot] com diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4f2f3b866..0f0d3b73b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -52,6 +52,11 @@ not released yet * NEW python 3.7 is now officially supported. +* NEW configuration option [[per_calendar]]priority = int (default 10). If + multiple calendars events are on the same day, the day will be colored with + the color of the calendar with highest priority. If multiple calendars have + the same highest priority, it falls back to the previous system. + 0.9.8 ===== released 2017-10-05 diff --git a/khal/calendar_display.py b/khal/calendar_display.py index 9aa0a4884..9c41741f1 100644 --- a/khal/calendar_display.py +++ b/khal/calendar_display.py @@ -59,15 +59,37 @@ def get_calendar_color(calendar, default_color, collection): return collection._calendars[calendar]['color'] +def get_color_list(calendars, default_color, collection): + """Get the list of possible colors for the day, taking into account priority + """ + dcolors = list( + map(lambda x: (get_calendar_color(x, default_color, collection), + collection._calendars[x]['priority']), calendars) + ) + + dcolors.sort(key=lambda x: x[1], reverse=True) + + maxPriority = dcolors[0][1] + dcolors = list( + filter(lambda x: x[1] == maxPriority, dcolors) + ) + + dcolors = list( + map(lambda x: x[0], dcolors) + ) + + dcolors = list(set(dcolors)) + + return dcolors + + def str_highlight_day( day, calendars, hmethod, default_color, multiple, color, bold_for_light_color, collection): """returns a string with day highlighted according to configuration """ dstr = str(day.day).rjust(2) if color == '': - dcolors = list(set( - map(lambda x: get_calendar_color(x, default_color, collection), calendars) - )) + dcolors = get_color_list(calendars, default_color, collection) if len(dcolors) > 1: if multiple == '': if hmethod == "foreground" or hmethod == "fg": diff --git a/khal/cli.py b/khal/cli.py index ee520f61d..0ae2b13d7 100644 --- a/khal/cli.py +++ b/khal/cli.py @@ -162,6 +162,7 @@ def build_collection(conf, selection): 'path': cal['path'], 'readonly': cal['readonly'], 'color': cal['color'], + 'priority': cal['priority'], 'ctype': cal['type'], } collection = khalendar.CalendarCollection( diff --git a/khal/khalendar/khalendar.py b/khal/khalendar/khalendar.py index 5cfdd6e79..dfb2d1507 100644 --- a/khal/khalendar/khalendar.py +++ b/khal/khalendar/khalendar.py @@ -65,6 +65,7 @@ def __init__(self, default_color: str='', multiple: str='', color: str='', + priority: int=10, highlight_event_days: bool=False, locale: Dict[str, Any]=dict(), dbpath: Optional[str]=None, @@ -93,6 +94,7 @@ def __init__(self, self.default_color = default_color self.multiple = multiple self.color = color + self.priority = priority self.highlight_event_days = highlight_event_days self._locale = locale self._backend = backend.SQLiteDb(self.names, dbpath, self._locale) diff --git a/khal/settings/khal.spec b/khal/settings/khal.spec index 9b39e80c9..056fba7f2 100644 --- a/khal/settings/khal.spec +++ b/khal/settings/khal.spec @@ -38,6 +38,12 @@ path = expand_path(default=None) color = color(default='auto') +# When coloring days, the color will be determined based on the calendar with +# the highest priority. If the priorities are equal, then the "multiple" color +# will be used. + +priority = integer(default=10) + # setting this to *True*, will keep khal from making any changes to this # calendar readonly = boolean(default=False) diff --git a/tests/cal_display_test.py b/tests/cal_display_test.py index 9c76ddb14..e3b247d91 100644 --- a/tests/cal_display_test.py +++ b/tests/cal_display_test.py @@ -4,7 +4,8 @@ import unicodedata import pytest -from khal.calendar_display import getweeknumber, str_week, vertical_month +from khal.calendar_display import (getweeknumber, str_week, vertical_month, + get_calendar_color, get_color_list) today = dt.date.today() yesterday = today - dt.timedelta(days=1) @@ -33,6 +34,68 @@ def test_str_week(): assert str_week(week, bday) == ' 6 7 \x1b[7m 8\x1b[0m 9 10 11 12 13 ' +class testCollection(): + def __init__(self): + self._calendars = {} + + def addCalendar(self, name, color, priority): + self._calendars[name] = {'color': color, 'priority': priority} + + +def test_get_calendar_color(): + + exampleCollection = testCollection() + exampleCollection.addCalendar('testCalendar1', 'dark red', 20) + exampleCollection.addCalendar('testCalendar2', 'light green', 10) + exampleCollection.addCalendar('testCalendar3', '', 10) + + assert get_calendar_color('testCalendar1', 'light blue', exampleCollection) == 'dark red' + assert get_calendar_color('testCalendar2', 'light blue', exampleCollection) == 'light green' + + # test default color + assert get_calendar_color('testCalendar3', 'light blue', exampleCollection) == 'light blue' + + +def test_get_color_list(): + + exampleCalendarList = ['testCalendar1', 'testCalendar2'] + + # test different priorities + exampleCollection1 = testCollection() + exampleCollection1.addCalendar('testCalendar1', 'dark red', 20) + exampleCollection1.addCalendar('testCalendar2', 'light green', 10) + + testList1 = get_color_list(exampleCalendarList, 'light_blue', exampleCollection1) + assert 'dark red' in testList1 + assert len(testList1) == 1 + + # test same priorities + exampleCollection2 = testCollection() + exampleCollection2.addCalendar('testCalendar1', 'dark red', 20) + exampleCollection2.addCalendar('testCalendar2', 'light green', 20) + + testList2 = get_color_list(exampleCalendarList, 'light_blue', exampleCollection2) + assert 'dark red' in testList2 + assert 'light green' in testList2 + assert len(testList2) == 2 + + # test duplicated colors + exampleCollection3 = testCollection() + exampleCollection3.addCalendar('testCalendar1', 'dark red', 20) + exampleCollection3.addCalendar('testCalendar2', 'dark red', 20) + + testList3 = get_color_list(exampleCalendarList, 'light_blue', exampleCollection3) + assert len(testList3) == 1 + + # test indexing operator (required by str_highlight_day()) + exampleCollection4 = testCollection() + exampleCollection4.addCalendar('testCalendar1', 'dark red', 20) + exampleCollection4.addCalendar('testCalendar2', 'dark red', 20) + + testList3 = get_color_list(exampleCalendarList, 'light_blue', exampleCollection4) + assert testList3[0] == 'dark red' + + example1 = [ '\x1b[1m Mo Tu We Th Fr Sa Su \x1b[0m', '\x1b[1mDec \x1b[0m28 29 30 1 2 3 4 ', diff --git a/tests/configs/small.conf b/tests/configs/small.conf index e9c59a191..9981df2fe 100644 --- a/tests/configs/small.conf +++ b/tests/configs/small.conf @@ -3,6 +3,7 @@ [[home]] path = ~/.calendars/home/ color = dark green + priority = 20 [[work]] path = ~/.calendars/work/ diff --git a/tests/settings_test.py b/tests/settings_test.py index abffdbbbf..037abac8d 100644 --- a/tests/settings_test.py +++ b/tests/settings_test.py @@ -26,9 +26,9 @@ def test_simple_config(self): comp_config = { 'calendars': { 'home': {'path': os.path.expanduser('~/.calendars/home/'), - 'readonly': False, 'color': None, 'type': 'calendar'}, + 'readonly': False, 'color': None, 'priority': 10, 'type': 'calendar'}, 'work': {'path': os.path.expanduser('~/.calendars/work/'), - 'readonly': False, 'color': None, 'type': 'calendar'}, + 'readonly': False, 'color': None, 'priority': 10, 'type': 'calendar'}, }, 'sqlite': {'path': os.path.expanduser('~/.local/share/khal/khal.db')}, 'locale': LOCALE_BERLIN, @@ -60,10 +60,10 @@ def test_small(self): comp_config = { 'calendars': { 'home': {'path': os.path.expanduser('~/.calendars/home/'), - 'color': 'dark green', 'readonly': False, + 'color': 'dark green', 'readonly': False, 'priority': 20, 'type': 'calendar'}, 'work': {'path': os.path.expanduser('~/.calendars/work/'), - 'readonly': True, 'color': None, + 'readonly': True, 'color': None, 'priority': 10, 'type': 'calendar'}}, 'sqlite': {'path': os.path.expanduser('~/.local/share/khal/khal.db')}, 'locale': {