mirror of
https://github.com/hkalexling/Mango.git
synced 2025-08-02 19:05:32 -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 "kemal"
|
||||||
|
require "./storage"
|
||||||
|
|
||||||
class AuthHandler < Kemal::Handler
|
class AuthHandler < Kemal::Handler
|
||||||
exclude ["/login"]
|
exclude ["/login"]
|
||||||
|
exclude ["/login"], "POST"
|
||||||
|
|
||||||
|
property storage : Storage
|
||||||
|
|
||||||
|
def initialize(@storage)
|
||||||
|
end
|
||||||
|
|
||||||
def call(env)
|
def call(env)
|
||||||
return call_next(env) if exclude_match?(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
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,14 @@
|
|||||||
require "zip"
|
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
|
class Entry
|
||||||
property zip_path : String
|
property zip_path : String
|
||||||
@ -10,6 +20,29 @@ class Entry
|
|||||||
@title = File.basename path, ".zip"
|
@title = File.basename path, ".zip"
|
||||||
@size = (File.size path).humanize_bytes
|
@size = (File.size path).humanize_bytes
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
class Title
|
class Title
|
||||||
@ -25,6 +58,9 @@ class Title
|
|||||||
.map { |path| Entry.new File.join dir, path }
|
.map { |path| Entry.new File.join dir, path }
|
||||||
.sort { |a, b| a.title <=> b.title }
|
.sort { |a, b| a.title <=> b.title }
|
||||||
end
|
end
|
||||||
|
def get_cover()
|
||||||
|
@entries[0].get_cover
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Library
|
class Library
|
||||||
|
42
src/mango.cr
42
src/mango.cr
@ -5,21 +5,47 @@ require "./storage"
|
|||||||
require "./auth_handler"
|
require "./auth_handler"
|
||||||
|
|
||||||
config = Config.load
|
config = Config.load
|
||||||
|
|
||||||
library = Library.new config.library_path
|
library = Library.new config.library_path
|
||||||
|
|
||||||
storage = Storage.new config.db_path
|
storage = Storage.new config.db_path
|
||||||
|
|
||||||
get "/" do
|
|
||||||
"Hello World!"
|
macro layout(name)
|
||||||
|
render "src/views/#{{{name}}}.ecr", "src/views/layout.ecr"
|
||||||
end
|
end
|
||||||
|
|
||||||
# APIs
|
macro send_img(env, img)
|
||||||
get "/api/test" do |env|
|
send_file env, image.data, image.mime
|
||||||
"Hello!"
|
|
||||||
end
|
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.config.port = config.port
|
||||||
Kemal.run
|
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