stumpapp / stump

A free and open source comics, manga and digital book server with OPDS support (WIP)
https://stumpapp.dev
MIT License
1.04k stars 46 forks source link

[FEATURE] Allow Multiple Formats / Versions #196

Open jacobkossman opened 1 year ago

jacobkossman commented 1 year ago

Is your feature request related to a problem? Please describe. When you have two versions of the same book (eg a PDF and an epub version) it currently just lists them next to each other. For example when on desktop I can use PDF but on my phone I'd like to use epub so I don't have to zoom into the PDF etc.

Describe the solution you'd like Ideally it would merge them into the same item and allow you to pick which one to read when clicking read. For me it would be nice if it could somehow automatically do this based on the folder it's in. For example:

Series/
  Harry Potter/
    Harry Potter and the Sorcerer's Stone/
      Harry Potter and the Sorcerer's Stone.epub
      Harry Potter and the Sorcerer's Stone.pdf
    Harry Potter and the Chamber of Secrets/
      Harry Potter and the Chamber of Secrets.epub
      Harry Potter and the Chamber of Secrets.pdf
    Harry Potter and the Prisoner of Azkaban.epub

It should recognize the two formats and combine them into one book for Sorcerer's Stone and Chamber but not Prisoner for example, but I'm not sure if this is possible with the way the structure is already set up.

Describe alternatives you've considered Perhaps just a .stump hidden file that marks the items in the folder as mergable or something if the folder structure above won't work.

aaronleopold commented 1 year ago

Is there any metadata you'd want to be able to associate with the relations, as well? For example, add a notes field or something that provides extra details on the relationship. Your example usecase is relating the same media together, but I could also see this as being useful for collections of research papers, etc.

jacobkossman commented 1 year ago

My use case would only be as duplicates (or potentially "editions") of the same exact book. so i know there are comic book variants with different covers, or books that have different editions / editing etc.

For metadata, I think that's a whole other beast and probably a different feature request. But my ideal would be allowing users to rename, pick the series, pick the number in the series regardless of where in the file / folder structure it is.

aaronleopold commented 10 months ago

I've been thinking about this recently and wanted to dump an idea I had here for when I am able to try and support this down the road. Basically, the idea would be to completely overhaul the representation of media in the DB so that media itself is more of a grouping than a concrete entity. So a single media entry might refer to 1+ books. Having thought this through, this kind of restructure would be ideal if audio support is ever added down the road (https://github.com/stumpapp/stump/issues/177), as well.

An example schema might look something like:

model Series {
  id String @id @default(uuid())

  name String

  // ... other stuff

  media Media[] // <-- Same as today
}

model Media {
  id String @id @default(uuid())

  name String // derived from ?? aggregate of book names? or just first book name? or ???

  series    Series? @relation(fields: [series_id], references: [id], onDelete: Cascade)
  series_id String?

  books      Book[] // <-- diverging from what exists today
  audiobooks AudioBook[] // <-- diverging from what exists today

  @@map("media")
}

model Book { // <-- diverging from what exists today
  id String @id @default(uuid())

  name String // derived from filename
  size Int // in bytes

  // ... other stuff

  media    Media  @relation(fields: [media_id], references: [id], onDelete: Cascade)
  media_id String

  metadata BookMetadata?

  // ... other stuff

  @@map("books")
}

model AudioBook { // <-- diverging from what exists today
  id String @id @default(uuid())

  media    Media  @relation(fields: [media_id], references: [id], onDelete: Cascade)
  media_id String

  @@map("audiobooks")
}

model BookMetadata { // <-- diverging from what exists today
  id String @id @default(cuid())

  // ... other stuff

  book    Book?   @relation(fields: [book_id], references: [id], onDelete: Cascade)
  book_id String? @unique
}

The biggest unknown for me would then be resolving metadata between instances of books. How would reconciling multiple books and their own corresponding metadata work? Merge? Some sort of priority? Etc. Regardless, just thought dumping for the future