This commit is contained in:
Andre Henriques 2023-10-20 12:37:56 +01:00
parent b5ba0d295a
commit bc801648a3
6 changed files with 182 additions and 131 deletions

View File

@ -6,6 +6,7 @@ import (
"strconv" "strconv"
. "git.andr3h3nriqu3s.com/andr3/fyp/logic/utils" . "git.andr3h3nriqu3s.com/andr3/fyp/logic/utils"
. "git.andr3h3nriqu3s.com/andr3/fyp/logic/models/utils"
) )
func HandleList(handle *Handle) { func HandleList(handle *Handle) {
@ -48,6 +49,11 @@ func HandleList(handle *Handle) {
return Error500(nil) return Error500(nil)
} }
model, err := GetBaseModel(c.Db, model_id)
if err != nil {
return Error500(err)
}
rows, err := handle.Db.Query("select id, file_path, model_mode, status from model_data_point where class_id=$1 limit 10 offset $2;", id, page * 10) rows, err := handle.Db.Query("select id, file_path, model_mode, status from model_data_point where class_id=$1 limit 10 offset $2;", id, page * 10)
if err != nil { if err != nil {
return Error500(err) return Error500(err)
@ -95,7 +101,7 @@ func HandleList(handle *Handle) {
"Page": page, "Page": page,
"Id": id, "Id": id,
"Name": name, "Name": name,
"ModelId": model_id, "Model": model,
})) }))
return nil return nil
}) })

View File

@ -24,11 +24,11 @@ func handleEdit(handle *Handle) {
} }
// TODO handle admin users // TODO handle admin users
rows, err := handle.Db.Query("select name, status, width, height, color_mode from models where id=$1 and user_id=$2;", id, c.User.Id) rows, err := handle.Db.Query("select name, status, width, height, color_mode, format from models where id=$1 and user_id=$2;", id, c.User.Id)
if err != nil { if err != nil {
return Error500(err) return Error500(err)
} }
defer rows.Close() defer rows.Close()
if !rows.Next() { if !rows.Next() {
return ErrorCode(nil, http.StatusNotFound, AnyMap{ return ErrorCode(nil, http.StatusNotFound, AnyMap{
@ -44,12 +44,13 @@ func handleEdit(handle *Handle) {
Width *int Width *int
Height *int Height *int
Color_mode *string Color_mode *string
Format string
} }
var model rowmodel = rowmodel{} var model rowmodel = rowmodel{}
model.Id = id model.Id = id
err = rows.Scan(&model.Name, &model.Status, &model.Width, &model.Height, &model.Color_mode) err = rows.Scan(&model.Name, &model.Status, &model.Width, &model.Height, &model.Color_mode, &model.Format)
if err != nil { if err != nil {
return Error500(err) return Error500(err)
} }
@ -70,60 +71,64 @@ func handleEdit(handle *Handle) {
})) }))
case CONFIRM_PRE_TRAINING: case CONFIRM_PRE_TRAINING:
wrong_number, err := model_classes.GetNumberOfWrongDataPoints(c.Db, model.Id) wrong_number, err := model_classes.GetNumberOfWrongDataPoints(c.Db, model.Id)
if err != nil { return c.Error500(err) } if err != nil {
return c.Error500(err)
}
cls, err := model_classes.ListClasses(handle.Db, id) cls, err := model_classes.ListClasses(handle.Db, id)
if err != nil { return c.Error500(err) } if err != nil {
return c.Error500(err)
}
has_data, err := model_classes.ModelHasDataPoints(handle.Db, id) has_data, err := model_classes.ModelHasDataPoints(handle.Db, id)
if err != nil { if err != nil {
return Error500(err) return Error500(err)
} }
LoadBasedOnAnswer(c.Mode, w, "/models/edit.html", c.AddMap(AnyMap{ LoadBasedOnAnswer(c.Mode, w, "/models/edit.html", c.AddMap(AnyMap{
"Model": model, "Model": model,
"Classes": cls, "Classes": cls,
"HasData": has_data, "HasData": has_data,
"NumberOfInvalidImages": wrong_number, "NumberOfInvalidImages": wrong_number,
})) }))
case READY: case READY:
LoadBasedOnAnswer(c.Mode, w, "/models/edit.html", c.AddMap(AnyMap{ LoadBasedOnAnswer(c.Mode, w, "/models/edit.html", c.AddMap(AnyMap{
"Model": model, "Model": model,
})) }))
case TRAINING: case TRAINING:
type defrow struct {
Status int
EpochProgress int
Accuracy int
}
def_rows, err := c.Db.Query("select status, epoch_progress, accuracy from model_definition where model_id=$1", model.Id) type defrow struct {
if err != nil { Status int
return c.Error500(err) EpochProgress int
} Accuracy int
defer def_rows.Close() }
defs := []defrow{} def_rows, err := c.Db.Query("select status, epoch_progress, accuracy from model_definition where model_id=$1", model.Id)
if err != nil {
return c.Error500(err)
}
defer def_rows.Close()
for def_rows.Next() { defs := []defrow{}
var def defrow
err = def_rows.Scan(&def.Status, &def.EpochProgress, &def.Accuracy)
if err != nil {
return c.Error500(err)
}
defs = append(defs, def)
}
LoadBasedOnAnswer(c.Mode, w, "/models/edit.html", c.AddMap(AnyMap{ for def_rows.Next() {
"Model": model, var def defrow
"Defs": defs, err = def_rows.Scan(&def.Status, &def.EpochProgress, &def.Accuracy)
})) if err != nil {
case PREPARING_ZIP_FILE: return c.Error500(err)
LoadBasedOnAnswer(c.Mode, w, "/models/edit.html", c.AddMap(AnyMap{ }
"Model": model, defs = append(defs, def)
})) }
LoadBasedOnAnswer(c.Mode, w, "/models/edit.html", c.AddMap(AnyMap{
"Model": model,
"Defs": defs,
}))
case PREPARING_ZIP_FILE:
LoadBasedOnAnswer(c.Mode, w, "/models/edit.html", c.AddMap(AnyMap{
"Model": model,
}))
default: default:
fmt.Printf("Unkown Status: %d\n", model.Status) fmt.Printf("Unkown Status: %d\n", model.Status)
return Error500(nil) return Error500(nil)

View File

@ -387,8 +387,8 @@ func trainModel(c *Context, model *BaseModel) {
ModelUpdateStatus(c, model.Id, READY) ModelUpdateStatus(c, model.Id, READY)
} }
func removeFailedDataPoints(db *sql.DB, model *BaseModel) (err error) { func removeFailedDataPoints(c *Context, model *BaseModel) (err error) {
rows, err := db.Query("select mdp.id from model_data_point as mdp join model_classes as mc on mc.id=mdp.class_id where mc.model_id=$1 and mdp.status=-1;", model.Id) rows, err := c.Db.Query("select mdp.id from model_data_point as mdp join model_classes as mc on mc.id=mdp.class_id where mc.model_id=$1 and mdp.status=-1;", model.Id)
if err != nil { if err != nil {
return return
} }
@ -402,13 +402,18 @@ func removeFailedDataPoints(db *sql.DB, model *BaseModel) (err error) {
if err != nil { if err != nil {
return return
} }
err = os.RemoveAll(path.Join(base_path, dataPointId+model.Format))
p := path.Join(base_path, dataPointId + "." + model.Format)
c.Logger.Warn("Removing image", "path", p)
err = os.RemoveAll(p)
if err != nil { if err != nil {
return return
} }
} }
_, err = db.Exec("delete from model_data_point as mdp using model_classes as mc where mdp.class_id = mc.id and mc.model_id=$1 and mdp.status=-1;", model.Id) _, err = c.Db.Exec("delete from model_data_point as mdp using model_classes as mc where mdp.class_id = mc.id and mc.model_id=$1 and mdp.status=-1;", model.Id)
return return
} }
@ -471,7 +476,7 @@ func generateDefinitions(c *Context, model *BaseModel, number_of_models int) *Er
return c.Error500(err) return c.Error500(err)
} }
err = removeFailedDataPoints(c.Db, model) err = removeFailedDataPoints(c, model)
if err != nil { if err != nil {
return c.Error500(err) return c.Error500(err)
} }

View File

@ -13,24 +13,24 @@ import (
"time" "time"
dbtypes "git.andr3h3nriqu3s.com/andr3/fyp/logic/db_types" dbtypes "git.andr3h3nriqu3s.com/andr3/fyp/logic/db_types"
"github.com/charmbracelet/log" "github.com/charmbracelet/log"
) )
func Mul (n1 int, n2 int) int { func Mul(n1 int, n2 int) int {
return n1 * n2 return n1 * n2
} }
func Add (n1 int, n2 int) int { func Add(n1 int, n2 int) int {
return n1 + n2 return n1 + n2
} }
func baseLoadTemplate(base string, path string) (*template.Template, any) { func baseLoadTemplate(base string, path string) (*template.Template, any) {
funcs := map[string]any { funcs := map[string]any{
"startsWith": strings.HasPrefix, "startsWith": strings.HasPrefix,
"replace": strings.Replace, "replace": strings.Replace,
"mul": Mul, "mul": Mul,
"add": Add, "add": Add,
} }
return template.New(base).Funcs(funcs).ParseFiles( return template.New(base).Funcs(funcs).ParseFiles(
"./views/"+base, "./views/"+base,
"./views/"+path, "./views/"+path,
@ -97,27 +97,27 @@ func LoadHtml(writer http.ResponseWriter, path string, data interface{}) {
} }
func LoadDefineTemplate(writer http.ResponseWriter, path string, base string, data AnyMap) { func LoadDefineTemplate(writer http.ResponseWriter, path string, base string, data AnyMap) {
if data == nil { if data == nil {
data = map[string]interface{} { data = map[string]interface{}{
"Error": true, "Error": true,
} }
} else { } else {
data["Error"] = true data["Error"] = true
} }
funcs := map[string]any { funcs := map[string]any{
"startsWith": strings.HasPrefix, "startsWith": strings.HasPrefix,
"mul": Mul, "mul": Mul,
"replace": strings.Replace, "replace": strings.Replace,
"add": Add, "add": Add,
} }
tmpl, err := template.New("").Funcs(funcs).Parse("{{template \"" + base + "\" . }}") tmpl, err := template.New("").Funcs(funcs).Parse("{{template \"" + base + "\" . }}")
if err != nil { if err != nil {
panic("Lol") panic("Lol")
} }
tmpl, err = tmpl.ParseFiles( tmpl, err = tmpl.ParseFiles(
"./views/"+path, "./views/"+path,
"./views/partials/header.html", "./views/partials/header.html",
) )
@ -222,10 +222,10 @@ func handleError(err *Error, w http.ResponseWriter, context *Context) {
if err != nil { if err != nil {
data := context.AddMap(err.data) data := context.AddMap(err.data)
if err.Code == http.StatusNotFound { if err.Code == http.StatusNotFound {
if context.Mode == HTML { if context.Mode == HTML {
w.WriteHeader(309) w.WriteHeader(309)
context.Mode = HTMLFULL context.Mode = HTMLFULL
} }
LoadBasedOnAnswer(context.Mode, w, "404.html", data) LoadBasedOnAnswer(context.Mode, w, "404.html", data)
return return
} }
@ -340,46 +340,46 @@ func AnswerTemplate(path string, data AnyMap, authLevel int) func(w http.Respons
} }
type Context struct { type Context struct {
Token *string Token *string
User *dbtypes.User User *dbtypes.User
Mode AnswerType Mode AnswerType
Logger *log.Logger Logger *log.Logger
Db *sql.DB Db *sql.DB
} }
func (c Context) Error400(err error, message string, w http.ResponseWriter, path string, base string, data AnyMap) *Error { func (c Context) Error400(err error, message string, w http.ResponseWriter, path string, base string, data AnyMap) *Error {
c.SetReportCaller(true) c.SetReportCaller(true)
c.Logger.Error(message) c.Logger.Error(message)
c.SetReportCaller(false) c.SetReportCaller(false)
if err != nil { if err != nil {
c.Logger.Errorf("Something went wrong returning with: %d\n.Err:\n", http.StatusBadRequest) c.Logger.Errorf("Something went wrong returning with: %d\n.Err:\n", http.StatusBadRequest)
c.Logger.Error(err) c.Logger.Error(err)
} }
if c.Mode == JSON { if c.Mode == JSON {
return &Error{http.StatusBadRequest, nil, c.AddMap(data)} return &Error{http.StatusBadRequest, nil, c.AddMap(data)}
} }
LoadDefineTemplate(w, path, base, c.AddMap(data)) LoadDefineTemplate(w, path, base, c.AddMap(data))
return nil return nil
} }
func (c Context) SetReportCaller(report bool) { func (c Context) SetReportCaller(report bool) {
if (report) { if report {
c.Logger.SetCallerOffset(2) c.Logger.SetCallerOffset(2)
c.Logger.SetReportCaller(true) c.Logger.SetReportCaller(true)
} else { } else {
c.Logger.SetCallerOffset(1) c.Logger.SetCallerOffset(1)
c.Logger.SetReportCaller(false) c.Logger.SetReportCaller(false)
} }
} }
func (c Context) ErrorCode(err error, code int, data AnyMap) *Error { func (c Context) ErrorCode(err error, code int, data AnyMap) *Error {
if (code == 400) { if code == 400 {
c.SetReportCaller(true) c.SetReportCaller(true)
c.Logger.Warn("When returning BadRequest(400) please use context.Error400\n") c.Logger.Warn("When returning BadRequest(400) please use context.Error400\n")
c.SetReportCaller(false) c.SetReportCaller(false)
} }
if err != nil { if err != nil {
c.Logger.Errorf("Something went wrong returning with: %d\n.Err:\n", code) c.Logger.Errorf("Something went wrong returning with: %d\n.Err:\n", code)
c.Logger.Error(err) c.Logger.Error(err)
@ -422,11 +422,11 @@ func (x Handle) createContext(handler *Handle, mode AnswerType, r *http.Request)
var token *string var token *string
logger := log.NewWithOptions(os.Stdout, log.Options{ logger := log.NewWithOptions(os.Stdout, log.Options{
ReportTimestamp: true, ReportTimestamp: true,
TimeFormat: time.Kitchen, TimeFormat: time.Kitchen,
Prefix: r.URL.Path, Prefix: r.URL.Path,
}) })
for _, r := range r.Cookies() { for _, r := range r.Cookies() {
if r.Name == "auth" { if r.Name == "auth" {
@ -438,9 +438,9 @@ func (x Handle) createContext(handler *Handle, mode AnswerType, r *http.Request)
if token == nil { if token == nil {
return &Context{ return &Context{
Mode: mode, Mode: mode,
Logger: logger, Logger: logger,
Db: handler.Db, Db: handler.Db,
}, nil }, nil
} }
@ -461,7 +461,7 @@ func Redirect(path string, mode AnswerType, w http.ResponseWriter, r *http.Reque
return return
} }
if mode&(HTMLFULL|HTML) != 0 { if mode&(HTMLFULL|HTML) != 0 {
w.Header().Add("HX-Redirect", path) w.Header().Add("HX-Redirect", path)
w.WriteHeader(204) w.WriteHeader(204)
} else { } else {
w.WriteHeader(http.StatusSeeOther) w.WriteHeader(http.StatusSeeOther)
@ -517,7 +517,7 @@ func (x Handle) StaticFiles(pathTest string, fileType string, contentType string
} }
func ErrorCode(err error, code int, data AnyMap) *Error { func ErrorCode(err error, code int, data AnyMap) *Error {
log.Warn("This function is deprecated please use the one provided by context") log.Warn("This function is deprecated please use the one provided by context")
// TODO Improve Logging // TODO Improve Logging
if err != nil { if err != nil {
fmt.Printf("Something went wrong returning with: %d\n.Err:\n", code) fmt.Printf("Something went wrong returning with: %d\n.Err:\n", code)
@ -527,7 +527,7 @@ func ErrorCode(err error, code int, data AnyMap) *Error {
} }
func Error500(err error) *Error { func Error500(err error) *Error {
log.Warn("This function is deprecated please use the one provided by context") log.Warn("This function is deprecated please use the one provided by context")
return ErrorCode(err, http.StatusInternalServerError, nil) return ErrorCode(err, http.StatusInternalServerError, nil)
} }
@ -556,6 +556,42 @@ func (x Handle) ReadFiles(pathTest string, baseFilePath string, fileType string,
}) })
} }
func (x Handle) ReadTypesFiles(pathTest string, baseFilePath string, fileTypes []string, contentTypes []string) {
http.HandleFunc(pathTest, func(w http.ResponseWriter, r *http.Request) {
user_path := r.URL.Path[len(pathTest):]
// fmt.Printf("Requested path: %s\n", user_path)
found := false
index := -1;
for i, fileType := range fileTypes {
if strings.HasSuffix(user_path, fileType) {
found = true
index = i;
break
}
}
if !found {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte("File not found"))
return
}
bytes, err := os.ReadFile(path.Join(baseFilePath, pathTest, user_path))
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Failed to load file"))
return
}
w.Header().Set("Content-Type", contentTypes[index])
w.Write(bytes)
})
}
func NewHandler(db *sql.DB) *Handle { func NewHandler(db *sql.DB) *Handle {
var gets []HandleFunc var gets []HandleFunc

23
main.go
View File

@ -31,25 +31,24 @@ func main() {
defer db.Close() defer db.Close()
fmt.Println("Starting server on :8000!") fmt.Println("Starting server on :8000!")
//TODO check if file structure exists to save data //TODO check if file structure exists to save data
handle := NewHandler(db) handle := NewHandler(db)
_, err = db.Exec("update models set status=$1 where status=$2", models_utils.FAILED_TRAINING, models_utils.TRAINING); _, err = db.Exec("update models set status=$1 where status=$2", models_utils.FAILED_TRAINING, models_utils.TRAINING)
if err != nil { if err != nil {
panic(err) panic(err)
} }
// TODO Handle this in other way // TODO Handle this in other way
handle.StaticFiles("/styles/", ".css", "text/css"); handle.StaticFiles("/styles/", ".css", "text/css")
handle.StaticFiles("/js/", ".js", "text/javascript"); handle.StaticFiles("/js/", ".js", "text/javascript")
handle.ReadFiles("/imgs/", "views", ".png", "image/png;"); handle.ReadFiles("/imgs/", "views", ".png", "image/png;")
handle.ReadFiles("/savedData/", ".", ".png", "image/png;"); handle.ReadTypesFiles("/savedData/", ".", []string{".png", ".jpeg"}, []string{"image/png", "image/jpeg"})
handle.GetHTML("/", AnswerTemplate("index.html", nil, 0)) handle.GetHTML("/", AnswerTemplate("index.html", nil, 0))
usersEndpints(db, handle) usersEndpints(db, handle)
HandleModels(handle) HandleModels(handle)
handle.Startup() handle.Startup()
} }

View File

@ -81,7 +81,7 @@
</td> </td>
<td class="text-center"> <td class="text-center">
{{ if startsWith .FilePath "id://" }} {{ if startsWith .FilePath "id://" }}
<img src="/savedData/{{ $.ModelId }}/data/{{ .Id }}.png" height="30px" width="30px" style="object-fit: contain;" /> <img src="/savedData/{{ $.Model.Id }}/data/{{ .Id }}.{{ $.Model.Format }}" height="30px" width="30px" style="object-fit: contain;" />
{{ else }} {{ else }}
TODO TODO
img {{ .FilePath }} img {{ .FilePath }}