add button to add new image to class closes #15

This commit is contained in:
2024-04-16 14:09:03 +01:00
parent 7d742e7970
commit 3ad07e6ce5
6 changed files with 240 additions and 11 deletions

View File

@@ -29,7 +29,7 @@ type BasePackStruct struct {
}
func (b BasePackStruct) GetHost() string {
return b.Host
return b.Host
}
func (b BasePackStruct) GetDb() *sql.DB {
@@ -315,6 +315,31 @@ func InsertReturnId(c QueryInterface, store interface{}, tablename string, retur
return
}
func GetDbVar[T interface{}](c QueryInterface, var_to_extract string, tablename string, args ...any) (*T, error) {
db_query, err := c.Prepare(fmt.Sprintf("select %s from %s", var_to_extract, tablename))
if err != nil {
return nil, err
}
defer db_query.Close()
rows, err := db_query.Query(args...)
if err != nil {
return nil, err
}
defer rows.Close()
if !rows.Next() {
return nil, NotFoundError
}
dat := new(T)
if err = rows.Scan(dat); err != nil {
return nil, err
}
return dat, nil
}
func GetDBOnce(db QueryInterface, store interface{}, tablename string, args ...any) error {
t := reflect.TypeOf(store).Elem()

View File

@@ -498,6 +498,88 @@ func handleDataUpload(handle *Handle) {
return c.SendJSON(modelClass)
})
type AddNewImage struct {
ClassId string `json:"id" validate:"required"`
}
PostAuthFormJson(handle, "/models/data/class/image", User_Normal, func(c *Context, dat *AddNewImage, file []byte) *Error {
model_id, err := GetDbVar[string](c, "m.id", "model_classes as mc inner join models as m on m.id = mc.model_id where mc.id=$1;", dat.ClassId)
if err == NotFoundError {
return c.JsonBadRequest("Could not find the class")
} else if err != nil {
return c.E500M("Error getting class information", err)
}
c.Logger.Info("model", "model", *model_id)
model, err := GetBaseModel(c.Db, *model_id)
if err == ModelNotFoundError {
return c.JsonBadRequest("Could not find the model")
} else if err != nil {
return c.E500M("Error getting model information", err)
}
// TODO make this work for zip files as well
/*c.Logger.Debug("Processing File", "file", file.Name)
data, err := reader.Open(file.Name)
if err != nil {
c.Logger.Error("Could not open file in zip %s\n", "file name", file.Name, "err", err)
back_channel <- index
continue
}
defer data.Close()
file_data, err := io.ReadAll(data)
if err != nil {
c.Logger.Error("Could not open file in zip %s\n", "file name", file.Name, "err", err)
back_channel <- index
continue
}*/
// TODO check if the file is a valid photo that matched the defined photo on the database
//parts := strings.Split(file.Name, "/")
mode := DATA_POINT_MODE_TRAINING
// TODO add the mode
/*mode := DATA_POINT_MODE_TRAINING
if parts[0] == "testing" {
mode = DATA_POINT_MODE_TESTING
}*/
data_point_id, err := model_classes.AddDataPoint(c.Db, dat.ClassId, "id://", mode)
if err != nil {
//c.Logger.Error("Failed to add datapoint", "model", model.Id, "file name", file.Name, "err", err)
c.Logger.Error("Failed to add datapoint", "data_point_id", data_point_id)
return c.E500M("Could not add image to model", err)
}
file_path := path.Join("savedData", model.Id, "data", data_point_id+"."+model.Format)
f, err := os.Create(file_path)
if err != nil {
//c.Logger.Error("Failed to save datapoint to disk", "model", model.Id, "file name", file.Name, "err", err)
c.Logger.Error("Failed to save datapoint to disk", "model", model.Id, "err", err)
return c.E500M("Could not add image to model", err)
}
defer f.Close()
f.Write(file)
if !TestImgForModel(c, model, file_path) {
//c.Logger.Errorf("Image did not have valid format for model %s (in zip: %s)!", file_path, file.Name)
c.Logger.Errorf("Image did not have valid format for model %s!", file_path)
c.Logger.Warn("Not failling updating data point to status -1")
message := "Image did not have valid format for the model"
if err = model_classes.UpdateDataPointStatus(c.Db, data_point_id, -1, &message); err != nil {
//c.Logger.Error("Failed to update data point", "model", model.Id, "file name", file.Name, "err", err)
c.Logger.Error("Failed to update data point", "model", model.Id, "err", err)
return c.E500M("Could not update information about the data point", err)
}
return c.JsonBadRequest("Provided file is not a valid image for this model")
}
return c.SendJSON(struct {
Id string `json:"id"`
}{data_point_id})
})
// ------
// ------ CLASS DATA UPLOAD
// ------

View File

@@ -1,9 +1,11 @@
package utils
import (
"bytes"
"database/sql"
"errors"
"fmt"
"io"
"net/http"
"os"
"path"
@@ -89,7 +91,7 @@ func (x *Handle) PostAuth(path string, authLevel dbtypes.UserType, fn func(c *Co
x.posts = append(x.posts, HandleFunc{path, inner_fn})
}
func PostAuthJson[T interface{}](x *Handle, path string, authLevel dbtypes.UserType, fn func(c *Context, obj *T) *Error) {
func PostAuthJson[T interface{}](x *Handle, path string, authLevel dbtypes.UserType, fn func(c *Context, dat *T) *Error) {
inner_fn := func(c *Context) *Error {
if !c.CheckAuthLevel(authLevel) {
return nil
@@ -107,6 +109,56 @@ func PostAuthJson[T interface{}](x *Handle, path string, authLevel dbtypes.UserT
x.posts = append(x.posts, HandleFunc{path, inner_fn})
}
func PostAuthFormJson[T interface{}](x *Handle, path string, authLevel dbtypes.UserType, fn func(c *Context, dat *T, file []byte) *Error) {
inner_fn := func(c *Context) *Error {
if !c.CheckAuthLevel(1) {
return nil
}
read_form, err := c.R.MultipartReader()
if err != nil {
return c.JsonBadRequest("Please provide a valid form data request!")
}
var json_data string
var file []byte
for {
part, err_part := read_form.NextPart()
if err_part == io.EOF {
break
} else if err_part != nil {
return c.JsonBadRequest("Please provide a valid form data request!")
}
if part.FormName() == "json_data" {
buf := new(bytes.Buffer)
buf.ReadFrom(part)
json_data = buf.String()
}
if part.FormName() == "file" {
buf := new(bytes.Buffer)
buf.ReadFrom(part)
file = buf.Bytes()
}
}
if !c.CheckAuthLevel(authLevel) {
return nil
}
dat := new(T)
decoder := json.NewDecoder(strings.NewReader(json_data))
if err := c.decodeAndValidade(decoder, dat); err != nil {
return err
}
return fn(c, dat, file)
}
x.posts = append(x.posts, HandleFunc{path, inner_fn})
}
func (x *Handle) Delete(path string, fn func(c *Context) *Error) {
x.deletes = append(x.deletes, HandleFunc{path, fn})
}
@@ -200,7 +252,7 @@ func (c Context) GetLogger() *log.Logger {
}
func (c Context) GetHost() string {
return c.Handle.Config.Hostname
return c.Handle.Config.Hostname
}
func (c Context) Query(query string, args ...any) (*sql.Rows, error) {