include-general.go (3276B)
1 package main 2 3 import ( 4 "log" 5 "net/http" 6 "net/url" 7 "strings" 8 ) 9 10 type TagDisplay struct { 11 Value string 12 Count int 13 } 14 15 type ListData struct { 16 Tagged []File 17 Untagged []File 18 Breadcrumbs []Breadcrumb 19 } 20 21 type PageData struct { 22 Title string 23 Data interface{} 24 Query string 25 IP string 26 Port string 27 Files []File 28 Tags map[string][]TagDisplay 29 Properties map[string][]PropertyDisplay 30 Breadcrumbs []Breadcrumb 31 Pagination *Pagination 32 GallerySize string 33 } 34 35 type File struct { 36 ID int 37 Filename string 38 EscapedFilename string 39 Path string 40 Description string 41 Tags map[string][]string 42 } 43 44 func sanitizeFilename(filename string) string { 45 if filename == "" { 46 return "file" 47 } 48 filename = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(filename, "/", "_"), "\\", "_"), "..", "_") 49 if filename == "" { 50 return "file" 51 } 52 return filename 53 } 54 55 func renderError(w http.ResponseWriter, message string, statusCode int) { 56 http.Error(w, message, statusCode) 57 } 58 59 func renderTemplate(w http.ResponseWriter, tmplName string, data PageData) { 60 if err := tmpl.ExecuteTemplate(w, tmplName, data); err != nil { 61 log.Printf("Error: renderTemplate: failed to execute template %s: %v", tmplName, err) 62 renderError(w, "Template rendering failed", http.StatusInternalServerError) 63 } 64 } 65 66 func redirectWithWarning(w http.ResponseWriter, r *http.Request, baseURL, warningMsg string) { 67 redirectURL := baseURL 68 if warningMsg != "" { 69 redirectURL += "?warning=" + url.QueryEscape(warningMsg) 70 } 71 http.Redirect(w, r, redirectURL, http.StatusSeeOther) 72 } 73 74 func errorString(err error) string { 75 if err != nil { 76 return err.Error() 77 } 78 return "" 79 } 80 81 func successString(err error, msg string) string { 82 if err == nil { 83 return msg 84 } 85 return "" 86 } 87 88 func buildPageData(title string, data interface{}) PageData { 89 tagMap, err := getTagData() 90 if err != nil { 91 log.Printf("Warning: buildPageData: failed to load tag data for page %q: %v", title, err) 92 } 93 propMap, err := getPropertyNav() 94 if err != nil { 95 log.Printf("Warning: buildPageData: failed to load property nav for page %q: %v", title, err) 96 } 97 return PageData{ 98 Title: title, 99 Data: data, 100 Tags: tagMap, 101 Properties: propMap, 102 GallerySize: config.GallerySize, 103 } 104 } 105 106 func getTagData() (map[string][]TagDisplay, error) { 107 rows, err := db.Query(` 108 SELECT c.name, t.value, COUNT(ft.file_id) 109 FROM tags t 110 JOIN categories c ON c.id = t.category_id 111 LEFT JOIN file_tags ft ON ft.tag_id = t.id 112 GROUP BY t.id 113 HAVING COUNT(ft.file_id) > 0 114 ORDER BY c.name, t.value`) 115 if err != nil { 116 return nil, err 117 } 118 defer rows.Close() 119 120 tagMap := make(map[string][]TagDisplay) 121 for rows.Next() { 122 var cat, val string 123 var count int 124 if err := rows.Scan(&cat, &val, &count); err != nil { 125 log.Printf("Warning: getTagData: failed to scan row: %v", err) 126 continue 127 } 128 tagMap[cat] = append(tagMap[cat], TagDisplay{Value: val, Count: count}) 129 } 130 if err := rows.Err(); err != nil { 131 return tagMap, err 132 } 133 return tagMap, nil 134 } 135 136 func tagsHandler(w http.ResponseWriter, r *http.Request) { 137 pageData := buildPageData("All Tags", nil) 138 pageData.Data = pageData.Tags 139 renderTemplate(w, "tags.html", pageData) 140 }