add file counter for upload file
This commit is contained in:
parent
ee252638cb
commit
5287f61c44
@ -2,10 +2,13 @@ package sysStorage
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LocalStorage struct {
|
type LocalStorage struct {
|
||||||
@ -30,35 +33,38 @@ func NewLocalStorage(basePath string) *LocalStorage {
|
|||||||
func (ls *LocalStorage) Upload(
|
func (ls *LocalStorage) Upload(
|
||||||
file *multipart.FileHeader,
|
file *multipart.FileHeader,
|
||||||
streamerID int,
|
streamerID int,
|
||||||
) error {
|
) (string, error) {
|
||||||
dirPath := ls.basePath + "/" + strconv.Itoa(streamerID)
|
dirPath := ls.basePath + "/" + strconv.Itoa(streamerID)
|
||||||
|
|
||||||
if _, err := os.Stat(dirPath); os.IsNotExist(err) {
|
if _, err := os.Stat(dirPath); os.IsNotExist(err) {
|
||||||
if err := os.MkdirAll(dirPath, os.ModePerm); err != nil {
|
if err := os.MkdirAll(dirPath, os.ModePerm); err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.Create(dirPath + "/" + file.Filename)
|
fileName := ls.ensureUniqueFileName(
|
||||||
|
dirPath,
|
||||||
|
file.Filename,
|
||||||
|
)
|
||||||
|
|
||||||
|
f, err := os.Create(dirPath + "/" + fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
// Открываем загруженный файл
|
|
||||||
srcFile, err := file.Open()
|
srcFile, err := file.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
defer srcFile.Close()
|
defer srcFile.Close()
|
||||||
|
|
||||||
// Копируем содержимое в новый файл
|
|
||||||
_, err = io.Copy(f, srcFile)
|
_, err = io.Copy(f, srcFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return fileName, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ls *LocalStorage) Download(
|
func (ls *LocalStorage) Download(
|
||||||
@ -95,3 +101,23 @@ func (ls *LocalStorage) Delete(
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
@ -117,7 +117,7 @@ type Error interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Storage interface {
|
type Storage interface {
|
||||||
Upload(file *multipart.FileHeader, streamerID int) error
|
Upload(file *multipart.FileHeader, streamerID int) (string, error)
|
||||||
Download(filename, extension, filePath string) ([]byte, error)
|
Download(filename, extension, filePath string) ([]byte, error)
|
||||||
Delete(filename, extension, filePath string) error
|
Delete(filename, extension, filePath string) error
|
||||||
}
|
}
|
||||||
@ -145,8 +145,13 @@ type FileRepo interface {
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
streamerID int,
|
streamerID int,
|
||||||
file multipart.FileHeader,
|
file multipart.FileHeader,
|
||||||
fileName, extension, fileType string,
|
extension, fileType string,
|
||||||
) (string, error)
|
) (string, error)
|
||||||
|
CheckFileExists(
|
||||||
|
ctx context.Context,
|
||||||
|
streamerID int,
|
||||||
|
fileName, extension, fileType string,
|
||||||
|
) (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileService interface {
|
type FileService interface {
|
||||||
|
@ -120,5 +120,9 @@ INSERT INTO files (streamer_id, file_name, file_type, extension)
|
|||||||
VALUES
|
VALUES
|
||||||
(@streamer_id, @file_name, @file_type, @extension)
|
(@streamer_id, @file_name, @file_type, @extension)
|
||||||
RETURNING id;
|
RETURNING id;
|
||||||
;
|
;`
|
||||||
`
|
|
||||||
|
var GetFileExists = `SELECT id FROM files WHERE (
|
||||||
|
streamer_id = @streamer_id AND
|
||||||
|
file_name = @file_name AND file_type = @file_type AND extension = @extension
|
||||||
|
;`
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"donat-widget/internal/model"
|
"donat-widget/internal/model"
|
||||||
"donat-widget/internal/model/sql"
|
"donat-widget/internal/model/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/georgysavva/scany/v2/pgxscan"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
@ -29,8 +30,13 @@ func (fileRepo *RepoFile) AddNew(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
streamerID int,
|
streamerID int,
|
||||||
file multipart.FileHeader,
|
file multipart.FileHeader,
|
||||||
fileName, extension, fileType string,
|
extension, fileType string,
|
||||||
) (string, error) {
|
) (string, error) {
|
||||||
|
fileName, err := fileRepo.storage.Upload(&file, streamerID)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
args := pgx.NamedArgs{
|
args := pgx.NamedArgs{
|
||||||
"streamer_id": streamerID,
|
"streamer_id": streamerID,
|
||||||
"file_name": fileName,
|
"file_name": fileName,
|
||||||
@ -47,13 +53,34 @@ func (fileRepo *RepoFile) AddNew(
|
|||||||
if !ok {
|
if !ok {
|
||||||
return "", fmt.Errorf("unexpected fileID type: %T", fileIDRaw)
|
return "", fmt.Errorf("unexpected fileID type: %T", fileIDRaw)
|
||||||
}
|
}
|
||||||
|
|
||||||
fileID := uuid.UUID(fileIDBytes).String()
|
fileID := uuid.UUID(fileIDBytes).String()
|
||||||
|
|
||||||
err = fileRepo.storage.Upload(&file, streamerID)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return fileID, nil
|
return fileID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fileRepo *RepoFile) CheckFileExists(
|
||||||
|
ctx context.Context,
|
||||||
|
streamerID int,
|
||||||
|
fileName, extension, fileType string,
|
||||||
|
) (bool, error) {
|
||||||
|
args := pgx.NamedArgs{
|
||||||
|
"streamer_id": streamerID,
|
||||||
|
"file_name": fileName,
|
||||||
|
"file_type": fileType,
|
||||||
|
"extension": extension,
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := fileRepo.db.Select(ctx, sql.GetFileExists, args)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileId [][16]uint8
|
||||||
|
err = pgxscan.ScanOne(fileId, rows)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -46,7 +46,6 @@ func (fileService *ServiceFile) AddNewFile(
|
|||||||
ctx,
|
ctx,
|
||||||
streamerID,
|
streamerID,
|
||||||
file,
|
file,
|
||||||
file.Filename,
|
|
||||||
fileExt,
|
fileExt,
|
||||||
mimeType,
|
mimeType,
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user