143 lines
3.5 KiB
Go
143 lines
3.5 KiB
Go
package filesystem
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"git.0x0001f346.de/andreas/ablage/config"
|
|
)
|
|
|
|
func Init() error {
|
|
err := createWriteableFolder(config.GetPathDataFolder())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = os.RemoveAll(config.GetPathUploadFolder())
|
|
if err != nil {
|
|
return fmt.Errorf("Could not delete upload folder '%s': %v", config.GetPathUploadFolder(), err)
|
|
}
|
|
|
|
err = createWriteableFolder(config.GetPathUploadFolder())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func DeleteFile(filename string) error {
|
|
return os.Remove(filepath.Join(config.GetPathDataFolder(), filename))
|
|
}
|
|
|
|
func GetFileListOfDataFolder() (map[string]int64, error) {
|
|
entries, err := os.ReadDir(config.GetPathDataFolder())
|
|
if err != nil {
|
|
return map[string]int64{}, fmt.Errorf(
|
|
"Data folder '%s' became unavailable: %v",
|
|
config.GetPathDataFolder(),
|
|
err,
|
|
)
|
|
}
|
|
|
|
files := map[string]int64{}
|
|
for _, entry := range entries {
|
|
if entry.IsDir() {
|
|
continue
|
|
}
|
|
|
|
info, err := entry.Info()
|
|
if err != nil {
|
|
log.Printf("WARN: Could not read info for '%s': %v", entry.Name(), err)
|
|
continue
|
|
}
|
|
|
|
files[info.Name()] = info.Size()
|
|
}
|
|
|
|
return files, nil
|
|
}
|
|
|
|
func GetHumanReadableSize(bytes int64) string {
|
|
const unit int64 = 1024
|
|
|
|
if bytes < unit {
|
|
return fmt.Sprintf("%d Bytes", bytes)
|
|
}
|
|
|
|
div, exp := int64(unit), 0
|
|
|
|
for n := bytes / unit; n >= unit; n /= unit {
|
|
div *= unit
|
|
exp++
|
|
}
|
|
|
|
return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp])
|
|
}
|
|
|
|
func SanitizeFilename(dirtyFilename string) string {
|
|
if dirtyFilename == "" {
|
|
return "upload.bin"
|
|
}
|
|
|
|
filenameWithoutPath := filepath.Base(dirtyFilename)
|
|
|
|
extension := filepath.Ext(filenameWithoutPath)
|
|
filenameWithoutPathAndExtension := filenameWithoutPath[:len(filenameWithoutPath)-len(extension)]
|
|
|
|
cleanedFilename := strings.ReplaceAll(filenameWithoutPathAndExtension, " ", "_")
|
|
cleanedFilename = strings.ReplaceAll(cleanedFilename, "Ä", "Ae")
|
|
cleanedFilename = strings.ReplaceAll(cleanedFilename, "ä", "äe")
|
|
cleanedFilename = strings.ReplaceAll(cleanedFilename, "Ö", "Oe")
|
|
cleanedFilename = strings.ReplaceAll(cleanedFilename, "ö", "oe")
|
|
cleanedFilename = strings.ReplaceAll(cleanedFilename, "Ü", "Ue")
|
|
cleanedFilename = strings.ReplaceAll(cleanedFilename, "ü", "ue")
|
|
cleanedFilename = strings.ReplaceAll(cleanedFilename, "ß", "ss")
|
|
|
|
var safeNameRegex = regexp.MustCompile(`[^a-zA-Z0-9._-]+`)
|
|
cleanedFilename = safeNameRegex.ReplaceAllString(cleanedFilename, "_")
|
|
|
|
for strings.Contains(cleanedFilename, "__") {
|
|
cleanedFilename = strings.ReplaceAll(cleanedFilename, "__", "_")
|
|
}
|
|
|
|
cleanedFilename = strings.Trim(cleanedFilename, "_")
|
|
|
|
const maxLenFilename int = 128
|
|
if len(cleanedFilename) > maxLenFilename {
|
|
cleanedFilename = cleanedFilename[:maxLenFilename]
|
|
}
|
|
|
|
return cleanedFilename + extension
|
|
}
|
|
|
|
func createWriteableFolder(path string) error {
|
|
info, err := os.Stat(path)
|
|
if os.IsNotExist(err) {
|
|
if err := os.MkdirAll(path, 0755); err != nil {
|
|
return fmt.Errorf("Could not create folder '%s': %v", path, err)
|
|
}
|
|
} else if err != nil {
|
|
return fmt.Errorf("Could not access '%s': %v", path, err)
|
|
} else if !info.IsDir() {
|
|
return fmt.Errorf("'%s' exists but is not a directory", path)
|
|
}
|
|
|
|
pathTestFile := filepath.Join(path, ".write_test")
|
|
err = os.WriteFile(pathTestFile, []byte("test"), 0644)
|
|
if err != nil {
|
|
return fmt.Errorf("Could not create test file '%s': %v", pathTestFile, err)
|
|
}
|
|
|
|
err = os.Remove(pathTestFile)
|
|
if err != nil {
|
|
return fmt.Errorf("Could not delete test file '%s': %v", pathTestFile, err)
|
|
}
|
|
|
|
return nil
|
|
}
|