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