mirror of
https://github.com/aluxnimm/outlookcaldavsynchronizer.git
synced 2025-10-05 16:02:49 +02:00
Workaround: Since DDay.iCal is not capable to parse events, which contain unsorted TimeZoneComponents, they must be sorted before parsing.
This commit is contained in:
@@ -32,6 +32,10 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="DDay.iCal, Version=1.0.2.575, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\DDay.iCal.1.0.2.575\lib\DDay.iCal.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Threading.Tasks">
|
||||
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -66,6 +70,7 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DDayICalWorkaround\CalendarDataPreprocessorFixture.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -78,9 +83,7 @@
|
||||
<Name>CalDavSynchronizer</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Implementation\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
|
@@ -0,0 +1,434 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using CalDavSynchronizer.DDayICalWorkaround;
|
||||
using DDay.iCal;
|
||||
using DDay.iCal.Serialization.iCalendar;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace CalDavSynchronizer.UnitTest.DDayICalWorkaround
|
||||
{
|
||||
[TestFixture]
|
||||
public class CalendarDataPreprocessorFixture
|
||||
{
|
||||
[Test]
|
||||
public void FixTimeZoneComponentOrder_TestRealEvent ()
|
||||
{
|
||||
string input = @"BEGIN:VCALENDAR
|
||||
PRODID:-//bitfire web engineering//DAVdroid 0.8.4.1 (ical4j 2.0-beta1)//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Europe/Vienna
|
||||
TZURL:http://tzurl.org/zoneinfo/Europe/Vienna
|
||||
X-LIC-LOCATION:Europe/Vienna
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+0100
|
||||
TZOFFSETTO:+0200
|
||||
TZNAME:CEST
|
||||
DTSTART:19810329T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+0200
|
||||
TZOFFSETTO:+0100
|
||||
TZNAME:CET
|
||||
DTSTART:19961027T030000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
|
||||
END:STANDARD
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+010521
|
||||
TZOFFSETTO:+0100
|
||||
TZNAME:CET
|
||||
DTSTART:18930401T000000
|
||||
RDATE:18930401T000000
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+0100
|
||||
TZOFFSETTO:+0200
|
||||
TZNAME:CEST
|
||||
DTSTART:19160501T000000
|
||||
RDATE:19160501T000000
|
||||
RDATE:19170416T030000
|
||||
RDATE:19180415T030000
|
||||
RDATE:19200405T030000
|
||||
RDATE:19400401T030000
|
||||
RDATE:19430329T030000
|
||||
RDATE:19440403T030000
|
||||
RDATE:19450402T030000
|
||||
RDATE:19460414T030000
|
||||
RDATE:19470406T030000
|
||||
RDATE:19480418T030000
|
||||
RDATE:19800406T000000
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+0200
|
||||
TZOFFSETTO:+0100
|
||||
TZNAME:CET
|
||||
DTSTART:19161001T010000
|
||||
RDATE:19161001T010000
|
||||
RDATE:19170917T030000
|
||||
RDATE:19180916T030000
|
||||
RDATE:19200913T030000
|
||||
RDATE:19421102T030000
|
||||
RDATE:19431004T030000
|
||||
RDATE:19441002T030000
|
||||
RDATE:19450412T030000
|
||||
RDATE:19461006T030000
|
||||
RDATE:19471005T030000
|
||||
RDATE:19481003T030000
|
||||
RDATE:19800928T000000
|
||||
RDATE:19810927T030000
|
||||
RDATE:19820926T030000
|
||||
RDATE:19830925T030000
|
||||
RDATE:19840930T030000
|
||||
RDATE:19850929T030000
|
||||
RDATE:19860928T030000
|
||||
RDATE:19870927T030000
|
||||
RDATE:19880925T030000
|
||||
RDATE:19890924T030000
|
||||
RDATE:19900930T030000
|
||||
RDATE:19910929T030000
|
||||
RDATE:19920927T030000
|
||||
RDATE:19930926T030000
|
||||
RDATE:19940925T030000
|
||||
RDATE:19950924T030000
|
||||
END:STANDARD
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+0100
|
||||
TZOFFSETTO:+0100
|
||||
TZNAME:CET
|
||||
DTSTART:19200101T000000
|
||||
RDATE:19200101T000000
|
||||
RDATE:19460101T000000
|
||||
RDATE:19810101T000000
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
DTSTAMP:20150925T061111Z
|
||||
UID:566745d3-04ed-497a-9d1b-47db1bb12629
|
||||
DTSTART;TZID=Europe/Vienna:20151125T133500
|
||||
DTEND;TZID=Europe/Vienna:20151125T151500
|
||||
SUMMARY:EZG-ILV EDV_F1.03 - MGS-1
|
||||
LOCATION:EDV_F1.03
|
||||
DESCRIPTION:EZG-ILV\nHesinaGe\nMGS-1 \nEDV_F1.03
|
||||
CLASS:PUBLIC
|
||||
LAST-MODIFIED:20150927T175324Z
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:2
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
";
|
||||
|
||||
string expected = @"BEGIN:VCALENDAR
|
||||
PRODID:-//bitfire web engineering//DAVdroid 0.8.4.1 (ical4j 2.0-beta1)//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Europe/Vienna
|
||||
TZURL:http://tzurl.org/zoneinfo/Europe/Vienna
|
||||
X-LIC-LOCATION:Europe/Vienna
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+010521
|
||||
TZOFFSETTO:+0100
|
||||
TZNAME:CET
|
||||
DTSTART:18930401T000000
|
||||
RDATE:18930401T000000
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+0100
|
||||
TZOFFSETTO:+0200
|
||||
TZNAME:CEST
|
||||
DTSTART:19160501T000000
|
||||
RDATE:19160501T000000
|
||||
RDATE:19170416T030000
|
||||
RDATE:19180415T030000
|
||||
RDATE:19200405T030000
|
||||
RDATE:19400401T030000
|
||||
RDATE:19430329T030000
|
||||
RDATE:19440403T030000
|
||||
RDATE:19450402T030000
|
||||
RDATE:19460414T030000
|
||||
RDATE:19470406T030000
|
||||
RDATE:19480418T030000
|
||||
RDATE:19800406T000000
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+0200
|
||||
TZOFFSETTO:+0100
|
||||
TZNAME:CET
|
||||
DTSTART:19161001T010000
|
||||
RDATE:19161001T010000
|
||||
RDATE:19170917T030000
|
||||
RDATE:19180916T030000
|
||||
RDATE:19200913T030000
|
||||
RDATE:19421102T030000
|
||||
RDATE:19431004T030000
|
||||
RDATE:19441002T030000
|
||||
RDATE:19450412T030000
|
||||
RDATE:19461006T030000
|
||||
RDATE:19471005T030000
|
||||
RDATE:19481003T030000
|
||||
RDATE:19800928T000000
|
||||
RDATE:19810927T030000
|
||||
RDATE:19820926T030000
|
||||
RDATE:19830925T030000
|
||||
RDATE:19840930T030000
|
||||
RDATE:19850929T030000
|
||||
RDATE:19860928T030000
|
||||
RDATE:19870927T030000
|
||||
RDATE:19880925T030000
|
||||
RDATE:19890924T030000
|
||||
RDATE:19900930T030000
|
||||
RDATE:19910929T030000
|
||||
RDATE:19920927T030000
|
||||
RDATE:19930926T030000
|
||||
RDATE:19940925T030000
|
||||
RDATE:19950924T030000
|
||||
END:STANDARD
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+0100
|
||||
TZOFFSETTO:+0100
|
||||
TZNAME:CET
|
||||
DTSTART:19200101T000000
|
||||
RDATE:19200101T000000
|
||||
RDATE:19460101T000000
|
||||
RDATE:19810101T000000
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+0100
|
||||
TZOFFSETTO:+0200
|
||||
TZNAME:CEST
|
||||
DTSTART:19810329T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+0200
|
||||
TZOFFSETTO:+0100
|
||||
TZNAME:CET
|
||||
DTSTART:19961027T030000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
DTSTAMP:20150925T061111Z
|
||||
UID:566745d3-04ed-497a-9d1b-47db1bb12629
|
||||
DTSTART;TZID=Europe/Vienna:20151125T133500
|
||||
DTEND;TZID=Europe/Vienna:20151125T151500
|
||||
SUMMARY:EZG-ILV EDV_F1.03 - MGS-1
|
||||
LOCATION:EDV_F1.03
|
||||
DESCRIPTION:EZG-ILV\nHesinaGe\nMGS-1 \nEDV_F1.03
|
||||
CLASS:PUBLIC
|
||||
LAST-MODIFIED:20150927T175324Z
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:2
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
";
|
||||
|
||||
var processed = CalendarDataPreprocessor.FixTimeZoneComponentOrderNoThrow (input);
|
||||
|
||||
Assert.That (processed, Is.EqualTo (expected));
|
||||
AssertCanDeserialize (processed);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void FixTimeZoneComponentOrder_EventHasNoTimeZones_DoesntChangeEvent ()
|
||||
{
|
||||
string input = @"BEGIN:VCALENDAR
|
||||
PRODID:-//bitfire web engineering//DAVdroid 0.8.4.1 (ical4j 2.0-beta1)//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
DTSTAMP:20150925T061111Z
|
||||
UID:566745d3-04ed-497a-9d1b-47db1bb12629
|
||||
DTSTART;TZID=Europe/Vienna:20151125T133500
|
||||
DTEND;TZID=Europe/Vienna:20151125T151500
|
||||
SUMMARY:EZG-ILV EDV_F1.03 - MGS-1
|
||||
LOCATION:EDV_F1.03
|
||||
DESCRIPTION:EZG-ILV\nHesinaGe\nMGS-1 \nEDV_F1.03
|
||||
CLASS:PUBLIC
|
||||
LAST-MODIFIED:20150927T175324Z
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:2
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
";
|
||||
|
||||
var processed = CalendarDataPreprocessor.FixTimeZoneComponentOrderNoThrow (input);
|
||||
|
||||
Assert.That (processed, Is.EqualTo (input));
|
||||
AssertCanDeserialize (processed);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void FixTimeZoneComponentOrder_StartTimeOfOneComponentIsNotParseable_IgnoresComnponentAndAddsItAfterSortedConmponents ()
|
||||
{
|
||||
string input = @"BEGIN:VCALENDAR
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Europe/Vienna
|
||||
X-LIC-LOCATION:Europe/Vienna
|
||||
BEGIN:STANDARD
|
||||
TZNAME:CET
|
||||
DTSTART:19961027T030000
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZNAME:CEST
|
||||
DTSTART:19810329T020000
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZNAME:CET
|
||||
DTSTART:19200101T000000
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZNAME:CEST
|
||||
DTSTART:xxxxxxxxxxxxxxxxxxxxxxx
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZNAME:CET
|
||||
DTSTART:19161001T010000
|
||||
END:STANDARD
|
||||
BEGIN:STANDARD
|
||||
TZNAME:CET
|
||||
DTSTART:18930401T000000
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
SUMMARY:Termin
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
";
|
||||
|
||||
string expected = @"BEGIN:VCALENDAR
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Europe/Vienna
|
||||
X-LIC-LOCATION:Europe/Vienna
|
||||
BEGIN:STANDARD
|
||||
TZNAME:CET
|
||||
DTSTART:18930401T000000
|
||||
END:STANDARD
|
||||
BEGIN:STANDARD
|
||||
TZNAME:CET
|
||||
DTSTART:19161001T010000
|
||||
END:STANDARD
|
||||
BEGIN:STANDARD
|
||||
TZNAME:CET
|
||||
DTSTART:19200101T000000
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZNAME:CEST
|
||||
DTSTART:19810329T020000
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZNAME:CET
|
||||
DTSTART:19961027T030000
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZNAME:CEST
|
||||
DTSTART:xxxxxxxxxxxxxxxxxxxxxxx
|
||||
END:DAYLIGHT
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
SUMMARY:Termin
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
";
|
||||
|
||||
var processed = CalendarDataPreprocessor.FixTimeZoneComponentOrderNoThrow (input);
|
||||
|
||||
Assert.That (processed, Is.EqualTo (expected));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FixTimeZoneComponentOrder_EventHasMultipleTimeZomes ()
|
||||
{
|
||||
string input = @"BEGIN:VCALENDAR
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Europe/Vienna
|
||||
X-LIC-LOCATION:Europe/Vienna
|
||||
BEGIN:STANDARD
|
||||
TZNAME:CET
|
||||
DTSTART:19901027T030000
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZNAME:CEST
|
||||
DTSTART:19800329T020000
|
||||
END:DAYLIGHT
|
||||
END:VTIMEZONE
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Blablubb
|
||||
X-LIC-LOCATION:SomewhereElse
|
||||
BEGIN:STANDARD
|
||||
TZNAME:CET
|
||||
DTSTART:19601027T030000
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZNAME:CEST
|
||||
DTSTART:19500329T020000
|
||||
END:DAYLIGHT
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
SUMMARY:Termin
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
";
|
||||
|
||||
string expected = @"BEGIN:VCALENDAR
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Europe/Vienna
|
||||
X-LIC-LOCATION:Europe/Vienna
|
||||
BEGIN:DAYLIGHT
|
||||
TZNAME:CEST
|
||||
DTSTART:19800329T020000
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZNAME:CET
|
||||
DTSTART:19901027T030000
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Blablubb
|
||||
X-LIC-LOCATION:SomewhereElse
|
||||
BEGIN:DAYLIGHT
|
||||
TZNAME:CEST
|
||||
DTSTART:19500329T020000
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZNAME:CET
|
||||
DTSTART:19601027T030000
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
SUMMARY:Termin
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
";
|
||||
|
||||
var processed = CalendarDataPreprocessor.FixTimeZoneComponentOrderNoThrow (input);
|
||||
|
||||
Assert.That (processed, Is.EqualTo (expected));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FixTimeZoneComponentOrder_CalenderDataIsNull_ReturnsNull ()
|
||||
{
|
||||
Assert.That (CalendarDataPreprocessor.FixTimeZoneComponentOrderNoThrow (null), Is.Null);
|
||||
}
|
||||
|
||||
|
||||
private static void AssertCanDeserialize (string iCalData)
|
||||
{
|
||||
Assert.That (
|
||||
() => DeserializeICalendar (iCalData),
|
||||
Throws.Nothing);
|
||||
}
|
||||
|
||||
|
||||
private static IICalendar DeserializeICalendar (string iCalData)
|
||||
{
|
||||
using (var reader = new StringReader (iCalData))
|
||||
{
|
||||
var calendarCollection = (iCalendarCollection) new iCalendarSerializer().Deserialize (reader);
|
||||
return calendarCollection[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="DDay.iCal" version="1.0.2.575" targetFramework="net45" />
|
||||
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
|
||||
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
|
||||
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
|
||||
|
@@ -215,6 +215,7 @@
|
||||
<Compile Include="DataAccess\ProfileListDataAccess.cs" />
|
||||
<Compile Include="DataAccess\WebRequestBasedClient\WebHeaderCollectionAdapter.cs" />
|
||||
<Compile Include="DataAccess\WebRequestBasedClient\WebDavClient.cs" />
|
||||
<Compile Include="DDayICalWorkaround\CalendarDataPreprocessor.cs" />
|
||||
<Compile Include="Implementation\ComWrappers\TaskItemWrapper.cs" />
|
||||
<Compile Include="Implementation\ComWrappers\AppointmentItemWrapper.cs" />
|
||||
<Compile Include="Implementation\ComWrappers\ComEnumerableExtensions.cs" />
|
||||
|
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using log4net;
|
||||
|
||||
namespace CalDavSynchronizer.DDayICalWorkaround
|
||||
{
|
||||
public static class CalendarDataPreprocessor
|
||||
{
|
||||
private static readonly ILog s_logger = LogManager.GetLogger (MethodInfo.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public static string FixTimeZoneComponentOrderNoThrow (string iCalenderData)
|
||||
{
|
||||
if (string.IsNullOrEmpty (iCalenderData))
|
||||
return iCalenderData;
|
||||
|
||||
try
|
||||
{
|
||||
var newCalenderData = iCalenderData;
|
||||
|
||||
for (
|
||||
var timeZoneMatch = Regex.Match (iCalenderData, "BEGIN:VTIMEZONE\r\n(.|\n)*?END:VTIMEZONE\r\n", RegexOptions.RightToLeft);
|
||||
timeZoneMatch.Success;
|
||||
timeZoneMatch = timeZoneMatch.NextMatch())
|
||||
{
|
||||
var sections = new List<Tuple<Match, DateTime>>();
|
||||
|
||||
for (
|
||||
var sectionMatch = Regex.Match (timeZoneMatch.Value, "BEGIN:STANDARD\r\n(.|\n)*?END:STANDARD\r\n", RegexOptions.RightToLeft);
|
||||
sectionMatch.Success;
|
||||
sectionMatch = sectionMatch.NextMatch())
|
||||
{
|
||||
var startMatch = Regex.Match (sectionMatch.Value, "DTSTART:(.*?)\r\n");
|
||||
if (startMatch.Success)
|
||||
{
|
||||
DateTime date;
|
||||
if (DateTime.TryParseExact (startMatch.Groups[1].Value, "yyyyMMdd'T'HHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
|
||||
{
|
||||
sections.Add (Tuple.Create (sectionMatch, date));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (
|
||||
var sectionMatch = Regex.Match (timeZoneMatch.Value, "BEGIN:DAYLIGHT\r\n(.|\n)*?END:DAYLIGHT\r\n", RegexOptions.RightToLeft);
|
||||
sectionMatch.Success;
|
||||
sectionMatch = sectionMatch.NextMatch())
|
||||
{
|
||||
var startMatch = Regex.Match (sectionMatch.Value, "DTSTART:(.*?)\r\n");
|
||||
if (startMatch.Success)
|
||||
{
|
||||
DateTime date;
|
||||
if (DateTime.TryParseExact (startMatch.Groups[1].Value, "yyyyMMdd'T'HHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
|
||||
{
|
||||
sections.Add (Tuple.Create (sectionMatch, date));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sections.Count > 0)
|
||||
{
|
||||
Match firstSection = null;
|
||||
|
||||
var newTimeZoneData = timeZoneMatch.Value;
|
||||
|
||||
foreach (var section in sections.OrderByDescending (s => s.Item1.Index))
|
||||
{
|
||||
newTimeZoneData = newTimeZoneData.Remove (section.Item1.Index, section.Item1.Length);
|
||||
firstSection = section.Item1;
|
||||
}
|
||||
|
||||
foreach (var section in sections.OrderByDescending (s => s.Item2))
|
||||
{
|
||||
newTimeZoneData = newTimeZoneData.Insert (firstSection.Index, section.Item1.Value);
|
||||
}
|
||||
|
||||
newCalenderData = newCalenderData.Remove (timeZoneMatch.Index, timeZoneMatch.Length);
|
||||
newCalenderData = newCalenderData.Insert (timeZoneMatch.Index, newTimeZoneData);
|
||||
}
|
||||
}
|
||||
|
||||
return newCalenderData;
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
s_logger.Error ("Could not process calender data. Using original data", x);
|
||||
return iCalenderData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -20,6 +20,7 @@ using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using CalDavSynchronizer.DataAccess;
|
||||
using CalDavSynchronizer.DDayICalWorkaround;
|
||||
using CalDavSynchronizer.Diagnostics;
|
||||
using CalDavSynchronizer.Implementation.TimeRangeFiltering;
|
||||
using DDay.iCal;
|
||||
@@ -102,7 +103,19 @@ namespace CalDavSynchronizer.Implementation
|
||||
IICalendar calendar;
|
||||
|
||||
if (TryDeserializeCalendar (serialized.Entity, out calendar, serialized.Id, threadLocal.Item1))
|
||||
{
|
||||
threadLocal.Item2.Add (Tuple.Create (serialized.Id, calendar));
|
||||
}
|
||||
else
|
||||
{
|
||||
// maybe deserialization failed because of the iCal-TimeZone-Bug => try to fix it
|
||||
var fixedICalData = CalendarDataPreprocessor.FixTimeZoneComponentOrderNoThrow (serialized.Entity);
|
||||
if (TryDeserializeCalendar (fixedICalData, out calendar, serialized.Id, threadLocal.Item1))
|
||||
{
|
||||
threadLocal.Item2.Add (Tuple.Create (serialized.Id, calendar));
|
||||
}
|
||||
}
|
||||
|
||||
return threadLocal;
|
||||
},
|
||||
threadLocal =>
|
||||
|
@@ -5,6 +5,7 @@
|
||||
<repository path="..\CalDavSynchronizer.UnitTest\packages.config" />
|
||||
<repository path="..\CalDavSynchronizer\packages.config" />
|
||||
<repository path="..\CalDavSynchronizerTestAutomation\packages.config" />
|
||||
<repository path="..\ConsoleApplication1\packages.config" />
|
||||
<repository path="..\GenSync.UnitTests\packages.config" />
|
||||
<repository path="..\GenSync\packages.config" />
|
||||
<repository path="..\TestRunner\packages.config" />
|
||||
|
Reference in New Issue
Block a user