Changed to navigation and empty root opds catalog

pull/3344/head
adechant 6 months ago
parent 409fb470da
commit de45129323

1
.gitignore vendored

@ -1,6 +1,7 @@
# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
src/**/[Bb]in/
src/**/[Oo]bj/
db/*
## Ignore Visual Studio temporary files, build results, and

@ -115,9 +115,15 @@ namespace Readarr.Api.V1.BookFiles
[HttpGet("download/{id:int}")]
public IActionResult GetBookFile(int id)
{
var bookFile = _mediaFileService.Get(id);
var files = _mediaFileService.GetFilesByBook(id);
if (files.Empty())
{
throw new BadRequestException(string.Format("no bookfiles exist for book with id: {0}", id));
}
var bookFile = files.First();
var filePath = bookFile.Path;
Response.Headers.Add("Content-Disposition", string.Format("attachment;filename={0}", PathExtensions.BaseName(filePath)));
Response.Headers.Add("content-disposition", string.Format("attachment;filename={0}", PathExtensions.BaseName(filePath)));
return new PhysicalFileResult(filePath, GetContentType(filePath));
}

@ -38,7 +38,7 @@ namespace Readarr.Api.V1.OPDS
// /opds
[HttpGet]
public OPDSCatalogResource GetOPDSCatalog([FromQuery] bool availableBooks = true)
public OPDSCatalogResource GetOPDSCatalog()
{
var metadataTask = Task.Run(() => _authorService.GetAllAuthors());
var books = _bookService.GetAllBooks();
@ -50,7 +50,8 @@ namespace Readarr.Api.V1.OPDS
}
var catalog = OPDSResourceMapper.ToOPDSCatalogResource();
catalog.Publications = MapToResource(books, false);
//catalog.Publications = MapToResource(books, wanted);
return catalog;
}
@ -72,6 +73,24 @@ namespace Readarr.Api.V1.OPDS
return publications;
}
// /opds/wanted
[HttpGet("wanted")]
public OPDSPublicationsResource GetOPDSWantedPublications()
{
var metadataTask = Task.Run(() => _authorService.GetAllAuthors());
var books = _bookService.GetAllBooks();
var authors = metadataTask.GetAwaiter().GetResult().ToDictionary(x => x.AuthorMetadataId);
foreach (var book in books)
{
book.Author = authors[book.AuthorMetadataId];
}
var publications = OPDSResourceMapper.ToOPDSPublicationsResource();
publications.Publications = MapToResource(books, true);
return publications;
}
// /opds/publications/{int:id}
[HttpGet("publications/{id:int}")]
public OPDSPublicationResource GetOPDSPublication(int id)
@ -87,16 +106,17 @@ namespace Readarr.Api.V1.OPDS
throw new BadRequestException("No book files exist for the given book id");
}
var ebookEdition = book.Editions?.Value.Where(x => x.IsEbook).SingleOrDefault();
var selectedEdition = book.Editions?.Value.Where(x => x.Monitored).SingleOrDefault();
var covers = selectedEdition?.Images ?? new List<MediaCover>();
_coverMapper.ConvertToLocalUrls(book.Id, MediaCoverEntity.Book, covers);
_coverMapper.ConvertToLocalUrls(book.Id, MediaCoverEntity.Book, images);
book.Author = author;
return OPDSResourceMapper.ToOPDSPublicationResource(book, bookfiles, images);
return OPDSResourceMapper.ToOPDSPublicationResource(book, bookfiles, ebookEdition, images);
}
protected List<OPDSPublicationResource> MapToResource(List<Book> books, bool availableBooks)
protected List<OPDSPublicationResource> MapToResource(List<Book> books, bool wanted)
{
var pubclications = new List<OPDSPublicationResource>();
for (var i = 0; i < books.Count; i++)
@ -105,17 +125,21 @@ namespace Readarr.Api.V1.OPDS
var book = books[i];
var bookfiles = _mediaFileService.GetFilesByBook(book.Id);
var selectedEdition = book.Editions?.Value.Where(x => x.Monitored).SingleOrDefault();
var ebookEdition = book.Editions?.Value.Where(x => x.IsEbook).FirstOrDefault();
var covers = selectedEdition?.Images ?? new List<MediaCover>();
_coverMapper.ConvertToLocalUrls(book.Id, MediaCoverEntity.Book, covers);
//only add publications for which we have a valid bookfile
if (!bookfiles.Any())
if (!bookfiles.Any() && wanted && book.Monitored)
{
continue;
var publication = OPDSResourceMapper.ToOPDSPublicationResource(book, bookfiles, ebookEdition, covers);
pubclications.Add(publication);
}
else if (bookfiles.Any() && !wanted)
{
var publication = OPDSResourceMapper.ToOPDSPublicationResource(book, bookfiles, ebookEdition, covers);
pubclications.Add(publication);
}
var publication = OPDSResourceMapper.ToOPDSPublicationResource(book, bookfiles, covers);
pubclications.Add(publication);
}
return pubclications;

@ -32,7 +32,7 @@ namespace Readarr.Api.V1.OPDS
public string Language { get; set; }
public DateTime Modified { get; set; }
public string Description { get; set; }
public List<string> Genre { get; set; }
public List<string> Genres { get; set; }
}
public class OPDSImageResource : IEmbeddedDocument
@ -78,16 +78,35 @@ namespace Readarr.Api.V1.OPDS
var links = new List<OPDSLinkResource>();
links.Add(self);
var nav = new List<OPDSLinkResource>();
var pubs = new OPDSLinkResource
{
Href = "/opds/publications",
Rel = "self",
Title = "Readarr OPDS Available Publications",
Type = "application/opds+json"
};
nav.Add(pubs);
var meta = new OPDSCatalogMetadataResource
{
Title = self.Title
};
var wanted = new OPDSLinkResource
{
Href = "/opds/wanted",
Rel = "self",
Title = "Readarr OPDS Wanted Publications",
Type = "application/opds+json"
};
nav.Add(wanted);
return new OPDSCatalogResource
{
Metadata = meta,
Links = links,
Navigation = new List<OPDSLinkResource>(),
Navigation = nav,
Publications = new List<OPDSPublicationResource>()
};
}
@ -130,7 +149,7 @@ namespace Readarr.Api.V1.OPDS
Language = edition.Language,
Modified = book.ReleaseDate ?? DateTime.Now,
Description = edition.Overview,
Genre = book.Genres
Genres = book.Genres
};
}
@ -143,7 +162,7 @@ namespace Readarr.Api.V1.OPDS
};
}
public static OPDSPublicationResource ToOPDSPublicationResource(Book book, List<BookFile> files, List<MediaCover> covers)
public static OPDSPublicationResource ToOPDSPublicationResource(Book book, List<BookFile> files, Edition edition, List<MediaCover> covers)
{
var linkResources = new List<OPDSLinkResource>();
var imageResources = new List<OPDSImageResource>();
@ -151,23 +170,36 @@ namespace Readarr.Api.V1.OPDS
//Must have link to self
linkResources.Add(new OPDSLinkResource
{
Href = string.Format("/opds/publications/{0}", book.Id),
Href = string.Format("opds/publications/{0}", book.Id),
Rel = "self",
Title = book.Title,
Type = "application/opds-publication+json"
});
//we'll only add the first bookfile (for now)
foreach (var file in files)
if (files.Count > 0)
{
//we'll only add the first bookfile (for now)
foreach (var file in files)
{
linkResources.Add(new OPDSLinkResource
{
Href = string.Format("bookfile/download/{0}", book.Id),
Rel = "http://opds-spec.org/acquisition",
Title = string.Format("Readarr OPDS Link:{0}", book.Id),
Type = GetContentType(file.Path)
});
break;
}
}
else if (edition != null)
{
linkResources.Add(new OPDSLinkResource
{
Href = string.Format("/bookfile/download/{0}", book.Id),
Href = edition.Links.First().Url,
Rel = "http://opds-spec.org/acquisition",
Title = string.Format("Readarr OPDS Link:{0}", book.Id),
Type = GetContentType(file.Path)
Type = GetContentType("test.epub")
});
break;
}
foreach (var cover in covers)

Loading…
Cancel
Save