2020-09-27 19:24:08 +00:00
|
|
|
package filesystem
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
2020-11-29 21:20:24 +00:00
|
|
|
"strconv"
|
2020-09-27 19:24:08 +00:00
|
|
|
"time"
|
2021-01-16 20:03:55 +00:00
|
|
|
|
|
|
|
"github.com/gabriel-vasile/mimetype"
|
2022-01-23 20:17:40 +00:00
|
|
|
"github.com/goccy/go-json"
|
2020-09-27 19:24:08 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Stat struct {
|
2021-01-16 20:03:55 +00:00
|
|
|
os.FileInfo
|
2020-09-27 19:24:08 +00:00
|
|
|
Mimetype string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Stat) MarshalJSON() ([]byte, error) {
|
|
|
|
return json.Marshal(struct {
|
|
|
|
Name string `json:"name"`
|
|
|
|
Created string `json:"created"`
|
|
|
|
Modified string `json:"modified"`
|
|
|
|
Mode string `json:"mode"`
|
2020-11-29 21:20:24 +00:00
|
|
|
ModeBits string `json:"mode_bits"`
|
2020-09-27 19:24:08 +00:00
|
|
|
Size int64 `json:"size"`
|
|
|
|
Directory bool `json:"directory"`
|
|
|
|
File bool `json:"file"`
|
|
|
|
Symlink bool `json:"symlink"`
|
|
|
|
Mime string `json:"mime"`
|
|
|
|
}{
|
2021-01-16 20:03:55 +00:00
|
|
|
Name: s.Name(),
|
2020-11-29 23:13:07 +00:00
|
|
|
Created: s.CTime().Format(time.RFC3339),
|
2021-01-16 20:03:55 +00:00
|
|
|
Modified: s.ModTime().Format(time.RFC3339),
|
|
|
|
Mode: s.Mode().String(),
|
2020-11-29 23:13:07 +00:00
|
|
|
// Using `&os.ModePerm` on the file's mode will cause the mode to only have the permission values, and nothing else.
|
2021-01-16 20:03:55 +00:00
|
|
|
ModeBits: strconv.FormatUint(uint64(s.Mode()&os.ModePerm), 8),
|
|
|
|
Size: s.Size(),
|
|
|
|
Directory: s.IsDir(),
|
|
|
|
File: !s.IsDir(),
|
|
|
|
Symlink: s.Mode().Perm()&os.ModeSymlink != 0,
|
2020-09-27 19:24:08 +00:00
|
|
|
Mime: s.Mimetype,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-01-16 20:03:55 +00:00
|
|
|
// Stat stats a file or folder and returns the base stat object from go along
|
|
|
|
// with the MIME data that can be used for editing files.
|
|
|
|
func (fs *Filesystem) Stat(p string) (Stat, error) {
|
2020-09-27 19:24:08 +00:00
|
|
|
cleaned, err := fs.SafePath(p)
|
|
|
|
if err != nil {
|
2021-01-16 20:03:55 +00:00
|
|
|
return Stat{}, err
|
2020-09-27 19:24:08 +00:00
|
|
|
}
|
|
|
|
return fs.unsafeStat(cleaned)
|
|
|
|
}
|
|
|
|
|
2021-01-16 20:03:55 +00:00
|
|
|
func (fs *Filesystem) unsafeStat(p string) (Stat, error) {
|
2020-09-27 19:24:08 +00:00
|
|
|
s, err := os.Stat(p)
|
|
|
|
if err != nil {
|
2021-01-16 20:03:55 +00:00
|
|
|
return Stat{}, err
|
2020-09-27 19:24:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var m *mimetype.MIME
|
|
|
|
if !s.IsDir() {
|
|
|
|
m, err = mimetype.DetectFile(p)
|
|
|
|
if err != nil {
|
2021-01-16 20:03:55 +00:00
|
|
|
return Stat{}, err
|
2020-09-27 19:24:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-16 20:03:55 +00:00
|
|
|
st := Stat{
|
|
|
|
FileInfo: s,
|
2020-09-27 19:24:08 +00:00
|
|
|
Mimetype: "inode/directory",
|
|
|
|
}
|
|
|
|
if m != nil {
|
|
|
|
st.Mimetype = m.String()
|
|
|
|
}
|
|
|
|
|
|
|
|
return st, nil
|
|
|
|
}
|