package sysStorage import ( "bytes" "fmt" "github.com/google/uuid" "io" "mime/multipart" "os" "path/filepath" "strconv" "strings" ) type LocalStorage struct { basePath string FileUrl string } func NewLocalStorage(basePath, fileUrl string) *LocalStorage { if basePath == "" { var err error basePath, err = os.Getwd() if err != nil { panic("Failed to get current directory: " + err.Error()) } } if err := os.MkdirAll(basePath, os.ModePerm); err != nil { panic("Failed to create storage directory: " + err.Error()) } fileUrl = "https://" + fileUrl return &LocalStorage{basePath: basePath, FileUrl: fileUrl} } func (ls *LocalStorage) Upload( file *multipart.FileHeader, streamerID int, ) (string, error) { dirPath := ls.basePath + "/" + strconv.Itoa(streamerID) if _, err := os.Stat(dirPath); os.IsNotExist(err) { if err := os.MkdirAll(dirPath, os.ModePerm); err != nil { return "", err } } fileName := ls.ensureUniqueFileName( dirPath, file.Filename, ) f, err := os.Create(dirPath + "/" + fileName) if err != nil { return "", err } defer f.Close() srcFile, err := file.Open() if err != nil { return "", err } defer srcFile.Close() _, err = io.Copy(f, srcFile) if err != nil { return "", err } return fileName, nil } func (ls *LocalStorage) Download( filename string, folder string, ) ([]byte, error) { f, err := os.Open(ls.basePath + "/" + folder + "/" + filename) if err != nil { return nil, err } defer f.Close() var fileBuffer bytes.Buffer _, err = io.Copy(&fileBuffer, f) if err != nil { return nil, err } return fileBuffer.Bytes(), nil } func (ls *LocalStorage) Delete( filename string, extension string, filePath string, ) error { fileFullPath := filePath + "/" + filename + "." + extension err := os.Remove(fileFullPath) if err != nil { return err } return nil } func (ls *LocalStorage) DownloadLink( fileId uuid.UUID, ) string { return ls.FileUrl + "/api/widget/files/" + fileId.String() } func (ls *LocalStorage) ensureUniqueFileName( dirPath, fileName string, ) string { ext := filepath.Ext(fileName) name := strings.TrimSuffix(fileName, ext) // Имя файла без расширения newFileName := fileName // Начальное имя файла counter := 1 // Счётчик для уникальности for { filePath := filepath.Join(dirPath, newFileName) if _, err := os.Stat(filePath); os.IsNotExist(err) { break } newFileName = fmt.Sprintf("%s(%d)%s", name, counter, ext) counter++ } return newFileName }