2023-09-21 16:43:11 +01:00
package models
import (
"bytes"
"image"
"image/color"
2023-10-06 12:13:19 +01:00
_ "image/jpeg"
_ "image/png"
2023-09-21 16:43:11 +01:00
"io"
"net/http"
"os"
"path"
2023-09-26 20:15:28 +01:00
. "git.andr3h3nriqu3s.com/andr3/fyp/logic/models/utils"
2023-10-06 12:13:19 +01:00
. "git.andr3h3nriqu3s.com/andr3/fyp/logic/utils"
2023-09-21 16:43:11 +01:00
)
2023-10-06 12:13:19 +01:00
func loadBaseImage ( c * Context , id string ) {
2023-09-21 16:43:11 +01:00
// TODO handle more types than png
infile , err := os . Open ( path . Join ( "savedData" , id , "baseimage.png" ) )
if err != nil {
2023-10-06 12:13:19 +01:00
c . Logger . Errorf ( "Failed to read image for model with id %s\n" , id )
2023-10-22 23:02:39 +01:00
c . Logger . Error ( err )
2023-10-06 12:13:19 +01:00
ModelUpdateStatus ( c , id , FAILED_PREPARING )
2023-09-21 16:43:11 +01:00
return
}
defer infile . Close ( )
src , format , err := image . Decode ( infile )
if err != nil {
2023-10-06 12:13:19 +01:00
c . Logger . Errorf ( "Failed to decode image for model with id %s\n" , id )
2023-10-22 23:02:39 +01:00
c . Logger . Error ( err )
2023-10-06 12:13:19 +01:00
ModelUpdateStatus ( c , id , FAILED_PREPARING )
2023-09-21 16:43:11 +01:00
return
}
2023-10-06 12:13:19 +01:00
switch format {
case "png" :
case "jpeg" :
default :
2023-10-22 23:02:39 +01:00
ModelUpdateStatus ( c , id , FAILED_PREPARING )
c . Logger . Error ( "Found unkown format '%s'\n" , "format" , format )
2023-09-21 16:43:11 +01:00
panic ( "Handle diferent files than .png" )
}
var model_color string
bounds := src . Bounds ( )
width , height := bounds . Max . X , bounds . Max . Y
switch src . ColorModel ( ) {
case color . Gray16Model :
fallthrough
case color . GrayModel :
model_color = "greyscale"
2023-10-22 23:02:39 +01:00
case color . NRGBAModel :
fallthrough
2023-10-06 12:13:19 +01:00
case color . YCbCrModel :
model_color = "rgb"
2023-09-21 16:43:11 +01:00
default :
2023-10-22 23:02:39 +01:00
c . Logger . Error ( "Do not know how to handle this color model" )
2023-09-21 16:43:11 +01:00
if src . ColorModel ( ) == color . RGBA64Model {
2023-10-22 23:02:39 +01:00
c . Logger . Error ( "Color is rgb" )
} else if src . ColorModel ( ) == color . NRGBA64Model {
c . Logger . Error ( "Color is nrgb 64" )
2023-09-21 16:43:11 +01:00
} else if src . ColorModel ( ) == color . AlphaModel {
2023-10-22 23:02:39 +01:00
c . Logger . Error ( "Color is alpha" )
2023-09-21 16:43:11 +01:00
} else if src . ColorModel ( ) == color . CMYKModel {
2023-10-22 23:02:39 +01:00
c . Logger . Error ( "Color is cmyk" )
2023-09-21 16:43:11 +01:00
} else {
2023-10-22 23:02:39 +01:00
c . Logger . Error ( "Other so assuming color" )
2023-09-21 16:43:11 +01:00
}
2023-10-22 23:02:39 +01:00
ModelUpdateStatus ( c , id , FAILED_PREPARING )
2023-09-21 16:43:11 +01:00
return
}
// Note: this also updates the status to 2
2023-10-06 12:13:19 +01:00
_ , err = c . Db . Exec ( "update models set width=$1, height=$2, color_mode=$3, format=$4, status=$5 where id=$6" , width , height , model_color , format , CONFIRM_PRE_TRAINING , id )
2023-09-21 16:43:11 +01:00
if err != nil {
2023-10-06 12:13:19 +01:00
c . Logger . Error ( "Could not update model" )
c . Logger . Error ( err )
ModelUpdateStatus ( c , id , - 1 )
2023-09-21 16:43:11 +01:00
return
}
}
func handleAdd ( handle * Handle ) {
2023-10-06 12:13:19 +01:00
handle . GetHTML ( "/models/add" , AnswerTemplate ( "models/add.html" , nil , 1 ) )
2023-09-21 16:43:11 +01:00
handle . Post ( "/models/add" , func ( w http . ResponseWriter , r * http . Request , c * Context ) * Error {
if ! CheckAuthLevel ( 1 , w , r , c ) {
return nil
}
2024-03-01 23:03:25 +00:00
2023-10-06 12:13:19 +01:00
if c . Mode == JSON {
2024-03-01 23:03:25 +00:00
read_form , err := r . MultipartReader ( )
if err != nil {
return c . JsonErrorBadRequest ( err , "Please provide a valid multipart Reader request" )
}
var name string
var file [ ] byte
for {
part , err_part := read_form . NextPart ( )
if err_part == io . EOF {
break
} else if err_part != nil {
return & Error { Code : http . StatusBadRequest }
}
if part . FormName ( ) == "name" {
buf := new ( bytes . Buffer )
buf . ReadFrom ( part )
name = buf . String ( )
}
if part . FormName ( ) == "file" {
buf := new ( bytes . Buffer )
buf . ReadFrom ( part )
file = buf . Bytes ( )
}
}
if name == "" || len ( file ) == 0 {
return c . JsonBadRequest ( "Name is empty or file is empty" )
}
row , err := handle . Db . Query ( "select id from models where name=$1 and user_id=$2;" , name , c . User . Id )
if err != nil {
return c . Error500 ( err )
}
if row . Next ( ) {
return c . JsonBadRequest ( "Model with that name already exists!" )
}
row , err = handle . Db . Query ( "insert into models (user_id, name) values ($1, $2) returning id" , c . User . Id , name )
if err != nil || ! row . Next ( ) {
return c . Error500 ( err )
}
var id string
err = row . Scan ( & id )
if err != nil {
return c . Error500 ( err )
}
// TODO mk this path configurable
dir_path := path . Join ( "savedData" , id )
err = os . Mkdir ( dir_path , os . ModePerm )
if err != nil {
return c . Error500 ( err )
}
f , err := os . Create ( path . Join ( dir_path , "baseimage.png" ) )
if err != nil {
return c . Error500 ( err )
}
defer f . Close ( )
f . Write ( file )
c . Logger . Warn ( "Created model with id %s! Started to proccess image!\n" , "id" , id )
go loadBaseImage ( c , id )
return c . SendJSON ( id )
2023-10-06 12:13:19 +01:00
}
2023-09-21 16:43:11 +01:00
read_form , err := r . MultipartReader ( )
if err != nil {
LoadBasedOnAnswer ( c . Mode , w , "models/add.html" , c . AddMap ( nil ) )
return nil
}
var name string
var file [ ] byte
for {
part , err_part := read_form . NextPart ( )
if err_part == io . EOF {
break
} else if err_part != nil {
return & Error { Code : http . StatusBadRequest }
}
if part . FormName ( ) == "name" {
buf := new ( bytes . Buffer )
buf . ReadFrom ( part )
name = buf . String ( )
}
if part . FormName ( ) == "file" {
buf := new ( bytes . Buffer )
buf . ReadFrom ( part )
file = buf . Bytes ( )
}
}
if name == "" || len ( file ) == 0 {
LoadBasedOnAnswer ( c . Mode , w , "models/add.html" , c . AddMap ( nil ) )
return nil
}
row , err := handle . Db . Query ( "select id from models where name=$1 and user_id=$2;" , name , c . User . Id )
if err != nil {
2023-10-22 23:02:39 +01:00
return c . Error500 ( err )
2023-09-21 16:43:11 +01:00
}
if row . Next ( ) {
LoadBasedOnAnswer ( c . Mode , w , "models/add.html" , c . AddMap ( AnyMap {
"NameFoundError" : true ,
"Name" : name ,
} ) )
return nil
}
_ , err = handle . Db . Exec ( "insert into models (user_id, name) values ($1, $2)" , c . User . Id , name )
if err != nil {
2023-10-22 23:02:39 +01:00
return c . Error500 ( err )
2023-09-21 16:43:11 +01:00
}
row , err = handle . Db . Query ( "select id from models where name=$1 and user_id=$2;" , name , c . User . Id )
if err != nil {
2023-10-22 23:02:39 +01:00
return c . Error500 ( err )
2023-09-21 16:43:11 +01:00
}
if ! row . Next ( ) {
return & Error { Code : http . StatusInternalServerError }
}
var id string
err = row . Scan ( & id )
if err != nil {
2023-10-22 23:02:39 +01:00
return c . Error500 ( err )
2023-09-21 16:43:11 +01:00
}
// TODO mk this path configurable
dir_path := path . Join ( "savedData" , id )
err = os . Mkdir ( dir_path , os . ModePerm )
if err != nil {
2023-10-22 23:02:39 +01:00
return c . Error500 ( err )
2023-09-21 16:43:11 +01:00
}
f , err := os . Create ( path . Join ( dir_path , "baseimage.png" ) )
if err != nil {
2023-10-22 23:02:39 +01:00
return c . Error500 ( err )
2023-09-21 16:43:11 +01:00
}
defer f . Close ( )
f . Write ( file )
2023-10-22 23:02:39 +01:00
c . Logger . Warn ( "Created model with id %s! Started to proccess image!\n" , "id" , id )
2023-10-06 12:13:19 +01:00
go loadBaseImage ( c , id )
2023-09-21 16:43:11 +01:00
Redirect ( "/models/edit?id=" + id , c . Mode , w , r )
return nil
} )
}