diff --git a/CHANGELOG.md b/CHANGELOG.md index 45f0e91a..d0d473e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 2.36 (2024-10-24) +* Fix: Categories with characters incompatible with the current locale opens (#778, Oussama Jarrousse). + # 2.35 (2024-09-22) * Add option to auto-indent text in editor and activate it by default (#561, #562, Allen Benter, Varunjay Varma). diff --git a/rednotebook/journal.py b/rednotebook/journal.py index a118f1a4..5f9aca37 100644 --- a/rednotebook/journal.py +++ b/rednotebook/journal.py @@ -540,7 +540,7 @@ def show_message(self, msg, title=None, error=False): def categories(self): return sorted( set(itertools.chain.from_iterable(day.categories for day in self.days)), - key=locale.strxfrm, + key=utils.safe_strxfrm, ) def get_entries(self, category): diff --git a/rednotebook/util/utils.py b/rednotebook/util/utils.py index e71653e7..027718ba 100644 --- a/rednotebook/util/utils.py +++ b/rednotebook/util/utils.py @@ -17,6 +17,7 @@ # ----------------------------------------------------------------------- import http.client +import locale import logging import os.path import re @@ -202,3 +203,14 @@ def flush(self): def close(self): for stream in self.streams: stream.close() + +def safe_strxfrm(value): + """ + Safely apply locale-aware sorting. If locale.strxfrm fails, fall back to default sorting. + """ + try: + return locale.strxfrm(value) + except OSError: + return value + except: + return value diff --git a/tests/test_journal.py b/tests/test_journal.py new file mode 100644 index 00000000..9321098a --- /dev/null +++ b/tests/test_journal.py @@ -0,0 +1,40 @@ +import pytest + +from datetime import date +from rednotebook.data import Month, Day # Assuming you have access to these + +from rednotebook.journal import Journal + +@pytest.fixture +def mock_month(): + month = Month(2024, 10) + day1 = Day(month, 1, {"text": "Example text", "Aria": {}}) + day2 = Day(month, 2, {"text": "More example text", "Aria": {}, "Opera":{}, "Étude":{}}) + day3 = Day(month, 3, {"text": "Another text", "Sonata": {}, "Prelude": {}, "Opera": {}, "Concerto":{}}) + day4 = Day(month, 4, {"text": "Regression test for issue 778", "Opera":{}, "المُوَشَّح":{}}) + + month.days[1] = day1 + month.days[2] = day2 + month.days[3] = day3 + month.days[4] = day4 + + yield month + + +def test_categories(mock_month): + # Create an empty journal instance + journal = Journal() + + # Add a month with no days to the journal + journal.months = { (2024, 10): Month(2024, 10) } + + # Ensure that the categories list is empty + assert journal.categories == [], "Expected no categories in an empty journal" + + # Add a month with days to the journal + journal.months = { (2024, 10): mock_month } + + # Assert the categories property returns expected categories sorted alphabetically + expected_categories = ['Aria', 'Concerto', 'Étude', 'Opera', 'Prelude', 'Sonata', 'المُوَشَّح'] + + assert journal.categories == expected_categories \ No newline at end of file