コード例 #1
0
 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);
 }
コード例 #2
0
        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;
            }
        }
コード例 #3
0
 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);
 }
コード例 #4
0
        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;
            }
        }
コード例 #5
0
 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;
 }
コード例 #6
0
 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);
 }
コード例 #7
0
 /// <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));
     }
 }
コード例 #8
0
        /// <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));
            }
        }
コード例 #9
0
ファイル: MegaStore.cs プロジェクト: exaphaser/megadesktop
 private void AssertId(MegaNodeHelper target, string expectedId)
 {
     if (target.Node.Id != expectedId)
     {
         throw new MegaStoreConcurrencyException("The node has different id") { Node = target };
     }
 }
コード例 #10
0
ファイル: MegaStore.cs プロジェクト: exaphaser/megadesktop
 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");
         }
     }
 }
コード例 #11
0
ファイル: MegaStore.cs プロジェクト: exaphaser/megadesktop
        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);
                }
            }
        }
コード例 #12
0
ファイル: MegaStore.cs プロジェクト: exaphaser/megadesktop
        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;
        }
コード例 #13
0
ファイル: MegaStore.cs プロジェクト: exaphaser/megadesktop
 public bool IsDirectory(MegaNodeHelper node)
 {
     return node.Node.Type == MegaNodeType.Folder;
 }
コード例 #14
0
ファイル: MegaStore.cs プロジェクト: exaphaser/megadesktop
 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);
     }
 }
コード例 #15
0
ファイル: MegaStore.cs プロジェクト: exaphaser/megadesktop
        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();
        }