1
0
dwelling-files/pkg/files/files.go

84 lines
1.8 KiB
Go

package files
import (
"net/url"
"os"
"path/filepath"
"time"
)
const FileDateFormat = "2006-01-02 15:04:05 MST"
type DirStat struct {
Files int64
FilesSize string
FilesSizeUnit string
Directories int64
}
type DirEntry struct {
Name string
Link string
Datetime time.Time
Size string
SizeUnit string
}
// ScanDirectory returns entries of directory which is located by its relative
// path within a base directory.
//
// rel path should start/end with a / symbol.
func ScanDirectory(base, rel string) (entries []DirEntry, stats DirStat, err error) {
abs := base + rel
dir, err := os.ReadDir(abs)
if err != nil {
return
}
var dirEntries []DirEntry = make([]DirEntry, 0)
var fileEntries []DirEntry = make([]DirEntry, 0)
var totalFilesSize int64 = 0
for _, ent := range dir {
entry, _ := ent.Info()
var isDirLink bool
if entry.Mode().Type()&os.ModeSymlink != 0 {
if slp, err := filepath.EvalSymlinks(filepath.Join(abs, entry.Name())); err == nil {
lStat, _ := os.Lstat(slp)
isDirLink = lStat.IsDir()
}
}
if entry.IsDir() || isDirLink {
dirEntries = append(dirEntries, DirEntry{
Name: entry.Name(),
Link: url.PathEscape(entry.Name()) + "/",
Datetime: entry.ModTime(),
Size: "DIR",
})
stats.Directories++
} else {
sz, ui := convertFileSize(entry.Size())
fileEntries = append(fileEntries, DirEntry{
Name: entry.Name(),
Link: "/file" + rel + url.PathEscape(entry.Name()),
Datetime: entry.ModTime(),
Size: sz,
SizeUnit: ui,
})
totalFilesSize += entry.Size()
stats.Files++
}
}
stats.FilesSize, stats.FilesSizeUnit = convertFileSize(totalFilesSize)
entries = append(entries, dirEntries...)
entries = append(entries, fileEntries...)
return
}