public async Task <bool> CopyToDestination(PLAsset photo, string destPath, IFileSystem fileSystem, DateTime filetime)
        {
            try
            {
                if (!photo.IsAvailable)
                {
                    throw new InvalidOperationException("This photo is no longer available.");
                }

                var options = new PHAssetResourceRequestOptions {
                    NetworkAccessAllowed = true
                };

                NSError lastError = null;
                var     original  = photo.Resources.FirstOrDefault(x => x.ResourceType == PHAssetResourceType.FullSizeVideo ||
                                                                   x.ResourceType == PHAssetResourceType.FullSizePhoto ||
                                                                   x.ResourceType == PHAssetResourceType.Photo ||
                                                                   x.ResourceType == PHAssetResourceType.Video ||
                                                                   x.ResourceType == PHAssetResourceType.Audio);

                if (original == null)
                {
                    throw new InvalidOperationException("Backup failed for this photo.");
                }

                var destTmpFile = destPath + ".temp";

                var  tcs         = new TaskCompletionSource <int>();
                long datawritten = 0;
                PHAssetResourceManager.DefaultManager.RequestData(original, options, data => {
                    var bytes = data.ToArray();
                    WriteToDest(bytes, datawritten, bytes.Length, destTmpFile, fileSystem).Wait();
                    datawritten += bytes.Length;
                }, error => {
                    if (error != null)
                    {
                        tcs.SetException(new InvalidOperationException(lastError.LocalizedDescription));
                    }
                    tcs.SetResult(0);
                });
                await tcs.Task.ConfigureAwait(false);


                return(await RenameDestinationFile(fileSystem, destTmpFile, destPath, filetime).ConfigureAwait(false));
            }
            catch (Exception)
            {
                return(false);
            }
        }
        public void WriteArchive(Stream zip)
        {
            if (!Photo.IsAvailable)
            {
                throw new InvalidOperationException("This photo is no longer available.");
            }

            using var archive = new ZipArchive(zip, ZipArchiveMode.Update, true);

            var options = new PHAssetResourceRequestOptions {
                NetworkAccessAllowed = true
            };
            var waitables = new List <ManualResetEvent>(Photo.Resources.Count + 1);

            NSError lastError = null;
            var     original  = Photo.Resources.FirstOrDefault(x => x.ResourceType == PHAssetResourceType.FullSizeVideo ||
                                                               x.ResourceType == PHAssetResourceType.FullSizePhoto ||
                                                               x.ResourceType == PHAssetResourceType.Photo ||
                                                               x.ResourceType == PHAssetResourceType.Video ||
                                                               x.ResourceType == PHAssetResourceType.Audio);

            if (original == null)
            {
                throw new InvalidOperationException("Backup failed for this photo.");
            }


            var baseName  = Path.GetFileNameWithoutExtension(Photo.FileName);
            var extension = Path.GetExtension(Photo.FileName)?.ToLowerInvariant() ?? string.Empty;

            foreach (var resource in Photo.Resources)
            {
                var entryName   = $"{baseName} ({resource.ResourceType:G}){extension}";
                var entryStream = archive.CreateEntry(entryName, CompressionLevel.NoCompression).Open();
                var waitable    = new ManualResetEvent(false);
                waitables.Add(waitable);
                PHAssetResourceManager.DefaultManager.RequestData(resource, options, data =>
                {
                    var bytes = data.ToArray();
                    entryStream.Write(bytes, 0, bytes.Length);
                }, error =>
                {
                    if (error != null)
                    {
                        lastError = error;
                    }
                    entryStream.Dispose();
                    waitable.Set();
                });
            }

            WaitHandle.WaitAll(waitables.ToArray());

            if (lastError != null)
            {
                throw new InvalidOperationException(lastError.LocalizedDescription);
            }

            // Write meta entry.
            Photo.BackupDate     = DateTime.Now;
            using var metaStream = archive.CreateEntry("@", CompressionLevel.NoCompression).Open();
            using var textStream = new StreamWriter(metaStream, Encoding.UTF8);
            using var jsonWriter = new JsonTextWriter(textStream)
                  {
                      Indentation = 4, IndentChar = ' ', Formatting = Formatting.Indented
                  };
            JsonSerializer.CreateDefault().Serialize(jsonWriter, Photo);
            zip.Flush();
        }
Exemple #3
0
        public Task <IEnumerable <MediaAsset> > Query(MediaTypes mediaTypes, DateTimeOffset date)
        {
            var tcs = new TaskCompletionSource <IEnumerable <MediaAsset> >();

            Task.Run(() =>
            {
                var filter = "creationDate >= %@ && " + GetFilter(mediaTypes);

                var fetchOptions = new PHFetchOptions
                {
                    IncludeHiddenAssets   = false,
                    IncludeAllBurstAssets = false,
                    Predicate             = NSPredicate.FromFormat(filter, (NSDate)date.LocalDateTime),
                    SortDescriptors       = new [] {
                        new NSSortDescriptor("creationDate", false)
                    }
                };

                var fetchAssets = PHAsset
                                  .FetchAssets(fetchOptions)
                                  .OfType <PHAsset>()
                                  .ToArray();

                var options = new PHAssetResourceRequestOptions
                {
                    NetworkAccessAllowed = false
                };


                var imageCache = new PHCachingImageManager();
                imageCache.StartCaching(
                    fetchAssets,
                    PHImageManager.MaximumSize,
                    PHImageContentMode.Default,
                    new PHImageRequestOptions
                {
                    NetworkAccessAllowed = false
                }
                    );

                var assets = new List <MediaAsset>(fetchAssets.Count());
                foreach (var asset in fetchAssets)
                {
                    //result.MediaType
                    //result.Hidden
                    //result.Duration
                    //result.LocalIdentifier
                    //result.Location;
                    //result.ModificationDate
                    //result.PixelHeight;
                    //result.PixelWidth;
                    //result.CreationDate

                    switch (asset.MediaType)
                    {
                    case PHAssetMediaType.Image:
                        imageCache.RequestImageData(
                            asset,
                            new PHImageRequestOptions
                        {
                        },
                            (data, fn, orientation, dict) => { }
                            );
                        break;

                    case PHAssetMediaType.Video:
                        imageCache.RequestAvAsset(
                            asset,
                            new PHVideoRequestOptions
                        {
                            NetworkAccessAllowed = false,
                            DeliveryMode         = PHVideoRequestOptionsDeliveryMode.HighQualityFormat
                        },
                            (ass, mix, dict) => { }
                            );
                        break;

                    case PHAssetMediaType.Audio:
                        break;
                    }
                }
                imageCache.StopCaching();
                tcs.SetResult(assets);
            });
            return(tcs.Task);
        }