added upload status

This commit is contained in:
2023-04-16 11:43:46 +01:00
parent 97c3001596
commit c60b75bd3b
4 changed files with 141 additions and 8 deletions

View File

@@ -36,6 +36,10 @@ type WebapiInstance struct {
// download info
downloads map[uuid.UUID]*downloadInfo
downloadsMutex sync.RWMutex
// upload info
uploads map[uuid.UUID]*UploadStatus
uploadsMutex sync.RWMutex
}
// WSUpgrader is used for websocket functionality. It allows all requests.
@@ -62,6 +66,7 @@ func Start(Backend *core.Backend, ListenAddresses []string, UseSSL bool, Certifi
AllowKeyInParam: []string{"/file/read", "/file/view"},
allJobs: make(map[uuid.UUID]*SearchJob),
downloads: make(map[uuid.UUID]*downloadInfo),
uploads: make(map[uuid.UUID]*UploadStatus),
}
if APIKey != uuid.Nil {
@@ -96,7 +101,9 @@ func Start(Backend *core.Backend, ListenAddresses []string, UseSSL bool, Certifi
api.Router.HandleFunc("/download/start", api.apiDownloadStart).Methods("GET")
api.Router.HandleFunc("/download/status", api.apiDownloadStatus).Methods("GET")
api.Router.HandleFunc("/download/action", api.apiDownloadAction).Methods("GET")
api.Router.HandleFunc("/warehouse/create", api.apiWarehouseCreateFile).Methods("POST")
api.Router.HandleFunc("/warehouse/create", api.ApiWarehouseCreateFile).Methods("POST")
api.Router.HandleFunc("/warehouse/create/uploadID", api.apiUploadID).Methods("GET")
api.Router.HandleFunc("/warehouse/create/track/uploadID", api.apiUploadInfo).Methods("GET")
api.Router.HandleFunc("/warehouse/create/path", api.apiWarehouseCreateFilePath).Methods("GET")
api.Router.HandleFunc("/warehouse/read", api.apiWarehouseReadFile).Methods("GET")
api.Router.HandleFunc("/warehouse/read/path", api.apiWarehouseReadFilePath).Methods("GET")

83
webapi/Upload.go Normal file
View File

@@ -0,0 +1,83 @@
package webapi
import (
"github.com/google/uuid"
"math"
"net/http"
)
type UploadStatus struct {
APIStatus int `json:"apistatus"` // Status of the API call. See DownloadResponseX.
ID uuid.UUID `json:"id"` // Download ID. This can be used to query the latest status and take actions.
UploadStatus int `json:"uploadstatus"` // Status of the download. See DownloadX.
Progress struct {
TotalSize uint64 `json:"totalsize"` // Total size in bytes.
UploadedSize uint64 `json:"uploadedsize"` // Count of bytes download so far.
Percentage float64 `json:"percentage"` // Percentage downloaded. Rounded to 2 decimal points. Between 0.00 and 100.00.
} `json:"progress"` // Progress of the download. Only valid for status >= DownloadWaitSwarm.
}
func (api *WebapiInstance) uploadAdd(info *UploadStatus) {
api.uploadsMutex.Lock()
api.uploads[info.ID] = info
api.uploadsMutex.Unlock()
}
func (api *WebapiInstance) uploadDelete(id uuid.UUID) {
api.uploadsMutex.Lock()
delete(api.uploads, id)
api.uploadsMutex.Unlock()
}
func (api *WebapiInstance) uploadLookup(id uuid.UUID) (info *UploadStatus) {
api.uploadsMutex.Lock()
info = api.uploads[id]
api.uploadsMutex.Unlock()
return info
}
// UploadID API to set a Status ID to track the upload
func (api *WebapiInstance) apiUploadID(w http.ResponseWriter, r *http.Request) {
var info UploadStatus
info.ID = uuid.New()
// Create a upload ID for adding the upload
// metadata later one
api.uploadAdd(&info)
EncodeJSON(api.Backend, w, r, info)
}
// Write is used to satisfy the io.Writer interface.
// Instead of writing somewhere, it simply aggregates
// the total bytes on each read
func (uploadStatus *UploadStatus) Write(p []byte) (n int, err error) {
n = len(p)
uploadStatus.Progress.UploadedSize += uint64(n)
uploadStatus.Progress.Percentage = math.Round(float64(uploadStatus.Progress.UploadedSize)/float64(uploadStatus.Progress.TotalSize)*100*100) / 100
return
}
// Get information about upload file status
func (api *WebapiInstance) apiUploadInfo(w http.ResponseWriter, r *http.Request) {
ID := r.URL.Query().Get("id")
if ID == "" {
api.Backend.LogError("upload.UploadInformation", "error: %v", "ID parameter not passed")
http.Error(w, "", http.StatusBadRequest)
return
}
IDUUID, err := uuid.Parse(ID)
if err != nil {
api.Backend.LogError("upload.UploadInformation", "error: %v", err)
return
}
info := api.uploadLookup(IDUUID)
if info == nil {
EncodeJSON(api.Backend, w, r, UploadStatus{APIStatus: DownloadResponseIDNotFound})
return
}
EncodeJSON(api.Backend, w, r, info)
}

View File

@@ -7,6 +7,7 @@ Author: Peter Kleissner
package webapi
import (
"github.com/google/uuid"
"net/http"
"strconv"
@@ -20,16 +21,52 @@ type WarehouseResult struct {
}
/*
apiWarehouseCreateFile creates a file in the warehouse.
ApiWarehouseCreateFile creates a file in the warehouse.
Request: POST /warehouse/create with raw data to create as new file
Response: 200 with JSON structure WarehouseResult
*/
func (api *WebapiInstance) apiWarehouseCreateFile(w http.ResponseWriter, r *http.Request) {
hash, status, err := api.Backend.UserWarehouse.CreateFile(r.Body, 0)
func (api *WebapiInstance) ApiWarehouseCreateFile(w http.ResponseWriter, r *http.Request) {
// changing parameter to take ID as a parameter for upload and file itself
ID := r.FormValue("ID")
file, handler, err := r.FormFile("File")
if err != nil {
api.Backend.LogError("warehouse.CreateFile", "error: %v", err)
http.Error(w, "", http.StatusBadRequest)
return
}
var hash []byte
var status int
if ID != "" {
IDUUID, err := uuid.Parse(ID)
if err != nil {
api.Backend.LogError("warehouse.CreateFile", "error: %v", err)
http.Error(w, "", http.StatusBadRequest)
return
}
info := api.uploadLookup(IDUUID)
if info == nil {
var newInfo UploadStatus
newInfo.ID = IDUUID
newInfo.Progress.TotalSize = uint64(handler.Size)
api.uploadAdd(&newInfo)
hash, status, err = api.Backend.UserWarehouse.CreateFile(file, uint64(handler.Size), &newInfo)
} else {
info.Progress.TotalSize = uint64(handler.Size)
hash, status, err = api.Backend.UserWarehouse.CreateFile(file, uint64(handler.Size), info)
}
} else {
// File := r.
hash, status, err = api.Backend.UserWarehouse.CreateFile(file, uint64(handler.Size), nil)
}
if err != nil {
api.Backend.LogError("warehouse.CreateFile", "status %d error: %v", status, err)
http.Error(w, "", http.StatusBadRequest)
return
}
EncodeJSON(api.Backend, w, r, WarehouseResult{Status: status, Hash: hash})