tagliatelle

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

main.go (2974B)


      1 package main
      2 
      3 import (
      4 	"database/sql"
      5 	"fmt"
      6 	"html/template"
      7 	"log"
      8 	"net/http"
      9 	"os"
     10 	"strings"
     11 
     12 	_ "github.com/mattn/go-sqlite3"
     13 )
     14 
     15 var (
     16 	db     *sql.DB
     17 	tmpl   *template.Template
     18 	config Config
     19 )
     20 
     21 func main() {
     22 	if err := loadConfig(); err != nil {
     23 		log.Fatalf("Failed to load config: %v", err)
     24 	}
     25 
     26 	var err error
     27 	db, err = sql.Open("sqlite3", config.DatabasePath)
     28 	if err != nil {
     29 		log.Fatal(err)
     30 	}
     31 	defer db.Close()
     32 
     33 	_, err = db.Exec(`
     34 	CREATE TABLE IF NOT EXISTS files (
     35 		id INTEGER PRIMARY KEY AUTOINCREMENT,
     36 		filename TEXT,
     37 		path TEXT,
     38 		description TEXT DEFAULT ''
     39 	);
     40 	CREATE TABLE IF NOT EXISTS categories (
     41 		id INTEGER PRIMARY KEY AUTOINCREMENT,
     42 		name TEXT UNIQUE
     43 	);
     44 	CREATE TABLE IF NOT EXISTS tags (
     45 		id INTEGER PRIMARY KEY AUTOINCREMENT,
     46 		category_id INTEGER,
     47 		value TEXT,
     48 		UNIQUE(category_id, value)
     49 	);
     50 	CREATE TABLE IF NOT EXISTS file_tags (
     51 		file_id INTEGER,
     52 		tag_id INTEGER,
     53 		UNIQUE(file_id, tag_id)
     54 	);
     55 	`)
     56 	if err != nil {
     57 		log.Fatal(err)
     58 	}
     59 
     60 	os.MkdirAll(config.UploadDir, 0755)
     61 	os.MkdirAll("static", 0755)
     62 
     63 	tmpl = template.Must(template.New("").Funcs(template.FuncMap{
     64 	    "add": func(a, b int) int { return a + b },
     65 	    "sub": func(a, b int) int { return a - b },
     66 		"hasAnySuffix": func(s string, suffixes ...string) bool {
     67 			for _, suf := range suffixes {
     68 				if strings.HasSuffix(strings.ToLower(s), suf) {
     69 					return true
     70 				}
     71 			}
     72 			return false
     73 		},
     74     "dict": func(values ...interface{}) (map[string]interface{}, error) {
     75         if len(values)%2 != 0 {
     76             return nil, fmt.Errorf("dict requires an even number of args")
     77         }
     78         dict := make(map[string]interface{}, len(values)/2)
     79         for i := 0; i < len(values); i += 2 {
     80             key, ok := values[i].(string)
     81             if !ok {
     82                 return nil, fmt.Errorf("dict keys must be strings")
     83             }
     84             dict[key] = values[i+1]
     85         }
     86         return dict, nil
     87     },
     88 	}).ParseGlob("templates/*.html"))
     89 
     90 	http.HandleFunc("/", listFilesHandler)
     91 	http.HandleFunc("/add", uploadHandler)
     92 	http.HandleFunc("/add-yt", ytdlpHandler)
     93 	http.HandleFunc("/upload-url", uploadFromURLHandler)
     94 	http.HandleFunc("/file/", fileRouter)
     95 	http.HandleFunc("/tags", tagsHandler)
     96 	http.HandleFunc("/tag/", tagFilterHandler)
     97 	http.HandleFunc("/untagged", untaggedFilesHandler)
     98 	http.HandleFunc("/search", searchHandler)
     99 	http.HandleFunc("/bulk-tag", bulkTagHandler)
    100 	http.HandleFunc("/admin", adminHandler)
    101 	http.HandleFunc("/thumbnails/generate", generateThumbnailHandler)
    102 	http.HandleFunc("/cbz/", cbzViewerHandler)
    103 
    104 	http.Handle("/uploads/", http.StripPrefix("/uploads/", http.FileServer(http.Dir(config.UploadDir))))
    105 	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
    106 
    107 	log.Printf("Server started at http://localhost%s", config.ServerPort)
    108 	log.Printf("Database: %s", config.DatabasePath)
    109 	log.Printf("Upload directory: %s", config.UploadDir)
    110 	http.ListenAndServe(config.ServerPort, nil)
    111 }