private void DoNothing( ItemMetadata item, ItemChange change, SaveChangeContext context, bool deleted = false, MegaNodeHelper existingNode = null) { // creating if (item == null) { if (existingNode == null) { context.RecordRecoverableErrorForItem(new RecoverableErrorData(new Exception())); } item = _metadataStore.Metadata.CreateItemMetadata(change.ItemId, change.CreationVersion); item.ChangeVersion = change.ChangeVersion; _metadataStore.SaveItemMetadata(item, existingNode.Node.Id, existingNode.Path); return; } if (deleted) { item.MarkAsDeleted(change.ChangeVersion); } item.ChangeVersion = change.ChangeVersion; _metadataStore.SaveItemMetadata(item); }
private void ProcessConstraint( ItemChange change, SaveChangeContext context, MegaStoreConstraintException e, ItemMetadata item, MegaNodeHelper conflictingNode) { switch (e.ConstraintType) { case MegaStoreConstraintType.TargetExists: ResolveConflict(item, change, context, conflictingNode); break; case MegaStoreConstraintType.NoParent: OnDemandedResync(); context.RecordConstraintConflictForItem(ConstraintConflictReason.NoParent); break; // todo add no-free-space handling case MegaStoreConstraintType.ZeroSize: context.RecordConstraintConflictForItem(ConstraintConflictReason.Other); break; case MegaStoreConstraintType.NotEmpty: OnDemandedResync(); context.RecordRecoverableErrorForItem(new RecoverableErrorData(e)); break; } }
private bool FilesAreEqual(IFileDataRetriever data, MegaNodeHelper node) { if (data.FileData.RelativePath != node.Path) { return(false); } if (data.FileData.IsDirectory) { return(true); } if (data.FileData.Size != node.Node.Size) { return(false); } if (data.FileData.Size < FileComparisionTreshold || node.Node.Size < FileComparisionTreshold) { // TODO compare streams } return(true); }
private bool FilesAreEqual(IFileDataRetriever data, MegaNodeHelper node) { if (data.FileData.RelativePath != node.Path) { return false; } if (data.FileData.IsDirectory) { return true; } if (data.FileData.Size != node.Node.Size) { return false; } if (data.FileData.Size < FileComparisionTreshold || node.Node.Size < FileComparisionTreshold) { // TODO compare streams } return true; }
/// <summary> /// CONFLICT /// </summary> private void ResolveConflict(ItemMetadata item, ItemChange change, SaveChangeContext context, MegaNodeHelper conflictingNode) { var data = (IFileDataRetriever)context.ChangeData; // item does not exist in metadata (can happen when create+create) if (item == null) { if (conflictingNode == null) { context.RecordRecoverableErrorForItem(new RecoverableErrorData(new Exception())); } if (FilesAreEqual(data, conflictingNode)) { DoNothing(item, change, context, false, conflictingNode); } else { BackupFile(item, conflictingNode.Path, change, context); } return; } var attr = _metadataStore.GetItemInfo(item); try { if (change.ChangeKind == ChangeKind.Deleted) { // local delete + remote delete if (item.IsDeleted) { DoNothing(item, change, context, true); } // local delete + remote update else { DownloadBack(item, change); } } else { // local update + remote delete if (item.IsDeleted) { UploadBack(item, change, context); } // update + update else { if (FilesAreEqual(data, _nodeStore.FindNodeById(attr.Id))) { DoNothing(item, change, context); } else { BackupFile(item, attr.Path, change, context); } } } } catch (MegaApiException e) { context.RecordRecoverableErrorForItem(new RecoverableErrorData(e)); } }
private void AssertId(MegaNodeHelper target, string expectedId) { if (target.Node.Id != expectedId) { throw new MegaStoreConcurrencyException("The node has different id") { Node = target }; } }
private void AssertNoChildren(MegaNodeHelper node) { if (IsDirectory(node)) { var children = serverNodes.Where(n => n.Node.ParentId == node.Node.Id).FirstOrDefault(); if (children != null) { throw new MegaStoreConstraintException(MegaStoreConstraintType.NotEmpty, "The folder is not empty"); } } }
internal void BackupFile(MegaNodeHelper node, int? version = null) { if (node == null) { return; } lock (serverNodes) { var newPath = Path.Combine( Path.GetDirectoryName(node.Path), String.Format("{0}.backup{1}{2}", Path.GetFileNameWithoutExtension(node.Path), version, Path.GetExtension(node.Path))); var found = FindNodeByPath(newPath); if (found != null) { BackupFile(node, version == null ? 1 : ++version); } else { var newName = Path.GetFileName(newPath); node.SetName(newName); api.UpdateNodeAttrSync(node.Node); } } }
public MegaNode CreateDirectory(string path) { var folders = Path.GetDirectoryName(path.TrimStart(new char[] { '\\' })) .Split(new char[] { '\\' }); if (string.IsNullOrEmpty(folders[0])) { return rootFolder.Node; } var parent = rootFolder; MegaNodeHelper helper = null; foreach (var folder in folders) { lock (serverNodes) { helper = serverNodes .Where(h => h.Node.Attributes.Name == folder && h.Node.ParentId == parent.Node.Id) .FirstOrDefault(); if (helper == null) { var n = api.CreateFolderSync(parent.Node.Id, folder); helper = new MegaNodeHelper { Node = n, Parent = parent == rootFolder ? null : parent }; } parent = helper; } } return helper.Node; }
public bool IsDirectory(MegaNodeHelper node) { return node.Node.Type == MegaNodeType.Folder; }
private void AddChildren(List<MegaNodeHelper> target, MegaNodeHelper parent, List<MegaNode> serverNodes, bool r = false) { var children = serverNodes.Where(n=>n.ParentId == parent.Node.Id); foreach (var child in children) { var c = new MegaNodeHelper { Node = child, // do not set the root folder as parent Parent = r ? parent : null }; target.Add(c); AddChildren(target, c, serverNodes, true); } }
private void RefreshNodeList() { lock (serverNodes) { refreshing = true; refreshTimer.Stop(); serverNodes = new List<MegaNodeHelper>(); List<MegaNode> nodes = null; nodes = api.GetNodesSync(); // todo ignore root folder in the trash var rootNode = nodes.Where(n => n.Attributes.Name == rootFolderName).FirstOrDefault(); if (rootNode == null) { rootNode = api.CreateFolderSync(nodes.Where(n => n.Type == MegaNodeType.RootFolder).First().Id, rootFolderName); } rootFolder = new MegaNodeHelper { Node = rootNode }; if (string.IsNullOrEmpty(recyclingId)) { var recycleNode = nodes.Where(n => n.Type == MegaNodeType.Trash).FirstOrDefault(); if (recycleNode == null) { RecycleDeletedItems = false; } else { recyclingId = recycleNode.Id; } } AddChildren(serverNodes, rootFolder, nodes); refreshTimer.Start(); refreshing = false; } OnUpdated(); }