🏷️ Improved Resource domain creation and usage

This commit is contained in:
Maxim Lebedev 2023-11-10 09:06:16 +06:00
parent 9a18b8c56f
commit d2a7e3beb5
Signed by: toby3d
GPG Key ID: 1F14E25B7C119FC5
1 changed files with 90 additions and 32 deletions

View File

@ -1,52 +1,110 @@
package domain
import (
"bytes"
"image"
_ "image/gif"
_ "image/jpeg"
_ "image/png"
"io"
"mime"
"path/filepath"
"strings"
"path"
"time"
_ "golang.org/x/image/bmp"
_ "golang.org/x/image/webp"
)
type Resource struct {
Path string
Updated time.Time
Content []byte
// Only for graphics
Width int
Height int
modTime time.Time
reader io.ReadSeeker
params map[string]any // TODO(toby3d): set from Page configuration
mediaType MediaType
key string
name string // TODO(toby3d): set from Page configuration
title string // TODO(toby3d): set from Page configuration
resourceType ResourceType
image image.Config
}
// LogicalName returns full file name without directory path.
func (f Resource) LogicalName() string {
return filepath.Base(f.Path)
}
// BaseFileName returns file name without extention and directory path.
func (f Resource) BaseFileName() string {
base := filepath.Base(f.Path)
return strings.TrimSuffix(base, filepath.Ext(base))
}
// Ext returns file extention.
func (f Resource) Ext() string {
if ext := filepath.Ext(f.Path); len(ext) > 1 {
return ext[1:]
func NewResource(modTime time.Time, content []byte, key string) *Resource {
mediaType, _, _ := mime.ParseMediaType(mime.TypeByExtension(path.Ext(key)))
out := &Resource{
modTime: modTime,
key: key,
name: key, // TODO(toby3d): set from Page configuration
title: "", // TODO(toby3d): set from Page configuration
params: make(map[string]any), // TODO(toby3d): set from Page configuration
mediaType: NewMediaType(mediaType),
reader: bytes.NewReader(content),
}
return ""
switch path.Ext(key) {
default:
out.resourceType, _ = ParseResourceType(out.mediaType.mainType)
case ".md":
out.resourceType = ResourceTypePage
case ".webmanifest":
out.resourceType = ResourceTypeText
}
switch out.resourceType {
case ResourceTypeImage:
out.image, _, _ = image.DecodeConfig(out.reader)
}
return out
}
// Dir returns file directory.
func (f Resource) Dir() string {
return filepath.Dir(f.Path)
func (r Resource) Key() string {
return r.key
}
func (f Resource) MediaType() string {
return mime.TypeByExtension(filepath.Ext(f.Path))
func (r Resource) Name() string {
return r.name
}
func (r Resource) MediaType() MediaType {
return r.mediaType
}
// Width returns width if current r is an image.
func (r Resource) Width() int {
return r.image.Width
}
// Height returns height if current r is an image.
func (r Resource) Height() int {
return r.image.Height
}
func (r Resource) ResourceType() ResourceType {
return r.resourceType
}
func (r Resource) Content() []byte {
content, _ := io.ReadAll(r.reader)
return content
}
func (r Resource) Read(p []byte) (int, error) {
return r.reader.Read(p)
}
func (r Resource) Seek(offset int64, whence int) (int64, error) {
return r.reader.Seek(offset, whence)
}
func (f Resource) GoString() string {
return "domain.Resource(" + f.Path + ")"
return "domain.Resource(" + f.key + ")"
}
// ResourceModTime used in http.ServeContent to get modtime of this resource.
func ResourceModTime(r *Resource) time.Time {
if r == nil {
return time.Time{}
}
return r.modTime
}