Use JsonInclude in BookMetadata to remove nulls

This commit is contained in:
aditya.chandel
2025-01-26 21:19:39 -07:00
parent a94ded10ee
commit a8d1f58c7f
9 changed files with 62 additions and 64 deletions

View File

@@ -1,6 +1,7 @@
package com.adityachandel.booklore.model.dto;
import com.adityachandel.booklore.model.enums.MetadataProvider;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Builder;
import lombok.Data;
@@ -10,14 +11,9 @@ import java.util.List;
@Data
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class BookMetadata {
// Identifiers
private Long bookId;
private MetadataProvider provider;
private String providerBookId;
private String thumbnailUrl;
// Book Information
private String title;
private String subtitle;
private String publisher;
@@ -30,21 +26,18 @@ public class BookMetadata {
private String isbn10;
private Integer pageCount;
private String language;
// Rating & Reviews
private Double rating;
private Integer ratingCount;
private Integer reviewCount;
// Cover Information
private Instant coverUpdatedOn;
// Content
private List<String> authors;
private List<String> categories;
private List<Award> awards;
// Locking Information
private MetadataProvider provider;
private String providerBookId;
private String thumbnailUrl;
private Boolean allFieldsLocked;
private Boolean titleLocked;
private Boolean subtitleLocked;

View File

@@ -94,11 +94,8 @@ public class BookMetadataService {
BookEntity bookEntity = bookRepository.findById(bookId).orElseThrow(() -> ApiError.BOOK_NOT_FOUND.createException(bookId));
AppSettings appSettings = appSettingService.getAppSettings();
MetadataRefreshRequest refreshRequest = MetadataRefreshRequest.builder().refreshOptions(appSettings.getMetadataRefreshOptions()).build();
List<MetadataProvider> providers = prepareProviders(refreshRequest);
Map<MetadataProvider, BookMetadata> metadataMap = fetchMetadataForBook(providers, bookEntity);
BookMetadata fetchedBookMetadata = buildFetchMetadata(refreshRequest, metadataMap);
BookMetadataEntity bookMetadataEntity = updateBookMetadata(bookEntity, fetchedBookMetadata, refreshRequest.getRefreshOptions().isRefreshCovers(), refreshRequest.getRefreshOptions().isMergeCategories());
return bookMetadataMapper.toBookMetadata(bookMetadataEntity, true);
Map<MetadataProvider, BookMetadata> metadataMap = fetchMetadataForBook(prepareProviders(refreshRequest), bookEntity);
return buildFetchMetadata(bookId, refreshRequest, metadataMap);
}
@Transactional
@@ -123,7 +120,7 @@ public class BookMetadataService {
if (providers.contains(GoodReads)) {
Thread.sleep(ThreadLocalRandom.current().nextLong(500, 1500));
}
BookMetadata fetchedBookMetadata = buildFetchMetadata(request, metadataMap);
BookMetadata fetchedBookMetadata = buildFetchMetadata(bookEntity.getId(), request, metadataMap);
updateBookMetadata(bookEntity, fetchedBookMetadata, request.getRefreshOptions().isRefreshCovers(), request.getRefreshOptions().isMergeCategories());
} catch (Exception e) {
log.error("Error while updating book metadata, book: {}", bookEntity.getFileName(), e);
@@ -170,8 +167,8 @@ public class BookMetadataService {
}
@Transactional
protected BookMetadata buildFetchMetadata(MetadataRefreshRequest request, Map<MetadataProvider, BookMetadata> metadataMap) {
BookMetadata metadata = BookMetadata.builder().build();
protected BookMetadata buildFetchMetadata(Long bookId, MetadataRefreshRequest request, Map<MetadataProvider, BookMetadata> metadataMap) {
BookMetadata metadata = BookMetadata.builder().bookId(bookId).build();
MetadataRefreshOptions.FieldOptions fieldOptions = request.getRefreshOptions().getFieldOptions();
metadata.setTitle(resolveFieldAsString(metadataMap, fieldOptions.getTitle(), BookMetadata::getTitle));

View File

@@ -13,6 +13,7 @@ import {AppSettingsService} from './core/service/app-settings.service';
selector: 'app-root',
templateUrl: './app.component.html',
styleUrl: './app.component.scss',
standalone: true,
imports: [ConfirmDialog, Toast, RouterOutlet]
})
export class AppComponent implements OnInit {

View File

@@ -23,6 +23,7 @@ import {NgIf} from '@angular/common';
templateUrl: './book-card.component.html',
styleUrls: ['./book-card.component.scss'],
imports: [Button, MenuModule, CheckboxModule, FormsModule, NgIf],
standalone: true
})
export class BookCardComponent implements OnInit {
@Input() book!: Book;

View File

@@ -10,12 +10,20 @@
<div class="flex flex-col items-center gap-2 relative">
<img
*ngIf="!metadata['thumbnailUrl']"
[src]="urlHelper.getCoverUrl(metadata.bookId, metadata?.coverUpdatedOn)"
alt="Image"
width="250"
[ngClass]="{ 'brightness-50': isUploading }"
class="transition-all duration-300 ease-in-out"/>
<img
*ngIf="metadata['thumbnailUrl']"
[src]="metadata['thumbnailUrl']"
alt="Image"
height="350"
width="250"/>
<p-progressSpinner
*ngIf="isUploading"
class="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-10">

View File

@@ -67,6 +67,7 @@ export class MetadataEditorComponent implements OnInit {
seriesName: new FormControl(''),
seriesNumber: new FormControl(''),
seriesTotal: new FormControl(''),
thumbnailUrl: new FormControl(''),
titleLocked: new FormControl(false),
subtitleLocked: new FormControl(false),
@@ -93,23 +94,24 @@ export class MetadataEditorComponent implements OnInit {
if (metadata) {
this.currentBookId = metadata.bookId;
this.metadataForm.setValue({
title: metadata.title,
subtitle: metadata.subtitle,
authors: metadata.authors.sort().join(', '),
categories: metadata.categories.sort().join(', '),
publisher: metadata.publisher,
publishedDate: metadata.publishedDate,
isbn10: metadata.isbn10,
isbn13: metadata.isbn13,
description: metadata.description,
pageCount: metadata.pageCount == 0 ? null : metadata.pageCount,
language: metadata.language,
rating: metadata.rating,
reviewCount: metadata.reviewCount,
seriesName: metadata.seriesName,
seriesNumber: metadata.seriesNumber,
seriesTotal: metadata.seriesTotal,
this.metadataForm.patchValue({
title: metadata.title || null,
subtitle: metadata.subtitle || null,
authors: (metadata.authors || []).sort().join(', '),
categories: (metadata.categories || []).sort().join(', '),
publisher: metadata.publisher || null,
publishedDate: metadata.publishedDate || null,
isbn10: metadata.isbn10 || null,
isbn13: metadata.isbn13 || null,
description: metadata.description || null,
pageCount: metadata.pageCount || null,
language: metadata.language || null,
rating: metadata.rating || null,
reviewCount: metadata.reviewCount || null,
seriesName: metadata.seriesName || null,
seriesNumber: metadata.seriesNumber || null,
seriesTotal: metadata.seriesTotal || null,
thumbnailUrl: metadata.thumbnailUrl || null,
titleLocked: metadata.titleLocked || false,
subtitleLocked: metadata.subtitleLocked || false,
@@ -215,6 +217,7 @@ export class MetadataEditorComponent implements OnInit {
seriesName: this.metadataForm.get('seriesName')?.value,
seriesNumber: this.metadataForm.get('seriesNumber')?.value,
seriesTotal: this.metadataForm.get('seriesTotal')?.value,
thumbnailUrl: this.metadataForm.get('thumbnailUrl')?.value,
titleLocked: this.metadataForm.get('titleLocked')?.value,
subtitleLocked: this.metadataForm.get('subtitleLocked')?.value,

View File

@@ -91,23 +91,23 @@ export class MetadataPickerComponent implements OnInit {
this.bookMetadata$.subscribe((metadata) => {
if (metadata) {
this.currentBookId = metadata.bookId;
this.metadataForm.setValue({
title: metadata.title,
subtitle: metadata.subtitle,
authors: metadata.authors.sort().join(', '),
categories: metadata.categories.sort().join(', '),
publisher: metadata.publisher,
publishedDate: metadata.publishedDate,
isbn10: metadata.isbn10,
isbn13: metadata.isbn13,
description: metadata.description,
pageCount: metadata.pageCount == 0 ? null : metadata.pageCount,
language: metadata.language,
rating: metadata.rating,
reviewCount: metadata.reviewCount,
seriesName: metadata.seriesName,
seriesNumber: metadata.seriesNumber,
seriesTotal: metadata.seriesTotal,
this.metadataForm.patchValue({
title: metadata.title || '',
subtitle: metadata.subtitle || '',
authors: (metadata.authors || []).sort().join(', '),
categories: (metadata.categories || []).sort().join(', '),
publisher: metadata.publisher || '',
publishedDate: metadata.publishedDate || '',
isbn10: metadata.isbn10 || '',
isbn13: metadata.isbn13 || '',
description: metadata.description || '',
pageCount: metadata.pageCount || '',
language: metadata.language || '',
rating: metadata.rating || '',
reviewCount: metadata.reviewCount || '',
seriesName: metadata.seriesName || '',
seriesNumber: metadata.seriesNumber || '',
seriesTotal: metadata.seriesTotal || '',
thumbnailUrl: this.urlHelper.getCoverUrl(metadata.bookId, metadata.coverUpdatedOn),
titleLocked: metadata.titleLocked || false,

View File

@@ -46,10 +46,10 @@ export class MetadataSearcherComponent implements OnInit {
this.metadataCenterService.currentMetadata$.subscribe((metadata => {
if (metadata) {
this.bookId = metadata.bookId;
this.form.setValue(({
this.form.patchValue(({
provider: Object.values(MetadataProvider),
isbn: metadata.isbn10,
title: metadata.title,
isbn: metadata.isbn10 || null,
title: metadata.title || null,
author: metadata.authors?.length! > 0 ? metadata.authors[0] : ''
}));
}

View File

@@ -25,12 +25,7 @@ export class MetadataService {
}
quickUpdateBookMetadataSynchronous(bookId: number): Observable<BookMetadata> {
return this.http.put<BookMetadata>(`${this.url}/${bookId}/refresh-book-sync`, {}).pipe(
map(updatedMetadata => {
this.bookService.handleBookMetadataUpdate(bookId, updatedMetadata);
return updatedMetadata;
})
);
return this.http.put<BookMetadata>(`${this.url}/${bookId}/refresh-book-sync`, {});
}
updateBookMetadata(bookId: number, bookMetadata: BookMetadata): Observable<BookMetadata> {