internal void AddItem(Item itemInfo)
        {
            var item = CloudItem.FromTemplate(itemInfo, _owner);

            _items.Add(item);

            // Link with parent if possible.
            if (item.IsShareRoot)
            {
                _shares.Add(item);

                // Pretend it has no parent, since share root parents are going to be external to the current filesystem.
                item.ParentID = null;
            }
            else if (item.ParentID != null)
            {
                item.Parent = AllItems.FirstOrDefault(i => i.ID == item.ParentID);

                if (item.Parent != null)
                {
                    item.Parent.Children = item.Parent.Children.Add(item);
                }
                else
                {
                    // The parent is not a part of the current filesystem. Weird, huh?
                    _orphans.Add(item);
                }
            }
            else
            {
                _roots.Add(item);
            }

            // Is this maybe a parent to any orphan item?
            foreach (var orphan in _orphans)
            {
                if (orphan.ParentID == item.ID)
                {
                    orphan.Parent = item;
                    item.Children.Add(orphan);
                }
            }

            // Remove any orhpans we de-orphaned.
            _orphans.RemoveAll(o => o.Parent != null);

            // Is it a special item?
            if (item.Type == ItemType.Files)
                Files = item;
            else if (item.Type == ItemType.Inbox)
                Inbox = item;
            else if (item.Type == ItemType.Trash)
                Trash = item;
        }
Example #2
0
		/// <summary>
		/// Materializes an instance from an Item structure returned by the Mega API, treated as a template for this item.
		/// Parent-child relationships are not automatically linked up - that is left up to the creator.
		/// </summary>
		internal static CloudItem FromTemplate(Item template, MegaClient client)
		{
			Argument.ValidateIsNotNull(template, "template");
			Argument.ValidateIsNotNull(client, "client");

			CloudItem item = new CloudItem(client)
			{
				TypeID = template.Type,
				// Filter out invalid sizes that Mega does not work with (anything less than 1).
				Size = template.Size.GetValueOrDefault() > 0 ? (long?)template.Size.Value : null,
				ID = template.ID,
				OwnerID = template.OwnerID,
				LastUpdated = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero).AddSeconds(template.Timestamp).ToLocalTime(),
				ParentID = template.ParentID,
				EncryptedKeys = template.EncryptedKeys.ToImmutableHashSet(),
				IsShareRoot = template.ShareKey.HasValue
			};

			bool hasEncryptedData = true;

			switch (template.Type)
			{
				case KnownItemTypes.File:
					item.Type = ItemType.File;
					break;
				case KnownItemTypes.Folder:
					item.Type = ItemType.Folder;
					break;
				case KnownItemTypes.Inbox:
					item.Type = ItemType.Inbox;
					hasEncryptedData = false;
					break;
				case KnownItemTypes.Trash:
					item.Type = ItemType.Trash;
					hasEncryptedData = false;
					break;
				case KnownItemTypes.Files:
					item.Type = ItemType.Files;
					hasEncryptedData = false;
					break;
				default:
					item.Type = ItemType.Unknown;
					break;
			}

			if (hasEncryptedData)
			{
				// Decrypt the item attributes, if the item has them and if we have a key.
				var itemKey = client.DecryptItemKey(item.EncryptedKeys);

				// We have a key for this item!
				var attributesKey = Algorithms.DeriveNodeAttributesKey(itemKey);
				item.Attributes = ItemAttributes.DecryptAndDeserialize(template.Attributes, attributesKey);
			}

			return item;
		}
Example #3
0
		private async Task DeleteUnwantedItems(CloudItem rootDirectory, ICollection<OpaqueID> wantedItems, IFeedbackChannel feedback)
		{
			foreach (var ci in rootDirectory.Children)
			{
				if (!wantedItems.Contains(ci.ID))
				{
					await ci.DeleteAsync(feedback);
					continue;
				}

				// If it is a wanted item, it might not have wanted children, so delete them.
				if (ci.Type == ItemType.Folder)
					await DeleteUnwantedItems(ci, wantedItems, feedback);
			}
		}
Example #4
0
		/// <summary>
		/// Moves the item under another item. This operation is valid for files and folders.
		/// The parent is not updated in any existing filesystem snapshot.
		/// </summary>
		/// <param name="newParent">The new parent of the item.</param>
		/// <param name="feedbackChannel">Allows you to receive feedback about the operation while it is running.</param>
		/// <param name="cancellationToken">Allows you to cancel the operation.</param>
		public async Task MoveAsync(CloudItem newParent, IFeedbackChannel feedbackChannel = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			Argument.ValidateIsNotNull(newParent, "newParent");

			if (Type != ItemType.File && Type != ItemType.Folder)
				throw new InvalidOperationException("You can only move files or folders.");

			if (!newParent.IsContainer)
				throw new InvalidOperationException("The specified destination cannot contain other items.");

			PatternHelper.LogMethodCall("MoveAsync", feedbackChannel, cancellationToken);
			PatternHelper.EnsureFeedbackChannel(ref feedbackChannel);

			using (await _client.AcquireLock(feedbackChannel, cancellationToken))
			{
				await _client.ExecuteCommandInternalAsync<SuccessResult>(feedbackChannel, cancellationToken, new MoveItemCommand
				{
					ClientInstanceID = _client._clientInstanceID,
					ItemID = ID,
					ParentID = newParent.ID
				});

				_client.InvalidateFilesystemInternal();
			}
		}