Aplicacion full-stack para explorar una biblioteca EPUB.
Este proyecto es una mejora del indexador de la Biblioteca Secreta: utiliza una base de datos construida a partir de libros provenientes del torrent de la biblioteca, y genera portadas (incluyendo thumbnails) a partir del contenido de cada archivo EPUB.
Para el pipeline de imagenes se utilizaron scripts en Python:
- un script que genera las portadas a partir de los libros EPUB,
- y otro script en Python que genera los thumbnails a partir de esas portadas.
Referencia del proyecto/origen de catalogo: http://bibliotecasecreta.nl/
Contexto y credito:
- Este proyecto nace como sustitucion/mejora del indexador incluido en el torrent de Biblioteca Secreta.
- El indexador original se asocia publicamente al alias MR. Fado.
- Este repositorio implementa una alternativa tecnica de indexacion, navegacion y visualizacion de metadatos/portadas.
Incluye:
- Frontend Angular para listado, filtros A-Z, detalle de libro y visor EPUB.
- Backend Spring Boot para API REST, acceso a PostgreSQL y servicio de archivos EPUB/portadas.
- Docker Compose para desplegar frontend + backend.
- Java 17
- Spring Boot 3.2.x
- Spring Web, Validation, Spring Data JPA
- PostgreSQL
- Flyway (migraciones)
- Angular 21 (standalone components)
- RxJS
epubjspara lectura EPUB en modal- CSS custom (sin framework UI)
- Docker / Docker Compose
- Nginx (frontend container + reverse proxy a backend)
libraryEPub/
├── backend/
│ ├── src/main/java/com/libraryepubapi/
│ │ ├── config/
│ │ ├── dto/
│ │ ├── entity/
│ │ ├── repository/
│ │ ├── service/
│ │ └── web/
│ ├── src/main/resources/
│ │ ├── db/migration/
│ │ └── application.yml
│ ├── build.gradle
│ └── Dockerfile
├── frontend/
│ ├── src/app/
│ │ ├── components/
│ │ ├── models/
│ │ ├── pages/
│ │ ├── services/
│ │ ├── app.html
│ │ └── app.css
│ ├── nginx.conf
│ ├── proxy.conf.json
│ ├── package.json
│ └── Dockerfile
├── docker-compose.yml
└── .gitignore
- Lista de libros con:
- portada
- autor(es)
- año y paginas
- filtro por letra (A-Z)
- busqueda
- paginacion
- boton de "Me gusta"
- Listado de autores y tematicas (labels) con filtro A-Z.
- Detalle de autor/tematica con sus libros relacionados.
- Detalle de libro con:
- portada, metadata y sinopsis
- descarga de EPUB
- visor EPUB embebido (paginado + navegacion)
- Pantalla "Mis Libros" para ver favoritos.
- Persistencia de estado de navegacion al volver:
- conserva pagina/filtros en URL (query params)
- restaura scroll por ruta
- Persistencia de favoritos en base de datos por dispositivo/navegador (UUID de cliente).
- Portadas optimizadas con soporte de thumbnails (
/covers/thumbs/...).
Configuracion base:
server.port=8080- datasource PostgreSQL
- Flyway habilitado
Variables importantes (sobrescribibles por entorno):
SPRING_DATASOURCE_URLSPRING_DATASOURCE_USERNAMESPRING_DATASOURCE_PASSWORDEPUB_STORAGE_BASE_PATH(ruta donde estan los.epub)
- Backend expuesto en
18081:8080 - Frontend expuesto en
4200:80 - Volumenes montados:
- EPUBs (
/srv/library/epubs) - Portadas (
/srv/library/covers)
- EPUBs (
cd backend
./gradlew bootRuncd frontend
npm install
npm startEl frontend usa proxy.conf.json para enviar /api al backend local.
Desde la raiz del proyecto:
docker-compose up -d --build backend frontendURLs:
- Frontend:
http://localhost:4200 - Backend API:
http://localhost:18081/api
GET /api/books?page=1&size=20GET /api/books/search?q=...&page=1&size=20GET /api/books/{bookId}GET /api/books/{bookId}/fileGET /api/books/by-title-prefix/{prefix}?page=1&size=20GET /api/books/by-author/{authorId}?prefix=A&page=1&size=20GET /api/books/by-label/{labelId}?prefix=A&page=1&size=20
GET /api/authors?page=1&size=20GET /api/authors/{authorId}GET /api/authors/search?prefix=A&page=1&size=20
GET /api/labels?page=1&size=20GET /api/labels/{labelId}GET /api/labels/search?prefix=A&page=1&size=20
GET /api/favorites(requiere headerX-Client-Id)POST /api/favorites/{bookId}(requiere headerX-Client-Id)DELETE /api/favorites/{bookId}(requiere headerX-Client-Id)
Respuesta de paginado estandar:
{
"page": 1,
"size": 20,
"totalElements": 123,
"totalPages": 7,
"items": []
}- Portada full-size:
/covers/{sha256}.webp - Thumbnail para listas:
/covers/thumbs/{sha256}.webp - Frontend usa thumbnails en la grilla de libros para carga mas rapida.
- Nginx aplica cache largo para
/covers/(immutable + max-age).
cd frontend
npm run buildcd backend
./gradlew build- Si cambias DTOs backend, reconstruye backend y frontend en Docker.
- Si cambias
nginx.conf, reconstruye la imagen frontend. - Usa
.gitignorede raiz para evitar subir artefactos (build/,.gradle/,node_modules/, etc.).


