package images import ( "fmt" "os" "path/filepath" "strings" "write-server/internal/config" "write-server/internal/posts" ) type ImageFile struct { Name string `json:"name"` Path string `json:"path"` Folder string `json:"folder"` Size int64 `json:"size"` URL string `json:"url"` Slug string `json:"slug"` LocalURL string `json:"localUrl"` } var imageExts = map[string]bool{ ".png": true, ".jpg": true, ".jpeg": true, ".gif": true, ".webp": true, ".svg": true, ".bmp": true, } func ScanImages() []ImageFile { var images []ImageFile filepath.WalkDir(config.CONTENT_DIR, func(p string, d os.DirEntry, err error) error { if err != nil { return nil } if d.IsDir() { if strings.HasPrefix(d.Name(), ".") { return filepath.SkipDir } return nil } ext := strings.ToLower(filepath.Ext(d.Name())) if !imageExts[ext] { return nil } info, _ := d.Info() size := int64(0) if info != nil { size = info.Size() } rel, _ := filepath.Rel(config.CONTENT_DIR, p) rel = strings.ReplaceAll(rel, "\\", "/") dir := filepath.Dir(p) slug := "" indexPath := filepath.Join(dir, "index.md") if data, err := os.ReadFile(indexPath); err == nil { fm, _ := posts.ParseFrontMatter(string(data)) slug = fm.Slug } u := "/" + rel if slug != "" { u = "/" + slug + "/" + d.Name() } images = append(images, ImageFile{ Name: d.Name(), Path: rel, Folder: filepath.Dir(rel), Size: size, URL: u, Slug: slug, LocalURL: fmt.Sprintf("/api/images?file=%s", rel), }) return nil }) // Sort by size desc for i := 0; i < len(images); i++ { for j := i + 1; j < len(images); j++ { if images[j].Size > images[i].Size { images[i], images[j] = images[j], images[i] } } } return images } func DeleteImage(relPath string) error { fullPath := filepath.Join(config.CONTENT_DIR, relPath) if !strings.HasPrefix(filepath.Clean(fullPath), filepath.Clean(config.CONTENT_DIR)) { return fmt.Errorf("invalid path") } return os.Remove(fullPath) }