diff --git a/public/css/mango.css b/public/css/mango.css new file mode 100644 index 0000000..f42cd79 --- /dev/null +++ b/public/css/mango.css @@ -0,0 +1,9 @@ +.uk-card-body { + padding: 20px; +} +.uk-card-media-top img { + max-height: 350px; +} +.acard:hover { + text-decoration: none; +} diff --git a/src/library.cr b/src/library.cr index a004b6f..d7982cb 100644 --- a/src/library.cr +++ b/src/library.cr @@ -1,5 +1,6 @@ require "zip" require "mime" +require "json" class Image property data : Bytes @@ -12,13 +13,21 @@ end class Entry property zip_path : String + property book_title : String property title : String property size : String + property pages : Int32 + property cover_url : String - def initialize(path : String) + JSON.mapping zip_path: String, book_title: String, title: String, \ + size: String, pages: Int32, cover_url: String + + def initialize(path, @book_title) @zip_path = path @title = File.basename path, ".zip" @size = (File.size path).humanize_bytes + @pages = Zip::File.new(path).entries.size + @cover_url = "/api/page/#{@book_title}/#{title}/0" end def read_page(page_num) Zip::File.open @zip_path do |file| @@ -40,32 +49,27 @@ class Entry end end end - def get_cover() - read_page 0 - end end class Title - property dir : String - property entries : Array(Entry) - property title : String + JSON.mapping dir: String, entries: Array(Entry), title: String def initialize(dir : String) @dir = dir @title = File.basename dir @entries = (Dir.entries dir) .select! { |path| (File.extname path) == ".zip" } - .map { |path| Entry.new File.join dir, path } + .map { |path| Entry.new File.join(dir, path), @title } .sort { |a, b| a.title <=> b.title } end - def get_cover() - @entries[0].get_cover + def get_entry(name) + @entries.find { |e| e.title == name } end + end class Library - property dir : String - property titles : Array(Title) + JSON.mapping dir: String, titles: Array(Title) def initialize(dir : String) @dir = dir @@ -77,4 +81,7 @@ class Library .map { |path| Title.new File.join dir, path } .select! { |title| !title.entries.empty? } end + def get_title(name) + @titles.find { |t| t.title == name } + end end diff --git a/src/mango.cr b/src/mango.cr index d52a2d2..f4264ca 100644 --- a/src/mango.cr +++ b/src/mango.cr @@ -14,17 +14,22 @@ macro layout(name) end macro send_img(env, img) - send_file env, image.data, image.mime + send_file {{env}}, {{img}}.data, {{img}}.mime end get "/" do |env| - image = library.titles[0].get_cover - unless image - "Failed to load image" + titles = library.titles + layout "index" +end + +get "/book/:title" do |env| + title = library.get_title env.params.url["title"] + if title.nil? + env.response.status_code = 404 next end - send_img env, image + layout "title" end get "/login" do |env| @@ -45,6 +50,49 @@ post "/login" do |env| env.redirect "/" end +get "/api/page/:title/:entry/:page" do |env| + begin + title = env.params.url["title"] + entry = env.params.url["entry"] + page = env.params.url["page"].to_i + + t = library.get_title title + raise "Title `#{title}` not found" if t.nil? + e = t.get_entry entry + raise "Entry `#{entry}` of `#{title}` not found" if e.nil? + img = e.read_page page + raise "Failed to load page #{page} of `#{title}/#{entry}`" if img.nil? + + send_img env, img + rescue e + STDERR.puts e + env.response.status_code = 500 + e.message + end +end + +get "/api/book/:title" do |env| + begin + title = env.params.url["title"] + + t = library.get_title title + raise "Title `#{title}` not found" if t.nil? + + env.response.content_type = "application/json" + t.to_json + rescue e + STDERR.puts e + env.response.status_code = 500 + e.message + end +end + +get "/api/book" do |env| + env.response.content_type = "application/json" + library.to_json +end + + add_handler AuthHandler.new storage Kemal.config.port = config.port diff --git a/src/views/index.ecr b/src/views/index.ecr new file mode 100644 index 0000000..e473a08 --- /dev/null +++ b/src/views/index.ecr @@ -0,0 +1,18 @@ +
Hello !