From 21d8d0e8a7ceb442bf72691881d10e50fe430921 Mon Sep 17 00:00:00 2001 From: Alex Ling Date: Tue, 22 Mar 2022 12:58:37 +0000 Subject: [PATCH] Optionally include reading progress in response --- src/library/library.cr | 25 +++++++++++++++-------- src/library/title.cr | 46 +++++++++++++++++++++++++++++------------- src/routes/api.cr | 10 +++++++-- 3 files changed, 57 insertions(+), 24 deletions(-) diff --git a/src/library/library.cr b/src/library/library.cr index f55df03..18a0772 100644 --- a/src/library/library.cr +++ b/src/library/library.cr @@ -139,21 +139,30 @@ class Library titles.flat_map &.deep_entries end - def build_json(*, slim = false, depth = -1, sort_context = nil) + def build_json(*, slim = false, depth = -1, sort_context = nil, percentage = false) + _titles = if sort_context + sorted_titles sort_context[:username], + sort_context[:opt] + else + self.titles + end JSON.build do |json| json.object do json.field "dir", @dir json.field "titles" do json.array do - _titles = if sort_context - sorted_titles sort_context[:username], - sort_context[:opt] - else - self.titles - end _titles.each do |title| json.raw title.build_json(slim: slim, depth: depth, - sort_context: sort_context) + sort_context: sort_context, percentage: percentage) + end + end + end + if percentage && sort_context + json.field "title_percentages" do + json.array do + _titles.each do |title| + json.number title.load_percentage sort_context[:username] + end end end end diff --git a/src/library/title.cr b/src/library/title.cr index 49ce8af..4125501 100644 --- a/src/library/title.cr +++ b/src/library/title.cr @@ -202,7 +202,21 @@ class Title alias SortContext = NamedTuple(username: String, opt: SortOptions) def build_json(*, slim = false, depth = -1, - sort_context : SortContext? = nil) + sort_context : SortContext? = nil, + percentage = false) + _titles = if sort_context + sorted_titles sort_context[:username], + sort_context[:opt] + else + self.titles + end + _entries = if sort_context + sorted_entries sort_context[:username], + sort_context[:opt] + else + @entries + end + JSON.build do |json| json.object do {% for str in ["dir", "title", "id"] %} @@ -218,32 +232,36 @@ class Title unless depth == 0 json.field "titles" do json.array do - _titles = if sort_context - sorted_titles sort_context[:username], - sort_context[:opt] - else - self.titles - end _titles.each do |title| json.raw title.build_json(slim: slim, depth: depth > 0 ? depth - 1 : depth, - sort_context: sort_context) + sort_context: sort_context, percentage: percentage) end end end json.field "entries" do json.array do - _entries = if sort_context - sorted_entries sort_context[:username], - sort_context[:opt] - else - @entries - end _entries.each do |entry| json.raw entry.build_json(slim: slim) end end end + if percentage && sort_context + json.field "title_percentages" do + json.array do + _titles.each do |t| + json.number t.load_percentage sort_context[:username] + end + end + end + json.field "entry_percentages" do + json.array do + load_percentage_for_all_entries(sort_context[:username], sort_context[:opt]).each do |percentage| + json.number percentage.nan? ? 0 : percentage + end + end + end + end end json.field "parents" do json.array do diff --git a/src/routes/api.cr b/src/routes/api.cr index 0154a2b..ba58f0c 100644 --- a/src/routes/api.cr +++ b/src/routes/api.cr @@ -168,6 +168,7 @@ struct APIRouter Koa.describe "Returns the book with title `tid`", <<-MD The entries and titles will be sorted by the default sorting method for the logged-in user. + - Supply the `percentage` query parameter to include the reading progress - Supply the `slim` query parameter to strip away "display_name", "cover_url", and "mtime" from the returned object to speed up the loading time - Supply the `depth` query parameter to control the depth of nested titles to return. - When `depth` is 1, returns the top-level titles and sub-titles/entries one level in them @@ -178,6 +179,7 @@ struct APIRouter Koa.path "tid", desc: "Title ID" Koa.query "slim" Koa.query "depth" + Koa.query "percentage" Koa.response 200, schema: "title" Koa.response 404, "Title not found" Koa.tag "library" @@ -193,10 +195,11 @@ struct APIRouter slim = !env.params.query["slim"]?.nil? depth = env.params.query["depth"]?.try(&.to_i?) || -1 + percentage = !env.params.query["percentage"]?.nil? send_json env, title.build_json(slim: slim, depth: depth, sort_context: {username: username, - opt: sort_opt}) + opt: sort_opt}, percentage: percentage) rescue e Logger.error e env.response.status_code = 404 @@ -281,6 +284,7 @@ struct APIRouter The titles will be sorted by the default sorting method for the logged-in user. - Supply the `slim` query parameter to strip away "display_name", "cover_url", and "mtime" from the returned object to speed up the loading time - Supply the `dpeth` query parameter to control the depth of nested titles to return. + - Supply the `percentage` query parameter to include the reading progress - When `depth` is 1, returns the requested title and sub-titles/entries one level in it - When `depth` is 0, returns the requested title without its sub-titles/entries - When `depth` is N, returns the requested title and sub-titles/entries N levels in it @@ -288,6 +292,7 @@ struct APIRouter MD Koa.query "slim" Koa.query "depth" + Koa.query "percentage" Koa.response 200, schema: { "dir" => String, "titles" => ["title"], @@ -300,10 +305,11 @@ struct APIRouter slim = !env.params.query["slim"]?.nil? depth = env.params.query["depth"]?.try(&.to_i?) || -1 + percentage = !env.params.query["percentage"]?.nil? send_json env, Library.default.build_json(slim: slim, depth: depth, sort_context: {username: username, - opt: sort_opt}) + opt: sort_opt}, percentage: percentage) rescue e Logger.error e send_json env, {