diff --git a/src/library/entry.cr b/src/library/entry.cr index 5694551..43fbb23 100644 --- a/src/library/entry.cr +++ b/src/library/entry.cr @@ -49,7 +49,7 @@ class Entry file.close end - def to_slim_json : String + def build_json(*, slim = false) JSON.build do |json| json.object do {% for str in ["zip_path", "title", "size", "id"] %} @@ -57,23 +57,15 @@ class Entry {% end %} json.field "title_id", @book.id json.field "pages" { json.number @pages } + unless slim + json.field "display_name", @book.display_name @title + json.field "cover_url", cover_url + json.field "mtime" { json.number @mtime.to_unix } + end end end end - def to_json(json : JSON::Builder) - json.object do - {% for str in ["zip_path", "title", "size", "id"] %} - json.field {{str}}, @{{str.id}} - {% end %} - json.field "title_id", @book.id - json.field "display_name", @book.display_name @title - json.field "cover_url", cover_url - json.field "pages" { json.number @pages } - json.field "mtime" { json.number @mtime.to_unix } - end - end - def display_name @book.display_name @title end diff --git a/src/library/library.cr b/src/library/library.cr index b50fb87..ea2a5e3 100644 --- a/src/library/library.cr +++ b/src/library/library.cr @@ -100,14 +100,14 @@ class Library titles.flat_map &.deep_entries end - def to_slim_json : String + def build_json(*, slim = false, shallow = false) JSON.build do |json| json.object do json.field "dir", @dir json.field "titles" do json.array do self.titles.each do |title| - json.raw title.to_slim_json + json.raw title.build_json(slim: slim, shallow: shallow) end end end @@ -115,15 +115,6 @@ class Library end end - def to_json(json : JSON::Builder) - json.object do - json.field "dir", @dir - json.field "titles" do - json.raw self.titles.to_json - end - end - end - def get_title(tid) @title_hash[tid]? end diff --git a/src/library/title.cr b/src/library/title.cr index 41efd7c..3abc38d 100644 --- a/src/library/title.cr +++ b/src/library/title.cr @@ -167,62 +167,50 @@ class Title true # Fixed, reuse this end - def to_slim_json : String + alias SortContext = NamedTuple(username: String, opt: SortOptions) + + def build_json(*, slim = false, shallow = false, + sort_context : SortContext? = nil) JSON.build do |json| json.object do {% for str in ["dir", "title", "id"] %} json.field {{str}}, @{{str.id}} {% end %} json.field "signature" { json.number @signature } - json.field "titles" do - json.array do - self.titles.each do |title| - json.raw title.to_slim_json - end - end + unless slim + json.field "display_name", display_name + json.field "cover_url", cover_url + json.field "mtime" { json.number @mtime.to_unix } end - json.field "entries" do - json.array do - @entries.each do |entry| - json.raw entry.to_slim_json - end - end - end - json.field "parents" do - json.array do - self.parents.each do |title| - json.object do - json.field "title", title.title - json.field "id", title.id + unless shallow + json.field "titles" do + json.array do + self.titles.each do |title| + json.raw title.build_json(slim: slim, shallow: shallow) end end end - end - end - end - end - - def to_json(json : JSON::Builder) - json.object do - {% for str in ["dir", "title", "id"] %} - json.field {{str}}, @{{str.id}} - {% end %} - json.field "signature" { json.number @signature } - json.field "display_name", display_name - json.field "cover_url", cover_url - json.field "mtime" { json.number @mtime.to_unix } - json.field "titles" do - json.raw self.titles.to_json - end - json.field "entries" do - json.raw @entries.to_json - end - json.field "parents" do - json.array do - self.parents.each do |title| - json.object do - json.field "title", title.title - json.field "id", title.id + 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 + json.field "parents" do + json.array do + self.parents.each do |title| + json.object do + json.field "title", title.title + json.field "id", title.id + end + end end end end diff --git a/src/routes/api.cr b/src/routes/api.cr index b1fb3b3..8c66e13 100644 --- a/src/routes/api.cr +++ b/src/routes/api.cr @@ -133,24 +133,34 @@ struct APIRouter end Koa.describe "Returns the book with title `tid`", <<-MD - Supply the `tid` query parameter to strip away "display_name", "cover_url", and "mtime" from the returned object to speed up the loading time + - 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 `shallow` query parameter to get only the title information, without the list of entries and nested titles MD Koa.path "tid", desc: "Title ID" Koa.query "slim" + Koa.query "shallow" + Koa.query "sort", desc: "Sorting option for entries. Can be one of 'auto', 'title', 'progress', 'time_added' and 'time_modified'" + Koa.query "ascend", desc: "Sorting direction for entries. Set to 0 for the descending order. Doesn't work without specifying 'sort'" Koa.response 200, schema: "title" Koa.response 404, "Title not found" Koa.tag "library" get "/api/book/:tid" do |env| begin + username = get_username env + + sort_opt = SortOptions.new + get_sort_opt + tid = env.params.url["tid"] title = Library.default.get_title tid raise "Title ID `#{tid}` not found" if title.nil? - if env.params.query["slim"]? - send_json env, title.to_slim_json - else - send_json env, title.to_json - end + slim = !env.params.query["slim"]?.nil? + shallow = !env.params.query["shallow"]?.nil? + + send_json env, title.build_json(slim: slim, shallow: shallow, + sort_context: {username: username, + opt: sort_opt}) rescue e Logger.error e env.response.status_code = 404 @@ -159,20 +169,21 @@ struct APIRouter end Koa.describe "Returns the entire library with all titles and entries", <<-MD - Supply the `tid` query parameter to strip away "display_name", "cover_url", and "mtime" from the returned object to speed up the loading time + - 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 `shallow` query parameter to get only the top-level titles, without the nested titles and entries MD Koa.query "slim" + Koa.query "shallow" Koa.response 200, schema: { "dir" => String, "titles" => ["title"], } Koa.tag "library" get "/api/library" do |env| - if env.params.query["slim"]? - send_json env, Library.default.to_slim_json - else - send_json env, Library.default.to_json - end + slim = !env.params.query["slim"]?.nil? + shallow = !env.params.query["shallow"]?.nil? + + send_json env, Library.default.build_json(slim: slim, shallow: shallow) end Koa.describe "Triggers a library scan"