diff --git a/src/library.cr b/src/library.cr index c5b8ca3..3dd7f48 100644 --- a/src/library.cr +++ b/src/library.cr @@ -136,9 +136,9 @@ class TitleInfo end class Library - JSON.mapping dir: String, titles: Array(Title), scan_interval: Int32 + JSON.mapping dir: String, titles: Array(Title), scan_interval: Int32, logger: MLogger - def initialize(@dir, @scan_interval, logger) + def initialize(@dir, @scan_interval, @logger) # explicitly initialize @titles to bypass the compiler check. it will # be filled with actual Titles in the `scan` call below @titles = [] of Title @@ -146,11 +146,11 @@ class Library return scan if @scan_interval < 1 spawn do loop do - logger.info "Starting periodic scan" + @logger.info "Starting periodic scan" start = Time.local scan ms = (Time.local - start).total_milliseconds - logger.info "Scanned #{@titles.size} titles in #{ms}ms" + @logger.info "Scanned #{@titles.size} titles in #{ms}ms" sleep @scan_interval * 60 end end @@ -160,11 +160,15 @@ class Library end def scan unless Dir.exists? @dir + @logger.info "The library directory #{@dir} does not exist. " \ + "Attempting to create it" Dir.mkdir_p @dir end @titles = (Dir.entries @dir) .select { |path| File.directory? File.join @dir, path } .map { |path| Title.new File.join @dir, path } .select { |title| !title.entries.empty? } + @logger.debug "Scan completed" + @logger.debug "Scanned library: \n#{self.to_pretty_json}" end end diff --git a/src/logger.cr b/src/logger.cr index 53c4af8..1e6d446 100644 --- a/src/logger.cr +++ b/src/logger.cr @@ -52,4 +52,8 @@ class MLogger @logger.{{lvl.id}} msg end {% end %} + + def to_json(json : JSON::Builder) + json.string self + end end diff --git a/src/server.cr b/src/server.cr index 623b046..e84292b 100644 --- a/src/server.cr +++ b/src/server.cr @@ -14,14 +14,10 @@ class Server end get "/" do |env| - begin - titles = @context.library.titles - username = get_username env - percentage = titles.map &.load_percetage username - layout "index" - rescue - env.response.status_code = 500 - end + titles = @context.library.titles + username = get_username env + percentage = titles.map &.load_percetage username + layout "index" end get "/book/:title" do |env| @@ -32,7 +28,8 @@ class Server percentage = title.entries.map { |e| title.load_percetage username, e.title } layout "title" - rescue + rescue e + @context.error e env.response.status_code = 404 end end @@ -86,7 +83,7 @@ class Server env.redirect "/admin/user" rescue e - @context.error e.message + @context.error e redirect_url = URI.new \ path: "/admin/user/edit",\ query: hash_to_query({"error" => e.message}) @@ -126,7 +123,7 @@ class Server env.redirect "/admin/user" rescue e - @context.error e.message + @context.error e redirect_url = URI.new \ path: "/admin/user/edit",\ query: hash_to_query({"username" => original_username, \ @@ -151,7 +148,8 @@ class Server page = [page - 2 * IMGS_PER_PAGE, 1].max env.redirect "/reader/#{title.title}/#{entry.title}/#{page}" - rescue + rescue e + @context.error e env.response.status_code = 404 end end @@ -182,7 +180,8 @@ class Server "/reader/#{title.title}/#{next_entry.title}" render "src/views/reader.ecr" - rescue + rescue e + @context.error e env.response.status_code = 404 end end @@ -196,7 +195,8 @@ class Server cookie = env.request.cookies .find { |c| c.name == "token" }.not_nil! @context.storage.logout cookie.value - rescue + rescue e + @context.error "Error when attempting to log out: #{e}" ensure env.redirect "/login" end @@ -233,7 +233,7 @@ class Server send_img env, img rescue e - @context.error e.message + @context.error e env.response.status_code = 500 e.message end @@ -248,7 +248,7 @@ class Server send_json env, t.to_json rescue e - @context.error e.message + @context.error e env.response.status_code = 500 e.message end @@ -273,6 +273,7 @@ class Server username = env.params.url["username"] @context.storage.delete_user username rescue e + @context.error e send_json env, { "success" => false, "error" => e.message @@ -293,6 +294,7 @@ class Server raise "incorrect page value" if page < 0 || page > entry.pages title.save_progress username, entry.title, page rescue e + @context.error e send_json env, { "success" => false, "error" => e.message @@ -307,12 +309,14 @@ class Server add_handler AuthHandler.new @context.storage {% if flag?(:release) %} # when building for relase, embed the static files in binary + @context.debug "We are in release mode. Using embeded static files." serve_static false add_handler StaticHandler.new {% end %} end def start + @context.debug "Starting Kemal server" {% if flag?(:release) %} Kemal.config.env = "production" {% end %} diff --git a/src/storage.cr b/src/storage.cr index c42063d..47fe302 100644 --- a/src/storage.cr +++ b/src/storage.cr @@ -19,17 +19,21 @@ class Storage def initialize(@path : String, @logger : MLogger) dir = File.dirname path unless Dir.exists? dir + @logger.info "The DB directory #{dir} does not exist. " \ + "Attepmting to create it" Dir.mkdir_p dir end DB.open "sqlite3://#{path}" do |db| begin db.exec "create table users" \ "(username text, password text, token text, admin integer)" - rescue e : SQLite3::Exception | DB::Error + rescue e unless e.message == "table users already exists" + @logger.fatal "Error when checking tables in DB: #{e}" raise e end else + @logger.debug "Creating DB file at #{@path}" db.exec "create unique index username_idx on users (username)" db.exec "create unique index token_idx on users (token)" random_pw = random_str @@ -49,14 +53,18 @@ class Storage "users where username = (?)", \ username, as: {String, String?} unless verify_password hash, password + @logger.debug "Password does not match the hash" return nil end + @logger.debug "Useer #{username} verified" return token if token token = random_str + @logger.debug "Updating token for #{username}" db.exec "update users set token = (?) where username = (?)", token, username return token - rescue e : SQLite3::Exception | DB::Error + rescue e + @logger.error "Error when verifying user #{username}: #{e}" return nil end end @@ -68,7 +76,8 @@ class Storage username = db.query_one "select username from users where " \ "token = (?)", token, as: String return username - rescue e : SQLite3::Exception | DB::Error + rescue e + @logger.debug "Unable to verify token" return nil end end @@ -79,7 +88,8 @@ class Storage begin return db.query_one "select admin from users where " \ "token = (?)", token, as: Bool - rescue e : SQLite3::Exception | DB::Error + rescue e + @logger.debug "Unable to verify user as admin" return false end end