Files
PPve/banner.go
T
Tomáš Dvořák 8052d9a9ff Add files via upload
2025-05-26 13:16:23 +02:00

229 lines
5.8 KiB
Go

package main
import (
"encoding/json"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"path/filepath"
"strings"
"sync"
)
// Initialize banner data
func init() {
// Create data directory if it doesn't exist
if err := os.MkdirAll("data", 0755); err != nil {
log.Printf("Warning: Failed to create data directory: %v", err)
}
// Create uploads directory if it doesn't exist
if err := os.MkdirAll(uploadDir, 0755); err != nil {
log.Printf("Warning: Failed to create uploads directory: %v", err)
}
// Load banner data from file if it exists
if data, err := ioutil.ReadFile(bannerDataFile); err == nil {
if err := json.Unmarshal(data, &banner); err != nil {
log.Printf("Error loading banner data: %v", err)
initDefaultBanner()
}
} else {
initDefaultBanner()
}
}
const (
bannerDataFile = "data/banner.json"
uploadDir = "uploads"
)
// Ensure directories exist
func ensureDirs() error {
if err := os.MkdirAll(filepath.Dir(bannerDataFile), 0755); err != nil {
return err
}
if err := os.MkdirAll(uploadDir, 0755); err != nil {
return err
}
return nil
}
type BannerContent struct {
Text string `json:"text"`
Image string `json:"image,omitempty"`
Link string `json:"link,omitempty"`
Style BannerStyle `json:"style"`
}
type BannerStyle struct {
BackgroundColor string `json:"backgroundColor"`
TextColor string `json:"textColor"`
TextAlign string `json:"textAlign"`
FontSize string `json:"fontSize"`
Padding string `json:"padding"`
Margin string `json:"margin"`
BorderRadius string `json:"borderRadius"`
IsVisible bool `json:"isVisible"`
}
var (
banner BannerContent
bannerLock sync.RWMutex
)
func init() {
// Ensure directories exist
if err := ensureDirs(); err != nil {
log.Printf("Warning: Failed to create required directories: %v", err)
}
// Load banner data from file if it exists
if data, err := ioutil.ReadFile(bannerDataFile); err == nil {
if err := json.Unmarshal(data, &banner); err != nil {
log.Printf("Error loading banner data: %v", err)
initDefaultBanner()
}
} else {
initDefaultBanner()
}
}
func initDefaultBanner() {
banner = BannerContent{
Text: "Vítejte na našem webu!",
Style: BannerStyle{
BackgroundColor: "#f8d7da",
TextColor: "#721c24",
TextAlign: "center",
FontSize: "18px",
Padding: "20px",
Margin: "20px",
BorderRadius: "8px",
IsVisible: true,
},
}
saveBannerData()
}
func saveBannerData() error {
bannerLock.Lock()
defer bannerLock.Unlock()
data, err := json.MarshalIndent(banner, "", " ")
if err != nil {
return err
}
return ioutil.WriteFile(bannerDataFile, data, 0644)
}
func GetBannerHandler(w http.ResponseWriter, r *http.Request) {
bannerLock.RLock()
defer bannerLock.RUnlock()
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
json.NewEncoder(w).Encode(banner)
}
func UpdateBannerHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusOK)
return
}
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Content-Type", "application/json")
// Parse multipart form for file uploads
if err := r.ParseMultipartForm(10 << 20); err != nil { // 10 MB max
http.Error(w, "Error parsing form data", http.StatusBadRequest)
return
}
newBanner := BannerContent{
Text: r.FormValue("text"),
Link: r.FormValue("link"),
Style: BannerStyle{
BackgroundColor: r.FormValue("style[backgroundColor]"),
TextColor: r.FormValue("style[textColor]"),
TextAlign: r.FormValue("style[textAlign]"),
FontSize: r.FormValue("style[fontSize]"),
Padding: r.FormValue("style[padding]"),
Margin: r.FormValue("style[margin]"),
BorderRadius: r.FormValue("style[borderRadius]"),
IsVisible: r.FormValue("style[isVisible]") == "true",
},
}
// Handle file upload
file, handler, err := r.FormFile("image")
if err == nil {
defer file.Close()
// Ensure uploads directory exists
if err := ensureDirs(); err != nil {
http.Error(w, "Error preparing upload directory", http.StatusInternalServerError)
return
}
// Create a new file in the uploads directory with a unique name
ext := filepath.Ext(handler.Filename)
tempFile, err := ioutil.TempFile(uploadDir, "upload-*"+ext)
if err != nil {
http.Error(w, "Error creating file", http.StatusInternalServerError)
return
}
defer tempFile.Close()
// Copy the uploaded file to the destination file
if _, err := io.Copy(tempFile, file); err != nil {
http.Error(w, "Error saving file", http.StatusInternalServerError)
return
}
// Update banner data with the new image path
newBanner.Image = "/uploads/" + filepath.Base(tempFile.Name())
} else if r.FormValue("removeImage") == "true" {
// If removeImage is set, clear the image
newBanner.Image = ""
} else {
// Keep the existing image if no new one is uploaded
bannerLock.RLock()
newBanner.Image = banner.Image
bannerLock.RUnlock()
}
// Update banner data
bannerLock.Lock()
banner = newBanner
err = saveBannerData()
bannerLock.Unlock()
if err != nil {
http.Error(w, "Error saving banner data", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(banner)
}
// ServeUploads handles serving uploaded files
func ServeUploads(w http.ResponseWriter, r *http.Request) {
// Only serve files from the uploads directory
if !strings.HasPrefix(r.URL.Path, "/"+uploadDir+"/") {
http.NotFound(w, r)
return
}
// Strip the leading slash to get the relative path
http.ServeFile(w, r, r.URL.Path[1:])
}