private static RemoteFileViewModel CreateFileViewModel(IRemoteItem listItem) { return(new RemoteFileViewModel { Item = listItem }); }
/// <summary>In case of items with same remote ids, some new exchange items resolved as apply to remote. /// In case there is no activity metadata, conflict resolved as apply to local.</summary> /// <param name="syncItem">Sync entity instance.</param> /// <param name="itemMetaData">Metadata instance.</param> /// <param name="localStoreId">Local storage id.</param> /// <returns>Sync conflict resoluton for sync item.</returns> public override SyncConflictResolution ResolveConflict(IRemoteItem syncItem, ItemMetadata itemMetaData, Guid localStoreId) { if (syncItem.Action == SyncAction.CreateRecurringMaster) { return(SyncConflictResolution.ApplyToLocal); } bool isActivityExists = itemMetaData.Any(item => item.SyncSchemaName == "Activity"); if (!isActivityExists) { return(SyncConflictResolution.ApplyToLocal); } if (_userConnection.GetIsFeatureEnabled("ResolveConflictsByContent")) { var appointment = syncItem as ExchangeAppointment; if (appointment.Action == SyncAction.Delete) { return(SyncConflictResolution.ApplyToRemote); } Exchange.Appointment remoteItem = appointment.Item as Exchange.Appointment; appointment.LoadItemProperties(remoteItem); string oldActivityHash = GetActivityHashFromMetadata(itemMetaData); if (!appointment.IsAppointmentChanged(remoteItem, oldActivityHash, _userConnection)) { return(SyncConflictResolution.ApplyToRemote); } } SyncConflictResolution result = base.ResolveConflict(syncItem, itemMetaData, localStoreId); return(result); }
/// <summary> /// <see cref="ExchangeSyncProvider.OnLocalItemAppliedInRemoteStore"/> /// </summary> public override void OnLocalItemAppliedInRemoteStore(SyncContext context, IRemoteItem remoteItem, LocalItem localItem) { if (!_userConnection.GetIsFeatureEnabled("SyncDeletedAppointments")) { return; } if (remoteItem.Action == SyncAction.Delete && remoteItem.State == SyncState.Deleted) { EntitySchema schema = context.UserConnection.EntitySchemaManager.GetInstanceByName("Activity"); IEnumerable <Guid> entityIds = localItem.Entities["Activity"] .Where(se => se.State != SyncState.Deleted).Select(se => se.EntityId).ToList(); foreach (Guid activityId in entityIds) { Entity activity = schema.CreateEntity(context.UserConnection); if (activity.FetchFromDB(activityId, false)) { localItem.AddOrReplace("Activity", new SyncEntity(activity, SyncState.Modified) { Action = SyncAction.Delete }); } } context.LocalProvider.ApplyChanges(context, localItem); } }
private Dictionary <string, IRemoteItem> ExpandPath(string basepath, IRemoteItem items) { var total = new ConcurrentBag <KeyValuePair <string, IRemoteItem> >(); string filename = items.Name; total.Add(new KeyValuePair <string, IRemoteItem>(basepath + filename, items)); if (items.ItemType == RemoteItemType.Folder) { var children = RemoteServerFactory.PathToItem(items.FullPath).Result.Children; if (children.Count() > 0) { Parallel.ForEach(children, new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 1.0)) }, () => new Dictionary <string, IRemoteItem>(), (x, state, local) => { return(local.Concat(ExpandPath(basepath + filename + "\\", RemoteServerFactory.PathToItem(x.FullPath).Result)).ToDictionary(y => y.Key, y => y.Value)); }, (subtotal) => { foreach (var i in subtotal) { total.Add(i); } }); } } return(total.ToDictionary(y => y.Key, y => y.Value)); }
private static RemoteDirectoryViewModel CreateDirectoryViewModel(IRemoteItem ftpListItem) { var directoryItems = new List <IDirectoryItemViewModel>(); return(new RemoteDirectoryViewModel { Item = ftpListItem }); }
/// <summary> /// <see cref="ExchangeSyncProvider.ApplyChanges"/> /// </summary> public override void ApplyChanges(SyncContext context, IRemoteItem syncItem) { base.ApplyChanges(context, syncItem); SyncAction action = syncItem.Action; if (action == SyncAction.Create) { ((ExchangeContact)syncItem).InitIdProperty(context, true); } }
/// <summary> Updates extra parameters in exchange appointment item.</summary> /// <param name="syncValueName">The name of the entity type.</param> private void UpdateAppointmentExtraParameters(string syncValueName, IRemoteItem syncItem) { if (syncValueName == ExchangeConsts.ExchangeAppointmentClassName) { var exchangeAppointmentSyncItem = (ExchangeAppointment)syncItem; var exchangeAppointment = (Exchange.Appointment)exchangeAppointmentSyncItem.Item; var propertySet = new Exchange.PropertySet(Exchange.AppointmentSchema.ICalUid); exchangeAppointment.Load(propertySet); exchangeAppointmentSyncItem.UpdateExtraParameters(exchangeAppointment); } ; }
/// <summary> /// Additional actions after synchronization, based on paramref name="item"/> sync action. /// </summary> /// <param name="context"><see cref="SyncContext"/> instance.</param> /// <param name="item">Current email <see cref="IRemoteItem"/> implementation instance.</param> protected void ProcessItemSyncAction(SyncContext context, IRemoteItem item) { if (!context.UserConnection.GetIsFeatureEnabled("AsyncEmailEventHandling")) { return; } if (item.Action == SyncAction.Repeat) { var itemId = item.Id; context.LogInfo(SyncAction.None, SyncDirection.DownloadAndUpload, "Item {0} synchronization need to be repeated", itemId); NeedReRun = true; } }
/// <summary> /// Creates and fills <see cref="LocalItem"/> instance. /// </summary> /// <param name="context"><see cref="SyncContext"/> instance.</param> /// <param name="itemId">Email item identifier.</param> /// <returns><see cref="LocalItem"/> instance.</returns> protected LocalItem GetLocalItem(SyncContext context, string itemId) { var remoteProvider = context.RemoteProvider; context.LogInfo(SyncAction.None, SyncDirection.DownloadAndUpload, "Start processing item {0}", itemId); SyncItemSchema schema = remoteProvider.SyncItemSchemaCollection.FirstOrDefault(s => s.SyncValueName == "ExchangeEmailMessage"); IRemoteItem item = remoteProvider.LoadSyncItem(schema, itemId); LocalItem localItem = context.LocalProvider.FetchItem(null, schema, true); item.FillLocalItem(context, ref localItem); ProcessItemSyncAction(context, item); return(localItem); }
public RcloneCryptSystemItem(IRemoteServer server, IRemoteItem orgItem, params IRemoteItem[] parent) : base(server, parent) { if (!(parent?.Length > 0)) { isRoot = true; } orgpath = orgItem.FullPath; itemtype = orgItem.ItemType; size = ((orgItem.Size == null) ? orgItem.Size : CryptRclone.CalcDecryptedSize(orgItem.Size.Value)); modifiedDate = orgItem.ModifiedDate; createdDate = orgItem.CreatedDate; accessDate = orgItem.AccessDate; var encryptor = (_server as RcloneCryptSystem).Encrypter; if (encryptor.IsEncryptedName) { decryptedName = encryptor.DecryptName(orgItem.Name) ?? ""; if (decryptedName == "" && !isRoot) { throw new FileNotFoundException("filename dedoce error"); } } else { if (itemtype == RemoteItemType.Folder) { decryptedName = orgItem.Name; } else { if (orgItem.Name.EndsWith(CryptRclone.encryptedSuffix)) { decryptedName = orgItem.Name.Substring(0, orgItem.Name.Length - CryptRclone.encryptedSuffix.Length); } else { throw new FileNotFoundException("filename dedoce error"); } } } decryptedPath = OrgPathToPath(orgItem as RemoteItemBase); if (isRoot) { SetParent(this); } }
private IEnumerable <IRemoteItem> GetItems(IRemoteItem rootitem) { List <IRemoteItem> ret = new List <IRemoteItem>(); if (rootitem == null) { return(ret); } ret.Add(rootitem); var target = rootitem.Children; if (target == null) { return(ret); } Parallel.ForEach( target, new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 1.0)) }, () => new List <IRemoteItem>(), (x, state, local) => { var item = RemoteServerFactory.PathToItem(x.FullPath).Result; if (item == null) { return(local); } local.Add(item); local.AddRange(GetItems(item)); return(local); }, (result) => { lock (ret) ret.AddRange(result); } ); return(ret); }
public CarotCryptSystemItem(IRemoteServer server, IRemoteItem orgItem, params IRemoteItem[] parent) : base(server, parent) { if (!(parent?.Length > 0)) { isRoot = true; } orgpath = orgItem.FullPath; itemtype = orgItem.ItemType; size = orgItem?.Size - (CryptCarotDAV.BlockSizeByte + CryptCarotDAV.CryptFooterByte + CryptCarotDAV.CryptFooterByte); modifiedDate = orgItem.ModifiedDate; createdDate = orgItem.CreatedDate; accessDate = orgItem.AccessDate; decryptedName = (_server as CarotCryptSystem).CryptCarot.DecryptFilename(orgItem.Name) ?? ""; decryptedPath = OrgPathToPath(orgItem as RemoteItemBase); if (isRoot) { SetParent(this); } }
//TechDebt: Change interface to ICollection public IRemoteItem[] GetItems(string Path) { var ftpListItems = _client.GetListing(Path); var remoteItems = new List <IRemoteItem>(); foreach (var item in ftpListItems) { IRemoteItem remoteItem = null; if (item.Type == FluentFTP.FtpFileSystemObjectType.File) { var remoteFile = DependencyService.Resolve <IRemoteFile>(); remoteFile.FullName = item.FullName; remoteFile.Name = item.Name; remoteItem = remoteFile; } else if (item.Type == FluentFTP.FtpFileSystemObjectType.Directory) { var remoteDirectory = DependencyService.Resolve <IRemoteDirectory>(); remoteDirectory.FullName = item.FullName; remoteDirectory.Name = item.Name; remoteItem = remoteDirectory; } else { continue; } remoteItems.Add(remoteItem); } return(remoteItems.ToArray()); }
/// <summary> /// <see cref="RemoteProvider.RealeaseItem"/> /// </summary> public override void RealeaseItem(ref IRemoteItem remoteItem) { remoteItem = null; }
private static int RunUpload(string[] targetArgs, string[] paramArgs) { string remotePath; string localPath; if (targetArgs.Length < 3) { Console.Error.WriteLine("upload needs more 2 arguments."); Console.Error.WriteLine("upload (localpath) (remotetarget)"); return(0); } remotePath = targetArgs[2]; remotePath = remotePath.Replace('\\', '/'); localPath = targetArgs[1]; if (!localPath.Contains(':') && !localPath.StartsWith(@"\\")) { localPath = Path.GetFullPath(localPath); } if (!localPath.StartsWith(@"\\")) { localPath = ItemControl.GetLongFilename(localPath); } Console.Error.WriteLine("upload"); Console.Error.WriteLine("remote: " + remotePath); Console.Error.WriteLine("local: " + ItemControl.GetOrgFilename(localPath)); bool createFolder = false; foreach (var p in paramArgs) { switch (p) { case "createfolder": Console.Error.WriteLine("(--createfolder: create folders)"); createFolder = true; break; } } var job = JobControler.CreateNewJob(JobClass.ControlMaster); job.DisplayName = "Upload"; JobControler.Run(job, (j) => { try { var j2 = InitServer(j); j2.Wait(ct: j.Ct); var target = FindItems(remotePath, ct: j.Ct); IRemoteItem remote = null; if (target.Count() != 1 && !createFolder) { Console.Error.WriteLine("upload needs 1 remote target item."); j.ResultAsObject = 2; return; } if (target.Count() == 0 && createFolder) { Console.Error.WriteLine("Create new folders."); remote = CreateFolders(remotePath, j); if (remote == null) { Console.Error.WriteLine("make folder failed."); j.ResultAsObject = 3; return; } } else { remote = target.First(); } ConsoleJobDisp.Run(); if (File.Exists(localPath)) { ItemControl.UploadFiles(remote, new[] { localPath }, true, j); } else if (Directory.Exists(localPath)) { if (!localPath.EndsWith(":\\") && localPath.EndsWith("\\")) { localPath = localPath.TrimEnd('\\'); } ItemControl.UploadFolder(remote, localPath, true, j); } else { Console.Error.WriteLine("upload localitem not found."); j.ResultAsObject = 2; return; } while (JobControler.JobTypeCount(JobClass.Upload) > 0) { JobControler.JobList().Where(x => x.JobType == JobClass.Upload).FirstOrDefault()?.Wait(ct: j.Ct); } var SaveConfigJob = JobControler.CreateNewJob(TSviewCloudPlugin.JobClass.Save); SaveConfigJob.DisplayName = "Save server list"; JobControler.Run(SaveConfigJob, (j3) => { j3.Progress = -1; j3.ProgressStr = "Save..."; TSviewCloudConfig.Config.Save(); RemoteServerFactory.Save(); j3.Progress = 1; j3.ProgressStr = "Done."; }); SaveConfigJob.Wait(); job.ResultAsObject = 0; } catch (OperationCanceledException) { job.ResultAsObject = -1; } catch (Exception ex) { Console.Error.WriteLine("error: " + ex.ToString()); job.ResultAsObject = 1; } }); try { job.Wait(ct: job.Ct); } catch (OperationCanceledException) { } TSviewCloudConfig.Config.ApplicationExit = true; Console.Out.Flush(); return((job.ResultAsObject as int?) ?? -1); }
public SlotTask(IRemoteItem targetItem, CancellationToken ct = default(CancellationToken)) { cts = CancellationTokenSource.CreateLinkedTokenSource(ct, Internal_cts.Token); this.targetItem = targetItem; lastslot = ((targetItem.Size ?? 0) - 1) / SeekableStreamConfig.slotsize; }
private List <UpdateItem> ProcessDirectory(IRemoteItem remoteDir, DirectoryInfo localDir, bool recursive, bool removeNotExisting, Func <IRemoteItem, FileInfo, bool> versionEqualsComparer, CancellationToken cancellationToken) { if (!remoteDir.IsDirectory) { throw new DirectoryNotFoundException(); } var results = new List <UpdateItem>(); var localContents = new List <FileSystemInfo>(); if (localDir.Exists) { localContents.AddRange(localDir.GetFileSystemInfos("*", SearchOption.TopDirectoryOnly)); } foreach (var remoteItem in remoteDir.GetDirectoryContents(cancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); if (remoteItem.IsDirectory) { if (recursive) { var localItem = localContents.OfType <DirectoryInfo>().FirstOrDefault(x => string.Equals(x.Name, remoteItem.Name, StringComparison.OrdinalIgnoreCase)); if (localItem == null) { localItem = new DirectoryInfo(Path.Combine(localDir.FullName, remoteItem.Name)); } else { localContents.Remove(localItem); } results.AddRange(ProcessDirectory(remoteItem, localItem, recursive, removeNotExisting, versionEqualsComparer, cancellationToken)); } } else if (remoteItem.IsFile) { var itemDate = remoteItem.ModifiedTime; if (itemDate > _latestModifiedDate) { _latestModifiedDate = itemDate; } var localFile = localContents.OfType <FileInfo>().FirstOrDefault(x => string.Equals(x.Name, remoteItem.Name, StringComparison.OrdinalIgnoreCase)); if (localFile == null) { localFile = new FileInfo(Path.Combine(localDir.FullName, remoteItem.Name)); } else { localContents.Remove(localFile); } var localIsUpToDate = localFile.Exists && versionEqualsComparer(remoteItem, localFile); results.Add(new UpdateItem(localFile, remoteItem, localIsUpToDate)); } } cancellationToken.ThrowIfCancellationRequested(); // Remove all files that were not on the remote if (removeNotExisting) { results.AddRange(UpdateSourceManager.FileInfosToDeleteItems(localContents)); } return(results); }
/// <summary> /// Executes CRUD operations for remote storage item. /// </summary> /// <param name="context">Sync context.</param> /// <param name="syncItem">Remote storage item.</param> public override void ApplyChanges(SyncContext context, IRemoteItem syncItem) { SyncAction action = syncItem.Action; if (action == SyncAction.None || GetCurrentActionIgnored(action)) { return; } var exchangeSyncItem = (ExchangeBase)syncItem; Exchange.Item exchangeItem = exchangeSyncItem.Item; string displayName = ""; string syncValueName = syncItem.Schema.SyncValueName; bool dontSendNotifications = syncValueName == ExchangeConsts.ExchangeAppointmentClassName; try { switch (action) { case SyncAction.Create: displayName = exchangeSyncItem.DisplayName; if (dontSendNotifications) { var exchangeAppointment = ((Exchange.Appointment)exchangeItem); exchangeAppointment.Save(Exchange.SendInvitationsMode.SendToNone); } else { exchangeItem.Save(); } UpdateAppointmentExtraParameters(syncValueName, syncItem); break; case SyncAction.Update: displayName = exchangeSyncItem.DisplayName; if (dontSendNotifications) { ((Exchange.Appointment)exchangeItem).Update(Exchange.ConflictResolutionMode.AlwaysOverwrite, Exchange.SendInvitationsOrCancellationsMode.SendToNone); } else { exchangeItem.Update(Exchange.ConflictResolutionMode.AlwaysOverwrite); } break; default: if (exchangeSyncItem.State != SyncState.Deleted) { if (dontSendNotifications) { ((Exchange.Appointment)exchangeItem).Delete(Exchange.DeleteMode.MoveToDeletedItems, Exchange.SendCancellationsMode.SendToNone); } else { exchangeItem.Delete(Exchange.DeleteMode.MoveToDeletedItems); } exchangeSyncItem.State = SyncState.Deleted; } break; } LogMessage(context, action, SyncDirection.Upload, OperationInfoLczStrings[action], null, displayName, syncValueName); } catch (Exception ex) { LogMessage(context, action, SyncDirection.Upload, OperationInfoLczStrings[action], ex, displayName, syncValueName); } }
/// <summary> /// <see cref="ExchangeSyncProvider.ApplyChanges"/> /// </summary> public override void ApplyChanges(SyncContext context, IRemoteItem syncItem) { _provider.ApplyChanges(context, syncItem); }
public UpdateItem(FileSystemInfo targetPath, IRemoteItem remoteFile, bool upToDate) { TargetPath = targetPath ?? throw new ArgumentNullException(nameof(targetPath)); RemoteFile = remoteFile; UpToDate = upToDate; }
private void DownloadFile(IFtpClient client, ILocalDirectory storageFolder, string fullRemotePath, IRemoteItem item, bool overwrite) { var file = storageFolder.TryGetItemAsync(item.Name).Result; if (file != null && !overwrite) { var downloadRemoteItem = DependencyService.Resolve <IDownloadRemoteItem>(); downloadRemoteItem.Destination = storageFolder; downloadRemoteItem.Item = item; FileConflicts.Add(downloadRemoteItem); return; } storageFolder.CreateFileAsync(item.Name, overwrite) .ContinueWith(fileStreamTask => { var stream = fileStreamTask.Result.OpenStreamForWriteAsync().Result; using (var fileStream = stream) { client.Download(fileStream, fullRemotePath); } }).Wait(); }
static IEnumerable <IRemoteItem> FindItems(string path_str, bool recursive = false, IRemoteItem root = null, CancellationToken ct = default(CancellationToken), ReloadType reload = ReloadType.Reload) { ct.ThrowIfCancellationRequested(); List <IRemoteItem> ret = new List <IRemoteItem>(); if (string.IsNullOrEmpty(path_str)) { if (root == null) { if (recursive) { ret.AddRange(RemoteServerFactory.ServerList.Values.Select(x => x[""]).Select(x => FindItems("", true, x, ct, reload)).SelectMany(x => x)); return(ret); } else { ret.AddRange(RemoteServerFactory.ServerList.Values.Select(x => x[""])); return(ret); } } else { root = RemoteServerFactory.PathToItem(root.FullPath, reload).Result; if (root == null) { return(ret); } ret.Add(root); var children = root.Children; if (recursive) { ret.AddRange(children.Where(x => x.ItemType == RemoteItemType.File)); ret.AddRange(children.Where(x => x.ItemType == RemoteItemType.Folder).Select(x => FindItems("", true, x, ct, reload)).SelectMany(x => x)); } return(ret); } } var m = Regex.Match(path_str, @"^(?<server>[^:]+)(://)(?<path>.*)$"); if (m.Success) { var servername = m.Groups["server"].Value; if (servername.IndexOfAny(new[] { '?', '*' }) < 0) { var server = RemoteServerFactory.ServerList[servername]; return(FindItems(m.Groups["path"].Value, recursive, server[""], ct, reload)); } else { var servers = RemoteServerFactory.ServerList.Keys; return(servers.Where(x => Regex.IsMatch(x, "^" + Regex.Escape(servername).Replace("\\*", ".*").Replace("\\?", ".") + "$")) .Select(x => FindItems(m.Groups["path"].Value, recursive, RemoteServerFactory.ServerList[x][""], ct, reload)) .SelectMany(x => x)); } } else { if (root == null) { return(ret); } m = Regex.Match(path_str, @"^(?<current>[^/\\]*)(/|\\)?(?<next>.*)$"); path_str = m.Groups["next"].Value; root = RemoteServerFactory.PathToItem(root.FullPath, reload).Result; if (root == null) { return(ret); } var children = root.Children; var itemname = m.Groups["current"].Value; if (itemname == "**") { ret.AddRange(FindItems(path_str, true, root, ct, reload)); ret.AddRange(children .Select(x => FindItems(path_str, true, x, ct, reload)) .SelectMany(x => x)); ret.AddRange(children .Select(x => FindItems("**/" + path_str, true, x, ct, reload)) .SelectMany(x => x)); return(ret.Distinct(new RemoteItemEqualityComparer())); } else if (itemname.IndexOfAny(new[] { '?', '*' }) < 0) { return(children.Where(x => x.Name == itemname || x.PathItemName == itemname) .Select(x => FindItems(path_str, recursive, x, ct, reload)) .SelectMany(x => x)); } else { return(children.Where(x => Regex.IsMatch(x.Name, "^" + Regex.Escape(itemname).Replace("\\*", ".*").Replace("\\?", ".") + "$")) .Select(x => FindItems(path_str, recursive, x, ct, reload)) .SelectMany(x => x)); } } }
public void AddChild(IRemoteItem newchild) { ChildrenIDs = ChildrenIDs?.Concat(new[] { newchild.ID }).ToArray() ?? new[] { newchild.ID }; ChildrenIDs = ChildrenIDs.Distinct().ToArray(); Age = DateTime.Now; }
public static bool IsAncestor(IRemoteItem childitem, IRemoteItem parentitem) { var p = childitem.Parents.Where(x => x.FullPath != childitem.FullPath); return(p.Any(x => parentitem.FullPath == x.FullPath) || p.Any(x => IsAncestor(x, parentitem))); }
public void RemoveChild(IRemoteItem child) { ChildrenIDs = ChildrenIDs?.Except(new[] { child.ID }).ToArray() ?? new[] { child.ID }; Age = DateTime.Now; }
public override Job <IRemoteItem> MakeFolder(string foldername, IRemoteItem remoteTarget, bool WeekDepend = false, params Job[] parentJob) { if (parentJob?.Any(x => x?.IsCanceled ?? false) ?? false) { return(null); } try { var check = CheckUpload(remoteTarget, foldername, null, WeekDepend, parentJob); if (check != null) { WeekDepend = false; parentJob = new[] { check }; } } catch { var mkjob = JobControler.CreateNewJob <IRemoteItem>( type: JobClass.RemoteOperation, depends: parentJob); mkjob.WeekDepend = WeekDepend; mkjob.ForceHidden = true; JobControler.Run <IRemoteItem>(mkjob, (j) => { j.Result = remoteTarget.Children.Where(x => x.Name == foldername).FirstOrDefault(); }); return(mkjob); } TSviewCloudConfig.Config.Log.LogOut("[MakeFolder(CarotCryptSystem)] " + foldername); var parent = pathlist[(remoteTarget.ID == cryptRootPath)? "": remoteTarget.ID]; var orgmakejob = parent.orgItem.MakeFolder(CryptCarot.EncryptFilename(foldername), WeekDepend, parentJob); var job = JobControler.CreateNewJob <IRemoteItem>( type: JobClass.RemoteOperation, depends: orgmakejob); job.DisplayName = "Make folder : " + foldername; job.ProgressStr = "wait for operation."; var ct = job.Ct; JobControler.Run <IRemoteItem>(job, (j) => { var result = j.ResultOfDepend[0]; if (result.TryGetTarget(out var item)) { j.ProgressStr = "Make folder..."; j.Progress = -1; var newitem = new CarotCryptSystemItem(this, item, remoteTarget); pathlist.AddOrUpdate(newitem.ID, (k) => newitem, (k, v) => newitem); remoteTarget.SetChildren(remoteTarget.Children.Concat(new[] { newitem })); j.Result = newitem; SetUpdate(remoteTarget); } j.ProgressStr = "Done"; j.Progress = 1; });
/// <summary> /// <see cref="RemoteProvider.ApplyChanges"/> /// </summary> /// <remarks> /// Email integration only loads messages from Exchange. /// </remarks> public override void ApplyChanges(SyncContext context, IRemoteItem syncItem) { }