require "./router" require "../mangadex/*" require "../upload" class APIRouter < Router def initialize get "/api/page/:tid/:eid/:page" do |env| begin tid = env.params.url["tid"] eid = env.params.url["eid"] page = env.params.url["page"].to_i title = @context.library.get_title tid raise "Title ID `#{tid}` not found" if title.nil? entry = title.get_entry eid raise "Entry ID `#{eid}` of `#{title.title}` not found" if entry.nil? img = entry.read_page page raise "Failed to load page #{page} of " \ "`#{title.title}/#{entry.title}`" if img.nil? send_img env, img rescue e @context.error e env.response.status_code = 500 e.message end end get "/api/book/:tid" do |env| begin tid = env.params.url["tid"] title = @context.library.get_title tid raise "Title ID `#{tid}` not found" if title.nil? send_json env, title.to_json rescue e @context.error e env.response.status_code = 500 e.message end end get "/api/book" do |env| send_json env, @context.library.to_json end post "/api/admin/scan" do |env| start = Time.utc @context.library.scan ms = (Time.utc - start).total_milliseconds send_json env, { "milliseconds" => ms, "titles" => @context.library.titles.size, }.to_json end post "/api/admin/user/delete/:username" do |env| begin username = env.params.url["username"] @context.storage.delete_user username rescue e @context.error e send_json env, { "success" => false, "error" => e.message, }.to_json else send_json env, {"success" => true}.to_json end end post "/api/progress/:title/:page" do |env| begin username = get_username env title = (@context.library.get_title env.params.url["title"]) .not_nil! page = env.params.url["page"].to_i entry_id = env.params.query["entry"]? if !entry_id.nil? entry = title.get_entry(entry_id).not_nil! raise "incorrect page value" if page < 0 || page > entry.pages entry.save_progress username, page elsif page == 0 title.unread_all username else title.read_all username end rescue e @context.error e send_json env, { "success" => false, "error" => e.message, }.to_json else send_json env, {"success" => true}.to_json end end post "/api/bulk-progress/:action/:title" do |env| begin username = get_username env title = (@context.library.get_title env.params.url["title"]).not_nil! action = env.params.url["action"] ids = env.params.json["ids"].as(Array).map &.as_s unless action.in? ["read", "unread"] raise "Unknow action #{action}" end title.bulk_progress action, ids, username rescue e @context.error e send_json env, { "success" => false, "error" => e.message, }.to_json else send_json env, {"success" => true}.to_json end end post "/api/admin/display_name/:title/:name" do |env| begin title = (@context.library.get_title env.params.url["title"]) .not_nil! name = env.params.url["name"] entry = env.params.query["entry"]? if entry.nil? title.set_display_name name else eobj = title.get_entry entry title.set_display_name eobj.not_nil!.title, name end rescue e @context.error e send_json env, { "success" => false, "error" => e.message, }.to_json else send_json env, {"success" => true}.to_json end end get "/api/admin/mangadex/manga/:id" do |env| begin id = env.params.url["id"] api = MangaDex::API.default manga = api.get_manga id send_json env, manga.to_info_json rescue e @context.error e send_json env, {"error" => e.message}.to_json end end post "/api/admin/mangadex/download" do |env| begin chapters = env.params.json["chapters"].as(Array).map { |c| c.as_h } jobs = chapters.map { |chapter| Queue::Job.new( chapter["id"].as_s, chapter["manga_id"].as_s, chapter["full_title"].as_s, chapter["manga_title"].as_s, Queue::JobStatus::Pending, Time.unix chapter["time"].as_s.to_i ) } inserted_count = @context.queue.push jobs send_json env, { "success": inserted_count, "fail": jobs.size - inserted_count, }.to_json rescue e @context.error e send_json env, {"error" => e.message}.to_json end end get "/api/admin/mangadex/queue" do |env| begin jobs = @context.queue.get_all send_json env, { "jobs" => jobs, "paused" => @context.queue.paused?, "success" => true, }.to_json rescue e send_json env, { "success" => false, "error" => e.message, }.to_json end end post "/api/admin/mangadex/queue/:action" do |env| begin action = env.params.url["action"] id = env.params.query["id"]? case action when "delete" if id.nil? @context.queue.delete_status Queue::JobStatus::Completed else @context.queue.delete id end when "retry" if id.nil? @context.queue.reset else @context.queue.reset id end when "pause" @context.queue.pause when "resume" @context.queue.resume else raise "Unknown queue action #{action}" end send_json env, {"success" => true}.to_json rescue e send_json env, { "success" => false, "error" => e.message, }.to_json end end post "/api/admin/upload/:target" do |env| begin target = env.params.url["target"] HTTP::FormData.parse env.request do |part| next if part.name != "file" filename = part.filename if filename.nil? raise "No file uploaded" end case target when "cover" title_id = env.params.query["title"] entry_id = env.params.query["entry"]? title = @context.library.get_title(title_id).not_nil! unless SUPPORTED_IMG_TYPES.includes? \ MIME.from_filename? filename raise "The uploaded image must be either JPEG or PNG" end ext = File.extname filename upload = Upload.new Config.current.upload_path url = upload.path_to_url upload.save "img", ext, part.body if url.nil? raise "Failed to generate a public URL for the uploaded file" end if entry_id.nil? title.set_cover_url url else entry_name = title.get_entry(entry_id).not_nil!.title title.set_cover_url entry_name, url end else raise "Unkown upload target #{target}" end send_json env, {"success" => true}.to_json env.response.close end raise "No part with name `file` found" rescue e send_json env, { "success" => false, "error" => e.message, }.to_json end end post "/api/admin/plugin/list" do |env| begin query = env.params.json["query"].as String plugin = Plugin.new env.params.json["plugin"].as String json = plugin.list_chapters query chapters = json["chapters"] title = json["title"] send_json env, { "success" => true, "chapters" => chapters, "title" => title, }.to_json rescue e send_json env, { "success" => false, "error" => e.message, }.to_json end end post "/api/admin/plugin/download" do |env| begin plugin = Plugin.new env.params.json["plugin"].as String chapters = env.params.json["chapters"].as Array(JSON::Any) manga_title = env.params.json["title"].as String jobs = chapters.map { |ch| Queue::Job.new( "#{plugin.info.id}-#{ch["id"]}", "", # manga_id ch["title"].as_s, manga_title, Queue::JobStatus::Pending, Time.utc ) } inserted_count = @context.queue.push jobs send_json env, { "success": inserted_count, "fail": jobs.size - inserted_count, }.to_json rescue e send_json env, { "success" => false, "error" => e.message, }.to_json end end get "/api/dimensions/:tid/:eid" do |env| begin tid = env.params.url["tid"] eid = env.params.url["eid"] title = @context.library.get_title tid raise "Title ID `#{tid}` not found" if title.nil? entry = title.get_entry eid raise "Entry ID `#{eid}` of `#{title.title}` not found" if entry.nil? sizes = entry.page_dimensions send_json env, { "success" => true, "dimensions" => sizes, }.to_json rescue e send_json env, { "success" => false, "error" => e.message, }.to_json end end end end