76 lines
1.4 KiB
Go
76 lines
1.4 KiB
Go
|
|
package scanner
|
||
|
|
|
||
|
|
import (
|
||
|
|
"os"
|
||
|
|
"path/filepath"
|
||
|
|
"strings"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
var videoExtensions = map[string]bool{
|
||
|
|
".mkv": true,
|
||
|
|
".mp4": true,
|
||
|
|
".avi": true,
|
||
|
|
".m4v": true,
|
||
|
|
".webm": true,
|
||
|
|
".ts": true,
|
||
|
|
".mov": true,
|
||
|
|
}
|
||
|
|
|
||
|
|
type MediaFile struct {
|
||
|
|
Path string `json:"-"`
|
||
|
|
RelPath string `json:"rel_path"`
|
||
|
|
Name string `json:"name"`
|
||
|
|
Size int64 `json:"size"`
|
||
|
|
ModTime time.Time `json:"mod_time"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// DisplayName converts a filename into a human-readable display name.
|
||
|
|
func DisplayName(filename string) string {
|
||
|
|
name := strings.TrimSuffix(filename, filepath.Ext(filename))
|
||
|
|
name = strings.ReplaceAll(name, ".", " ")
|
||
|
|
name = strings.ReplaceAll(name, "_", " ")
|
||
|
|
return name
|
||
|
|
}
|
||
|
|
|
||
|
|
// Scan recursively walks rootDir and returns all video files found.
|
||
|
|
func Scan(rootDir string) ([]MediaFile, error) {
|
||
|
|
var files []MediaFile
|
||
|
|
|
||
|
|
err := filepath.WalkDir(rootDir, func(path string, d os.DirEntry, err error) error {
|
||
|
|
if err != nil {
|
||
|
|
return nil // skip inaccessible paths
|
||
|
|
}
|
||
|
|
if d.IsDir() {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
ext := strings.ToLower(filepath.Ext(d.Name()))
|
||
|
|
if !videoExtensions[ext] {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
info, err := d.Info()
|
||
|
|
if err != nil {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
relPath, err := filepath.Rel(rootDir, path)
|
||
|
|
if err != nil {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
files = append(files, MediaFile{
|
||
|
|
Path: path,
|
||
|
|
RelPath: relPath,
|
||
|
|
Name: DisplayName(d.Name()),
|
||
|
|
Size: info.Size(),
|
||
|
|
ModTime: info.ModTime(),
|
||
|
|
})
|
||
|
|
|
||
|
|
return nil
|
||
|
|
})
|
||
|
|
|
||
|
|
return files, err
|
||
|
|
}
|