Project-wise code formatting

This commit is contained in:
Alex Ling 2020-04-08 03:38:02 +00:00
parent 3866c81588
commit 8b184ed48d
23 changed files with 1864 additions and 1870 deletions

View File

@ -102,4 +102,3 @@ describe Queue do
State.reset State.reset
end end
end end

View File

@ -7,8 +7,7 @@ class AuthHandler < Kemal::Handler
end end
def call(env) def call(env)
return call_next(env) \ return call_next(env) if request_path_startswith env, ["/login", "/logout"]
if request_path_startswith env, ["/login", "/logout"]
cookie = env.request.cookies.find { |c| c.name == "token" } cookie = env.request.cookies.find { |c| c.name == "token" }
if cookie.nil? || !@storage.verify_token cookie.value if cookie.nil? || !@storage.verify_token cookie.value

View File

@ -4,10 +4,8 @@ class Config
include YAML::Serializable include YAML::Serializable
property port : Int32 = 9000 property port : Int32 = 9000
property library_path : String = \ property library_path : String = File.expand_path "~/mango/library", home: true
File.expand_path "~/mango/library", home: true property db_path : String = File.expand_path "~/mango/mango.db", home: true
property db_path : String = \
File.expand_path "~/mango/mango.db", home: true
@[YAML::Field(key: "scan_interval_minutes")] @[YAML::Field(key: "scan_interval_minutes")]
property scan_interval : Int32 = 5 property scan_interval : Int32 = 5
property log_level : String = "info" property log_level : String = "info"
@ -19,8 +17,8 @@ class Config
"api_url" => "https://mangadex.org/api", "api_url" => "https://mangadex.org/api",
"download_wait_seconds" => 5, "download_wait_seconds" => 5,
"download_retries" => 4, "download_retries" => 4,
"download_queue_db_path" => File.expand_path "~/mango/queue.db", "download_queue_db_path" => File.expand_path("~/mango/queue.db",
home: true home: true),
} }
def self.load(path : String?) def self.load(path : String?)

View File

@ -76,7 +76,7 @@ class Entry
unless bytes_read unless bytes_read
return nil return nil
end end
return Image.new slice, MIME.from_filename(page.filename),\ return Image.new slice, MIME.from_filename(page.filename),
page.filename, bytes_read page.filename, bytes_read
end end
end end
@ -323,9 +323,11 @@ class Library
end end
end end
end end
def titles def titles
@title_ids.map { |tid| self.get_title!(tid) } @title_ids.map { |tid| self.get_title!(tid) }
end end
def to_json(json : JSON::Builder) def to_json(json : JSON::Builder)
json.object do json.object do
json.field "dir", @dir json.field "dir", @dir
@ -334,12 +336,15 @@ class Library
end end
end end
end end
def get_title(tid) def get_title(tid)
@title_hash[tid]? @title_hash[tid]?
end end
def get_title!(tid) def get_title!(tid)
@title_hash[tid] @title_hash[tid]
end end
def scan def scan
unless Dir.exists? @dir unless Dir.exists? @dir
@logger.info "The library directory #{@dir} does not exist. " \ @logger.info "The library directory #{@dir} does not exist. " \

View File

@ -10,12 +10,12 @@ class LogHandler < Kemal::BaseLogHandler
elapsed_text = elapsed_text elapsed_time elapsed_text = elapsed_text elapsed_time
msg = "#{env.response.status_code} #{env.request.method}" \ msg = "#{env.response.status_code} #{env.request.method}" \
" #{env.request.resource} #{elapsed_text}" " #{env.request.resource} #{elapsed_text}"
@logger.debug(msg) @logger.debug msg
env env
end end
def write(msg) def write(msg)
@logger.debug(msg) @logger.debug msg
end end
private def elapsed_text(elapsed) private def elapsed_text(elapsed)

View File

@ -25,8 +25,8 @@ module MangaDex
property pages = [] of {String, String} # filename, url property pages = [] of {String, String} # filename, url
property groups = [] of {Int32, String} # group_id, group_name property groups = [] of {Int32, String} # group_id, group_name
def initialize(@id, json_obj : JSON::Any, @manga, lang : def initialize(@id, json_obj : JSON::Any, @manga,
Hash(String, String)) lang : Hash(String, String))
self.parse_json json_obj, lang self.parse_json json_obj, lang
end end
@ -77,9 +77,9 @@ module MangaDex
end end
end end
end end
class Manga class Manga
string_properties ["cover_url", "description", "title", "author", string_properties ["cover_url", "description", "title", "author", "artist"]
"artist"]
property chapters = [] of Chapter property chapters = [] of Chapter
property id : String property id : String
@ -90,8 +90,8 @@ module MangaDex
def to_info_json(with_chapters = true) def to_info_json(with_chapters = true)
JSON.build do |json| JSON.build do |json|
json.object do json.object do
{% for name in ["id", "title", "description", {% for name in ["id", "title", "description", "author", "artist",
"author", "artist", "cover_url"] %} "cover_url"] %}
json.field {{name}}, @{{name.id}} json.field {{name}}, @{{name.id}}
{% end %} {% end %}
if with_chapters if with_chapters
@ -109,13 +109,14 @@ module MangaDex
def parse_json(obj) def parse_json(obj)
begin begin
parse_strings_from_json ["cover_url", "description", "title", parse_strings_from_json ["cover_url", "description", "title", "author",
"author", "artist"] "artist"]
rescue e rescue e
raise "failed to parse json: #{e}" raise "failed to parse json: #{e}"
end end
end end
end end
class API class API
def initialize(@base_url = "https://mangadex.org/api/") def initialize(@base_url = "https://mangadex.org/api/")
@lang = {} of String => String @lang = {} of String => String
@ -126,7 +127,7 @@ module MangaDex
def get(url) def get(url)
headers = HTTP::Headers{ headers = HTTP::Headers{
"User-agent" => "Mangadex.cr" "User-agent" => "Mangadex.cr",
} }
res = HTTP::Client.get url, headers res = HTTP::Client.get url, headers
raise "Failed to get #{url}. [#{res.status_code}] " \ raise "Failed to get #{url}. [#{res.status_code}] " \
@ -137,8 +138,7 @@ module MangaDex
def get_manga(id) def get_manga(id)
obj = self.get File.join @base_url, "manga/#{id}" obj = self.get File.join @base_url, "manga/#{id}"
if obj["status"]? != "OK" if obj["status"]? != "OK"
raise "Expecting `OK` in the `status` field. " \ raise "Expecting `OK` in the `status` field. Got `#{obj["status"]?}`"
"Got `#{obj["status"]?}`"
end end
begin begin
manga = Manga.new id, obj["manga"] manga = Manga.new id, obj["manga"]
@ -160,8 +160,7 @@ module MangaDex
"external chapters." "external chapters."
end end
if obj["status"]? != "OK" if obj["status"]? != "OK"
raise "Expecting `OK` in the `status` field. " \ raise "Expecting `OK` in the `status` field. Got `#{obj["status"]?}`"
"Got `#{obj["status"]?}`"
end end
begin begin
server = obj["server"].as_s server = obj["server"].as_s
@ -169,7 +168,7 @@ module MangaDex
chapter.pages = obj["page_array"].as_a.map do |fn| chapter.pages = obj["page_array"].as_a.map do |fn|
{ {
fn.as_s, fn.as_s,
"#{server}#{hash}/#{fn.as_s}" "#{server}#{hash}/#{fn.as_s}",
} }
end end
rescue rescue
@ -185,8 +184,7 @@ module MangaDex
"external chapters." "external chapters."
end end
if obj["status"]? != "OK" if obj["status"]? != "OK"
raise "Expecting `OK` in the `status` field. " \ raise "Expecting `OK` in the `status` field. Got `#{obj["status"]?}`"
"Got `#{obj["status"]?}`"
end end
manga_id = "" manga_id = ""
begin begin

View File

@ -8,6 +8,7 @@ module MangaDex
property filename : String property filename : String
property writer : Zip::Writer property writer : Zip::Writer
property tries_remaning : Int32 property tries_remaning : Int32
def initialize(@url, @filename, @writer, @tries_remaning) def initialize(@url, @filename, @writer, @tries_remaning)
end end
end end
@ -198,7 +199,7 @@ module MangaDex
def get_all def get_all
jobs = [] of Job jobs = [] of Job
DB.open "sqlite3://#{@path}" do |db| DB.open "sqlite3://#{@path}" do |db|
jobs = db.query_all "select * from queue order by time", do |rs| jobs = db.query_all "select * from queue order by time" do |rs|
Job.from_query_result rs Job.from_query_result rs
end end
end end
@ -354,7 +355,7 @@ module MangaDex
private def download_page(job : PageJob) private def download_page(job : PageJob)
@logger.debug "downloading #{job.url}" @logger.debug "downloading #{job.url}"
headers = HTTP::Headers{ headers = HTTP::Headers{
"User-agent" => "Mangadex.cr" "User-agent" => "Mangadex.cr",
} }
begin begin
HTTP::Client.get job.url, headers do |res| HTTP::Client.get job.url, headers do |res|

View File

@ -18,8 +18,8 @@ parser = OptionParser.parse do |parser|
puts parser puts parser
exit exit
end end
parser.on "-c PATH", "--config=PATH", "Path to the config file. " \ parser.on "-c PATH", "--config=PATH",
"Default is `~/.config/mango/config.yml`" do |path| "Path to the config file. Default is `~/.config/mango/config.yml`" do |path|
config_path = path config_path = path
end end
end end

View File

@ -53,7 +53,7 @@ class AdminRouter < Router
rescue e rescue e
@context.error e @context.error e
redirect_url = URI.new \ redirect_url = URI.new \
path: "/admin/user/edit",\ path: "/admin/user/edit",
query: hash_to_query({"error" => e.message}) query: hash_to_query({"error" => e.message})
env.redirect redirect_url.to_s env.redirect redirect_url.to_s
end end
@ -64,8 +64,7 @@ class AdminRouter < Router
begin begin
username = env.params.body["username"] username = env.params.body["username"]
password = env.params.body["password"] password = env.params.body["password"]
# if `admin` is unchecked, the body # if `admin` is unchecked, the body hash would not contain `admin`
# hash would not contain `admin`
admin = !env.params.body["admin"]?.nil? admin = !env.params.body["admin"]?.nil?
original_username = env.params.url["original_username"] original_username = env.params.url["original_username"]
@ -93,7 +92,7 @@ class AdminRouter < Router
rescue e rescue e
@context.error e @context.error e
redirect_url = URI.new \ redirect_url = URI.new \
path: "/admin/user/edit",\ path: "/admin/user/edit",
query: hash_to_query({"username" => original_username, \ query: hash_to_query({"username" => original_username, \
"admin" => admin, "error" => e.message}) "admin" => admin, "error" => e.message})
env.redirect redirect_url.to_s env.redirect redirect_url.to_s
@ -101,7 +100,7 @@ class AdminRouter < Router
end end
get "/admin/downloads" do |env| get "/admin/downloads" do |env|
base_url = @context.config.mangadex["base_url"]; base_url = @context.config.mangadex["base_url"]
layout "download-manager" layout "download-manager"
end end
end end

View File

@ -12,8 +12,7 @@ class APIRouter < Router
title = @context.library.get_title tid title = @context.library.get_title tid
raise "Title ID `#{tid}` not found" if title.nil? raise "Title ID `#{tid}` not found" if title.nil?
entry = title.get_entry eid entry = title.get_entry eid
raise "Entry ID `#{eid}` of `#{title.title}` not found" if \ raise "Entry ID `#{eid}` of `#{title.title}` not found" if entry.nil?
entry.nil?
img = entry.read_page page img = entry.read_page page
raise "Failed to load page #{page} of " \ raise "Failed to load page #{page} of " \
"`#{title.title}/#{entry.title}`" if img.nil? "`#{title.title}/#{entry.title}`" if img.nil?
@ -50,7 +49,7 @@ class APIRouter < Router
ms = (Time.utc - start).total_milliseconds ms = (Time.utc - start).total_milliseconds
send_json env, { send_json env, {
"milliseconds" => ms, "milliseconds" => ms,
"titles" => @context.library.titles.size "titles" => @context.library.titles.size,
}.to_json }.to_json
end end
@ -62,7 +61,7 @@ class APIRouter < Router
@context.error e @context.error e
send_json env, { send_json env, {
"success" => false, "success" => false,
"error" => e.message "error" => e.message,
}.to_json }.to_json
else else
send_json env, {"success" => true}.to_json send_json env, {"success" => true}.to_json
@ -83,7 +82,7 @@ class APIRouter < Router
@context.error e @context.error e
send_json env, { send_json env, {
"success" => false, "success" => false,
"error" => e.message "error" => e.message,
}.to_json }.to_json
else else
send_json env, {"success" => true}.to_json send_json env, {"success" => true}.to_json
@ -106,7 +105,7 @@ class APIRouter < Router
@context.error e @context.error e
send_json env, { send_json env, {
"success" => false, "success" => false,
"error" => e.message "error" => e.message,
}.to_json }.to_json
else else
send_json env, {"success" => true}.to_json send_json env, {"success" => true}.to_json
@ -116,8 +115,7 @@ class APIRouter < Router
get "/api/admin/mangadex/manga/:id" do |env| get "/api/admin/mangadex/manga/:id" do |env|
begin begin
id = env.params.url["id"] id = env.params.url["id"]
api = MangaDex::API.new \ api = MangaDex::API.new @context.config.mangadex["api_url"].to_s
@context.config.mangadex["api_url"].to_s
manga = api.get_manga id manga = api.get_manga id
send_json env, manga.to_info_json send_json env, manga.to_info_json
rescue e rescue e
@ -142,7 +140,7 @@ class APIRouter < Router
inserted_count = @context.queue.push jobs inserted_count = @context.queue.push jobs
send_json env, { send_json env, {
"success": inserted_count, "success": inserted_count,
"fail": jobs.size - inserted_count "fail": jobs.size - inserted_count,
}.to_json }.to_json
rescue e rescue e
@context.error e @context.error e
@ -156,12 +154,12 @@ class APIRouter < Router
send_json env, { send_json env, {
"jobs" => jobs, "jobs" => jobs,
"paused" => @context.queue.paused?, "paused" => @context.queue.paused?,
"success" => true "success" => true,
}.to_json }.to_json
rescue e rescue e
send_json env, { send_json env, {
"success" => false, "success" => false,
"error" => e.message "error" => e.message,
}.to_json }.to_json
end end
end end
@ -195,7 +193,7 @@ class APIRouter < Router
rescue e rescue e
send_json env, { send_json env, {
"success" => false, "success" => false,
"error" => e.message "error" => e.message,
}.to_json }.to_json
end end
end end

View File

@ -8,8 +8,7 @@ class MainRouter < Router
get "/logout" do |env| get "/logout" do |env|
begin begin
cookie = env.request.cookies cookie = env.request.cookies.find { |c| c.name == "token" }.not_nil!
.find { |c| c.name == "token" }.not_nil!
@context.storage.logout cookie.value @context.storage.logout cookie.value
rescue e rescue e
@context.error "Error when attempting to log out: #{e}" @context.error "Error when attempting to log out: #{e}"
@ -22,8 +21,7 @@ class MainRouter < Router
begin begin
username = env.params.body["username"] username = env.params.body["username"]
password = env.params.body["password"] password = env.params.body["password"]
token = @context.storage.verify_user(username, password) token = @context.storage.verify_user(username, password).not_nil!
.not_nil!
cookie = HTTP::Cookie.new "token", token cookie = HTTP::Cookie.new "token", token
cookie.expires = Time.local.shift years: 1 cookie.expires = Time.local.shift years: 1
@ -43,11 +41,11 @@ class MainRouter < Router
get "/book/:title" do |env| get "/book/:title" do |env|
begin begin
title = (@context.library.get_title env.params.url["title"]) title = (@context.library.get_title env.params.url["title"]).not_nil!
.not_nil!
username = get_username env username = get_username env
percentage = title.entries.map { |e| percentage = title.entries.map { |e|
title.load_percetage username, e.title } title.load_percetage username, e.title
}
layout "title" layout "title"
rescue e rescue e
@context.error e @context.error e
@ -56,7 +54,7 @@ class MainRouter < Router
end end
get "/download" do |env| get "/download" do |env|
base_url = @context.config.mangadex["base_url"]; base_url = @context.config.mangadex["base_url"]
layout "download" layout "download"
end end
end end

View File

@ -4,8 +4,7 @@ class ReaderRouter < Router
def setup def setup
get "/reader/:title/:entry" do |env| get "/reader/:title/:entry" do |env|
begin begin
title = (@context.library.get_title env.params.url["title"]) title = (@context.library.get_title env.params.url["title"]).not_nil!
.not_nil!
entry = (title.get_entry env.params.url["entry"]).not_nil! entry = (title.get_entry env.params.url["entry"]).not_nil!
# load progress # load progress
@ -25,8 +24,7 @@ class ReaderRouter < Router
get "/reader/:title/:entry/:page" do |env| get "/reader/:title/:entry/:page" do |env|
begin begin
title = (@context.library.get_title env.params.url["title"]) title = (@context.library.get_title env.params.url["title"]).not_nil!
.not_nil!
entry = (title.get_entry env.params.url["entry"]).not_nil! entry = (title.get_entry env.params.url["entry"]).not_nil!
page = env.params.url["page"].to_i page = env.params.url["page"].to_i
raise "" if page > entry.pages || page <= 0 raise "" if page > entry.pages || page <= 0
@ -37,16 +35,21 @@ class ReaderRouter < Router
pages = (page...[entry.pages + 1, page + IMGS_PER_PAGE].min) pages = (page...[entry.pages + 1, page + IMGS_PER_PAGE].min)
urls = pages.map { |idx| urls = pages.map { |idx|
"/api/page/#{title.id}/#{entry.id}/#{idx}" } "/api/page/#{title.id}/#{entry.id}/#{idx}"
}
reader_urls = pages.map { |idx| reader_urls = pages.map { |idx|
"/reader/#{title.id}/#{entry.id}/#{idx}" } "/reader/#{title.id}/#{entry.id}/#{idx}"
}
next_page = page + IMGS_PER_PAGE next_page = page + IMGS_PER_PAGE
next_url = next_page > entry.pages ? nil : next_url = next_entry_url = nil
"/reader/#{title.id}/#{entry.id}/#{next_page}"
exit_url = "/book/#{title.id}" exit_url = "/book/#{title.id}"
next_entry = title.next_entry entry next_entry = title.next_entry entry
next_entry_url = next_entry.nil? ? nil : \ unless next_page > entry.pages
"/reader/#{title.id}/#{next_entry.id}" next_url = "/reader/#{title.id}/#{entry.id}/#{next_page}"
end
unless next_entry.nil?
next_entry_url = "/reader/#{title.id}/#{next_entry.id}"
end
render "src/views/reader.ecr" render "src/views/reader.ecr"
rescue e rescue e

View File

@ -8,10 +8,8 @@ require "./routes/*"
class Server class Server
def initialize(@context : Context) def initialize(@context : Context)
error 403 do |env| error 403 do |env|
message = "HTTP 403: You are not authorized to visit " \ message = "HTTP 403: You are not authorized to visit #{env.request.path}"
"#{env.request.path}"
layout "message" layout "message"
end end
error 404 do |env| error 404 do |env|

View File

@ -58,7 +58,7 @@ class Storage
DB.open "sqlite3://#{@path}" do |db| DB.open "sqlite3://#{@path}" do |db|
begin begin
hash, token = db.query_one "select password, token from " \ hash, token = db.query_one "select password, token from " \
"users where username = (?)", \ "users where username = (?)",
username, as: {String, String?} username, as: {String, String?}
unless verify_password hash, password unless verify_password hash, password
@logger.debug "Password does not match the hash" @logger.debug "Password does not match the hash"
@ -129,12 +129,12 @@ class Storage
DB.open "sqlite3://#{@path}" do |db| DB.open "sqlite3://#{@path}" do |db|
if password.size == 0 if password.size == 0
db.exec "update users set username = (?), admin = (?) " \ db.exec "update users set username = (?), admin = (?) " \
"where username = (?)",\ "where username = (?)",
username, admin, original_username username, admin, original_username
else else
hash = hash_password password hash = hash_password password
db.exec "update users set username = (?), admin = (?)," \ db.exec "update users set username = (?), admin = (?)," \
"password = (?) where username = (?)",\ "password = (?) where username = (?)",
username, admin, hash, original_username username, admin, hash, original_username
end end
end end
@ -149,8 +149,7 @@ class Storage
def logout(token) def logout(token)
DB.open "sqlite3://#{@path}" do |db| DB.open "sqlite3://#{@path}" do |db|
begin begin
db.exec "update users set token = (?) where token = (?)", \ db.exec "update users set token = (?) where token = (?)", nil, token
nil, token
rescue rescue
end end
end end
@ -159,13 +158,12 @@ class Storage
def get_id(path, is_title) def get_id(path, is_title)
DB.open "sqlite3://#{@path}" do |db| DB.open "sqlite3://#{@path}" do |db|
begin begin
id = db.query_one "select id from ids where path = (?)", id = db.query_one "select id from ids where path = (?)", path,
path, as: {String} as: {String}
return id return id
rescue rescue
id = random_str id = random_str
db.exec "insert into ids values (?, ?, ?)", path, id, db.exec "insert into ids values (?, ?, ?)", path, id, is_title ? 1 : 0
is_title ? 1 : 0
return id return id
end end
end end