init: main and templates
This commit is contained in:
commit
484ecd1cc3
96
main.go
Normal file
96
main.go
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DEFAULT_HTTP_PORT = "8080"
|
||||||
|
DEFAULT_HTTPS_PORT = "4433"
|
||||||
|
)
|
||||||
|
|
||||||
|
type apiMessageResponse struct {
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Logger struct {
|
||||||
|
Handler http.Handler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
tNow := time.Now().UTC()
|
||||||
|
l.Handler.ServeHTTP(w, r)
|
||||||
|
methodString := l.getMethodLogString(r.Method)
|
||||||
|
log.Printf(" %s %s %s %v", r.RemoteAddr, methodString, r.URL, time.Since(tNow))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) getMethodLogString(method string) string {
|
||||||
|
colorBlue := "\033[34m"
|
||||||
|
colorReset := "\033[0m"
|
||||||
|
// colorRed := "\033[31m"
|
||||||
|
// colorGreen := "\033[32m"
|
||||||
|
// colorYellow := "\033[33m"
|
||||||
|
// colorPurple := "\033[35m"
|
||||||
|
// colorCyan := "\033[36m"
|
||||||
|
// colorWhite := "\033[37m"
|
||||||
|
if method == "GET" { return colorBlue + "GET" + colorReset }
|
||||||
|
return method
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLogger(handler http.Handler) *Logger {
|
||||||
|
return &Logger{Handler: handler}
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeJSONResponse(w http.ResponseWriter, s string) http.ResponseWriter {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
jsonResp, err := json.Marshal(apiMessageResponse{Message: s})
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
_, err = w.Write(jsonResp)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
return w
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
handler := http.NewServeMux()
|
||||||
|
|
||||||
|
handler.HandleFunc(
|
||||||
|
"/download",
|
||||||
|
func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
userURL := r.URL.Query().Get("url")
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
if userURL == "" {
|
||||||
|
w = writeJSONResponse(w, "Provide URL as query")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w = writeJSONResponse(w, fmt.Sprintf("You sent %s ", userURL))},
|
||||||
|
)
|
||||||
|
|
||||||
|
wrappedHandler := NewLogger(handler)
|
||||||
|
srv := http.Server{
|
||||||
|
ReadTimeout: 3 * time.Second,
|
||||||
|
WriteTimeout: 10 * time.Second,
|
||||||
|
Addr: ":" + DEFAULT_HTTP_PORT,
|
||||||
|
Handler: wrappedHandler,
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Starting HTTP on %s", DEFAULT_HTTP_PORT)
|
||||||
|
log.Fatalln(srv.ListenAndServe())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
92
templates/index-pico.html
Normal file
92
templates/index-pico.html
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>Sign in example • Pico.css</title>
|
||||||
|
<meta name="description" content="A minimalist layout for Login pages. Built with Pico CSS." />
|
||||||
|
<link rel="shortcut icon" href="https://picocss.com/favicon.ico" />
|
||||||
|
<link rel="canonical" href="https://picocss.com/examples/sign-in/" />
|
||||||
|
|
||||||
|
<!-- Pico.css -->
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@1/css/pico.min.css" />
|
||||||
|
|
||||||
|
<!-- Custom styles for this example -->
|
||||||
|
<link rel="stylesheet" href="custom.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<!-- Nav -->
|
||||||
|
<nav class="container-fluid">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="./" class="contrast" onclick="event.preventDefault()"><strong>Brand</strong></a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<details role="list" dir="rtl">
|
||||||
|
<summary aria-haspopup="listbox" role="link" class="secondary">Theme</summary>
|
||||||
|
<ul role="listbox">
|
||||||
|
<li><a href="#" data-theme-switcher="auto">Auto</a></li>
|
||||||
|
<li><a href="#" data-theme-switcher="light">Light</a></li>
|
||||||
|
<li><a href="#" data-theme-switcher="dark">Dark</a></li>
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<!-- ./ Nav -->
|
||||||
|
|
||||||
|
<!-- Main -->
|
||||||
|
<main class="container">
|
||||||
|
<article class="grid">
|
||||||
|
<div>
|
||||||
|
<hgroup>
|
||||||
|
<h1>Sign in</h1>
|
||||||
|
<h2>A minimalist layout for Login pages</h2>
|
||||||
|
</hgroup>
|
||||||
|
<form>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="login"
|
||||||
|
placeholder="Login"
|
||||||
|
aria-label="Login"
|
||||||
|
autocomplete="nickname"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
name="password"
|
||||||
|
placeholder="Password"
|
||||||
|
aria-label="Password"
|
||||||
|
autocomplete="current-password"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<fieldset>
|
||||||
|
<label for="remember">
|
||||||
|
<input type="checkbox" role="switch" id="remember" name="remember" />
|
||||||
|
Remember me
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
<button type="submit" class="contrast" onclick="event.preventDefault()">Login</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div></div>
|
||||||
|
</article>
|
||||||
|
</main>
|
||||||
|
<!-- ./ Main -->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="container-fluid">
|
||||||
|
<small>
|
||||||
|
yt-mdl
|
||||||
|
</small>
|
||||||
|
</footer>
|
||||||
|
<!-- ./ Footer -->
|
||||||
|
|
||||||
|
<!-- Minimal theme switcher -->
|
||||||
|
<script src="js/minimal-theme-switcher.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
72
templates/index-tail.html
Normal file
72
templates/index-tail.html
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.5"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This example requires some changes to your config:
|
||||||
|
|
||||||
|
```
|
||||||
|
// tailwind.config.js
|
||||||
|
module.exports = {
|
||||||
|
// ...
|
||||||
|
plugins: [
|
||||||
|
// ...
|
||||||
|
require('@tailwindcss/forms'),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
```
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
This example requires updating your template:
|
||||||
|
|
||||||
|
```
|
||||||
|
<html class="h-full bg-white">
|
||||||
|
<body class="h-full">
|
||||||
|
```
|
||||||
|
-->
|
||||||
|
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
|
||||||
|
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
|
||||||
|
<img class="mx-auto h-10 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600" alt="Your Company">
|
||||||
|
<h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">Sign in to your account</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
|
||||||
|
<form class="space-y-6" action="#" method="POST">
|
||||||
|
<div>
|
||||||
|
<label for="email" class="block text-sm font-medium leading-6 text-gray-900">Email address</label>
|
||||||
|
<div class="mt-2">
|
||||||
|
<input id="email" name="email" type="email" autocomplete="email" required class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<label for="password" class="block text-sm font-medium leading-6 text-gray-900">Password</label>
|
||||||
|
<div class="text-sm">
|
||||||
|
<a href="#" class="font-semibold text-indigo-600 hover:text-indigo-500">Forgot password?</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2">
|
||||||
|
<input id="password" name="password" type="password" autocomplete="current-password" required class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button type="submit" class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Sign in</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<p class="mt-10 text-center text-sm text-gray-500">
|
||||||
|
Not a member?
|
||||||
|
<a href="#" class="font-semibold leading-6 text-indigo-600 hover:text-indigo-500">Start a 14 day free trial</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
19
templates/index.html
Normal file
19
templates/index.html
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="css/pico.min.css">
|
||||||
|
<title>Hello, world!</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main class="container">
|
||||||
|
<h1>Download Videos</h1>
|
||||||
|
<div>
|
||||||
|
<label for="user-url">URL</label>
|
||||||
|
<input type="url" id="user-url" name="user-url" required>
|
||||||
|
</div>
|
||||||
|
<button>Start Download</button>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user