Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Opds categories feed #492

Merged
merged 26 commits into from
Jun 8, 2021
Merged

Opds categories feed #492

merged 26 commits into from
Jun 8, 2021

Conversation

veloman-yunkan
Copy link
Collaborator

@veloman-yunkan veloman-yunkan commented Apr 15, 2021

Will fix #518

This PR introduces a new OPDS API at /catalog/v2 (as well as fixes a few noticed issues unrelated to that enhancement).
Currently available endpoints are:

  • /catalog/v2/root.xml: top level navigation feed, pointing to the full acquisition feed and to the list of categories
  • /catalog/v2/entries: an equivalent of both /catalog/root.xml and /catalog/search of the old OPDS API.
  • /vatalog/v2/categories: a navigation feed containing an entry for each category with a link to the corresponding acquisition feed filtered by that category.

Notes:

@veloman-yunkan veloman-yunkan force-pushed the opds_categories_feed branch 2 times, most recently from e5ce43c to e65d629 Compare April 16, 2021 20:36
@codecov
Copy link

codecov bot commented Apr 16, 2021

Codecov Report

Merging #492 (78083f1) into master (86ef2e2) will increase coverage by 0.43%.
The diff coverage is 97.39%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #492      +/-   ##
==========================================
+ Coverage   64.60%   65.03%   +0.43%     
==========================================
  Files          50       51       +1     
  Lines        3551     3627      +76     
  Branches     1801     1824      +23     
==========================================
+ Hits         2294     2359      +65     
- Misses       1255     1266      +11     
  Partials        2        2              
Impacted Files Coverage Δ
include/library.h 91.66% <ø> (ø)
src/server/internalServer.h 100.00% <ø> (ø)
src/server/response.cpp 86.60% <ø> (-0.47%) ⬇️
src/server/internalServer.cpp 86.10% <93.33%> (-0.54%) ⬇️
src/server/internalServer_catalog_v2.cpp 93.75% <93.75%> (ø)
include/opds_dumper.h 100.00% <100.00%> (ø)
src/library.cpp 79.12% <100.00%> (+0.43%) ⬆️
src/opds_dumper.cpp 100.00% <100.00%> (+2.40%) ⬆️
src/server/request_context.cpp 64.94% <100.00%> (+1.61%) ⬆️
src/server/request_context.h 100.00% <100.00%> (+40.00%) ⬆️
... and 8 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 86ef2e2...78083f1. Read the comment docs.

@veloman-yunkan veloman-yunkan force-pushed the opds_categories_feed branch 2 times, most recently from 6893ca6 to e6453d3 Compare April 28, 2021 07:22
@veloman-yunkan veloman-yunkan changed the title [WIP] Opds categories feed Opds categories feed May 13, 2021
@veloman-yunkan veloman-yunkan marked this pull request as ready for review May 13, 2021 08:42
@veloman-yunkan
Copy link
Collaborator Author

We will not have have clean CI until #522 is merged and #523 is fixed. If possible, please review without waiting for the CI to pass.

Copy link
Member

@mgautierfr mgautierfr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OPDSDumper is not utilized. mustache was used instead.

I dislike the idea. Now we have two ways to generate opds feed.
I'm not against using mustache, but it would be better to port OPDSDumper to mustache and use OPDSDumper everywhere.
(And having a specific OPDSDumper class would allow us to test it without creating a instance of the server)

/catalog/v2/entries: an equivalent of both /catalog/root.xml and /catalog/search of the old OPDS API.

With issue #209 the plan is to move to a partial feed for the entries.
In this PR, the entries feed is a complete acquisition feed.
It is not a blocker for this PR, it is probably better to do it in two PR.
But we must care to not do a release with a complete acquisition feed.

Also, now we have only one url for listing all entries and search for them. I don't know if it is good thing or not, but I prefer to mention it explicitly.

src/library.cpp Outdated Show resolved Hide resolved
src/server/internalServer.cpp Outdated Show resolved Hide resolved
src/server/internalServer.h Show resolved Hide resolved
src/server/internalServer.cpp Outdated Show resolved Hide resolved
src/server/internalServer.cpp Outdated Show resolved Hide resolved
@kelson42
Copy link
Collaborator

If we change the URL paths/schemas we need to be careful. We have Kiwix Desktop and Kiwix iOS relying on them!

@mgautierfr
Copy link
Member

If we change the URL paths/schemas we need to be careful. We have Kiwix Desktop and Kiwix iOS relying on them!

We don't change the paths/schemas, we add new ones (catalog/v2/*)

@veloman-yunkan
Copy link
Collaborator Author

OPDSDumper is not utilized. mustache was used instead.

I dislike the idea. Now we have two ways to generate opds feed.
I'm not against using mustache, but it would be better to port OPDSDumper to mustache and use OPDSDumper everywhere.
(And having a specific OPDSDumper class would allow us to test it without creating a instance of the server)

I moved most of the new code into OPDSDumper but didn't port pre-existing code to mustache. That can be done in another PR.

@veloman-yunkan
Copy link
Collaborator Author

New commits start from /catalog/v2/entries going through OPDSDumper

@mgautierfr
Copy link
Member

The ideas is not to "have a OPDSDumper" but to avoid having two different implementations to do the same thing (transform a list of books, with some metadata, to a opds stream).
Moving mustache implementation inside OPDSDumper but in another method and keep the previous implementation is useless.
If mustache is a better implementation, then we should replace the previous implementation.

@veloman-yunkan
Copy link
Collaborator Author

The ideas is not to "have a OPDSDumper" but to avoid having two different implementations to do the same thing (transform a list of books, with some metadata, to a opds stream).
Moving mustache implementation inside OPDSDumper but in another method and keep the previous implementation is useless.
If mustache is a better implementation, then we should replace the previous implementation.

Done

@stale
Copy link

stale bot commented Jun 5, 2021

This pull request has been automatically marked as stale because it has not had recent activity. It will be now be reviewed manually. Thank you for your contributions.

@stale stale bot added the stale label Jun 5, 2021
@kelson42
Copy link
Collaborator

kelson42 commented Jun 7, 2021

@veloman-yunkan @mgautierfr This PR is key and need review and rebase.

@stale stale bot removed the stale label Jun 7, 2021
Copy link
Member

@mgautierfr mgautierfr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two small commenst on the code to fix and we are good. This is far better with all the code in the rendered and using mustache everywhere.


On a more general comment, #209 implies that the root/search feed is partial and then we get the full information doing another request (and so another endpoint).
We will definitively not do it in this PR. But I would like to mention that the v2 API may change in close future and client should not start to use it right now.
(And to have a more stable API, we may move the endpoint /catalog/v2/entries to /catalog/v2/search (and so keep entry/entries for the endpoint to get all information about entries)

src/opds_dumper.cpp Outdated Show resolved Hide resolved
Comment on lines +89 to +99
const auto bookData = getBookData(library, bookIds);
const kainjow::mustache::object template_data{
{"date", gen_date_str()},
{"root", rootLocation},
{"feed_id", gen_uuid(libraryId + "/catalog/search?"+query)},
{"filter", query.empty() ? MustacheData(false) : MustacheData(query)},
{"totalResults", to_string(m_totalResults)},
{"startIndex", to_string(m_startIndex)},
{"itemsPerPage", to_string(m_count)},
{"books", bookData }
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that this data is pretty closed from the ones used in dumpOPDSFeedV2.
Could be have "only one method" using two different templates ?
(Or maybe even better, one template with just the endpoint changing ? If possible)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's consider that after the new API is finalized. I don't want the old API to be a drag on the new API, and a premature attempt to share code between them will do just that.

The new negative test-point demonstrates that Kiwix server doesn't
distinguish /catalogBLABLABLA from /catalog.
Also removed an unneeded namespace qualifier.
@mgautierfr
Copy link
Member

We are good. Please rebase-fixup and we can merge.

Note: no unit test added
Under Ubuntu 16.04/xenial, ccache seems to have issues with multiline
raw string literals used inside macros.
The new field is intended to serve as a seed for generating semi-stable
OPDS feed ids that only need to change when the library is updated.
/catalog/v2/entries is intended to play the combined role of
/catalog/root.xml and /catalog/search of the old OPDS API. Currently,
the latter role is not yet implemented.

Implementation note: instead of tweaking and reusing
`OPDSDumper::dumpOPDSFeed()`, the generation of the OPDS feed is done via `mustache`
and a new template `static/catalog_v2_entries.xml`.
Reordered several statements so that the next couple of commits are a
little simpler.
OPDSDumper sensed threats to its job security, so it lobbied to be
involved in handling the /catalog/v2 endpoints, too.
This changes the output of `/catalog/search` as follows:

- Entire search query (rather than only the value of the `q` parameter)
  is put in the <title> node.

- Search performed with an empty query presents itself as "All zims".

- The feed id remains stable for identical searches on the same
  library.
@veloman-yunkan
Copy link
Collaborator Author

We are good. Please rebase-fixup and we can merge.

Done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

OPDS endpoint for categories
3 participants