You've already forked filebrowser
mirror of
https://github.com/filebrowser/filebrowser.git
synced 2025-11-26 14:25:26 +08:00
rebuilding js
Former-commit-id: 027e2f6546614d28750e437b9a3545cb95235d9d [formerly 6dbfe621a5774304295c17f216b5c96beaaaa95a] [formerly d44822f30d9a3649b20daa7a3cdbf86c87e63c99 [formerly 3258552349]]
Former-commit-id: 7f34ddc1b32076c6ad2c2a4374b170b7f5d84000 [formerly aaafd299a933d25ebcb5fdebe1b00cb9e8309d7a]
Former-commit-id: 7bb183c165ba2c9711ba1c04e3af6e2048245ded
This commit is contained in:
231
file.go
231
file.go
@@ -1,6 +1,7 @@
|
||||
package filemanager
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
@@ -14,7 +15,9 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -29,25 +32,53 @@ var (
|
||||
type fileInfo struct {
|
||||
// Used to store the file's content temporarily.
|
||||
content []byte
|
||||
|
||||
Name string
|
||||
Size int64
|
||||
URL string
|
||||
// The name of the file.
|
||||
Name string
|
||||
// The Size of the file.
|
||||
Size int64
|
||||
// The absolute URL.
|
||||
URL string
|
||||
// The extension of the file.
|
||||
Extension string
|
||||
ModTime time.Time
|
||||
Mode os.FileMode
|
||||
IsDir bool
|
||||
|
||||
// The last modified time.
|
||||
ModTime time.Time
|
||||
// The File Mode.
|
||||
Mode os.FileMode
|
||||
// Indicates if this file is a directory.
|
||||
IsDir bool
|
||||
// Absolute path.
|
||||
Path string
|
||||
|
||||
// Relative path to user's virtual File System.
|
||||
VirtualPath string
|
||||
|
||||
// Indicates the file content type: video, text, image, music or blob.
|
||||
Type string
|
||||
}
|
||||
|
||||
// A listing is the context used to fill out a template.
|
||||
type listing struct {
|
||||
// The name of the directory (the last element of the path).
|
||||
Name string
|
||||
// The full path of the request relatively to a File System.
|
||||
Path string
|
||||
// The items (files and folders) in the path.
|
||||
Items []fileInfo
|
||||
// The number of directories in the listing.
|
||||
NumDirs int
|
||||
// The number of files (items that aren't directories) in the listing.
|
||||
NumFiles int
|
||||
// Which sorting order is used.
|
||||
Sort string
|
||||
// And which order.
|
||||
Order string
|
||||
// If ≠0 then Items have been limited to that many elements.
|
||||
ItemsLimitedTo int
|
||||
Display string
|
||||
// Indicates if we're showing a preview in this Listing
|
||||
Preview bool
|
||||
// File to preview if Preview is true
|
||||
PreviewItem *fileInfo
|
||||
}
|
||||
|
||||
// getInfo gets the file information and, in case of error, returns the
|
||||
// respective HTTP error code
|
||||
func getInfo(url *url.URL, c *FileManager, u *User) (*fileInfo, error) {
|
||||
@@ -75,21 +106,65 @@ func getInfo(url *url.URL, c *FileManager, u *User) (*fileInfo, error) {
|
||||
return i, nil
|
||||
}
|
||||
|
||||
var textExtensions = [...]string{
|
||||
".md", ".markdown", ".mdown", ".mmark",
|
||||
".asciidoc", ".adoc", ".ad",
|
||||
".rst",
|
||||
".json", ".toml", ".yaml", ".csv", ".xml", ".rss", ".conf", ".ini",
|
||||
".tex", ".sty",
|
||||
".css", ".sass", ".scss",
|
||||
".js",
|
||||
".html",
|
||||
".txt", ".rtf",
|
||||
".sh", ".bash", ".ps1", ".bat", ".cmd",
|
||||
".php", ".pl", ".py",
|
||||
"Caddyfile",
|
||||
".c", ".cc", ".h", ".hh", ".cpp", ".hpp", ".f90",
|
||||
".f", ".bas", ".d", ".ada", ".nim", ".cr", ".java", ".cs", ".vala", ".vapi",
|
||||
// getListing gets the information about a specific directory and its files.
|
||||
func getListing(u *User, filePath string, baseURL string) (*listing, error) {
|
||||
// Gets the directory information using the Virtual File System of
|
||||
// the user configuration.
|
||||
file, err := u.fileSystem.OpenFile(context.TODO(), filePath, os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// Reads the directory and gets the information about the files.
|
||||
files, err := file.Readdir(-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
fileinfos []fileInfo
|
||||
dirCount, fileCount int
|
||||
)
|
||||
|
||||
for _, f := range files {
|
||||
name := f.Name()
|
||||
allowed := u.Allowed("/" + name)
|
||||
|
||||
if !allowed {
|
||||
continue
|
||||
}
|
||||
|
||||
if f.IsDir() {
|
||||
name += "/"
|
||||
dirCount++
|
||||
} else {
|
||||
fileCount++
|
||||
}
|
||||
|
||||
// Absolute URL
|
||||
url := url.URL{Path: baseURL + name}
|
||||
|
||||
i := fileInfo{
|
||||
Name: f.Name(),
|
||||
Size: f.Size(),
|
||||
ModTime: f.ModTime(),
|
||||
Mode: f.Mode(),
|
||||
IsDir: f.IsDir(),
|
||||
URL: url.String(),
|
||||
}
|
||||
i.RetrieveFileType()
|
||||
|
||||
fileinfos = append(fileinfos, i)
|
||||
}
|
||||
|
||||
return &listing{
|
||||
Name: path.Base(filePath),
|
||||
Path: filePath,
|
||||
Items: fileinfos,
|
||||
NumDirs: dirCount,
|
||||
NumFiles: fileCount,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RetrieveFileType obtains the mimetype and converts it to a simple
|
||||
@@ -212,3 +287,109 @@ func (i fileInfo) HumanModTime(format string) string {
|
||||
func (i fileInfo) CanBeEdited() bool {
|
||||
return i.Type == "text"
|
||||
}
|
||||
|
||||
// ApplySort applies the sort order using .Order and .Sort
|
||||
func (l listing) ApplySort() {
|
||||
// Check '.Order' to know how to sort
|
||||
if l.Order == "desc" {
|
||||
switch l.Sort {
|
||||
case "name":
|
||||
sort.Sort(sort.Reverse(byName(l)))
|
||||
case "size":
|
||||
sort.Sort(sort.Reverse(bySize(l)))
|
||||
case "time":
|
||||
sort.Sort(sort.Reverse(byTime(l)))
|
||||
default:
|
||||
// If not one of the above, do nothing
|
||||
return
|
||||
}
|
||||
} else { // If we had more Orderings we could add them here
|
||||
switch l.Sort {
|
||||
case "name":
|
||||
sort.Sort(byName(l))
|
||||
case "size":
|
||||
sort.Sort(bySize(l))
|
||||
case "time":
|
||||
sort.Sort(byTime(l))
|
||||
default:
|
||||
sort.Sort(byName(l))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implement sorting for listing
|
||||
type byName listing
|
||||
type bySize listing
|
||||
type byTime listing
|
||||
|
||||
// By Name
|
||||
func (l byName) Len() int {
|
||||
return len(l.Items)
|
||||
}
|
||||
|
||||
func (l byName) Swap(i, j int) {
|
||||
l.Items[i], l.Items[j] = l.Items[j], l.Items[i]
|
||||
}
|
||||
|
||||
// Treat upper and lower case equally
|
||||
func (l byName) Less(i, j int) bool {
|
||||
if l.Items[i].IsDir && !l.Items[j].IsDir {
|
||||
return true
|
||||
}
|
||||
|
||||
if !l.Items[i].IsDir && l.Items[j].IsDir {
|
||||
return false
|
||||
}
|
||||
|
||||
return strings.ToLower(l.Items[i].Name) < strings.ToLower(l.Items[j].Name)
|
||||
}
|
||||
|
||||
// By Size
|
||||
func (l bySize) Len() int {
|
||||
return len(l.Items)
|
||||
}
|
||||
|
||||
func (l bySize) Swap(i, j int) {
|
||||
l.Items[i], l.Items[j] = l.Items[j], l.Items[i]
|
||||
}
|
||||
|
||||
const directoryOffset = -1 << 31 // = math.MinInt32
|
||||
func (l bySize) Less(i, j int) bool {
|
||||
iSize, jSize := l.Items[i].Size, l.Items[j].Size
|
||||
if l.Items[i].IsDir {
|
||||
iSize = directoryOffset + iSize
|
||||
}
|
||||
if l.Items[j].IsDir {
|
||||
jSize = directoryOffset + jSize
|
||||
}
|
||||
return iSize < jSize
|
||||
}
|
||||
|
||||
// By Time
|
||||
func (l byTime) Len() int {
|
||||
return len(l.Items)
|
||||
}
|
||||
func (l byTime) Swap(i, j int) {
|
||||
l.Items[i], l.Items[j] = l.Items[j], l.Items[i]
|
||||
}
|
||||
func (l byTime) Less(i, j int) bool {
|
||||
return l.Items[i].ModTime.Before(l.Items[j].ModTime)
|
||||
}
|
||||
|
||||
var textExtensions = [...]string{
|
||||
".md", ".markdown", ".mdown", ".mmark",
|
||||
".asciidoc", ".adoc", ".ad",
|
||||
".rst",
|
||||
".json", ".toml", ".yaml", ".csv", ".xml", ".rss", ".conf", ".ini",
|
||||
".tex", ".sty",
|
||||
".css", ".sass", ".scss",
|
||||
".js",
|
||||
".html",
|
||||
".txt", ".rtf",
|
||||
".sh", ".bash", ".ps1", ".bat", ".cmd",
|
||||
".php", ".pl", ".py",
|
||||
"Caddyfile",
|
||||
".c", ".cc", ".h", ".hh", ".cpp", ".hpp", ".f90",
|
||||
".f", ".bas", ".d", ".ada", ".nim", ".cr", ".java", ".cs", ".vala", ".vapi",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user