diff --git a/HomeLibProt.CollectionManager/Inpx/InpxGenerator.fs b/HomeLibProt.CollectionManager/Inpx/InpxGenerator.fs index 0052e5d..ea9ca00 100644 --- a/HomeLibProt.CollectionManager/Inpx/InpxGenerator.fs +++ b/HomeLibProt.CollectionManager/Inpx/InpxGenerator.fs @@ -28,6 +28,16 @@ type InpxGeneratorParameters = ErrorReport: string -> unit DoInTransactionAsync: DbConnection * (DbConnection -> Task) -> Task } +type private InpStat = + { Processed: uint + Skipped: uint + Added: uint } + +type private InpxStat = + { Processed: uint + Skipped: uint + Added: uint } + let private authorInpxInfoToAuthorsName (author: AuthorInpxInfo) : InpLine.AuthorName = { First = author.FirstName Middle = author.MiddleName @@ -69,16 +79,22 @@ let private getInpLinesAsync (bookId: int64) (extension: string) (size: string) + (inpStat: InpStat) (reportError: string -> unit) (connection: DbConnection) - : Task = + : Task = task { let! bookInfo = Books.GetBookInpxInfosByIdAsync(connection, bookId) match bookInfo with | [||] -> reportError $"Not found any information in database for Book Id: {bookId}" - return [||] + + return + [||], + { inpStat with + Processed = inpStat.Processed + 1u + Skipped = inpStat.Skipped + 1u } | bf -> let! authors = Authors.GetAuthorInpxInfosByBookIdAsync(connection, bookId) let! genres = Genres.GetGenreKeysByBookIdAsync(connection, bookId) @@ -89,24 +105,33 @@ let private getInpLinesAsync bf |> Array.map (fun bi -> bookAttributesToInpRecord (bookId.ToString()) extension size rate bi authors genres keywords - |> InpLine.makeLine) + |> InpLine.makeLine), + { inpStat with + Processed = inpStat.Processed + 1u + Added = inpStat.Added + 1u } } let private tryToGetInpLinesAsync (reportError: string -> unit) (entry: ZipArchiveEntry) + (inpStat: InpStat) (connection: DbConnection) - : Task = + : Task = task { match Int64.TryParse(entry.Name |> Path.GetFileNameWithoutExtension) with | true, bookId -> let extension = (entry.Name |> Path.GetExtension).Replace(".", String.Empty) let size = entry.Length.ToString() - let! lines = getInpLinesAsync bookId extension size reportError connection + let! lines, stat = getInpLinesAsync bookId extension size inpStat reportError connection - return Some lines - | false, _ -> return None + return Some lines, stat + | false, _ -> + return + None, + { inpStat with + Processed = inpStat.Processed + 1u + Skipped = inpStat.Skipped + 1u } } let private createInp (inpx: ZipArchive) (name: string) : ZipArchiveEntry = inpx.CreateEntry name @@ -118,22 +143,31 @@ let private createInpFromLibraryArchive (reportError: string -> unit) (connection: DbConnection) (libraryArchive: ZipArchive) - : Task = + : Task = task { let inp = Path.ChangeExtension(archiveName, "inp") |> createInp inpx use fs = inp.Open() use sw = new StreamWriter(fs) + let mutable inpStat: InpStat = + { Processed = 0u + Skipped = 0u + Added = 0u } + for entry in libraryArchive.Entries do - let! linesResult = tryToGetInpLinesAsync reportError entry connection + let! linesResult, stat = tryToGetInpLinesAsync reportError entry inpStat connection + + inpStat <- stat match linesResult with | Some lines -> for line in lines do do! sw.WriteLineAsync line | None -> () + + return inpStat } let private genreInpxEntityToString (genre: GenreInpxEntity) : string = @@ -211,19 +245,34 @@ let private fillInpxAsync let zipArchives = Directory.EnumerateFiles(pathToLibrary, "*.zip") + let mutable inpxStat: InpxStat = + { Processed = 0u + Skipped = 0u + Added = 0u } + for archive in zipArchives do let archiveName = Path.GetFileName archive - reportProgress $"Generating inp for {archiveName}" - try - do! + let! inpStat = ArchiveUtils.DoWithArchiveAsync( archive, createInpFromLibraryArchive archiveName inpx reportProgress reportError connection ) + + inpxStat <- + { inpxStat with + Processed = inpxStat.Processed + inpStat.Processed + Added = inpxStat.Added + inpStat.Added + Skipped = inpxStat.Skipped + inpStat.Skipped } + + reportProgress + $"Generated inp for {archiveName}. Processed: {inpStat.Processed}, Added: {inpStat.Added}, Skipped: {inpStat.Skipped}" with :? InvalidDataException as _ -> reportError $"Invalid archive {archiveName}" + + reportProgress + $"Total books Processed: {inpxStat.Processed}, Added: {inpxStat.Added}, Skipped: {inpxStat.Skipped}" } let private createInpxAndFillAsync (path: string) (fillInpx: ZipArchive -> Task) : Task =