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
end
end

View File

@ -3,7 +3,7 @@ require "./spec_helper"
describe "compare_alphanumerically" do
it "sorts filenames with leading zeros correctly" do
ary = ["010.jpg", "001.jpg", "002.png"]
ary.sort! {|a, b|
ary.sort! { |a, b|
compare_alphanumerically a, b
}
ary.should eq ["001.jpg", "002.png", "010.jpg"]
@ -11,7 +11,7 @@ describe "compare_alphanumerically" do
it "sorts filenames without leading zeros correctly" do
ary = ["10.jpg", "1.jpg", "0.png", "0100.jpg"]
ary.sort! {|a, b|
ary.sort! { |a, b|
compare_alphanumerically a, b
}
ary.should eq ["0.png", "1.jpg", "10.jpg", "0100.jpg"]
@ -21,7 +21,7 @@ describe "compare_alphanumerically" do
it "sorts like the stack exchange post" do
ary = ["2", "12", "200000", "1000000", "a", "a12", "b2", "text2",
"text2a", "text2a2", "text2a12", "text2ab", "text12", "text12a"]
ary.reverse.sort {|a, b|
ary.reverse.sort { |a, b|
compare_alphanumerically a, b
}.should eq ary
end
@ -29,7 +29,7 @@ describe "compare_alphanumerically" do
# https://github.com/hkalexling/Mango/issues/22
it "handles numbers larger than Int32" do
ary = ["14410155591588.jpg", "21410155591588.png", "104410155591588.jpg"]
ary.reverse.sort {|a, b|
ary.reverse.sort { |a, b|
compare_alphanumerically a, b
}.should eq ary
end

View File

@ -7,11 +7,10 @@ class AuthHandler < Kemal::Handler
end
def call(env)
return call_next(env) \
if request_path_startswith env, ["/login", "/logout"]
return call_next(env) if request_path_startswith env, ["/login", "/logout"]
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
return env.redirect "/login"
end

View File

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

View File

@ -46,8 +46,8 @@ class Entry
json.field {{str}}, @{{str.id}}
{% end %}
json.field "display_name", @book.display_name @title
json.field "pages" {json.number @pages}
json.field "mtime" {json.number @mtime.to_unix}
json.field "pages" { json.number @pages }
json.field "mtime" { json.number @mtime.to_unix }
end
end
@ -76,7 +76,7 @@ class Entry
unless bytes_read
return nil
end
return Image.new slice, MIME.from_filename(page.filename),\
return Image.new slice, MIME.from_filename(page.filename),
page.filename, bytes_read
end
end
@ -115,8 +115,8 @@ class Title
end
mtimes = [@mtime]
mtimes += @title_ids.map{|e| @library.title_hash[e].mtime}
mtimes += @entries.map{|e| e.mtime}
mtimes += @title_ids.map { |e| @library.title_hash[e].mtime }
mtimes += @entries.map { |e| e.mtime }
@mtime = mtimes.max
@title_ids.sort! do |a, b|
@ -134,7 +134,7 @@ class Title
json.field {{str}}, @{{str.id}}
{% end %}
json.field "display_name", display_name
json.field "mtime" {json.number @mtime.to_unix}
json.field "mtime" { json.number @mtime.to_unix }
json.field "titles" do
json.raw self.titles.to_json
end
@ -155,7 +155,7 @@ class Title
end
def titles
@title_ids.map {|tid| @library.get_title! tid}
@title_ids.map { |tid| @library.get_title! tid }
end
def parents
@ -183,7 +183,7 @@ class Title
file.close
return true
rescue
@logger.warn "File #{path} is corrupted or is not a valid zip "\
@logger.warn "File #{path} is corrupted or is not a valid zip " \
"archive. Ignoring it."
return false
end
@ -251,7 +251,7 @@ class Title
def load_percetage(username, entry)
info = TitleInfo.new @dir
page = load_progress username, entry
entry_obj = @entries.find{|e| e.title == entry}
entry_obj = @entries.find { |e| e.title == entry }
return 0.0 if entry_obj.nil?
page / entry_obj.pages
end
@ -323,9 +323,11 @@ class Library
end
end
end
def titles
@title_ids.map {|tid| self.get_title!(tid) }
@title_ids.map { |tid| self.get_title!(tid) }
end
def to_json(json : JSON::Builder)
json.object do
json.field "dir", @dir
@ -334,12 +336,15 @@ class Library
end
end
end
def get_title(tid)
@title_hash[tid]?
end
def get_title!(tid)
@title_hash[tid]
end
def scan
unless Dir.exists? @dir
@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
msg = "#{env.response.status_code} #{env.request.method}" \
" #{env.request.resource} #{elapsed_text}"
@logger.debug(msg)
@logger.debug msg
env
end
def write(msg)
@logger.debug(msg)
@logger.debug msg
end
private def elapsed_text(elapsed)

View File

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

View File

@ -8,6 +8,7 @@ module MangaDex
property filename : String
property writer : Zip::Writer
property tries_remaning : Int32
def initialize(@url, @filename, @writer, @tries_remaning)
end
end
@ -112,7 +113,7 @@ module MangaDex
job = nil
DB.open "sqlite3://#{@path}" do |db|
begin
db.query_one "select * from queue where status = 0 "\
db.query_one "select * from queue where status = 0 " \
"or status = 1 order by time limit 1" do |res|
job = Job.from_query_result res
end
@ -128,7 +129,7 @@ module MangaDex
start_count = self.count
DB.open "sqlite3://#{@path}" do |db|
jobs.each do |job|
db.exec "insert or ignore into queue values "\
db.exec "insert or ignore into queue values " \
"(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
job.id, job.manga_id, job.title, job.manga_title,
job.status.to_i, job.status_message, job.pages,
@ -146,7 +147,7 @@ module MangaDex
end
end
def reset (job : Job)
def reset(job : Job)
self.reset job.id
end
@ -177,7 +178,7 @@ module MangaDex
def count_status(status : JobStatus)
DB.open "sqlite3://#{@path}" do |db|
return db.query_one "select count(*) from queue where "\
return db.query_one "select count(*) from queue where " \
"status = (?)", status.to_i, as: Int32
end
end
@ -198,7 +199,7 @@ module MangaDex
def get_all
jobs = [] of Job
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
end
end
@ -337,8 +338,8 @@ module MangaDex
@logger.error msg
end
end
fail_count = page_jobs.select{|j| !j.success}.size
@logger.debug "Download completed. "\
fail_count = page_jobs.select { |j| !j.success }.size
@logger.debug "Download completed. " \
"#{fail_count}/#{page_jobs.size} failed"
writer.close
@logger.debug "cbz File created at #{zip_path}"
@ -353,8 +354,8 @@ module MangaDex
private def download_page(job : PageJob)
@logger.debug "downloading #{job.url}"
headers = HTTP::Headers {
"User-agent" => "Mangadex.cr"
headers = HTTP::Headers{
"User-agent" => "Mangadex.cr",
}
begin
HTTP::Client.get job.url, headers do |res|

View File

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

View File

@ -37,7 +37,7 @@ class AdminRouter < Router
raise "Username should contain at least 3 characters"
end
if (username =~ /^[A-Za-z0-9_]+$/).nil?
raise "Username should contain alphanumeric characters "\
raise "Username should contain alphanumeric characters " \
"and underscores only"
end
if password.size < 6
@ -53,7 +53,7 @@ class AdminRouter < Router
rescue e
@context.error e
redirect_url = URI.new \
path: "/admin/user/edit",\
path: "/admin/user/edit",
query: hash_to_query({"error" => e.message})
env.redirect redirect_url.to_s
end
@ -64,8 +64,7 @@ class AdminRouter < Router
begin
username = env.params.body["username"]
password = env.params.body["password"]
# if `admin` is unchecked, the body
# hash would not contain `admin`
# if `admin` is unchecked, the body hash would not contain `admin`
admin = !env.params.body["admin"]?.nil?
original_username = env.params.url["original_username"]
@ -73,7 +72,7 @@ class AdminRouter < Router
raise "Username should contain at least 3 characters"
end
if (username =~ /^[A-Za-z0-9_]+$/).nil?
raise "Username should contain alphanumeric characters "\
raise "Username should contain alphanumeric characters " \
"and underscores only"
end
@ -93,7 +92,7 @@ class AdminRouter < Router
rescue e
@context.error e
redirect_url = URI.new \
path: "/admin/user/edit",\
path: "/admin/user/edit",
query: hash_to_query({"username" => original_username, \
"admin" => admin, "error" => e.message})
env.redirect redirect_url.to_s
@ -101,7 +100,7 @@ class AdminRouter < Router
end
get "/admin/downloads" do |env|
base_url = @context.config.mangadex["base_url"];
base_url = @context.config.mangadex["base_url"]
layout "download-manager"
end
end

View File

@ -12,8 +12,7 @@ class APIRouter < Router
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?
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?
@ -50,7 +49,7 @@ class APIRouter < Router
ms = (Time.utc - start).total_milliseconds
send_json env, {
"milliseconds" => ms,
"titles" => @context.library.titles.size
"titles" => @context.library.titles.size,
}.to_json
end
@ -62,7 +61,7 @@ class APIRouter < Router
@context.error e
send_json env, {
"success" => false,
"error" => e.message
"error" => e.message,
}.to_json
else
send_json env, {"success" => true}.to_json
@ -83,7 +82,7 @@ class APIRouter < Router
@context.error e
send_json env, {
"success" => false,
"error" => e.message
"error" => e.message,
}.to_json
else
send_json env, {"success" => true}.to_json
@ -106,7 +105,7 @@ class APIRouter < Router
@context.error e
send_json env, {
"success" => false,
"error" => e.message
"error" => e.message,
}.to_json
else
send_json env, {"success" => true}.to_json
@ -116,8 +115,7 @@ class APIRouter < Router
get "/api/admin/mangadex/manga/:id" do |env|
begin
id = env.params.url["id"]
api = MangaDex::API.new \
@context.config.mangadex["api_url"].to_s
api = MangaDex::API.new @context.config.mangadex["api_url"].to_s
manga = api.get_manga id
send_json env, manga.to_info_json
rescue e
@ -128,8 +126,8 @@ class APIRouter < Router
post "/api/admin/mangadex/download" do |env|
begin
chapters = env.params.json["chapters"].as(Array).map{|c| c.as_h}
jobs = chapters.map {|chapter|
chapters = env.params.json["chapters"].as(Array).map { |c| c.as_h }
jobs = chapters.map { |chapter|
MangaDex::Job.new(
chapter["id"].as_s,
chapter["manga_id"].as_s,
@ -142,7 +140,7 @@ class APIRouter < Router
inserted_count = @context.queue.push jobs
send_json env, {
"success": inserted_count,
"fail": jobs.size - inserted_count
"fail": jobs.size - inserted_count,
}.to_json
rescue e
@context.error e
@ -156,12 +154,12 @@ class APIRouter < Router
send_json env, {
"jobs" => jobs,
"paused" => @context.queue.paused?,
"success" => true
"success" => true,
}.to_json
rescue e
send_json env, {
"success" => false,
"error" => e.message
"error" => e.message,
}.to_json
end
end
@ -195,7 +193,7 @@ class APIRouter < Router
rescue e
send_json env, {
"success" => false,
"error" => e.message
"error" => e.message,
}.to_json
end
end

View File

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

View File

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

View File

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

View File

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

View File

@ -52,7 +52,7 @@ end
def split_by_alphanumeric(str)
arr = [] of String
str.scan(/([^\d\n\r]*)(\d*)([^\d\n\r]*)/) do |match|
arr += match.captures.select{|s| s != ""}
arr += match.captures.select { |s| s != "" }
end
arr
end