ShiftScheduler/Services/IcsExportService.cs
Copilot 5103aecacf
Add Google Calendar integration with direct sync functionality and rate limiting protection (#45)
* Initial plan

* Implement Google Calendar integration with sync button and calendar selection

Co-authored-by: clayschaad <11883505+clayschaad@users.noreply.github.com>

* Add Google Calendar sync documentation and finalize implementation

Co-authored-by: clayschaad <11883505+clayschaad@users.noreply.github.com>

* Fix build errors

* Fix Google Calendar rate limiting issues with retry logic and delays

Co-authored-by: clayschaad <11883505+clayschaad@users.noreply.github.com>

* optimize

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: clayschaad <11883505+clayschaad@users.noreply.github.com>
Co-authored-by: Claudio Schaad <c.schaad@pog.ch>
2025-09-06 16:47:48 +02:00

76 lines
2.8 KiB
C#

using Ical.Net;
using Ical.Net.CalendarComponents;
using Ical.Net.DataTypes;
using Ical.Net.Serialization;
using ShiftScheduler.Shared;
namespace ShiftScheduler.Services
{
public class IcsExportService
{
public string GenerateIcs(List<ShiftWithTransport> shiftsWithTransport)
{
var calendar = new Calendar();
foreach (var shiftWithTransport in shiftsWithTransport)
{
var date = shiftWithTransport.Date;
var shift = shiftWithTransport.Shift;
if (string.IsNullOrEmpty(shift.MorningTime) && string.IsNullOrEmpty(shift.AfternoonTime))
continue;
if (!string.IsNullOrEmpty(shift.MorningTime))
{
var times = shift.MorningTime.Split('-');
var summary = $"{shift.Name}";
var description = "";
if (shiftWithTransport.MorningTransport != null)
{
var transportSummary = FormatTransportInfo(shiftWithTransport.MorningTransport);
description = $"Transport: {transportSummary}";
}
calendar.Events.Add(new CalendarEvent
{
Summary = summary,
Description = description,
Start = new CalDateTime(date.Add(TimeSpan.Parse(times[0]))),
End = new CalDateTime(date.Add(TimeSpan.Parse(times[1])))
});
}
if (!string.IsNullOrEmpty(shift.AfternoonTime))
{
var times = shift.AfternoonTime.Split('-');
var summary = $"{shift.Name}";
var description = "";
if (shiftWithTransport.AfternoonTransport != null)
{
var transportSummary = FormatTransportInfo(shiftWithTransport.AfternoonTransport);
description = $"Transport: {transportSummary}";
}
calendar.Events.Add(new CalendarEvent
{
Summary = summary,
Description = description,
Start = new CalDateTime(date.Add(TimeSpan.Parse(times[0]))),
End = new CalDateTime(date.Add(TimeSpan.Parse(times[1])))
});
}
}
return new CalendarSerializer().SerializeToString(calendar);
}
private string FormatTransportInfo(TransportConnection transport)
{
var departure =transport.DepartureTime.ToString("HH:mm");
var arrival = transport.ArrivalTime.ToString("HH:mm");
return $"{departure} → {arrival}";
}
}
}