mirror of
https://github.com/booklore-app/booklore.git
synced 2026-02-18 00:17:53 +01:00
fix(metadata): improve cover errors, reduce metadata fetch count, and hide attach option (#2690)
* fix(metadata): improve cover regen errors and reduce detailed metadata fetch count * fix(metadata): hide attach-to-book option in single-format libraries --------- Co-authored-by: acx10 <acx10@users.noreply.github.com>
This commit is contained in:
@@ -34,7 +34,7 @@ public enum ApiError {
|
||||
SCHEDULE_REFRESH_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "Failed to schedule metadata refresh job. Error: %s"),
|
||||
ANOTHER_METADATA_JOB_RUNNING(HttpStatus.CONFLICT, "A metadata refresh job is currently running. Please wait for it to complete before initiating a new one."),
|
||||
METADATA_SOURCE_NOT_IMPLEMENT_OR_DOES_NOT_EXIST(HttpStatus.BAD_REQUEST, "Metadata source not implement or does not exist"),
|
||||
FAILED_TO_REGENERATE_COVER(HttpStatus.BAD_REQUEST, "Failed to regenerate cover"),
|
||||
FAILED_TO_REGENERATE_COVER(HttpStatus.BAD_REQUEST, "Failed to regenerate cover: %s"),
|
||||
NO_COVER_IN_FILE(HttpStatus.BAD_REQUEST, "No embedded cover image found in the audiobook file"),
|
||||
FAILED_TO_DOWNLOAD_FILE(HttpStatus.INTERNAL_SERVER_ERROR, "Error while downloading file, bookId: %s"),
|
||||
INVALID_REFRESH_TYPE(HttpStatus.BAD_REQUEST, "The refresh type is invalid"),
|
||||
|
||||
@@ -172,12 +172,12 @@ public class BookCoverService {
|
||||
var audiobookFile = bookEntity.getBookFiles().stream()
|
||||
.filter(f -> f.getBookType() == BookFileType.AUDIOBOOK)
|
||||
.findFirst()
|
||||
.orElseThrow(ApiError.FAILED_TO_REGENERATE_COVER::createException);
|
||||
.orElseThrow(() -> ApiError.FAILED_TO_REGENERATE_COVER.createException("no audiobook file found"));
|
||||
|
||||
BookFileProcessor processor = processorRegistry.getProcessorOrThrow(audiobookFile.getBookType());
|
||||
boolean success = processor.generateAudiobookCover(bookEntity);
|
||||
if (!success) {
|
||||
throw ApiError.FAILED_TO_REGENERATE_COVER.createException();
|
||||
throw ApiError.FAILED_TO_REGENERATE_COVER.createException("no embedded cover image found in the audiobook file");
|
||||
}
|
||||
updateAudiobookCoverMetadata(bookEntity);
|
||||
bookRepository.save(bookEntity);
|
||||
@@ -233,13 +233,13 @@ public class BookCoverService {
|
||||
|
||||
BookFileEntity ebookFile = findEbookFile(bookEntity);
|
||||
if (ebookFile == null) {
|
||||
throw ApiError.FAILED_TO_REGENERATE_COVER.createException();
|
||||
throw ApiError.FAILED_TO_REGENERATE_COVER.createException("no ebook file found for the book");
|
||||
}
|
||||
|
||||
BookFileProcessor processor = processorRegistry.getProcessorOrThrow(ebookFile.getBookType());
|
||||
boolean success = processor.generateCover(bookEntity, ebookFile);
|
||||
if (!success) {
|
||||
throw ApiError.FAILED_TO_REGENERATE_COVER.createException();
|
||||
throw ApiError.FAILED_TO_REGENERATE_COVER.createException("no embedded cover image found in the file");
|
||||
}
|
||||
updateBookCoverMetadata(bookEntity);
|
||||
bookRepository.save(bookEntity);
|
||||
|
||||
@@ -45,7 +45,7 @@ public class AmazonBookParser implements BookParser, DetailedMetadataProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private static final int COUNT_DETAILED_METADATA_TO_GET = 4;
|
||||
private static final int COUNT_DETAILED_METADATA_TO_GET = 3;
|
||||
private static final String BASE_BOOK_URL_SUFFIX = "/dp/";
|
||||
private static final Pattern NON_DIGIT_PATTERN = Pattern.compile("[^\\d]");
|
||||
private static final Pattern SERIES_FORMAT_PATTERN = Pattern.compile("Book (\\d+(?:\\.\\d+)?) of (\\d+)");
|
||||
|
||||
@@ -36,7 +36,7 @@ import java.util.stream.Collectors;
|
||||
@AllArgsConstructor
|
||||
public class AudibleParser implements BookParser, DetailedMetadataProvider {
|
||||
|
||||
private static final int COUNT_DETAILED_METADATA_TO_GET = 4;
|
||||
private static final int COUNT_DETAILED_METADATA_TO_GET = 3;
|
||||
private static final long MIN_REQUEST_INTERVAL_MS = 1500;
|
||||
private static final String DEFAULT_DOMAIN = "com";
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import {ProgressSpinner} from 'primeng/progressspinner';
|
||||
import {TieredMenu} from 'primeng/tieredmenu';
|
||||
import {Image} from 'primeng/image';
|
||||
import {BookDialogHelperService} from '../../../../book/components/book-browser/book-dialog-helper.service';
|
||||
import {LibraryService} from '../../../../book/service/library.service';
|
||||
import {TagColor, TagComponent} from '../../../../../shared/components/tag/tag.component';
|
||||
import {TaskHelperService} from '../../../../settings/task-management/task-helper.service';
|
||||
import {AGE_RATING_OPTIONS, CONTENT_RATING_LABELS, fileSizeRanges, matchScoreRanges, pageCountRanges} from '../../../../book/components/book-browser/book-filter/book-filter.config';
|
||||
@@ -50,6 +51,7 @@ export class MetadataViewerComponent implements OnInit, OnChanges {
|
||||
private originalRecommendedBooks: BookRecommendation[] = [];
|
||||
|
||||
private readonly t = inject(TranslocoService);
|
||||
private libraryService = inject(LibraryService);
|
||||
private bookDialogHelperService = inject(BookDialogHelperService)
|
||||
private emailService = inject(EmailService);
|
||||
private messageService = inject(MessageService);
|
||||
@@ -267,8 +269,11 @@ export class MetadataViewerComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
// Show "Attach to Another Book" for single-file books (detached books) - not for physical books
|
||||
// Hide in single-format libraries where attaching provides no cross-format benefit
|
||||
const isSingleFileBook = hasFiles && !book.alternativeFormats?.length;
|
||||
if (isSingleFileBook && (userState?.user?.permissions.canManageLibrary || userState?.user?.permissions.admin)) {
|
||||
const library = this.libraryService.findLibraryById(book.libraryId);
|
||||
const isMultiFormatLibrary = !library?.allowedFormats?.length || library.allowedFormats.length > 1;
|
||||
if (isSingleFileBook && isMultiFormatLibrary && (userState?.user?.permissions.canManageLibrary || userState?.user?.permissions.admin)) {
|
||||
items.push({
|
||||
label: this.t.translate('metadata.viewer.menuAttachToAnotherBook'),
|
||||
icon: 'pi pi-link',
|
||||
|
||||
Reference in New Issue
Block a user