Files
1Panel/agent/utils/appicon/appicon.go
KOMATA fc5e583481 feat: implement app icon management and caching mechanism (#11719)
* feat: implement app icon management and caching mechanism

* feat: enhance app synchronization and icon management

- Refactored app synchronization tasks to improve structure and clarity.
- Introduced shared context for managing app sync state and metadata.
- Updated icon handling to ensure proper content type and caching.
- Adjusted cache control settings for app icons to extend cache duration.
- Improved error handling and logging during app sync processes.

* refactor: streamline app icon retrieval by removing unused fileName return

- Removed the fileName return value from GetAppIcon function as it was not utilized.
- Enhanced the GetAppIcon method in BaseApi to improve clarity and maintainability.
- Ensured proper caching headers are set for app icons.
2026-01-27 14:02:38 +08:00

94 lines
1.9 KiB
Go

package appicon
import (
"fmt"
"net/url"
"os"
"path"
"path/filepath"
"strings"
"github.com/1Panel-dev/1Panel/agent/global"
)
const IconPrefix = "app_"
func IsIconFile(icon string) bool {
return strings.HasPrefix(icon, IconPrefix)
}
func ParseIconField(icon string) (fileName, etag string) {
if !IsIconFile(icon) {
return "", ""
}
parts := strings.SplitN(icon, "?", 2)
fileName = parts[0]
if len(parts) == 2 {
values, err := url.ParseQuery(parts[1])
if err == nil {
etag = values.Get("etag")
}
}
return
}
func BuildIconField(fileName, etag string) string {
if etag == "" {
return fileName
}
return fmt.Sprintf("%s?etag=%s", fileName, url.QueryEscape(etag))
}
func GetIconFilePath(fileName string) string {
return path.Join(global.Dir.IconCacheDir, fileName)
}
func BuildIconFileName(appKey, ext string) string {
return fmt.Sprintf("%s%s.%s", IconPrefix, appKey, ext)
}
const ContentTypePNG = "image/png"
func WriteIconFile(appKey string, data []byte) (fileName string, err error) {
fileName = BuildIconFileName(appKey, "png")
filePath := GetIconFilePath(fileName)
_ = CleanOldIconFiles(appKey)
err = os.WriteFile(filePath, data, 0644)
return
}
func CleanOldIconFiles(appKey string) error {
pattern := path.Join(global.Dir.IconCacheDir, fmt.Sprintf("%s%s.*", IconPrefix, appKey))
matches, err := filepath.Glob(pattern)
if err != nil {
return err
}
keepFileName := BuildIconFileName(appKey, "png")
for _, match := range matches {
baseName := filepath.Base(match)
if baseName == keepFileName {
continue
}
_ = os.Remove(match)
}
return nil
}
func ReadIconFile(fileName string) ([]byte, error) {
filePath := GetIconFilePath(fileName)
return os.ReadFile(filePath)
}
func IconFileExists(fileName string) bool {
filePath := GetIconFilePath(fileName)
_, err := os.Stat(filePath)
return err == nil
}
func GetETagFromIconField(icon string) string {
_, etag := ParseIconField(icon)
return etag
}