public FileInfoEx(DirectorySetup directorySetup, FileInfo fileInfo)
        {
            if (directorySetup.Id != fileInfo.DirectorySetupId)
            {
                throw new InvalidOperationException($"{nameof(FileInfoEx)} tried to link dirSetup {directorySetup.Id} with fileInfo {fileInfo} with the dirSetupId {fileInfo.DirectorySetupId}");
            }

            FileInfo       = fileInfo;
            DirectorySetup = directorySetup;
            AbsoluteUri    = new Uri(directorySetup.Path, fileInfo.Path);
        }
        public void LinkThumbnail(ItemEx item, string thumbnailPath, out FileInfo file, out FileItemLinkChangeset linkCs, FileItemLink?linkSource = null)
        {
            FileHash hash = fileManagement.HashFile(thumbnailPath);

            file = new FileInfoChangeset(item.DirectorySetups.FirstOrDefault(), new SysFileInfo(thumbnailPath), hash).ToEntity();

            var existing = fileDataService.GetExtendedByHash().Lookup(file.HashKey.Value);

            if (existing.HasValue)
            {
                file = existing.Value.FileInfo;
            }

            linkCs = new FileItemLinkChangeset(linkSource ?? item.LatestVersionedFile.Value.Link.Link)
            {
                ThumbnailKey = file.HashKey
            };

            this.fileDataService.Post(file);
        }
        public void CreateAndLinkThumbnail(ItemEx item, Action <FileStream> streamWriter, out FileInfo file, out FileItemLinkChangeset linkCs, FileItemLink?linkSource = null)
        {
            var relativeThumbnailPath = item.GenerateRelativeThumbnailPath();
            var root         = item.RootPath;
            var absolutePath = Path.Combine(root, relativeThumbnailPath);

            createThumbnailDir(absolutePath);

            using (var fs = File.OpenWrite(absolutePath))
            {
                streamWriter(fs);
                fs.Close();
            }

            LinkThumbnail(item, absolutePath, out file, out linkCs, linkSource);
        }
        public IEnumerable <ITaskProgressionInfo> CreateAndLinkThumbnail()
        {
            return(this.itemService
                   .GetExtended()
                   .Items
                   .Where(item =>
                          !item.LatestThumbnail.HasValue &&
                          item.LatestVersionedFile != null
                          )
                   .SplitEvenly(settingsService.ThreadCount)
                   .Select(chunk =>
            {
                TaskProgression prog = new TaskProgression();
                prog.Title = "Creating Thumbnails";
                prog.RequiredProgress = chunk.Count();
                Observable.Start(() =>
                {
                    prog.State = TaskState.InProgress;
                    var chunkResult = chunk.Select(item =>
                    {
                        FileInfo file = default;
                        FileItemLinkChangeset linkCs = null;
                        FailedThumbnailResult?err = null;

                        var imgPath = item.GenerateAbsoluteThumbnailPath();
                        var itemPath = item.LatestFilePath;
                        try
                        {
                            this.CreateAndLinkThumbnail(item, fs =>
                            {
                                createThumbnail(itemPath, fs);
                            }, out file, out linkCs);
                        }
                        catch (Exception ex)
                        {
                            err = new FailedThumbnailResult(ex, itemPath, imgPath);
                            prog.State = TaskState.RunningWithErrors;
                        }
                        prog.CurrentProgress++;
                        return new { file, linkCs, err };
                    }).ToArray();


                    var groupedResult = chunkResult.GroupBy(data => data.err.HasValue);
                    var successes = groupedResult.FirstOrDefault(x => !x.Key)?.Where(x => x != null);
                    var errors = groupedResult.FirstOrDefault(x => x.Key)?.Select(x => x.err.Value);

                    if (prog.State == TaskState.RunningWithErrors)
                    {
                        prog.State = successes?.Any() == true ? TaskState.PartialSuccess : TaskState.Failed;
                    }
                    else
                    {
                        prog.State = TaskState.Done;
                    }

                    if (errors?.Any() == true)
                    {
                        var eGroups = errors.GroupBy(e => e.Exception.GetType().FullName);
                        string msg = "the following Thumbnails could not be created";

                        foreach (var eGroup in eGroups)
                        {
                            msg += string.Join(Environment.NewLine, new string[] {
                                "",
                                "--------------------------------",
                                eGroup.Key,
                                "3dFile / thumbnail",
                                string.Join(Environment.NewLine, eGroup.Select(e => $"{e.FilePath} / {e.ThumbnailPath}"))
                            });
                        }
                        prog.Error = new Exception(msg);
                    }
                }, RxApp.TaskpoolScheduler);
                return prog as ITaskProgressionInfo;
            })
                   .ToArray());
        }