| package types |
|
|
| import ( |
| "fmt" |
| "image" |
| "os" |
| "sync" |
| ) |
|
|
| |
| type FileSourceType string |
|
|
| const ( |
| FileSourceTypeURL FileSourceType = "url" |
| FileSourceTypeBase64 FileSourceType = "base64" |
| ) |
|
|
| |
| |
| type FileSource struct { |
| Type FileSourceType `json:"type"` |
| URL string `json:"url,omitempty"` |
| Base64Data string `json:"base64_data,omitempty"` |
| MimeType string `json:"mime_type,omitempty"` |
|
|
| |
| cachedData *CachedFileData |
| cacheLoaded bool |
| registered bool |
| mu sync.Mutex |
| } |
|
|
| |
| func (f *FileSource) Mu() *sync.Mutex { |
| return &f.mu |
| } |
|
|
| |
| |
| type CachedFileData struct { |
| base64Data string |
| MimeType string |
| Size int64 |
| DiskSize int64 |
| ImageConfig *image.Config |
| ImageFormat string |
|
|
| |
| diskPath string |
| isDisk bool |
| diskMu sync.Mutex |
| diskClosed bool |
| statDecremented bool |
|
|
| |
| OnClose func(size int64) |
| } |
|
|
| |
| func NewMemoryCachedData(base64Data string, mimeType string, size int64) *CachedFileData { |
| return &CachedFileData{ |
| base64Data: base64Data, |
| MimeType: mimeType, |
| Size: size, |
| isDisk: false, |
| } |
| } |
|
|
| |
| func NewDiskCachedData(diskPath string, mimeType string, size int64) *CachedFileData { |
| return &CachedFileData{ |
| diskPath: diskPath, |
| MimeType: mimeType, |
| Size: size, |
| isDisk: true, |
| } |
| } |
|
|
| |
| func (c *CachedFileData) GetBase64Data() (string, error) { |
| if !c.isDisk { |
| return c.base64Data, nil |
| } |
|
|
| c.diskMu.Lock() |
| defer c.diskMu.Unlock() |
|
|
| if c.diskClosed { |
| return "", fmt.Errorf("disk cache already closed") |
| } |
|
|
| |
| data, err := os.ReadFile(c.diskPath) |
| if err != nil { |
| return "", fmt.Errorf("failed to read from disk cache: %w", err) |
| } |
| return string(data), nil |
| } |
|
|
| |
| func (c *CachedFileData) SetBase64Data(data string) { |
| if !c.isDisk { |
| c.base64Data = data |
| } |
| } |
|
|
| |
| func (c *CachedFileData) IsDisk() bool { |
| return c.isDisk |
| } |
|
|
| |
| func (c *CachedFileData) Close() error { |
| if !c.isDisk { |
| c.base64Data = "" |
| return nil |
| } |
|
|
| c.diskMu.Lock() |
| defer c.diskMu.Unlock() |
|
|
| if c.diskClosed { |
| return nil |
| } |
|
|
| c.diskClosed = true |
| if c.diskPath != "" { |
| err := os.Remove(c.diskPath) |
| |
| if err == nil && !c.statDecremented && c.OnClose != nil { |
| c.OnClose(c.DiskSize) |
| c.statDecremented = true |
| } |
| return err |
| } |
| return nil |
| } |
|
|
| |
| func NewURLFileSource(url string) *FileSource { |
| return &FileSource{ |
| Type: FileSourceTypeURL, |
| URL: url, |
| } |
| } |
|
|
| |
| func NewBase64FileSource(base64Data string, mimeType string) *FileSource { |
| return &FileSource{ |
| Type: FileSourceTypeBase64, |
| Base64Data: base64Data, |
| MimeType: mimeType, |
| } |
| } |
|
|
| |
| func (f *FileSource) IsURL() bool { |
| return f.Type == FileSourceTypeURL |
| } |
|
|
| |
| func (f *FileSource) IsBase64() bool { |
| return f.Type == FileSourceTypeBase64 |
| } |
|
|
| |
| func (f *FileSource) GetIdentifier() string { |
| if f.IsURL() { |
| if len(f.URL) > 100 { |
| return f.URL[:100] + "..." |
| } |
| return f.URL |
| } |
| if len(f.Base64Data) > 50 { |
| return "base64:" + f.Base64Data[:50] + "..." |
| } |
| return "base64:" + f.Base64Data |
| } |
|
|
| |
| func (f *FileSource) GetRawData() string { |
| if f.IsURL() { |
| return f.URL |
| } |
| return f.Base64Data |
| } |
|
|
| |
| func (f *FileSource) SetCache(data *CachedFileData) { |
| f.cachedData = data |
| f.cacheLoaded = true |
| } |
|
|
| |
| func (f *FileSource) IsRegistered() bool { |
| return f.registered |
| } |
|
|
| |
| func (f *FileSource) SetRegistered(registered bool) { |
| f.registered = registered |
| } |
|
|
| |
| func (f *FileSource) GetCache() *CachedFileData { |
| return f.cachedData |
| } |
|
|
| |
| func (f *FileSource) HasCache() bool { |
| return f.cacheLoaded && f.cachedData != nil |
| } |
|
|
| |
| func (f *FileSource) ClearCache() { |
| |
| if f.cachedData != nil { |
| f.cachedData.Close() |
| } |
| f.cachedData = nil |
| f.cacheLoaded = false |
| } |
|
|
| |
| |
| func (f *FileSource) ClearRawData() { |
| |
| if f.IsBase64() && len(f.Base64Data) > 1024 { |
| f.Base64Data = "" |
| } |
| } |
|
|