diff --git a/cmd/root.go b/cmd/root.go
index 0a04b4e..4561b21 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -12,7 +12,7 @@ import (
)
const (
- ReleaseVersion string = "0.73.1"
+ ReleaseVersion string = "0.74.0"
)
var (
diff --git a/cmd/web.go b/cmd/web.go
index 93ca041..03e02c0 100644
--- a/cmd/web.go
+++ b/cmd/web.go
@@ -313,27 +313,27 @@ func ServePage(args []string) error {
formats := &types.Types{
Extensions: make(map[string]string),
- MimeTypes: make(map[string]*types.Type),
+ MimeTypes: make(map[string]types.Type),
}
if Audio || All {
- formats.Add(types.RegisterAudio())
+ formats.Add(types.Audio{})
}
if Flash || All {
- formats.Add(types.RegisterFlash())
+ formats.Add(types.Flash{})
}
if Images || All {
- formats.Add(types.RegisterImages())
+ formats.Add(types.Images{})
}
if Text || All {
- formats.Add(types.RegisterText())
+ formats.Add(types.Text{})
}
if Videos || All {
- formats.Add(types.RegisterVideos())
+ formats.Add(types.Video{})
}
paths, err := normalizePaths(args, formats)
diff --git a/types/audio.go b/types/audio.go
index bfe6671..8b3fdd2 100644
--- a/types/audio.go
+++ b/types/audio.go
@@ -9,41 +9,48 @@ import (
"strings"
)
-func RegisterAudio() *Type {
- return &Type{
- Css: func() string {
- var css strings.Builder
+type Audio struct{}
- css.WriteString(`html,body{margin:0;padding:0;height:100%;}`)
- css.WriteString(`a{color:inherit;display:block;height:100%;width:100%;text-decoration:none;}`)
+func (t Audio) Css() string {
+ var css strings.Builder
- return css.String()
- },
- Title: func(queryParams, fileUri, filePath, fileName, mime string) string {
- return fmt.Sprintf(`
%s`, fileName)
- },
- Body: func(queryParams, fileUri, filePath, fileName, mime string) string {
- return fmt.Sprintf(``,
- queryParams,
- fileUri,
- mime,
- fileName)
- },
- Extensions: map[string]string{
- `.mp3`: `audio/mpeg`,
- `.ogg`: `audio/ogg`,
- `.oga`: `audio/ogg`,
- },
- MimeTypes: []string{
- `application/ogg`,
- `audio/mp3`,
- `audio/mpeg`,
- `audio/mpeg3`,
- `audio/ogg`,
- `audio/x-mpeg-3`,
- },
- Validate: func(filePath string) bool {
- return true
- },
+ css.WriteString(`html,body{margin:0;padding:0;height:100%;}`)
+ css.WriteString(`a{color:inherit;display:block;height:100%;width:100%;text-decoration:none;}`)
+
+ return css.String()
+}
+
+func (t Audio) Title(queryParams, fileUri, filePath, fileName, mime string) string {
+ return fmt.Sprintf(`%s`, fileName)
+}
+
+func (t Audio) Body(queryParams, fileUri, filePath, fileName, mime string) string {
+ return fmt.Sprintf(``,
+ queryParams,
+ fileUri,
+ mime,
+ fileName)
+}
+
+func (t Audio) Extensions() map[string]string {
+ return map[string]string{
+ `.mp3`: `audio/mpeg`,
+ `.ogg`: `audio/ogg`,
+ `.oga`: `audio/ogg`,
}
}
+
+func (t Audio) MimeTypes() []string {
+ return []string{
+ `application/ogg`,
+ `audio/mp3`,
+ `audio/mpeg`,
+ `audio/mpeg3`,
+ `audio/ogg`,
+ `audio/x-mpeg-3`,
+ }
+}
+
+func (t Audio) Validate(filePath string) bool {
+ return true
+}
diff --git a/types/flash.go b/types/flash.go
index ca38ecc..31a2eaa 100644
--- a/types/flash.go
+++ b/types/flash.go
@@ -9,35 +9,42 @@ import (
"strings"
)
-func RegisterFlash() *Type {
- return &Type{
- Css: func() string {
- var css strings.Builder
+type Flash struct{}
- css.WriteString(`html,body{margin:0;padding:0;height:100%;}`)
- css.WriteString(`a{color:inherit;display:block;height:100%;width:100%;text-decoration:none;}`)
+func (t Flash) Css() string {
+ var css strings.Builder
- return css.String()
- },
- Title: func(queryParams, fileUri, filePath, fileName, mime string) string {
- return fmt.Sprintf(`%s`, fileName)
- },
- Body: func(queryParams, fileUri, filePath, fileName, mime string) string {
- var html strings.Builder
+ css.WriteString(`html,body{margin:0;padding:0;height:100%;}`)
+ css.WriteString(`a{color:inherit;display:block;height:100%;width:100%;text-decoration:none;}`)
- html.WriteString(fmt.Sprintf(``, fileUri))
- html.WriteString(fmt.Sprintf(`
`, queryParams))
+ return css.String()
+}
- return html.String()
- },
- Extensions: map[string]string{
- `.swf`: `application/x-shockwave-flash`,
- },
- MimeTypes: []string{
- `application/x-shockwave-flash`,
- },
- Validate: func(filePath string) bool {
- return true
- },
+func (t Flash) Title(queryParams, fileUri, filePath, fileName, mime string) string {
+ return fmt.Sprintf(`%s`, fileName)
+}
+
+func (t Flash) Body(queryParams, fileUri, filePath, fileName, mime string) string {
+ var html strings.Builder
+
+ html.WriteString(fmt.Sprintf(``, fileUri))
+ html.WriteString(fmt.Sprintf(`
`, queryParams))
+
+ return html.String()
+}
+
+func (t Flash) Extensions() map[string]string {
+ return map[string]string{
+ `.swf`: `application/x-shockwave-flash`,
}
}
+
+func (t Flash) MimeTypes() []string {
+ return []string{
+ `application/x-shockwave-flash`,
+ }
+}
+
+func (t Flash) Validate(filePath string) bool {
+ return true
+}
diff --git a/types/images.go b/types/images.go
index 9f75870..8ee0041 100644
--- a/types/images.go
+++ b/types/images.go
@@ -23,71 +23,78 @@ type Dimensions struct {
Height int
}
-func RegisterImages() *Type {
- return &Type{
- Css: func() string {
- var css strings.Builder
+type Images struct{}
- css.WriteString(`html,body{margin:0;padding:0;height:100%;}`)
- css.WriteString(`a{color:inherit;display:block;height:100%;width:100%;text-decoration:none;}`)
- css.WriteString(`img{margin:auto;display:block;max-width:97%;max-height:97%;`)
- css.WriteString(`object-fit:scale-down;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);}`)
+func (t Images) Css() string {
+ var css strings.Builder
- return css.String()
- },
- Title: func(queryParams, fileUri, filePath, fileName, mime string) string {
- dimensions, err := ImageDimensions(filePath)
- if err != nil {
- fmt.Println(err)
- }
+ css.WriteString(`html,body{margin:0;padding:0;height:100%;}`)
+ css.WriteString(`a{color:inherit;display:block;height:100%;width:100%;text-decoration:none;}`)
+ css.WriteString(`img{margin:auto;display:block;max-width:97%;max-height:97%;`)
+ css.WriteString(`object-fit:scale-down;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);}`)
- return fmt.Sprintf(`%s (%dx%d)`,
- fileName,
- dimensions.Width,
- dimensions.Height)
- },
- Body: func(queryParams, fileUri, filePath, fileName, mime string) string {
- dimensions, err := ImageDimensions(filePath)
- if err != nil {
- fmt.Println(err)
- }
+ return css.String()
+}
- return fmt.Sprintf(``,
- queryParams,
- fileUri,
- dimensions.Width,
- dimensions.Height,
- mime,
- fileName)
- },
- Extensions: map[string]string{
- `.apng`: `image/apng`,
- `.avif`: `image/avif`,
- `.bmp`: `image/bmp`,
- `.gif`: `image/gif`,
- `.jpg`: `image/jpeg`,
- `.jpeg`: `image/jpeg`,
- `.jfif`: `image/jpeg`,
- `.pjp`: `image/jpeg`,
- `.pjpeg`: `image/jpeg`,
- `.png`: `image/png`,
- `.svg`: `image/svg+xml`,
- `.webp`: `image/webp`,
- },
- MimeTypes: []string{
- `image/apng`,
- `image/avif`,
- `image/bmp`,
- `image/gif`,
- `image/jpeg`,
- `image/png`,
- `image/svg+xml`,
- `image/webp`,
- },
- Validate: func(filePath string) bool {
- return true
- },
+func (t Images) Title(queryParams, fileUri, filePath, fileName, mime string) string {
+ dimensions, err := ImageDimensions(filePath)
+ if err != nil {
+ fmt.Println(err)
}
+
+ return fmt.Sprintf(`%s (%dx%d)`,
+ fileName,
+ dimensions.Width,
+ dimensions.Height)
+}
+
+func (t Images) Body(queryParams, fileUri, filePath, fileName, mime string) string {
+ dimensions, err := ImageDimensions(filePath)
+ if err != nil {
+ fmt.Println(err)
+ }
+
+ return fmt.Sprintf(``,
+ queryParams,
+ fileUri,
+ dimensions.Width,
+ dimensions.Height,
+ mime,
+ fileName)
+}
+
+func (t Images) Extensions() map[string]string {
+ return map[string]string{
+ `.apng`: `image/apng`,
+ `.avif`: `image/avif`,
+ `.bmp`: `image/bmp`,
+ `.gif`: `image/gif`,
+ `.jpg`: `image/jpeg`,
+ `.jpeg`: `image/jpeg`,
+ `.jfif`: `image/jpeg`,
+ `.pjp`: `image/jpeg`,
+ `.pjpeg`: `image/jpeg`,
+ `.png`: `image/png`,
+ `.svg`: `image/svg+xml`,
+ `.webp`: `image/webp`,
+ }
+}
+
+func (t Images) MimeTypes() []string {
+ return []string{
+ `image/apng`,
+ `image/avif`,
+ `image/bmp`,
+ `image/gif`,
+ `image/jpeg`,
+ `image/png`,
+ `image/svg+xml`,
+ `image/webp`,
+ }
+}
+
+func (t Images) Validate(filePath string) bool {
+ return true
}
func ImageDimensions(path string) (*Dimensions, error) {
diff --git a/types/text.go b/types/text.go
index 75b6e9c..e5c3fec 100644
--- a/types/text.go
+++ b/types/text.go
@@ -12,64 +12,71 @@ import (
"unicode/utf8"
)
-func RegisterText() *Type {
- return &Type{
- Css: func() string {
- var css strings.Builder
+type Text struct{}
- css.WriteString(`html,body{margin:0;padding:0;height:100%;}`)
- css.WriteString(`a{color:inherit;display:block;height:100%;width:100%;text-decoration:none;overflow:hidden;}`)
- css.WriteString(`textarea{border:none;caret-color:transparent;outline:none;margin:.5rem;`)
- css.WriteString(`height:99%;width:99%;white-space:pre;overflow:auto;}`)
+func (t Text) Css() string {
+ var css strings.Builder
- return css.String()
- },
- Title: func(queryParams, fileUri, filePath, fileName, mime string) string {
- return fmt.Sprintf(`%s`, fileName)
- },
- Body: func(queryParams, fileUri, filePath, fileName, mime string) string {
- body, err := os.ReadFile(filePath)
- if err != nil {
- body = []byte{}
- }
+ css.WriteString(`html,body{margin:0;padding:0;height:100%;}`)
+ css.WriteString(`a{color:inherit;display:block;height:100%;width:100%;text-decoration:none;overflow:hidden;}`)
+ css.WriteString(`textarea{border:none;caret-color:transparent;outline:none;margin:.5rem;`)
+ css.WriteString(`height:99%;width:99%;white-space:pre;overflow:auto;}`)
- return fmt.Sprintf(``,
- queryParams,
- body)
- },
- Extensions: map[string]string{
- `.css`: `text/css`,
- `.csv`: `text/csv`,
- `.html`: `text/html`,
- `.js`: `text/javascript`,
- `.json`: `application/json`,
- `.md`: `text/markdown`,
- `.txt`: `text/plain`,
- `.xml`: `application/xml`,
- },
- MimeTypes: []string{
- `application/json`,
- `application/xml`,
- `text/css`,
- `text/csv`,
- `text/javascript`,
- `text/plain`,
- `text/plain; charset=utf-8`,
- },
- Validate: func(path string) bool {
- file, err := os.Open(path)
- switch {
- case errors.Is(err, os.ErrNotExist):
- return false
- case err != nil:
- return false
- }
- defer file.Close()
+ return css.String()
+}
- head := make([]byte, 512)
- file.Read(head)
+func (t Text) Title(queryParams, fileUri, filePath, fileName, mime string) string {
+ return fmt.Sprintf(`%s`, fileName)
+}
- return utf8.Valid(head)
- },
+func (t Text) Body(queryParams, fileUri, filePath, fileName, mime string) string {
+ body, err := os.ReadFile(filePath)
+ if err != nil {
+ body = []byte{}
+ }
+
+ return fmt.Sprintf(``,
+ queryParams,
+ body)
+}
+
+func (t Text) Extensions() map[string]string {
+ return map[string]string{
+ `.css`: `text/css`,
+ `.csv`: `text/csv`,
+ `.html`: `text/html`,
+ `.js`: `text/javascript`,
+ `.json`: `application/json`,
+ `.md`: `text/markdown`,
+ `.txt`: `text/plain`,
+ `.xml`: `application/xml`,
}
}
+
+func (t Text) MimeTypes() []string {
+ return []string{
+ `application/json`,
+ `application/xml`,
+ `text/css`,
+ `text/csv`,
+ `text/javascript`,
+ `text/plain`,
+ `text/plain; charset=utf-8`,
+ }
+}
+
+func (t Text) Validate(filePath string) bool {
+ file, err := os.Open(filePath)
+ switch {
+ case errors.Is(err, os.ErrNotExist):
+ return false
+ case err != nil:
+ return false
+ }
+ defer file.Close()
+
+ head := make([]byte, 512)
+ file.Read(head)
+
+ return utf8.Valid(head)
+}
diff --git a/types/types.go b/types/types.go
index bad02b4..5e3e3da 100644
--- a/types/types.go
+++ b/types/types.go
@@ -11,29 +11,29 @@ import (
"path/filepath"
)
-type Type struct {
- Css func() string
- Title func(queryParams, fileUri, filePath, fileName, mime string) string
- Body func(queryParams, fileUri, filePath, fileName, mime string) string
- Extensions map[string]string
- MimeTypes []string
- Validate func(filePath string) bool
+type Type interface {
+ Css() string
+ Title(queryParams, fileUri, filePath, fileName, mime string) string
+ Body(queryParams, fileUri, filePath, fileName, mime string) string
+ Extensions() map[string]string
+ MimeTypes() []string
+ Validate(filePath string) bool
}
type Types struct {
Extensions map[string]string
- MimeTypes map[string]*Type
+ MimeTypes map[string]Type
}
-func (s *Types) Add(t *Type) {
- for k, v := range t.Extensions {
+func (s *Types) Add(t Type) {
+ for k, v := range t.Extensions() {
_, exists := s.Extensions[k]
if !exists {
s.Extensions[k] = v
}
}
- for _, v := range t.MimeTypes {
+ for _, v := range t.MimeTypes() {
_, exists := s.Extensions[v]
if !exists {
s.MimeTypes[v] = t
@@ -41,7 +41,7 @@ func (s *Types) Add(t *Type) {
}
}
-func FileType(path string, registeredFormats *Types) (bool, *Type, string, error) {
+func FileType(path string, registeredFormats *Types) (bool, Type, string, error) {
file, err := os.Open(path)
switch {
case errors.Is(err, os.ErrNotExist):
diff --git a/types/video.go b/types/video.go
index c27c155..b870f54 100644
--- a/types/video.go
+++ b/types/video.go
@@ -9,41 +9,48 @@ import (
"strings"
)
-func RegisterVideos() *Type {
- return &Type{
- Css: func() string {
- var css strings.Builder
+type Video struct{}
- css.WriteString(`html,body{margin:0;padding:0;height:100%;}`)
- css.WriteString(`a{color:inherit;display:block;height:100%;width:100%;text-decoration:none;}`)
- css.WriteString(`video{margin:auto;display:block;max-width:97%;max-height:97%;`)
- css.WriteString(`object-fit:scale-down;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);}`)
+func (t Video) Css() string {
+ var css strings.Builder
- return css.String()
- },
- Title: func(queryParams, fileUri, filePath, fileName, mime string) string {
- return fmt.Sprintf(`%s`, fileName)
- },
- Body: func(queryParams, fileUri, filePath, fileName, mime string) string {
- return fmt.Sprintf(``,
- queryParams,
- fileUri,
- mime,
- fileName)
- },
- Extensions: map[string]string{
- `.mp4`: `video/mp4`,
- `.ogm`: `video/ogg`,
- `.ogv`: `video/ogg`,
- `.webm`: `video/webm`,
- },
- MimeTypes: []string{
- `video/mp4`,
- `video/ogg`,
- `video/webm`,
- },
- Validate: func(filePath string) bool {
- return true
- },
+ css.WriteString(`html,body{margin:0;padding:0;height:100%;}`)
+ css.WriteString(`a{color:inherit;display:block;height:100%;width:100%;text-decoration:none;}`)
+ css.WriteString(`video{margin:auto;display:block;max-width:97%;max-height:97%;`)
+ css.WriteString(`object-fit:scale-down;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);}`)
+
+ return css.String()
+}
+
+func (t Video) Title(queryParams, fileUri, filePath, fileName, mime string) string {
+ return fmt.Sprintf(`%s`, fileName)
+}
+
+func (t Video) Body(queryParams, fileUri, filePath, fileName, mime string) string {
+ return fmt.Sprintf(``,
+ queryParams,
+ fileUri,
+ mime,
+ fileName)
+}
+
+func (t Video) Extensions() map[string]string {
+ return map[string]string{
+ `.mp4`: `video/mp4`,
+ `.ogm`: `video/ogg`,
+ `.ogv`: `video/ogg`,
+ `.webm`: `video/webm`,
}
}
+
+func (t Video) MimeTypes() []string {
+ return []string{
+ `video/mp4`,
+ `video/ogg`,
+ `video/webm`,
+ }
+}
+
+func (t Video) Validate(filePath string) bool {
+ return true
+}