diff --git a/README.md b/README.md index f0f4891..3f54a5e 100644 --- a/README.md +++ b/README.md @@ -43,10 +43,61 @@ Here’s how you can get involved: ``` make test ``` -4. To start application run: - ``` - make start - ``` + +## Usage +```go +import( + "github.com/gin-gonic/gin" + "github.com/Nicolas-ggd/filestream" +) + +func Upload(c *gin.Context) { + // Retrieve the uploaded file + uploadFile, err := c.FormFile("file") + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "failed to get file"}) + return + } + + // Open the uploaded file + file, err := uploadFile.Open() + if err != nil { + fmt.Println("Error opening uploaded file:", err) + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to open uploaded file"}) + return + } + + defer file.Close() + + + // Construct the FileRequest + fileReq := fstream.RFileRequest{ + File: file, + UploadFile: uploadFile, + MaxRange: rangeMax, + FileSize: fileSize, + UploadDirectory: "uploads/", + FileUniqueName: true, // remember that if you set true here, you will receive unique name file + } + + + // Call StoreChunk to handle the uploaded chunk + prFile, err := fstream.StoreChunk(&fileReq) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "failed to store chunk"}) + return + } + + // You can write your own if statement to check whatever you want + if isLast { + // You can perform your own logic here, before return 200 status, + // it's better to remove chunks which is uploaded and doesn't use anymore + fstream.RemoveUploadedFile(&fileReq) + } + + c.JSON(http.StatusOK, gin.H{"message": "file chunk processed"}) +} +``` ## License FileStream is open-source software licensed under the MIT License. diff --git a/file.go b/file.go index 3ef1487..adc0cf2 100644 --- a/file.go +++ b/file.go @@ -18,7 +18,7 @@ type File struct { // Original uploaded file name FileName string // FileUniqueName is unique name - FileUniqueName string + FileUniqueName *string // Uploaded file path FilePath string // Uploaded file extension @@ -43,8 +43,8 @@ type RFileRequest struct { FileUniqueName bool } -// generateUuidUniqueName function generates unique string using UUID -func (r *File) generateUuidUniqueName(request *RFileRequest) { +// uniqueName function generates unique string using UUID +func uniqueName(request *RFileRequest) string { ext := filepath.Ext(request.UploadFile.Filename) id, err := uuid.NewUUID() @@ -52,7 +52,7 @@ func (r *File) generateUuidUniqueName(request *RFileRequest) { log.Fatalln(err) } - r.FileUniqueName = fmt.Sprintf("%s%s", id.String(), ext) + return fmt.Sprintf("%s%s", id.String(), ext) } // RemoveUploadedFile function removes uploaded file from uploaded directory, it takes param and returns nothing: @@ -118,7 +118,7 @@ func StoreChunk(r *RFileRequest) (*File, error) { }() // Copy the chunk data to the file - if _, err := io.Copy(f, r.File); err != nil { + if _, err = io.Copy(f, r.File); err != nil { return nil, fmt.Errorf("failed to copying file: %v", err) } @@ -132,13 +132,18 @@ func StoreChunk(r *RFileRequest) (*File, error) { // Calculate file size in bytes size := prettyByteSize(int(fileInfo.Size())) + // Check if FileUniqueName field is true to generate unique name for file + if r.FileUniqueName { + uName := uniqueName(r) + rFile.FileUniqueName = &uName + } + // Bind File struct and return rFile = &File{ - FileName: r.UploadFile.Filename, - FileUniqueName: r.UploadFile.Filename, - FilePath: filePath, - FileExtension: filepath.Ext(r.UploadFile.Filename), - FileSize: size, + FileName: r.UploadFile.Filename, + FilePath: filePath, + FileExtension: filepath.Ext(r.UploadFile.Filename), + FileSize: size, } } diff --git a/file_test.go b/file_test.go new file mode 100644 index 0000000..e78dece --- /dev/null +++ b/file_test.go @@ -0,0 +1,8 @@ +package fstream + +import "testing" + +func FuzzStoreChunk(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + }) +} diff --git a/filestream b/filestream deleted file mode 100755 index 2ea2ae5..0000000 Binary files a/filestream and /dev/null differ