mirror of
https://github.com/gotson/komga.git
synced 2025-12-29 03:43:43 +01:00
moved natural sorting directly in Serie (for books) and BookMetadata (for pages)
This commit is contained in:
parent
db7e5e3c53
commit
a188cf9598
9 changed files with 77 additions and 27 deletions
|
|
@ -1,5 +1,7 @@
|
|||
package org.gotson.komga.domain.model
|
||||
|
||||
import net.greypanther.natsort.CaseInsensitiveSimpleNaturalComparator
|
||||
import java.util.*
|
||||
import javax.persistence.CollectionTable
|
||||
import javax.persistence.Column
|
||||
import javax.persistence.ElementCollection
|
||||
|
|
@ -12,8 +14,11 @@ import javax.persistence.Id
|
|||
import javax.persistence.JoinColumn
|
||||
import javax.persistence.Lob
|
||||
import javax.persistence.OneToOne
|
||||
import javax.persistence.OrderColumn
|
||||
import javax.persistence.Table
|
||||
|
||||
private val natSortComparator: Comparator<String> = CaseInsensitiveSimpleNaturalComparator.getInstance()
|
||||
|
||||
@Entity
|
||||
@Table(name = "book_metadata")
|
||||
class BookMetadata(
|
||||
|
|
@ -40,21 +45,26 @@ class BookMetadata(
|
|||
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
@CollectionTable(name = "book_metadata_page", joinColumns = [JoinColumn(name = "book_metadata_id")])
|
||||
var pages: MutableList<BookPage> = mutableListOf()
|
||||
@OrderColumn(name = "number")
|
||||
private var _pages: MutableList<BookPage> = mutableListOf()
|
||||
|
||||
var pages: List<BookPage>
|
||||
get() = _pages.toList()
|
||||
set(value) {
|
||||
pages.clear()
|
||||
pages.addAll(value)
|
||||
_pages.clear()
|
||||
_pages.addAll(value.sortedWith(compareBy(natSortComparator) { it.fileName }))
|
||||
}
|
||||
|
||||
|
||||
fun reset() {
|
||||
status = Status.UNKNOWN
|
||||
mediaType = null
|
||||
thumbnail = null
|
||||
pages.clear()
|
||||
_pages.clear()
|
||||
}
|
||||
|
||||
init {
|
||||
this.pages = pages.toMutableList()
|
||||
this.pages = pages.toList()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package org.gotson.komga.domain.model
|
||||
|
||||
import net.greypanther.natsort.CaseInsensitiveSimpleNaturalComparator
|
||||
import java.net.URL
|
||||
import java.time.LocalDateTime
|
||||
import java.util.*
|
||||
import javax.persistence.CascadeType
|
||||
import javax.persistence.Column
|
||||
import javax.persistence.Entity
|
||||
|
|
@ -9,9 +11,12 @@ import javax.persistence.FetchType
|
|||
import javax.persistence.GeneratedValue
|
||||
import javax.persistence.Id
|
||||
import javax.persistence.OneToMany
|
||||
import javax.persistence.OrderColumn
|
||||
import javax.persistence.Table
|
||||
import javax.validation.constraints.NotBlank
|
||||
|
||||
private val natSortComparator: Comparator<String> = CaseInsensitiveSimpleNaturalComparator.getInstance()
|
||||
|
||||
@Entity
|
||||
@Table(name = "serie")
|
||||
class Serie(
|
||||
|
|
@ -34,6 +39,7 @@ class Serie(
|
|||
var id: Long = 0
|
||||
|
||||
@OneToMany(cascade = [CascadeType.ALL], fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "serie")
|
||||
@OrderColumn(name = "index")
|
||||
private var _books: MutableList<Book> = mutableListOf()
|
||||
|
||||
var books: List<Book>
|
||||
|
|
@ -41,10 +47,10 @@ class Serie(
|
|||
set(value) {
|
||||
_books.clear()
|
||||
value.forEach { it.serie = this }
|
||||
_books.addAll(value)
|
||||
_books.addAll(value.sortedWith(compareBy(natSortComparator) { it.name }))
|
||||
}
|
||||
|
||||
init {
|
||||
this.books = books.toMutableList()
|
||||
this.books = books.toList()
|
||||
}
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ class BookParser(
|
|||
null
|
||||
}
|
||||
|
||||
return BookMetadata(mediaType = mediaType, status = Status.READY, pages = pages.toMutableList(), thumbnail = thumbnail)
|
||||
return BookMetadata(mediaType = mediaType, status = Status.READY, pages = pages, thumbnail = thumbnail)
|
||||
}
|
||||
|
||||
fun getPageContent(book: Book, number: Int): ByteArray {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,9 @@
|
|||
package org.gotson.komga.infrastructure.archive
|
||||
|
||||
import net.greypanther.natsort.CaseInsensitiveSimpleNaturalComparator
|
||||
import org.gotson.komga.domain.model.BookPage
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
|
||||
abstract class ArchiveExtractor {
|
||||
protected val natSortComparator: Comparator<String> = CaseInsensitiveSimpleNaturalComparator.getInstance()
|
||||
|
||||
abstract fun getPagesList(path: Path): List<BookPage>
|
||||
abstract fun getPageStream(path: Path, entryName: String): ByteArray
|
||||
}
|
||||
|
|
@ -22,9 +22,6 @@ class RarExtractor(
|
|||
)
|
||||
}
|
||||
.filter { contentDetector.isImage(it.mediaType) }
|
||||
.sortedWith(
|
||||
compareBy(natSortComparator) { it.fileName }
|
||||
)
|
||||
}
|
||||
|
||||
override fun getPageStream(path: Path, entryName: String): ByteArray =
|
||||
|
|
|
|||
|
|
@ -21,9 +21,6 @@ class ZipExtractor(
|
|||
)
|
||||
}
|
||||
.filter { contentDetector.isImage(it.mediaType) }
|
||||
.sortedWith(
|
||||
compareBy(natSortComparator) { it.fileName }
|
||||
)
|
||||
}
|
||||
|
||||
override fun getPageStream(path: Path, entryName: String): ByteArray =
|
||||
|
|
|
|||
|
|
@ -90,16 +90,10 @@ class SerieController(
|
|||
page: Pageable
|
||||
): Page<BookDto> {
|
||||
if (!serieRepository.existsById(id)) throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
val pageRequest = PageRequest.of(
|
||||
page.pageNumber,
|
||||
page.pageSize,
|
||||
if (page.sort.isSorted) page.sort
|
||||
else Sort.by(Sort.Order.asc("name").ignoreCase())
|
||||
)
|
||||
return if (readyFilter) {
|
||||
bookRepository.findAllByMetadataStatusAndSerieId(Status.READY, id, pageRequest)
|
||||
bookRepository.findAllByMetadataStatusAndSerieId(Status.READY, id, page)
|
||||
} else {
|
||||
bookRepository.findAllBySerieId(id, pageRequest)
|
||||
bookRepository.findAllBySerieId(id, page)
|
||||
}.map { it.toDto() }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ create table book
|
|||
url varchar not null,
|
||||
book_metadata_id bigint not null,
|
||||
serie_id bigint not null,
|
||||
index integer,
|
||||
primary key (id)
|
||||
);
|
||||
|
||||
|
|
@ -26,7 +27,8 @@ create table book_metadata_page
|
|||
(
|
||||
book_metadata_id bigint not null,
|
||||
file_name varchar not null,
|
||||
media_type varchar not null
|
||||
media_type varchar not null,
|
||||
number integer
|
||||
);
|
||||
|
||||
create table serie
|
||||
|
|
|
|||
|
|
@ -44,6 +44,26 @@ class PersistenceTest(
|
|||
assertThat(bookMetadataRepository.count()).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given serie with unordered books when saving then books are ordered with natural sort`() {
|
||||
// given
|
||||
val serie = makeSerie(name = "serie", books = listOf(
|
||||
makeBook("book 1"),
|
||||
makeBook("book 05"),
|
||||
makeBook("book 6"),
|
||||
makeBook("book 002")
|
||||
))
|
||||
|
||||
// when
|
||||
serieRepository.save(serie)
|
||||
|
||||
// then
|
||||
assertThat(serieRepository.count()).isEqualTo(1)
|
||||
assertThat(bookRepository.count()).isEqualTo(4)
|
||||
assertThat(serieRepository.findAll().first().books.map { it.name })
|
||||
.containsExactly("book 1", "book 002", "book 05", "book 6")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given existing book when updating metadata then new metadata is saved`() {
|
||||
// given
|
||||
|
|
@ -67,4 +87,32 @@ class PersistenceTest(
|
|||
assertThat(it.pages.first().fileName).isEqualTo("page1")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given book pages unordered when saving then pages are ordered with natural sort`() {
|
||||
// given
|
||||
val serie = makeSerie(name = "serie", books = listOf(makeBook("book1")))
|
||||
serieRepository.save(serie)
|
||||
|
||||
// when
|
||||
val book = bookRepository.findAll().first()
|
||||
book.metadata = BookMetadata(status = Status.READY, mediaType = "test", pages = listOf(
|
||||
makeBookPage("2"),
|
||||
makeBookPage("003"),
|
||||
makeBookPage("001")
|
||||
))
|
||||
|
||||
bookRepository.save(book)
|
||||
|
||||
// then
|
||||
assertThat(serieRepository.count()).isEqualTo(1)
|
||||
assertThat(bookRepository.count()).isEqualTo(1)
|
||||
assertThat(bookMetadataRepository.count()).isEqualTo(1)
|
||||
bookMetadataRepository.findAll().first().let {
|
||||
assertThat(it.status == Status.READY)
|
||||
assertThat(it.mediaType == "test")
|
||||
assertThat(it.pages).hasSize(3)
|
||||
assertThat(it.pages.map { it.fileName }).containsExactly("001", "2", "003")
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue