refactor(komga): add functions to send multiple tasks in TaskEmitter

This commit is contained in:
Gauthier Roebroeck 2023-10-13 16:00:19 +08:00
parent 72cf68bb79
commit 12a786ba6e
8 changed files with 61 additions and 50 deletions

View file

@ -10,7 +10,6 @@ import org.gotson.komga.domain.model.CopyMode
import org.gotson.komga.domain.model.Library
import org.gotson.komga.domain.model.Media
import org.gotson.komga.domain.persistence.BookRepository
import org.gotson.komga.domain.persistence.LibraryRepository
import org.gotson.komga.domain.service.BookConverter
import org.gotson.komga.infrastructure.jms.JMS_PROPERTY_TYPE
import org.gotson.komga.infrastructure.jms.QUEUE_TASKS
@ -26,7 +25,6 @@ private val logger = KotlinLogging.logger {}
@Service
class TaskEmitter(
connectionFactory: ConnectionFactory,
private val libraryRepository: LibraryRepository,
private val bookRepository: BookRepository,
private val bookConverter: BookConverter,
) {
@ -38,10 +36,6 @@ class TaskEmitter(
}
}
fun scanLibraries() {
libraryRepository.findAll().forEach { scanLibrary(it.id) }
}
fun scanLibrary(libraryId: String, scanDeep: Boolean = false, priority: Int = DEFAULT_PRIORITY) {
submitTask(Task.ScanLibrary(libraryId, scanDeep, priority))
}
@ -73,16 +67,20 @@ class TaskEmitter(
submitTask(Task.FindBooksWithMissingPageHash(library.id, priority))
}
fun hashBookPages(bookId: String, seriesId: String, priority: Int = DEFAULT_PRIORITY) {
submitTask(Task.HashBookPages(bookId, priority, seriesId))
fun hashBookPages(bookIdToSeriesId: Collection<Pair<String, String>>, priority: Int = DEFAULT_PRIORITY) {
bookIdToSeriesId.forEach { (bookId, seriesId) ->
submitTask(Task.HashBookPages(bookId, priority, seriesId))
}
}
fun findBooksToConvert(library: Library, priority: Int = DEFAULT_PRIORITY) {
submitTask(Task.FindBooksToConvert(library.id, priority))
}
fun convertBookToCbz(book: Book, priority: Int = DEFAULT_PRIORITY) {
submitTask(Task.ConvertBook(book.id, priority, book.seriesId))
fun convertBookToCbz(books: Collection<Book>, priority: Int = DEFAULT_PRIORITY) {
books.forEach { book ->
submitTask(Task.ConvertBook(book.id, priority, book.seriesId))
}
}
fun repairExtensions(library: Library, priority: Int = DEFAULT_PRIORITY) {
@ -100,10 +98,18 @@ class TaskEmitter(
submitTask(Task.RemoveHashedPages(bookId, pages, priority, bookId))
}
fun removeDuplicatePages(bookIdToPages: Map<String, Collection<BookPageNumbered>>, priority: Int = DEFAULT_PRIORITY) {
bookIdToPages.forEach { removeDuplicatePages(it.key, it.value) }
}
fun analyzeBook(book: Book, priority: Int = DEFAULT_PRIORITY) {
submitTask(Task.AnalyzeBook(book.id, priority, book.seriesId))
}
fun analyzeBook(books: Collection<Book>, priority: Int = DEFAULT_PRIORITY) {
books.forEach { analyzeBook(it, priority) }
}
fun generateBookThumbnail(book: Book, priority: Int = DEFAULT_PRIORITY) {
submitTask(Task.GenerateBookThumbnail(book.id, priority, book.seriesId))
}
@ -112,6 +118,10 @@ class TaskEmitter(
submitTask(Task.GenerateBookThumbnail(bookId, priority, bookId))
}
fun generateBookThumbnail(bookIds: Collection<String>, priority: Int = DEFAULT_PRIORITY) {
bookIds.forEach { generateBookThumbnail(it, priority) }
}
fun refreshBookMetadata(
book: Book,
capabilities: Set<BookMetadataPatchCapability> = BookMetadataPatchCapability.values().toSet(),
@ -120,6 +130,14 @@ class TaskEmitter(
submitTask(Task.RefreshBookMetadata(book.id, capabilities, priority, book.seriesId))
}
fun refreshBookMetadata(
books: Collection<Book>,
capabilities: Set<BookMetadataPatchCapability> = BookMetadataPatchCapability.values().toSet(),
priority: Int = DEFAULT_PRIORITY,
) {
books.forEach { refreshBookMetadata(it, capabilities, priority) }
}
fun refreshSeriesMetadata(seriesId: String, priority: Int = DEFAULT_PRIORITY) {
submitTask(Task.RefreshSeriesMetadata(seriesId, priority))
}
@ -132,10 +150,18 @@ class TaskEmitter(
submitTask(Task.RefreshBookLocalArtwork(book.id, priority, book.seriesId))
}
fun refreshBookLocalArtwork(books: Collection<Book>, priority: Int = DEFAULT_PRIORITY) {
books.forEach { refreshBookLocalArtwork(it, priority) }
}
fun refreshSeriesLocalArtwork(seriesId: String, priority: Int = DEFAULT_PRIORITY) {
submitTask(Task.RefreshSeriesLocalArtwork(seriesId, priority))
}
fun refreshSeriesLocalArtwork(seriesIds: Collection<String>, priority: Int = DEFAULT_PRIORITY) {
seriesIds.forEach { refreshSeriesLocalArtwork(it, priority) }
}
fun importBook(sourceFile: String, seriesId: String, copyMode: CopyMode, destinationName: String?, upgradeBookId: String?, priority: Int = DEFAULT_PRIORITY) {
submitTask(Task.ImportBook(sourceFile, seriesId, copyMode, destinationName, upgradeBookId, priority))
}

View file

@ -70,23 +70,17 @@ class TaskHandler(
is Task.FindBooksToConvert ->
libraryRepository.findByIdOrNull(task.libraryId)?.let { library ->
bookConverter.getConvertibleBooks(library).forEach {
taskEmitter.convertBookToCbz(it, task.priority + 1)
}
taskEmitter.convertBookToCbz(bookConverter.getConvertibleBooks(library), task.priority + 1)
} ?: logger.warn { "Cannot execute task $task: Library does not exist" }
is Task.FindBooksWithMissingPageHash ->
libraryRepository.findByIdOrNull(task.libraryId)?.let { library ->
pageHashLifecycle.getBookAndSeriesIdsWithMissingPageHash(library).forEach {
taskEmitter.hashBookPages(it.first, it.second, task.priority + 1)
}
taskEmitter.hashBookPages(pageHashLifecycle.getBookAndSeriesIdsWithMissingPageHash(library), task.priority + 1)
} ?: logger.warn { "Cannot execute task $task: Library does not exist" }
is Task.FindDuplicatePagesToDelete ->
libraryRepository.findByIdOrNull(task.libraryId)?.let { library ->
pageHashLifecycle.getBookPagesToDeleteAutomatically(library).forEach { (bookId, pages) ->
taskEmitter.removeDuplicatePages(bookId, pages, task.priority + 1)
}
taskEmitter.removeDuplicatePages(pageHashLifecycle.getBookPagesToDeleteAutomatically(library), task.priority + 1)
} ?: logger.warn { "Cannot execute task $task: Library does not exist" }
is Task.EmptyTrash ->
@ -189,10 +183,7 @@ class TaskHandler(
}
is Task.FindBookThumbnailsToRegenerate -> {
val bookIds = bookLifecycle.findBookThumbnailsToRegenerate(task.forBiggerResultOnly)
bookIds.forEach {
taskEmitter.generateBookThumbnail(it, task.priority)
}
taskEmitter.generateBookThumbnail(bookLifecycle.findBookThumbnailsToRegenerate(task.forBiggerResultOnly), task.priority)
}
}
}.also {

View file

@ -219,22 +219,17 @@ class LibraryController(
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun analyze(@PathVariable libraryId: String) {
bookRepository.findAll(BookSearch(libraryIds = listOf(libraryId))).forEach {
taskEmitter.analyzeBook(it, HIGH_PRIORITY)
}
taskEmitter.analyzeBook(bookRepository.findAll(BookSearch(libraryIds = listOf(libraryId))), HIGH_PRIORITY)
}
@PostMapping("{libraryId}/metadata/refresh")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun refreshMetadata(@PathVariable libraryId: String) {
bookRepository.findAll(BookSearch(libraryIds = listOf(libraryId))).forEach {
taskEmitter.refreshBookMetadata(it, priority = HIGH_PRIORITY)
taskEmitter.refreshBookLocalArtwork(it, priority = HIGH_PRIORITY)
}
seriesRepository.findAllIdsByLibraryId(libraryId).forEach {
taskEmitter.refreshSeriesLocalArtwork(it, priority = HIGH_PRIORITY)
}
val books = bookRepository.findAll(BookSearch(libraryIds = listOf(libraryId)))
taskEmitter.refreshBookMetadata(books, priority = HIGH_PRIORITY)
taskEmitter.refreshBookLocalArtwork(books, priority = HIGH_PRIORITY)
taskEmitter.refreshSeriesLocalArtwork(seriesRepository.findAllIdsByLibraryId(libraryId), priority = HIGH_PRIORITY)
}
@PostMapping("{libraryId}/empty-trash")

View file

@ -128,7 +128,7 @@ class PageHashController(
},
)
toRemove.forEach { taskEmitter.removeDuplicatePages(it.key, it.value) }
taskEmitter.removeDuplicatePages(toRemove)
}
@PostMapping("{pageHash}/delete-match")

View file

@ -517,19 +517,16 @@ class SeriesController(
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun analyze(@PathVariable seriesId: String) {
bookRepository.findAllBySeriesId(seriesId).forEach {
taskEmitter.analyzeBook(it, HIGH_PRIORITY)
}
taskEmitter.analyzeBook(bookRepository.findAllBySeriesId(seriesId), HIGH_PRIORITY)
}
@PostMapping("v1/series/{seriesId}/metadata/refresh")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun refreshMetadata(@PathVariable seriesId: String) {
bookRepository.findAllBySeriesId(seriesId).forEach {
taskEmitter.refreshBookMetadata(it, priority = HIGH_PRIORITY)
taskEmitter.refreshBookLocalArtwork(it, priority = HIGH_PRIORITY)
}
val books = bookRepository.findAllBySeriesId(seriesId)
taskEmitter.refreshBookMetadata(books, priority = HIGH_PRIORITY)
taskEmitter.refreshBookLocalArtwork(books, priority = HIGH_PRIORITY)
taskEmitter.refreshSeriesLocalArtwork(seriesId, priority = HIGH_PRIORITY)
}

View file

@ -10,6 +10,7 @@ import io.mockk.verify
import org.assertj.core.api.Assertions
import org.assertj.core.api.Assertions.assertThat
import org.gotson.komga.application.tasks.TaskEmitter
import org.gotson.komga.domain.model.Book
import org.gotson.komga.domain.model.BookPage
import org.gotson.komga.domain.model.CopyMode
import org.gotson.komga.domain.model.KomgaUser
@ -82,8 +83,8 @@ class BookImporterTest(
@BeforeEach
fun initMocks() {
every { mockTackReceiver.refreshBookMetadata(any(), any(), any()) } just Runs
every { mockTackReceiver.refreshBookLocalArtwork(any(), any()) } just Runs
every { mockTackReceiver.refreshBookMetadata(any<Book>(), any(), any()) } just Runs
every { mockTackReceiver.refreshBookLocalArtwork(any<Book>(), any()) } just Runs
}
@AfterEach
@ -238,7 +239,7 @@ class BookImporterTest(
bookImporter.importBook(sourceFile, series, CopyMode.COPY)
// then
verify(exactly = 2) { mockTackReceiver.refreshBookLocalArtwork(any()) }
verify(exactly = 2) { mockTackReceiver.refreshBookLocalArtwork(any<Book>()) }
assertThat(destDir.resolve("book 2.cbz")).exists()
assertThat(destDir.resolve("book 2.jpg")).exists()
@ -271,7 +272,7 @@ class BookImporterTest(
bookImporter.importBook(sourceFile, series, CopyMode.COPY, destinationName = "book 5")
// then
verify(exactly = 2) { mockTackReceiver.refreshBookLocalArtwork(any()) }
verify(exactly = 2) { mockTackReceiver.refreshBookLocalArtwork(any<Book>()) }
assertThat(destDir.resolve("book 5.cbz")).exists()
assertThat(destDir.resolve("book 5.jpg")).exists()

View file

@ -97,8 +97,8 @@ class LibraryContentLifecycleTest(
@BeforeEach
fun beforeEach() {
every { mockTaskEmitter.refreshBookMetadata(any(), any()) } just Runs
every { mockTaskEmitter.refreshSeriesMetadata(any(), any()) } just Runs
every { mockTaskEmitter.refreshBookMetadata(any<Book>(), any()) } just Runs
every { mockTaskEmitter.refreshSeriesMetadata(any<String>(), any()) } just Runs
}
@AfterAll
@ -894,7 +894,7 @@ class LibraryContentLifecycleTest(
// then
verify(exactly = 1) { mockHasher.computeHash(any<Path>()) }
verify(exactly = 1) { mockTaskEmitter.refreshBookMetadata(withArg { assertThat(it.id).isEqualTo(bookRenamed.id) }, setOf(BookMetadataPatchCapability.TITLE)) }
verify(exactly = 1) { mockTaskEmitter.refreshBookMetadata(withArg<Book> { assertThat(it.id).isEqualTo(bookRenamed.id) }, setOf(BookMetadataPatchCapability.TITLE)) }
val allSeries = seriesRepository.findAll()
val allBooks = bookRepository.findAll().sortedBy { it.number }
@ -1277,7 +1277,7 @@ class LibraryContentLifecycleTest(
libraryContentLifecycle.scanRootFolder(library) // rename
// then
verify(exactly = 1) { mockTaskEmitter.refreshBookMetadata(withArg { assertThat(it.id).isEqualTo(book2Moved.id) }, setOf(BookMetadataPatchCapability.TITLE)) }
verify(exactly = 1) { mockTaskEmitter.refreshBookMetadata(withArg<Book> { assertThat(it.id).isEqualTo(book2Moved.id) }, setOf(BookMetadataPatchCapability.TITLE)) }
val allSeries = seriesRepository.findAll()
val allBooks = bookRepository.findAll().sortedBy { it.number }

View file

@ -6,6 +6,7 @@ import io.mockk.every
import io.mockk.just
import org.assertj.core.api.Assertions.assertThat
import org.gotson.komga.application.tasks.TaskEmitter
import org.gotson.komga.domain.model.Book
import org.gotson.komga.domain.model.ReadList
import org.gotson.komga.domain.model.ReadListRequest
import org.gotson.komga.domain.model.ReadListRequestBook
@ -51,7 +52,7 @@ class ReadListMatcherTest(
@BeforeEach
fun beforeEach() {
every { mockTaskEmitter.refreshBookMetadata(any(), any()) } just Runs
every { mockTaskEmitter.refreshBookMetadata(any<Book>(), any()) } just Runs
}
@AfterAll