public static Uri AlignServerUrl(Uri configuredServerUrl, WebResourceName referenceResourceNameOrNull) { if (referenceResourceNameOrNull != null) { var filename = Path.GetFileName(referenceResourceNameOrNull.OriginalAbsolutePath); if (!string.IsNullOrEmpty(filename)) { var filenameIndex = referenceResourceNameOrNull.OriginalAbsolutePath.LastIndexOf(filename); if (filenameIndex != -1) { var resourcePath = referenceResourceNameOrNull.OriginalAbsolutePath.Remove(filenameIndex); var newUri = new Uri(configuredServerUrl, resourcePath); // Only if new aligned Uri has a different encoded AbsolutePath but is identical when decoded return newUri // else we assume filename truncation didn't work and return the original configuredServerUrl if (newUri.AbsolutePath != configuredServerUrl.AbsolutePath) { if (DecodeUrlString(newUri.AbsolutePath) == DecodeUrlString(configuredServerUrl.AbsolutePath)) { return(newUri); } s_logger.DebugFormat("Aligned decoded resource uri path '{0}' different from server uri '{1}'", newUri.AbsolutePath, configuredServerUrl.AbsolutePath); } } } } return(configuredServerUrl); }
public async Task <bool> TryDelete(WebResourceName entityId, string version, TContext context) { using (AutomaticStopwatch.StartDebug(s_logger)) { return(await _cardDavDataAccess.TryDeleteEntity(entityId, version)); } }
public void LogEntityExists(WebResourceName id) { if (!_cacheItems.ContainsKey(id)) { _cacheItems.Add(id, CreateEmptyCacheItem(id)); } }
public Task <EntityVersion <WebResourceName, string> > CreateEntity(string iCalData, string uid) { var id = new WebResourceName(Guid.NewGuid().ToString()); const int version = 1; _entites.Add(id, Tuple.Create(version.ToString(), iCalData)); return(Task.FromResult(EntityVersion.Create(id, version.ToString()))); }
public void LogEntityExists(WebResourceName entityId, vCard vCard) { if (!_cacheItems.TryGetValue(entityId, out var cacheItem)) { _cacheItems.Add(entityId, cacheItem = new CacheItem { Id = entityId }); } cacheItem.EmailAddresses = vCard.EmailAddresses.Select(a => a.Address).ToArray(); cacheItem.Uid = vCard.UniqueId; }
public async void DiplayBEntityAsync(Guid synchronizationProfileId, string entityId) { try { var options = GetOptionsOrNull(synchronizationProfileId); if (options == null) { return; } var availableComponents = (await _synchronizerFactory.CreateSynchronizerWithComponents(options, _generalOptionsDataAccess.LoadOptions())).Item2.GetDataAccessComponents(); if (availableComponents.CalDavDataAccess != null) { var entityName = new WebResourceName { Id = entityId, OriginalAbsolutePath = entityId }; var entities = await availableComponents.CalDavDataAccess.GetEntities(new[] { entityName }); DisplayFirstEntityIfAvailable(entities.FirstOrDefault()); } else if (availableComponents.CardDavDataAccess != null || availableComponents.DistListDataAccess != null) { var entityName = new WebResourceName { Id = entityId, OriginalAbsolutePath = entityId }; EntityWithId <WebResourceName, string> entity = null; if (availableComponents.CardDavDataAccess != null) { entity = (await availableComponents.CardDavDataAccess.GetEntities(new[] { entityName })).FirstOrDefault(); } if (entity == null && availableComponents.DistListDataAccess != null) { entity = (await availableComponents.DistListDataAccess.GetEntities(new[] { entityName })).FirstOrDefault(); } DisplayFirstEntityIfAvailable(entity); } else { MessageBox.Show(Strings.Get($"The type of profile '{options.Name}' doesn't provide a way to display server entities.")); } } catch (Exception x) { ExceptionHandler.Instance.DisplayException(x, s_logger); } }
public Task <bool> TryDeleteEntity(WebResourceName uri, string etag) { if (!_entites.ContainsKey(uri)) { throw new Exception("tried to delete non existing entity!"); } if (_entites[uri].Item1 != etag) { throw new Exception("tried to delete stale version!"); } _entites.Remove(uri); return(Task.FromResult(true)); }
public Task <EntityVersion <WebResourceName, string> > TryUpdateEntity( WebResourceName url, string version, string iCalData) { var existingVersion = _entites[url].Item1; if (version != existingVersion) { throw new Exception("tried to update stale version!"); } var newVersion = (version + "x"); _entites[url] = Tuple.Create(newVersion, iCalData); return(Task.FromResult(EntityVersion.Create(url, newVersion))); }
public async Task <EntityVersion <WebResourceName, string> > TryUpdate( WebResourceName entityId, string entityVersion, TEntity entityToUpdate, Func <TEntity, Task <TEntity> > entityModifier, TContext context) { using (AutomaticStopwatch.StartDebug(s_logger)) { var updatedEntity = await entityModifier(entityToUpdate); if (string.IsNullOrEmpty(GetUid(updatedEntity))) { SetUid(updatedEntity, Guid.NewGuid().ToString()); } return(await _cardDavDataAccess.TryUpdateEntity(entityId, entityVersion, Serialize (updatedEntity))); } }
public async void DiplayBEntityAsync(Guid synchronizationProfileId, string entityId) { try { var options = GetOptionsOrNull(synchronizationProfileId); if (options == null) { return; } SynchronizerFactory.AvailableSynchronizerComponents availableSynchronizerComponents; _synchronizerFactory.CreateSynchronizer(options, out availableSynchronizerComponents); if (availableSynchronizerComponents.CalDavDataAccess != null) { var entityName = new WebResourceName { Id = entityId, OriginalAbsolutePath = entityId }; var entities = await availableSynchronizerComponents.CalDavDataAccess.GetEntities(new[] { entityName }); DisplayFirstEntityIfAvailable(entities); } else if (availableSynchronizerComponents.CardDavDataAccess != null) { var entityName = new WebResourceName { Id = entityId, OriginalAbsolutePath = entityId }; var entities = await availableSynchronizerComponents.CardDavDataAccess.GetEntities(new[] { entityName }); DisplayFirstEntityIfAvailable(entities); } else { MessageBox.Show($"The type of profile '{options.Name}' doesn't provide a way to display server entities."); } } catch (Exception x) { ExceptionHandler.Instance.DisplayException(x, s_logger); } }
/// <inheritdoc /> protected override void Execute(Context context) { var name = WebResourceName.Get(context); var webResource = context.Service.RetrieveMultiple(new FetchExpression($@"<fetch top=""1"" no-lock=""true"" > <entity name=""webresource"" > <attribute name=""content"" /> <filter> <condition attribute=""name"" operator=""eq"" value=""{name}"" /> </filter> </entity> </fetch>")).Entities.FirstOrDefault(); if (webResource == null) { throw new Exception($"Веб-ресурс с именем \"{name}\" не найден."); } var content = webResource.GetAttributeValue <string>("content"); Base64Content.Set(context, content); StringContent.Set(context, Encoding.UTF8.GetString(Convert.FromBase64String(content))); }
public static void SyncCalDavToOutlook(string eventData, IEntityRelationDataAccess <string, DateTime, WebResourceName, string> entityRelationDataAccess) { var calDavDataAccess = MockRepository.GenerateMock <ICalDavDataAccess>(); var entityUri = new WebResourceName("/e1"); calDavDataAccess .Expect(r => r.GetEventVersions(null)) .IgnoreArguments() .Return(Task.FromResult <IReadOnlyList <EntityVersion <WebResourceName, string> > > ( new[] { EntityVersion.Create(entityUri, "v1") })); calDavDataAccess .Expect(r => r.GetEntities(Arg <ICollection <WebResourceName> > .List.Equal(new[] { entityUri }))) .Return(Task.FromResult <IReadOnlyList <EntityWithId <WebResourceName, string> > > ( new[] { EntityWithId.Create(entityUri, eventData) })); var synchronizer = OutlookTestContext.CreateEventSynchronizer( SynchronizationMode.ReplicateServerIntoOutlook, calDavDataAccess, entityRelationDataAccess); WaitForTask(synchronizer.SynchronizeNoThrow(NullSynchronizationLogger.Instance)); }
public static string SyncOutlookToCalDav_EventsExistsInCalDav(string existingEventData, IEntityRelationDataAccess <string, DateTime, WebResourceName, string> entityRelationDataAccess = null) { string roundTrippedData = null; ICalDavDataAccess calDavDataAccess = MockRepository.GenerateMock <ICalDavDataAccess>(); var entityUri = new WebResourceName("/e1"); calDavDataAccess .Expect(r => r.GetEventVersions(null)) .IgnoreArguments() .Return(Task.FromResult <IReadOnlyList <EntityVersion <WebResourceName, string> > > ( new[] { EntityVersion.Create(entityUri, "v1") })); calDavDataAccess .Expect(r => r.GetEntities(Arg <ICollection <WebResourceName> > .List.Equal(new[] { entityUri }))) .Return(Task.FromResult <IReadOnlyList <EntityWithId <WebResourceName, string> > > ( new[] { EntityWithId.Create(entityUri, existingEventData) })); calDavDataAccess .Expect(r => r.TryUpdateEntity( new WebResourceName("http://bla.com"), null, null)) .IgnoreArguments() .Return(Task.FromResult <EntityVersion <WebResourceName, string> > ( EntityVersion.Create(new WebResourceName("http://bla.com"), "blubb"))) .WhenCalled(a => { roundTrippedData = (string)a.Arguments[2]; }); var synchronizer = OutlookTestContext.CreateEventSynchronizer( SynchronizationMode.ReplicateOutlookIntoServer, calDavDataAccess, entityRelationDataAccess); WaitForTask(synchronizer.SynchronizeNoThrow(NullSynchronizationLogger.Instance)); return(roundTrippedData); }
protected override bool TryDeserialize( string vcardData, out vCard vcard, WebResourceName uriOfAddressbookForLogging, vCardStandardReader deserializer, ILoadEntityLogger logger) { vcard = null; // fix some linebreak issues with Open-Xchange string normalizedVcardData = vcardData.Contains("\r\r\n") ? ContactDataPreprocessor.NormalizeLineBreaks(vcardData) : vcardData; try { vcard = Deserialize(normalizedVcardData, deserializer); return(true); } catch (Exception x) { s_logger.Error(string.Format("Could not deserialize vcardData of '{0}':\r\n{1}", uriOfAddressbookForLogging, normalizedVcardData), x); logger.LogSkipLoadBecauseOfError(uriOfAddressbookForLogging, x); return(false); } }
public void LogEntityExists(WebResourceName entity) { }
public void LogEntityDeleted(WebResourceName entityId) { }
public static Uri AlignServerUrl (Uri configuredServerUrl, WebResourceName referenceResourceNameOrNull) { if (referenceResourceNameOrNull != null) { var filename = Path.GetFileName (referenceResourceNameOrNull.OriginalAbsolutePath); if (!string.IsNullOrEmpty (filename)) { var filenameIndex = referenceResourceNameOrNull.OriginalAbsolutePath.LastIndexOf (filename); if (filenameIndex != -1) { var resourcePath = referenceResourceNameOrNull.OriginalAbsolutePath.Remove (filenameIndex); var newUri = new Uri (configuredServerUrl, resourcePath); // Only if new aligned Uri has a different encoded AbsolutePath but is identical when decoded return newUri // else we assume filename truncation didn't work and return the original configuredServerUrl if (newUri.AbsolutePath != configuredServerUrl.AbsolutePath) { if (DecodeUrlString (newUri.AbsolutePath) == DecodeUrlString (configuredServerUrl.AbsolutePath)) { return newUri; } s_logger.DebugFormat ("Aligned decoded resource uri path '{0}' different from server uri '{1}'", newUri.AbsolutePath, configuredServerUrl.AbsolutePath); } } } } return configuredServerUrl; }
/* * BEGIN:VLIST * UID:4250-58658600-5-45D0678.vlf * VERSION:1.0 * FN:Simpsons * CARD;[email protected];FN="Simpson, Homer":5228bf7b-f3a6-4c16-ae3e-90102d86ab43.vcf * CARD;[email protected];FN="Simpson, Marge":c520e3ad-3d19-4c2f-b093-3f17736bce8e.vcf * END:VLIST */ protected override bool TryDeserialize(string vcardData, out DistributionList vcard, WebResourceName uriOfAddressbookForLogging, int deserializationThreadLocal, ILoadEntityLogger logger) { vcardData = vcardData.Replace("\r\n\t", string.Empty).Replace("\r\n ", string.Empty); vcard = new DistributionList(); foreach (var contentLine in vcardData.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)) { var valueStartIndex = contentLine.LastIndexOf(':') + 1; var value = contentLine.Substring(valueStartIndex); if (contentLine.StartsWith("UID")) { vcard.Uid = value; } else if (contentLine.StartsWith("FN")) { vcard.Name = vCardStandardReader.DecodeEscaped(value); } else if (contentLine.StartsWith("DESCRIPTION")) { vcard.Description = vCardStandardReader.DecodeEscaped(value); } else if (contentLine.StartsWith("NICKNAME")) { vcard.Nickname = vCardStandardReader.DecodeEscaped(value); } else if (contentLine.StartsWith("CARD")) { string displayName = null; string emailAddress = null; ParseMemberContentLineParameters(contentLine.Substring(0, valueStartIndex - 1), out emailAddress, out displayName); vcard.Members.Add(new KnownDistributionListMember(emailAddress, displayName, value)); } else if (contentLine.StartsWith(NonAddressBookMemberValueName)) { string displayName = null; string emailAddress = value; var contentWithoutMailto = contentLine.Substring(0, valueStartIndex - 8); // substract :mailto: ParseXAddressBookServerMemberContentLineParameters(contentWithoutMailto, out displayName); vcard.NonAddressBookMembers.Add(new DistributionListMember(emailAddress, displayName)); } } return(true); }
public Task<EntityVersion<WebResourceName, string>> TryUpdateEntity ( WebResourceName url, string version, string iCalData) { var existingVersion = _entites[url].Item1; if (version != existingVersion) throw new Exception ("tried to update stale version!"); var newVersion = (version + "x"); _entites[url] = Tuple.Create (newVersion, iCalData); return Task.FromResult (EntityVersion.Create (url, newVersion)); }
public void LogEntityDeleted(WebResourceName entityId) { _cacheItems.Remove(entityId); }
public Task <bool> TryDelete(WebResourceName entityId, string version, TContext context, IEntitySynchronizationLogger logger) { return(_decorated.TryDelete(entityId, version, context, logger)); }
public void LogEntityDeleted(WebResourceName entityId) { _addressesByEntityId.Remove(entityId); }
private async Task<IReadOnlyList<EntityVersion<WebResourceName, string>>> GetVersions (DateTimeRange? range, string entityType) { var entities = new List<EntityVersion<WebResourceName, string>>(); try { var responseXml = await _webDavClient.ExecuteWebDavRequestAndReadResponse ( _serverUrl, "REPORT", 1, null, null, "application/xml", string.Format ( @"<?xml version=""1.0""?> <C:calendar-query xmlns:C=""urn:ietf:params:xml:ns:caldav""> <D:prop xmlns:D=""DAV:""> <D:getetag/> </D:prop> <C:filter> <C:comp-filter name=""VCALENDAR""> <C:comp-filter name=""{0}""> {1} </C:comp-filter> </C:comp-filter> </C:filter> </C:calendar-query> ", entityType, range == null ? string.Empty : string.Format (@"<C:time-range start=""{0}"" end=""{1}""/>", range.Value.From.ToString (s_calDavDateTimeFormatString), range.Value.To.ToString (s_calDavDateTimeFormatString)) )); XmlNodeList responseNodes = responseXml.XmlDocument.SelectNodes ("/D:multistatus/D:response", responseXml.XmlNamespaceManager); // ReSharper disable once LoopCanBeConvertedToQuery // ReSharper disable once PossibleNullReferenceException foreach (XmlElement responseElement in responseNodes) { var urlNode = responseElement.SelectSingleNode ("D:href", responseXml.XmlNamespaceManager); var etagNode = responseElement.SelectSingleNode ("D:propstat/D:prop/D:getetag", responseXml.XmlNamespaceManager); if (urlNode != null && etagNode != null && _serverUrl.AbsolutePath != UriHelper.DecodeUrlString (urlNode.InnerText)) { var uri = new WebResourceName (urlNode.InnerText); entities.Add (EntityVersion.Create (uri, HttpUtility.GetQuotedEtag (etagNode.InnerText))); } } } catch (WebDavClientException x) { // Workaround for Synology NAS, which returns 404 insteaod of an empty response if no events are present if (x.StatusCode == HttpStatusCode.NotFound && await IsResourceCalender()) return entities; throw; } return entities; }
protected abstract bool TryDeserialize( string vcardData, out TEntity vcard, WebResourceName uriOfAddressbookForLogging, TDeserializationThreadLocal deserializationThreadLocal, ILoadEntityLogger logger);
public static void SyncCalDavToOutlook (string eventData, IEntityRelationDataAccess<AppointmentId, DateTime, WebResourceName, string> entityRelationDataAccess) { var calDavDataAccess = MockRepository.GenerateMock<ICalDavDataAccess>(); var entityUri = new WebResourceName("/e1"); calDavDataAccess .Expect (r => r.GetEventVersions (null)) .IgnoreArguments() .Return (Task.FromResult<IReadOnlyList<EntityVersion<WebResourceName, string>>> ( new[] { EntityVersion.Create (entityUri, "v1") })); calDavDataAccess .Expect (r => r.GetEntities (Arg<ICollection<WebResourceName>>.List.Equal (new[] { entityUri }))) .Return (Task.FromResult<IReadOnlyList<EntityWithId<WebResourceName, string>>> ( new[] { EntityWithId.Create (entityUri, eventData) })); var synchronizer = OutlookTestContext.CreateEventSynchronizer ( SynchronizationMode.ReplicateServerIntoOutlook, calDavDataAccess, entityRelationDataAccess); WaitForTask (synchronizer.SynchronizeNoThrow (NullSynchronizationLogger.Instance)); }
public static string SyncOutlookToCalDav_EventsExistsInCalDav (string existingEventData, IEntityRelationDataAccess<AppointmentId, DateTime, WebResourceName, string> entityRelationDataAccess = null) { string roundTrippedData = null; ICalDavDataAccess calDavDataAccess = MockRepository.GenerateMock<ICalDavDataAccess>(); var entityUri = new WebResourceName("/e1"); calDavDataAccess .Expect (r => r.GetEventVersions (null)) .IgnoreArguments() .Return (Task.FromResult<IReadOnlyList<EntityVersion<WebResourceName, string>>> ( new[] { EntityVersion.Create (entityUri, "v1") })); calDavDataAccess .Expect (r => r.GetEntities (Arg<ICollection<WebResourceName>>.List.Equal (new[] { entityUri }))) .Return (Task.FromResult<IReadOnlyList<EntityWithId<WebResourceName, string>>> ( new[] { EntityWithId.Create (entityUri, existingEventData) })); calDavDataAccess .Expect (r => r.TryUpdateEntity ( new WebResourceName("http://bla.com"), null, null)) .IgnoreArguments() .Return (Task.FromResult<EntityVersion<WebResourceName, string>> ( EntityVersion.Create (new WebResourceName("http://bla.com"), "blubb"))) .WhenCalled (a => { roundTrippedData = (string) a.Arguments[2]; }); var synchronizer = OutlookTestContext.CreateEventSynchronizer ( SynchronizationMode.ReplicateOutlookIntoServer, calDavDataAccess, entityRelationDataAccess); WaitForTask (synchronizer.SynchronizeNoThrow (NullSynchronizationLogger.Instance)); return roundTrippedData; }
public void LogEntityExists(WebResourceName entityId, vCard vCard) { }
public CacheItem(WebResourceName id, string[] emailAddresses) { Id = id; EmailAddresses = emailAddresses; }
private static CacheItem CreateEmptyCacheItem(WebResourceName id) { return(new CacheItem { Id = id }); }
public Task <EntityVersion <WebResourceName, string> > TryUpdate(WebResourceName entityId, string version, vCard entityToUpdate, Func <vCard, Task <vCard> > entityModifier, TContext context, IEntitySynchronizationLogger logger) { return(_decorated.TryUpdate(entityId, version, entityToUpdate, entityModifier, context, logger)); }
public Task<bool> TryDeleteEntity(WebResourceName uri, string etag) { var path = Path.Combine(_directory.FullName, uri.OriginalAbsolutePath); if (!File.Exists(path)) return Task.FromResult(false); File.Delete(path); return Task.FromResult(true); }
public Task<bool> TryDeleteEntity (WebResourceName uri, string etag) { if (!_entites.ContainsKey (uri)) throw new Exception ("tried to delete non existing entity!"); if (_entites[uri].Item1 != etag) throw new Exception ("tried to delete stale version!"); _entites.Remove (uri); return Task.FromResult (true); }
public Task<EntityVersion<WebResourceName, string>> TryUpdateEntity(WebResourceName url, string etag, string iCalData) { var path = Path.Combine(_directory.FullName, url.OriginalAbsolutePath); File.WriteAllText(path, iCalData); return Task.FromResult(EntityVersion.Create(url, File.GetLastWriteTimeUtc(path).ToString("o"))); }
public Task<EntityVersion<WebResourceName, string>> CreateEntity (string iCalData, string uid) { var id = new WebResourceName( Guid.NewGuid().ToString()); const int version = 1; _entites.Add (id, Tuple.Create (version.ToString(), iCalData)); return Task.FromResult (EntityVersion.Create (id, version.ToString())); }
public Task <bool> TryDelete(WebResourceName entityId, string version, TContext context) { return(_decorated.TryDelete(entityId, version, context)); }
public async Task<EntityVersion<WebResourceName, string>> TryUpdateEntity (WebResourceName url, string etag, string contents) { s_logger.DebugFormat ("Updating entity '{0}'", url); var absoluteEventUrl = new Uri(_serverUrl, url.OriginalAbsolutePath); s_logger.DebugFormat ("Absolute entity location: '{0}'", absoluteEventUrl); IHttpHeaders responseHeaders; try { responseHeaders = await _webDavClient.ExecuteWebDavRequestAndReturnResponseHeaders( absoluteEventUrl, "PUT", null, etag, null, "text/calendar", contents); } catch (WebDavClientException x) when (x.StatusCode == HttpStatusCode.NotFound || x.StatusCode == HttpStatusCode.PreconditionFailed) { return null; } if (s_logger.IsDebugEnabled) s_logger.DebugFormat ("Updated entity. Server response header: '{0}'", responseHeaders.ToString().Replace ("\r\n", " <CR> ")); Uri effectiveEventUrl; if (responseHeaders.Location != null) { s_logger.DebugFormat ("Server sent new location: '{0}'", responseHeaders.Location); effectiveEventUrl = responseHeaders.Location.IsAbsoluteUri ? responseHeaders.Location : new Uri(_serverUrl, responseHeaders.Location); s_logger.DebugFormat ("New entity location: '{0}'", effectiveEventUrl); } else { effectiveEventUrl = absoluteEventUrl; } var newEtag = responseHeaders.ETag; string version; if (newEtag != null) { version = newEtag; } else { version = await GetEtag (effectiveEventUrl); } return new EntityVersion<WebResourceName, string> (new WebResourceName(effectiveEventUrl), version); }
public async Task<bool> TryDeleteEntity (WebResourceName uri, string etag) { s_logger.DebugFormat ("Deleting entity '{0}'", uri); var absoluteEventUrl = new Uri (_serverUrl, uri.OriginalAbsolutePath); s_logger.DebugFormat ("Absolute entity location: '{0}'", absoluteEventUrl); IHttpHeaders responseHeaders = null; try { responseHeaders = await _webDavClient.ExecuteWebDavRequestAndReturnResponseHeaders ( absoluteEventUrl, "DELETE", null, etag, null, null, string.Empty); } catch (WebDavClientException x) when (x.StatusCode == HttpStatusCode.NotFound || x.StatusCode == HttpStatusCode.PreconditionFailed) { return false; } IEnumerable<string> errorValues; if (responseHeaders.TryGetValues ("X-Dav-Error", out errorValues)) { var errorList = errorValues.ToList(); if (errorList.Any (v => v != "200 No error")) throw new Exception (string.Format ("Error deleting entity with url '{0}' and etag '{1}': {2}", uri, etag, string.Join (",", errorList))); } return true; }
/* * BEGIN:VLIST * UID:4250-58658600-5-45D0678.vlf * VERSION:1.0 * FN:Simpsons * CARD;[email protected];FN="Simpson, Homer":5228bf7b-f3a6-4c16-ae3e-90102d86ab43.vcf * CARD;[email protected];FN="Simpson, Marge":c520e3ad-3d19-4c2f-b093-3f17736bce8e.vcf * END:VLIST */ protected override bool TryDeserialize(string vcardData, out DistributionList vcard, WebResourceName uriOfAddressbookForLogging, int deserializationThreadLocal, ILoadEntityLogger logger) { var cardReader = new vCardStandardReader(); vcard = new DistributionList(); using (var reader = new StringReader(vcardData)) { vCardProperty property; do { property = cardReader.ReadProperty(reader); if (!string.IsNullOrEmpty(property?.Name)) { var propNameToProcess = property.Name.ToUpperInvariant(); switch (propNameToProcess) { case "UID": vcard.Uid = property.ToString(); break; case "FN": vcard.Name = property.ToString(); break; case "DESCRIPTION": vcard.Description = property.ToString(); break; case "NICKNAME": vcard.Nickname = property.ToString(); break; case "CARD": if (property.Value != null) { var emailAddress = property.Subproperties.GetValue("EMAIL"); var displayName = property.Subproperties.GetValue("FN"); vcard.Members.Add(new KnownDistributionListMember(emailAddress, displayName, property.Value.ToString())); } break; case NonAddressBookMemberValueName: if (property.Value != null) { var displayName = property.Subproperties.GetValue("CN"); string emailAddress = null; var value = property.Value.ToString(); if (!string.IsNullOrEmpty(value)) { if (value.StartsWith("mailto:", StringComparison.InvariantCultureIgnoreCase)) { emailAddress = value.Substring(7); //skip mailto: } } vcard.NonAddressBookMembers.Add(new DistributionListMember(emailAddress, displayName)); } break; } } } while (property != null); } return(true); }
public void LogEntityExists(WebResourceName entityId, vCard vCard) { _addressesByEntityId[entityId] = vCard.EmailAddresses.Select(a => a.Address).ToArray(); }