mirror of
https://github.com/Dvorinka/PPve.git
synced 2026-06-05 04:52:58 +00:00
Add files via upload
This commit is contained in:
@@ -2,82 +2,121 @@ 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"`
|
||||
FontSize string `json:"fontSize"`
|
||||
TextAlign string `json:"textAlign"`
|
||||
FontSize string `json:"fontSize"`
|
||||
Padding string `json:"padding"`
|
||||
Margin string `json:"margin"`
|
||||
BorderRadius string `json:"borderRadius"`
|
||||
IsVisible bool `json:"isVisible"`
|
||||
}
|
||||
|
||||
type BannerContent struct {
|
||||
Text string `json:"text"`
|
||||
Image string `json:"image,omitempty"`
|
||||
Link string `json:"link,omitempty"`
|
||||
Style BannerStyle `json:"style"`
|
||||
}
|
||||
|
||||
var (
|
||||
banner BannerContent
|
||||
bannerLock sync.RWMutex
|
||||
bannerFile = "banner.json"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Initialize with default values
|
||||
// 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: "Důležité oznámení: Tento banner lze upravit v administraci.",
|
||||
Text: "Vítejte na našem webu!",
|
||||
Style: BannerStyle{
|
||||
BackgroundColor: "#f8d7da",
|
||||
TextColor: "#721c24",
|
||||
FontSize: "16px",
|
||||
TextAlign: "center",
|
||||
Padding: "10px",
|
||||
FontSize: "18px",
|
||||
Padding: "20px",
|
||||
Margin: "20px",
|
||||
BorderRadius: "8px",
|
||||
IsVisible: true,
|
||||
},
|
||||
}
|
||||
loadBanner()
|
||||
saveBannerData()
|
||||
}
|
||||
|
||||
func loadBanner() {
|
||||
if _, err := os.Stat(bannerFile); os.IsNotExist(err) {
|
||||
saveBanner()
|
||||
return
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(bannerFile)
|
||||
if err != nil {
|
||||
log.Printf("Error reading banner file: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
func saveBannerData() error {
|
||||
bannerLock.Lock()
|
||||
defer bannerLock.Unlock()
|
||||
|
||||
if err := json.Unmarshal(data, &banner); err != nil {
|
||||
log.Printf("Error parsing banner data: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func saveBanner() error {
|
||||
bannerLock.RLock()
|
||||
defer bannerLock.RUnlock()
|
||||
|
||||
data, err := json.MarshalIndent(banner, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.WriteFile(bannerFile, data, 0644)
|
||||
return ioutil.WriteFile(bannerDataFile, data, 0644)
|
||||
}
|
||||
|
||||
func GetBannerHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -85,31 +124,105 @@ func GetBannerHandler(w http.ResponseWriter, r *http.Request) {
|
||||
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
|
||||
}
|
||||
|
||||
var newBanner BannerContent
|
||||
if err := json.NewDecoder(r.Body).Decode(&newBanner); err != nil {
|
||||
http.Error(w, "Invalid request body", http.StatusBadRequest)
|
||||
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 := saveBanner()
|
||||
err = saveBannerData()
|
||||
bannerLock.Unlock()
|
||||
|
||||
if err != nil {
|
||||
http.Error(w, "Error saving banner", http.StatusInternalServerError)
|
||||
http.Error(w, "Error saving banner data", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]string{"status": "success"})
|
||||
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:])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user