filebrowser/file/info.go

141 lines
3.0 KiB
Go
Raw Normal View History

2016-10-18 20:49:46 +00:00
package file
2016-10-18 20:06:31 +00:00
import (
"io/ioutil"
"net/http"
"net/url"
"os"
"path/filepath"
"strings"
humanize "github.com/dustin/go-humanize"
"github.com/hacdias/caddy-filemanager/config"
2016-10-22 11:07:19 +00:00
"github.com/hacdias/caddy-filemanager/utils/errors"
2016-10-18 20:06:31 +00:00
)
2016-10-18 20:49:46 +00:00
// Info contains the information about a particular file or directory
type Info struct {
2016-10-18 20:06:31 +00:00
os.FileInfo
2016-10-22 12:09:38 +00:00
File *os.File
2016-10-18 20:06:31 +00:00
URL string
Path string // Relative path to Caddyfile
VirtualPath string // Relative path to u.FileSystem
Mimetype string
Content []byte
Type string
UserAllowed bool // Indicates if the user has enough permissions
}
// GetInfo gets the file information and, in case of error, returns the
// respective HTTP error code
2016-10-18 20:49:46 +00:00
func GetInfo(url *url.URL, c *config.Config, u *config.User) (*Info, int, error) {
2016-10-18 20:06:31 +00:00
var err error
2016-10-18 20:49:46 +00:00
i := &Info{URL: url.Path}
2016-10-18 20:06:31 +00:00
i.VirtualPath = strings.Replace(url.Path, c.BaseURL, "", 1)
i.VirtualPath = strings.TrimPrefix(i.VirtualPath, "/")
i.VirtualPath = "/" + i.VirtualPath
i.Path = u.Scope + i.VirtualPath
i.Path = strings.Replace(i.Path, "\\", "/", -1)
i.Path = filepath.Clean(i.Path)
2016-10-22 12:09:38 +00:00
i.File, err = os.Open(i.Path)
2016-10-18 20:06:31 +00:00
if err != nil {
2016-10-22 11:07:19 +00:00
return i, errors.ErrorToHTTPCode(err, false), err
2016-10-18 20:06:31 +00:00
}
2016-10-22 12:09:38 +00:00
i.FileInfo, err = i.File.Stat()
if err != nil {
return i, errors.ErrorToHTTPCode(err, true), err
}
p := make([]byte, 512)
_, err = i.File.Read(p)
if err != nil {
return i, errors.ErrorToHTTPCode(err, false), err
}
i.Mimetype = http.DetectContentType(p)
i.Type = simplifyMediaType(i.Mimetype)
2016-10-18 20:06:31 +00:00
return i, 0, nil
}
2016-10-18 20:49:46 +00:00
func (i *Info) Read() error {
2016-10-18 20:06:31 +00:00
var err error
i.Content, err = ioutil.ReadFile(i.Path)
if err != nil {
return err
}
2016-10-22 12:09:38 +00:00
2016-10-18 20:06:31 +00:00
i.Mimetype = http.DetectContentType(i.Content)
2016-10-18 20:49:46 +00:00
i.Type = simplifyMediaType(i.Mimetype)
2016-10-18 20:06:31 +00:00
return nil
}
2016-10-18 20:49:46 +00:00
// StringifyContent returns the string version of Raw
func (i Info) StringifyContent() string {
2016-10-18 20:06:31 +00:00
return string(i.Content)
}
// HumanSize returns the size of the file as a human-readable string
// in IEC format (i.e. power of 2 or base 1024).
2016-10-18 20:49:46 +00:00
func (i Info) HumanSize() string {
2016-10-18 20:06:31 +00:00
return humanize.IBytes(uint64(i.Size()))
}
// HumanModTime returns the modified time of the file as a human-readable string.
2016-10-18 20:49:46 +00:00
func (i Info) HumanModTime(format string) string {
2016-10-18 20:06:31 +00:00
return i.ModTime().Format(format)
}
2016-10-22 11:07:19 +00:00
// CanBeEdited checks if the extension of a file is supported by the editor
func (i Info) CanBeEdited() bool {
if i.Type == "text" {
return true
}
extensions := [...]string{
"md", "markdown", "mdown", "mmark",
"asciidoc", "adoc", "ad",
"rst",
".json", ".toml", ".yaml",
".css", ".sass", ".scss",
".js",
".html",
".txt",
}
for _, extension := range extensions {
if strings.HasSuffix(i.Name(), extension) {
return true
}
}
return false
}
2016-10-18 20:49:46 +00:00
func simplifyMediaType(name string) string {
2016-10-18 20:06:31 +00:00
if strings.HasPrefix(name, "video") {
return "video"
}
if strings.HasPrefix(name, "audio") {
return "audio"
}
if strings.HasPrefix(name, "image") {
return "image"
}
if strings.HasPrefix(name, "text") {
return "text"
}
if strings.HasPrefix(name, "application/javascript") {
return "text"
}
return "blob"
}