/// <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; }