From b02e9945d1fb2cc5e894bfa2536c381ef34eb2eb Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 24 Apr 2026 15:05:16 +0300 Subject: [PATCH 1/2] Bump Ical.Net to 5.2.1 --- .../Calendar/CalendarFeedController.cs | 12 ++++++------ src/Sonarr.Api.V3/Sonarr.Api.V3.csproj | 2 +- .../Calendar/CalendarFeedController.cs | 14 +++++++------- src/Sonarr.Api.V5/Sonarr.Api.V5.csproj | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Sonarr.Api.V3/Calendar/CalendarFeedController.cs b/src/Sonarr.Api.V3/Calendar/CalendarFeedController.cs index fcd8208d0..b7cdc43f3 100644 --- a/src/Sonarr.Api.V3/Calendar/CalendarFeedController.cs +++ b/src/Sonarr.Api.V3/Calendar/CalendarFeedController.cs @@ -77,12 +77,12 @@ public IActionResult GetCalendarFeed(int pastDays = 7, int futureDays = 28, stri if (asAllDay) { - occurrence.Start = new CalDateTime(episode.AirDateUtc.Value.ToLocalTime()) { HasTime = false }; + occurrence.Start = new CalDateTime(episode.AirDateUtc.Value.ToLocalTime(), false); } else { - occurrence.Start = new CalDateTime(episode.AirDateUtc.Value) { HasTime = true }; - occurrence.End = new CalDateTime(episode.AirDateUtc.Value.AddMinutes(series.Runtime)) { HasTime = true }; + occurrence.Start = new CalDateTime(episode.AirDateUtc.Value, true); + occurrence.End = new CalDateTime(episode.AirDateUtc.Value.AddMinutes(series.Runtime), true); } switch (series.SeriesType) @@ -96,10 +96,10 @@ public IActionResult GetCalendarFeed(int pastDays = 7, int futureDays = 28, stri } } - var serializer = (IStringSerializer)new SerializerFactory().Build(calendar.GetType(), new SerializationContext()); - var icalendar = serializer.SerializeToString(calendar); + var serializer = new SerializerFactory().Build(calendar.GetType(), new SerializationContext()) as IStringSerializer; + var icalendar = serializer?.SerializeToString(calendar); - return Content(icalendar, "text/calendar"); + return icalendar is null ? NoContent() : Content(icalendar, "text/calendar"); } } } diff --git a/src/Sonarr.Api.V3/Sonarr.Api.V3.csproj b/src/Sonarr.Api.V3/Sonarr.Api.V3.csproj index 020e9cdff..7b95108f6 100644 --- a/src/Sonarr.Api.V3/Sonarr.Api.V3.csproj +++ b/src/Sonarr.Api.V3/Sonarr.Api.V3.csproj @@ -4,7 +4,7 @@ - + diff --git a/src/Sonarr.Api.V5/Calendar/CalendarFeedController.cs b/src/Sonarr.Api.V5/Calendar/CalendarFeedController.cs index c8c0b4095..ed11365a6 100644 --- a/src/Sonarr.Api.V5/Calendar/CalendarFeedController.cs +++ b/src/Sonarr.Api.V5/Calendar/CalendarFeedController.cs @@ -27,7 +27,7 @@ public CalendarFeedController(IEpisodeService episodeService, ISeriesService ser } [HttpGet("Sonarr.ics")] - public ContentHttpResult GetCalendarFeed(int pastDays = 7, int futureDays = 28, string tags = "", bool unmonitored = false, bool premieresOnly = false, bool asAllDay = false, bool includeSpecials = true) + public Results GetCalendarFeed(int pastDays = 7, int futureDays = 28, string tags = "", bool unmonitored = false, bool premieresOnly = false, bool asAllDay = false, bool includeSpecials = true) { var start = DateTime.Today.AddDays(-pastDays); var end = DateTime.Today.AddDays(futureDays); @@ -76,12 +76,12 @@ public ContentHttpResult GetCalendarFeed(int pastDays = 7, int futureDays = 28, if (asAllDay) { - occurrence.Start = new CalDateTime(episode.AirDateUtc!.Value.ToLocalTime()) { HasTime = false }; + occurrence.Start = new CalDateTime(episode.AirDateUtc!.Value.ToLocalTime(), false); } else { - occurrence.Start = new CalDateTime(episode.AirDateUtc!.Value) { HasTime = true }; - occurrence.End = new CalDateTime(episode.AirDateUtc.Value.AddMinutes(series.Runtime)) { HasTime = true }; + occurrence.Start = new CalDateTime(episode.AirDateUtc!.Value, true); + occurrence.End = new CalDateTime(episode.AirDateUtc.Value.AddMinutes(series.Runtime), true); } switch (series.SeriesType) @@ -95,9 +95,9 @@ public ContentHttpResult GetCalendarFeed(int pastDays = 7, int futureDays = 28, } } - var serializer = (IStringSerializer)new SerializerFactory().Build(calendar.GetType(), new SerializationContext()); - var icalendar = serializer.SerializeToString(calendar); + var serializer = new SerializerFactory().Build(calendar.GetType(), new SerializationContext()) as IStringSerializer; + var icalendar = serializer?.SerializeToString(calendar); - return TypedResults.Content(icalendar, "text/calendar"); + return icalendar is null ? TypedResults.NoContent() : TypedResults.Content(icalendar, "text/calendar"); } } diff --git a/src/Sonarr.Api.V5/Sonarr.Api.V5.csproj b/src/Sonarr.Api.V5/Sonarr.Api.V5.csproj index 9e67c56e1..0b7a7df98 100644 --- a/src/Sonarr.Api.V5/Sonarr.Api.V5.csproj +++ b/src/Sonarr.Api.V5/Sonarr.Api.V5.csproj @@ -7,7 +7,7 @@ - + From b1995060c757a00848b33c201dce009a13167734 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 24 Apr 2026 15:06:43 +0300 Subject: [PATCH 2/2] Generate calendar feed link with V5 API --- frontend/src/Calendar/iCal/CalendarLinkModalContent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/Calendar/iCal/CalendarLinkModalContent.tsx b/frontend/src/Calendar/iCal/CalendarLinkModalContent.tsx index b8c32cb60..3b9b9cd45 100644 --- a/frontend/src/Calendar/iCal/CalendarLinkModalContent.tsx +++ b/frontend/src/Calendar/iCal/CalendarLinkModalContent.tsx @@ -48,7 +48,7 @@ function CalendarLinkModalContent({ ); const { iCalHttpUrl, iCalWebCalUrl } = useMemo(() => { - let icalUrl = `${window.location.host}${window.Sonarr.urlBase}/feed/v3/calendar/Sonarr.ics?`; + let icalUrl = `${window.location.host}${window.Sonarr.urlBase}/feed/v5/calendar/Sonarr.ics?`; if (unmonitored) { icalUrl += 'unmonitored=true&';