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 }