77 lines
3.1 KiB
Go
77 lines
3.1 KiB
Go
// Package static سرویسدهیِ تصاویرِ کارت (هر اسکین یک پوشه) را انجام میدهد.
|
|
// دو منبع: ۱) پوشهی دیسکیِ ماندگار (diskDir) برای اسکینهایی که از پنل ادمین
|
|
// آپلود میشوند، ۲) فایلسیستمِ embedشده برای اسکینهای پیشفرض (simple/epic).
|
|
// ابتدا دیسک بررسی میشود، سپس embed؛ پس آپلودها بدونِ کامپایلِ دوباره سرو میشوند.
|
|
// مسیر: GET /cards/<skin>/<code>.png و /cards/<skin>/back.jpg
|
|
package static
|
|
|
|
import (
|
|
"embed"
|
|
"io/fs"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
//go:embed cards
|
|
var cardsFS embed.FS
|
|
|
|
//go:embed carpets
|
|
var carpetsFS embed.FS
|
|
|
|
// CardsHandler یک http.Handler برای سرویسدهیِ فایلهای کارت زیر /cards/ است.
|
|
// diskDir پوشهی اسکینهای آپلودی است (میتواند خالی/ناموجود باشد).
|
|
// CORS باز است تا نسخهٔ وب (Flutter web / canvaskit) هم بتواند تصاویر را بکشد.
|
|
func CardsHandler(diskDir string) http.Handler {
|
|
sub, err := fs.Sub(cardsFS, "cards")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
embedded := http.StripPrefix("/cards/", http.FileServer(http.FS(sub)))
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
w.Header().Set("Cache-Control", "public, max-age=604800") // یک هفته کش
|
|
|
|
// تلاشِ اول: پوشهی دیسکی (اسکینهای آپلودشده از پنل ادمین).
|
|
if diskDir != "" {
|
|
rel := strings.TrimPrefix(r.URL.Path, "/cards/")
|
|
rel = filepath.Clean("/" + rel) // جلوگیری از path traversal
|
|
full := filepath.Join(diskDir, rel)
|
|
if st, err := os.Stat(full); err == nil && !st.IsDir() {
|
|
http.ServeFile(w, r, full)
|
|
return
|
|
}
|
|
}
|
|
// تلاشِ دوم: اسکینهای embedشده (simple/epic).
|
|
embedded.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
|
|
// CarpetsHandler تصاویرِ فرش را سرو میکند: GET /carpets/<id>.jpg
|
|
// ابتدا از پوشهی دیسکی (آپلودِ ادمین)، سپس از فرشهای embedشدهی پیشفرض.
|
|
// اگر هیچکدام نبود ۴۰۴ (اپ به میزِ ترسیمیِ classic برمیگردد).
|
|
func CarpetsHandler(diskDir string) http.Handler {
|
|
sub, err := fs.Sub(carpetsFS, "carpets")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
embedded := http.StripPrefix("/carpets/", http.FileServer(http.FS(sub)))
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
w.Header().Set("Cache-Control", "public, max-age=604800")
|
|
// تلاشِ اول: پوشهی دیسکی (آپلودِ ادمین).
|
|
if diskDir != "" {
|
|
rel := filepath.Clean("/" + strings.TrimPrefix(r.URL.Path, "/carpets/"))
|
|
full := filepath.Join(diskDir, rel)
|
|
if st, err := os.Stat(full); err == nil && !st.IsDir() {
|
|
http.ServeFile(w, r, full)
|
|
return
|
|
}
|
|
}
|
|
// تلاشِ دوم: فرشهای embedشده.
|
|
embedded.ServeHTTP(w, r)
|
|
})
|
|
}
|