mirror of
https://github.com/nxshock/gallery.git
synced 2024-11-27 00:11:00 +05:00
100 lines
2.1 KiB
Go
100 lines
2.1 KiB
Go
|
package main
|
|||
|
|
|||
|
import (
|
|||
|
"errors"
|
|||
|
"math/rand"
|
|||
|
"os"
|
|||
|
"path/filepath"
|
|||
|
"strconv"
|
|||
|
"time"
|
|||
|
)
|
|||
|
|
|||
|
var errPatternHasSeparator = errors.New("pattern contains path separator")
|
|||
|
|
|||
|
func TempFileName(pattern string) (string, error) {
|
|||
|
dir := os.TempDir()
|
|||
|
|
|||
|
prefix, suffix, err := prefixAndSuffix(pattern)
|
|||
|
if err != nil {
|
|||
|
return "", &os.PathError{Op: "createtemp", Path: pattern, Err: err}
|
|||
|
}
|
|||
|
prefix = joinPath(dir, prefix)
|
|||
|
|
|||
|
try := 0
|
|||
|
for {
|
|||
|
name := prefix + nextRandom() + suffix
|
|||
|
if exists, _ := IsFileExists(name); exists {
|
|||
|
if try++; try < 10000 {
|
|||
|
continue
|
|||
|
}
|
|||
|
return "", &os.PathError{Op: "createtemp", Path: prefix + "*" + suffix, Err: os.ErrExist}
|
|||
|
}
|
|||
|
return name, err
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func IsFileExists(filePath string) (bool, error) {
|
|||
|
if _, err := os.Stat(filePath); err == nil {
|
|||
|
return true, nil
|
|||
|
} else if errors.Is(err, os.ErrNotExist) {
|
|||
|
return false, nil
|
|||
|
|
|||
|
} else {
|
|||
|
return false, err
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func prefixAndSuffix(pattern string) (prefix, suffix string, err error) {
|
|||
|
for i := 0; i < len(pattern); i++ {
|
|||
|
if os.IsPathSeparator(pattern[i]) {
|
|||
|
return "", "", errPatternHasSeparator
|
|||
|
}
|
|||
|
}
|
|||
|
if pos := lastIndex(pattern, '*'); pos != -1 {
|
|||
|
prefix, suffix = pattern[:pos], pattern[pos+1:]
|
|||
|
} else {
|
|||
|
prefix = pattern
|
|||
|
}
|
|||
|
return prefix, suffix, nil
|
|||
|
}
|
|||
|
|
|||
|
func joinPath(dir, name string) string {
|
|||
|
if len(dir) > 0 && os.IsPathSeparator(dir[len(dir)-1]) {
|
|||
|
return dir + name
|
|||
|
}
|
|||
|
return dir + string(os.PathSeparator) + name
|
|||
|
}
|
|||
|
|
|||
|
func nextRandom() string {
|
|||
|
|
|||
|
return strconv.Itoa(int(rand.Uint64()))
|
|||
|
}
|
|||
|
|
|||
|
func lastIndex(s string, sep byte) int {
|
|||
|
for i := len(s) - 1; i >= 0; i-- {
|
|||
|
if s[i] == sep {
|
|||
|
return i
|
|||
|
}
|
|||
|
}
|
|||
|
return -1
|
|||
|
}
|
|||
|
|
|||
|
func getRandomFiles(path string, numberOfFiles int) ([]string, error) { // TODO: оптимизировать алгоритм и предусмотреть папки с менее 4 шт. файлов
|
|||
|
fileNames, err := filepath.Glob(path + "/*")
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
|
|||
|
rand.Seed(time.Now().UnixNano())
|
|||
|
for i := len(fileNames) - 1; i > 0; i-- {
|
|||
|
j := rand.Intn(i + 1)
|
|||
|
fileNames[i], fileNames[j] = fileNames[j], fileNames[i]
|
|||
|
}
|
|||
|
|
|||
|
for len(fileNames) < 4 {
|
|||
|
fileNames = append(fileNames, "black.png")
|
|||
|
}
|
|||
|
|
|||
|
return fileNames[:4], nil
|
|||
|
}
|