mirror of
https://github.com/hkalexling/Mango.git
synced 2025-08-02 10:55:30 -04:00
- implement login and load images from zip
This commit is contained in:
parent
a3203dccba
commit
cc031c9aef
@ -1,15 +1,25 @@
|
||||
require "kemal"
|
||||
require "./storage"
|
||||
|
||||
class AuthHandler < Kemal::Handler
|
||||
exclude ["/login"]
|
||||
exclude ["/login"], "POST"
|
||||
|
||||
property storage : Storage
|
||||
|
||||
def initialize(@storage)
|
||||
end
|
||||
|
||||
def call(env)
|
||||
return call_next(env) if exclude_match?(env)
|
||||
my_cookie = HTTP::Cookie.new(
|
||||
name: "Example",
|
||||
value: "KemalCR"
|
||||
)
|
||||
env.response.cookies << my_cookie
|
||||
|
||||
pp env.request.cookies
|
||||
env.request.cookies.each do |c|
|
||||
next if c.name != "token"
|
||||
if @storage.verify_token c.value
|
||||
return call_next env
|
||||
end
|
||||
end
|
||||
|
||||
env.redirect "/login"
|
||||
end
|
||||
end
|
||||
|
@ -1,4 +1,14 @@
|
||||
require "zip"
|
||||
require "mime"
|
||||
|
||||
class Image
|
||||
property data : Bytes
|
||||
property mime : String
|
||||
property filename : String
|
||||
property size : Int32
|
||||
def initialize(@data, @mime, @filename, @size)
|
||||
end
|
||||
end
|
||||
|
||||
class Entry
|
||||
property zip_path : String
|
||||
@ -10,6 +20,29 @@ class Entry
|
||||
@title = File.basename path, ".zip"
|
||||
@size = (File.size path).humanize_bytes
|
||||
end
|
||||
def read_page(page_num)
|
||||
Zip::File.open @zip_path do |file|
|
||||
page = file.entries
|
||||
.select { |e|
|
||||
["image/jpeg", "image/png"].includes? \
|
||||
MIME.from_filename? e.filename
|
||||
}
|
||||
.sort { |a, b| a.filename <=> b.filename }
|
||||
.[page_num]
|
||||
page.open do |io|
|
||||
slice = Bytes.new page.uncompressed_size
|
||||
bytes_read = io.read_fully? slice
|
||||
unless bytes_read
|
||||
return nil
|
||||
end
|
||||
return Image.new slice, MIME.from_filename(page.filename),\
|
||||
page.filename, bytes_read
|
||||
end
|
||||
end
|
||||
end
|
||||
def get_cover()
|
||||
read_page 0
|
||||
end
|
||||
end
|
||||
|
||||
class Title
|
||||
@ -25,6 +58,9 @@ class Title
|
||||
.map { |path| Entry.new File.join dir, path }
|
||||
.sort { |a, b| a.title <=> b.title }
|
||||
end
|
||||
def get_cover()
|
||||
@entries[0].get_cover
|
||||
end
|
||||
end
|
||||
|
||||
class Library
|
||||
|
42
src/mango.cr
42
src/mango.cr
@ -5,21 +5,47 @@ require "./storage"
|
||||
require "./auth_handler"
|
||||
|
||||
config = Config.load
|
||||
|
||||
library = Library.new config.library_path
|
||||
|
||||
storage = Storage.new config.db_path
|
||||
|
||||
get "/" do
|
||||
"Hello World!"
|
||||
|
||||
macro layout(name)
|
||||
render "src/views/#{{{name}}}.ecr", "src/views/layout.ecr"
|
||||
end
|
||||
|
||||
# APIs
|
||||
get "/api/test" do |env|
|
||||
"Hello!"
|
||||
macro send_img(env, img)
|
||||
send_file env, image.data, image.mime
|
||||
end
|
||||
|
||||
add_handler AuthHandler.new
|
||||
|
||||
get "/" do |env|
|
||||
image = library.titles[0].get_cover
|
||||
unless image
|
||||
"Failed to load image"
|
||||
next
|
||||
end
|
||||
send_img env, image
|
||||
end
|
||||
|
||||
get "/login" do |env|
|
||||
render "src/views/login.ecr"
|
||||
end
|
||||
|
||||
post "/login" do |env|
|
||||
username = env.params.body["username"]
|
||||
password = env.params.body["password"]
|
||||
token = storage.verify_user username, password
|
||||
if token.nil?
|
||||
env.redirect "/login"
|
||||
next
|
||||
end
|
||||
|
||||
cookie = HTTP::Cookie.new "token", token
|
||||
env.response.cookies << cookie
|
||||
env.redirect "/"
|
||||
end
|
||||
|
||||
add_handler AuthHandler.new storage
|
||||
|
||||
Kemal.config.port = config.port
|
||||
Kemal.run
|
||||
|
24
src/views/layout.ecr
Normal file
24
src/views/layout.ecr
Normal file
@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="X-UA-Compatible" content="IE=edge">
|
||||
<title>Mango</title>
|
||||
<meta name="description" content="Mango Manga Server">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.3.1/dist/css/uikit.min.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="uk-section uk-section-primary uk-section-small">
|
||||
<p class="uk-align-right uk-margin-right">Hello !</p>
|
||||
</div>
|
||||
<div class="uk-section uk-section-default uk-section-small">
|
||||
<%= content %>
|
||||
</div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/uikit@3.3.1/dist/js/uikit.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/uikit@3.3.1/dist/js/uikit-icons.min.js"></script>
|
||||
</body>
|
||||
</html>
|
38
src/views/login.ecr
Normal file
38
src/views/login.ecr
Normal file
@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="X-UA-Compatible" content="IE=edge">
|
||||
<title>Mango</title>
|
||||
<meta name="description" content="Mango Manga Server">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.3.1/dist/css/uikit.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="uk-section uk-section-muted uk-flex uk-flex-middle uk-animation-fade" uk-height-viewport="">
|
||||
<div class="uk-width-1-1">
|
||||
<div class="uk-container">
|
||||
<div class="uk-grid-margin uk-grid uk-grid-stack" uk-grid="">
|
||||
<div class="uk-width-1-1@m">
|
||||
<div class="uk-margin uk-width-large uk-margin-auto uk-card uk-card-default uk-card-body uk-box-shadow-large">
|
||||
<h3 class="uk-card-title uk-text-center">Log In</h3>
|
||||
<form action="/login" method="post">
|
||||
<div class="uk-margin">
|
||||
<div class="uk-inline uk-width-1-1"><span class="uk-form-icon" uk-icon="icon:user"></span><input class="uk-input uk-form-large" type="text" name="username"></div>
|
||||
</div>
|
||||
<div class="uk-margin">
|
||||
<div class="uk-inline uk-width-1-1"><span class="uk-form-icon" uk-icon="icon:lock"></span><input class="uk-input uk-form-large" type="password" name="password"></div>
|
||||
</div>
|
||||
<div class="uk-margin"><button class="uk-button uk-button-primary uk-button-large uk-width-1-1">Login</button></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/uikit@3.3.1/dist/js/uikit.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/uikit@3.3.1/dist/js/uikit-icons.min.js"></script>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user