mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-08-05 02:45:28 +00:00
* Fix YEARLY recurring CalDAV events only showing on DTSTART year (#170) Recurring events with RRULE:FREQ=YEARLY only appeared in the calendar on the year matching DTSTART, not in subsequent years. The list_events query filtered by , which excludes recurring events whose original dtend (e.g. 2019-07-22) falls before the requested window (e.g. 2026). Fix: split the query into two branches — non-recurring events still require window overlap, but recurring events (with non-empty RRULE) are fetched by dtstart < end_dt alone. A new helper, _expand_rrule_occurrences(), uses dateutil.rrule to expand each recurring event into individual occurrence dicts within the requested date range, so YEARLY/WEEKLY/MONTHLY events render correctly across all years. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * recurrence: compound UIDs, frontend fixes, python-dateutil req, tests - Replace _expand_rrule_occurrences with _expand_rrule that emits stable compound UIDs ({base_uid}::{date_or_datetime}) so the frontend can distinguish occurrences from the same series. Non-recurring events pass through with is_recurrence=false and series_uid=uid. - Add _resolve_base_uid() to extract the base series UID from compound UIDs — used by PUT/DELETE /api/calendar/events/{uid} and the manage_calendar tool so edits/deletes always target the base row. - Update manage_calendar tool to import and use _resolve_base_uid. - Frontend _updateEvent / _deleteEvent: detect compound UIDs and invalidate localStorage cache after success so stale sibling occurrences aren't shown. - Add python-dateutil to requirements.txt as an explicit dependency. - Add 14 regression tests in tests/test_calendar_recurrence.py covering _resolve_base_uid edge cases, _expand_rrule with yearly/weekly/monthly/all-day/bad-rrule, unique UIDs, and metadata inheritance. - Merge upstream's cleaner SQLAlchemy or_/and_ query pattern. * recurrence: overlapping malformed-RRULE, exclusive end, multi-day crossings Fix three edge cases in _expand_rrule: 1. Malformed-RRULE fallback now checks window overlap. list_events fetches recurring rows with only dtstart < end_dt, so a broken old recurring event could appear in unrelated future windows. Now fallback returns [] unless the base event's dtstart/dtend actually intersect [start, end). 2. Exclusive end boundary. rule.between(start, end, inc=True) was inclusive on end, but the route contract and non-recurring SQL filter both use [start, end). Added occ_start >= end guard. 3. Multi-day crossings. A recurring occurrence that starts before the window but ends inside it was missed (only occ_start was checked). Now expands from start - duration and filters by occ_start < end AND occ_end > start, matching non-recurring overlap behavior. Tests: +4 tests for these cases (18 total) --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| search | ||
| agent_loop.py | ||
| agent_runs.py | ||
| agent_tools.py | ||
| ai_interaction.py | ||
| api_key_manager.py | ||
| app_helpers.py | ||
| app_initializer.py | ||
| assistant_log.py | ||
| auth_helpers.py | ||
| bg_jobs.py | ||
| bg_monitor.py | ||
| builtin_actions.py | ||
| builtin_mcp.py | ||
| caldav_sync.py | ||
| chat_handler.py | ||
| chat_helpers.py | ||
| chat_processor.py | ||
| chroma_client.py | ||
| cleanup_service.py | ||
| config.py | ||
| constants.py | ||
| context_compactor.py | ||
| database.py | ||
| deep_research.py | ||
| document_actions.py | ||
| document_processor.py | ||
| email_thread_parser.py | ||
| embeddings.py | ||
| endpoint_resolver.py | ||
| event_bus.py | ||
| exceptions.py | ||
| goal_based_extractor.py | ||
| integrations.py | ||
| llm_core.py | ||
| mcp_manager.py | ||
| memory.py | ||
| memory_vector.py | ||
| model_context.py | ||
| model_discovery.py | ||
| pdf_form_doc.py | ||
| pdf_forms.py | ||
| personal_docs.py | ||
| preset_manager.py | ||
| prompt_security.py | ||
| rag_manager.py | ||
| rag_singleton.py | ||
| rag_vector.py | ||
| rate_limiter.py | ||
| request_models.py | ||
| research_handler.py | ||
| research_utils.py | ||
| secret_storage.py | ||
| session_actions.py | ||
| settings.py | ||
| task_endpoint.py | ||
| task_scheduler.py | ||
| teacher_escalation.py | ||
| text_helpers.py | ||
| tool_execution.py | ||
| tool_implementations.py | ||
| tool_index.py | ||
| tool_parsing.py | ||
| tool_schemas.py | ||
| tool_security.py | ||
| topic_analyzer.py | ||
| upload_handler.py | ||
| visual_report.py | ||
| webhook_manager.py | ||
| youtube_handler.py | ||