feat: #10 added the base for the class on the page
This commit is contained in:
parent
1964303dce
commit
04de6ad574
@ -15,22 +15,22 @@ type User struct {
|
|||||||
var ErrUserNotFound = errors.New("User Not found")
|
var ErrUserNotFound = errors.New("User Not found")
|
||||||
|
|
||||||
func UserFromToken(db *sql.DB, token string) (*User, error) {
|
func UserFromToken(db *sql.DB, token string) (*User, error) {
|
||||||
row, err := db.Query("select users.id, users.username, users.email, users.user_type from users inner join tokens on tokens.user_id = users.id where tokens.token = $1;", token)
|
rows, err := db.Query("select users.id, users.username, users.email, users.user_type from users inner join tokens on tokens.user_id = users.id where tokens.token = $1;", token)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
var id string
|
var id string
|
||||||
var username string
|
var username string
|
||||||
var email string
|
var email string
|
||||||
var user_type int
|
var user_type int
|
||||||
|
|
||||||
if !row.Next() {
|
if !rows.Next() {
|
||||||
return nil, ErrUserNotFound
|
return nil, ErrUserNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
err = row.Scan(&id, &username, &email, &user_type)
|
err = rows.Scan(&id, &username, &email, &user_type)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
101
logic/models/classes/list.go
Normal file
101
logic/models/classes/list.go
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package model_classes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
. "git.andr3h3nriqu3s.com/andr3/fyp/logic/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func HandleList(handle *Handle) {
|
||||||
|
handle.Get("/models/data/list", func(w http.ResponseWriter, r *http.Request, c *Context) *Error {
|
||||||
|
if !CheckAuthLevel(1, w, r, c) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if c.Mode == JSON {
|
||||||
|
panic("TODO JSON on /models/data/list")
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := GetIdFromUrl(r, "id")
|
||||||
|
if err != nil {
|
||||||
|
return ErrorCode(err, 400, c.AddMap(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
page := 0
|
||||||
|
if r.URL.Query().Has("page") {
|
||||||
|
page_url := r.URL.Query().Get("page")
|
||||||
|
page_url_number, err := strconv.Atoi(page_url)
|
||||||
|
if err != nil {
|
||||||
|
return ErrorCode(err, http.StatusBadRequest, c.AddMap(nil))
|
||||||
|
}
|
||||||
|
page = page_url_number
|
||||||
|
}
|
||||||
|
|
||||||
|
class_rows, err := handle.Db.Query("select name, model_id from model_classes where id=$1;", id)
|
||||||
|
if err != nil {
|
||||||
|
return Error500(err)
|
||||||
|
}
|
||||||
|
defer class_rows.Close()
|
||||||
|
|
||||||
|
if !class_rows.Next() {
|
||||||
|
return ErrorCode(nil, 404, c.AddMap(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
name := ""
|
||||||
|
model_id := ""
|
||||||
|
if err = class_rows.Scan(&name, &model_id); err != nil {
|
||||||
|
return Error500(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := handle.Db.Query("select id, file_path, model_mode from model_data_point where class_id=$1 limit 10 offset $2;", id, page * 10)
|
||||||
|
if err != nil {
|
||||||
|
return Error500(err)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
type baserow struct {
|
||||||
|
Id string
|
||||||
|
FilePath string
|
||||||
|
Mode int
|
||||||
|
}
|
||||||
|
|
||||||
|
got := []baserow{}
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
nrow := baserow{}
|
||||||
|
err = rows.Scan(&nrow.Id, &nrow.FilePath, &nrow.Mode)
|
||||||
|
if err != nil {
|
||||||
|
return Error500(err)
|
||||||
|
}
|
||||||
|
got = append(got, nrow)
|
||||||
|
}
|
||||||
|
|
||||||
|
rows_count, err := handle.Db.Query("select count(*) from model_data_point where class_id=$1;", id)
|
||||||
|
if err != nil {
|
||||||
|
return Error500(err)
|
||||||
|
}
|
||||||
|
defer rows_count.Close()
|
||||||
|
|
||||||
|
if !rows_count.Next() {
|
||||||
|
fmt.Printf("select count(*) from model_data_point where class_id='%s';\n", id)
|
||||||
|
return Error500(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
count := 0
|
||||||
|
err = rows_count.Scan(&count)
|
||||||
|
if err != nil {
|
||||||
|
return Error500(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadDefineTemplate(w, "/models/edit.html", "data-model-create-class-table-table", c.AddMap(AnyMap{
|
||||||
|
"List": got,
|
||||||
|
"Count": count,
|
||||||
|
"Page": page,
|
||||||
|
"Id": id,
|
||||||
|
"Name": name,
|
||||||
|
"ModelId": model_id,
|
||||||
|
}))
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
@ -122,6 +122,8 @@ func processZipFile(handle *Handle, id string) {
|
|||||||
file_data, err := io.ReadAll(data)
|
file_data, err := io.ReadAll(data)
|
||||||
f.Write(file_data)
|
f.Write(file_data)
|
||||||
|
|
||||||
|
// TODO check if the file is a valid photo that matched the defined photo on the database
|
||||||
|
|
||||||
parts := strings.Split(file.Name, "/")
|
parts := strings.Split(file.Name, "/")
|
||||||
|
|
||||||
mode := model_classes.DATA_POINT_MODE_TRAINING
|
mode := model_classes.DATA_POINT_MODE_TRAINING
|
||||||
|
@ -92,7 +92,7 @@ func handleDelete(handle *Handle) {
|
|||||||
|
|
||||||
name := f.Get("name")
|
name := f.Get("name")
|
||||||
if name != model.Name {
|
if name != model.Name {
|
||||||
LoadError(w, "/models/edit.html", "delete-model-card", c.AddMap(AnyMap{
|
LoadDefineTemplate(w, "/models/edit.html", "delete-model-card", c.AddMap(AnyMap{
|
||||||
"NameDoesNotMatch": true,
|
"NameDoesNotMatch": true,
|
||||||
"Model": model,
|
"Model": model,
|
||||||
}))
|
}))
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
model_classes "git.andr3h3nriqu3s.com/andr3/fyp/logic/models/classes"
|
||||||
. "git.andr3h3nriqu3s.com/andr3/fyp/logic/utils"
|
. "git.andr3h3nriqu3s.com/andr3/fyp/logic/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -12,5 +13,7 @@ func HandleModels (handle *Handle) {
|
|||||||
|
|
||||||
// Data endpoints
|
// Data endpoints
|
||||||
handleDataUpload(handle)
|
handleDataUpload(handle)
|
||||||
|
|
||||||
|
model_classes.HandleList(handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,8 +16,22 @@ import (
|
|||||||
dbtypes "git.andr3h3nriqu3s.com/andr3/fyp/logic/db_types"
|
dbtypes "git.andr3h3nriqu3s.com/andr3/fyp/logic/db_types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func Mul (n1 int, n2 int) int {
|
||||||
|
return n1 * n2
|
||||||
|
}
|
||||||
|
|
||||||
|
func Add (n1 int, n2 int) int {
|
||||||
|
return n1 + n2
|
||||||
|
}
|
||||||
|
|
||||||
func baseLoadTemplate(base string, path string) (*template.Template, any) {
|
func baseLoadTemplate(base string, path string) (*template.Template, any) {
|
||||||
return template.New(base).ParseFiles(
|
funcs := map[string]any {
|
||||||
|
"startsWith": strings.HasPrefix,
|
||||||
|
"replace": strings.Replace,
|
||||||
|
"mul": Mul,
|
||||||
|
"add": Add,
|
||||||
|
}
|
||||||
|
return template.New(base).Funcs(funcs).ParseFiles(
|
||||||
"./views/"+base,
|
"./views/"+base,
|
||||||
"./views/"+path,
|
"./views/"+path,
|
||||||
"./views/partials/header.html",
|
"./views/partials/header.html",
|
||||||
@ -82,7 +96,7 @@ func LoadHtml(writer http.ResponseWriter, path string, data interface{}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadError(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,
|
||||||
@ -91,7 +105,14 @@ func LoadError(writer http.ResponseWriter, path string, base string, data AnyMap
|
|||||||
data["Error"] = true
|
data["Error"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := template.New("").Parse("{{template \"" + base + "\" . }}")
|
funcs := map[string]any {
|
||||||
|
"startsWith": strings.HasPrefix,
|
||||||
|
"mul": Mul,
|
||||||
|
"replace": strings.Replace,
|
||||||
|
"add": Add,
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.New("").Funcs(funcs).Parse("{{template \"" + base + "\" . }}")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("Lol")
|
panic("Lol")
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,115 @@
|
|||||||
</form>
|
</form>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
{{/* Is called from a diffrent endpoint so that it does not matter where this is from :) which means that . can mean what ever I want */}}
|
||||||
|
{{ define "data-model-create-class-table-table" }}
|
||||||
|
<div>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
File Path
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Mode
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<!-- Img -->
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{range .List}}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{.FilePath}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ if (eq .Mode 2) }}
|
||||||
|
Testing
|
||||||
|
{{ else }}
|
||||||
|
Training
|
||||||
|
{{ end }}
|
||||||
|
</td>
|
||||||
|
<td class="text-center">
|
||||||
|
{{ if startsWith .FilePath "file://" }}
|
||||||
|
<img src="/savedData/{{ $.ModelId }}/data/{{ if (eq .Mode 2) }}testing{{ else }}training{{ end }}/{{ $.Name }}/{{ replace .FilePath "file://" "" 1 }}" height="30px" width="30px" style="object-fit: contain;" />
|
||||||
|
{{ else }}
|
||||||
|
TODO
|
||||||
|
img {{ .FilePath }}
|
||||||
|
{{ end }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="flex justify-center align-center">
|
||||||
|
<div class="grow-1 flex justify-end align-center ">
|
||||||
|
{{ if gt .Page 0 }}
|
||||||
|
<button
|
||||||
|
hx-get="/models/data/list?id={{ .Id }}&page={{ add .Page -1 }}"
|
||||||
|
hx-target=".content[data-tab='{{ .Name }}']"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-headers='{"REQUEST-TYPE": "html"}'
|
||||||
|
data-tab="{{ .Name }}">
|
||||||
|
Prev
|
||||||
|
</button>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="padding: 10px;">
|
||||||
|
{{ .Page }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grow-1 flex justify-start align-center">
|
||||||
|
{{ if lt (mul .Page 10) .Count }}
|
||||||
|
<button
|
||||||
|
hx-get="/models/data/list?id={{ .Id }}&page={{ add .Page 1 }}"
|
||||||
|
hx-target=".content[data-tab='{{ .Name }}']"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-headers='{"REQUEST-TYPE": "html"}'
|
||||||
|
data-tab="{{ .Name }}">
|
||||||
|
Next
|
||||||
|
</button>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ define "data-model-create-class-table" }}
|
||||||
|
{{ if eq (len .Classes) 0 }}
|
||||||
|
TODO CREATE TABLE
|
||||||
|
{{else}}
|
||||||
|
<div class="tabs">
|
||||||
|
{{/* Handle the case where there are to many buttons */}}
|
||||||
|
{{ range .Classes }}
|
||||||
|
{{/* TODO Auto Load 1st */}}
|
||||||
|
<button
|
||||||
|
hx-get="/models/data/list?id={{ .Id }}"
|
||||||
|
hx-target=".content[data-tab='{{ .Name }}']"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-headers='{"REQUEST-TYPE": "html"}'
|
||||||
|
class="tab"
|
||||||
|
data-tab="{{ .Name }}">
|
||||||
|
{{ .Name }}
|
||||||
|
</button>
|
||||||
|
{{ end }}
|
||||||
|
{{ range .Classes }}
|
||||||
|
<div
|
||||||
|
class="content"
|
||||||
|
data-tab="{{ .Name }}"
|
||||||
|
hx-get="/models/data/list?id={{ .Id }}"
|
||||||
|
hx-target=".content[data-tab='{{ .Name }}']"
|
||||||
|
hx-trigger="load"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-headers='{"REQUEST-TYPE": "html"}'>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
{{ define "data-model-card" }}
|
{{ define "data-model-card" }}
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h3>
|
<h3>
|
||||||
@ -114,7 +223,7 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="content" data-tab="create_class">
|
<div class="content" data-tab="create_class">
|
||||||
TODO
|
{{ template "data-model-create-class-table" . }}
|
||||||
</div>
|
</div>
|
||||||
<div class="content" data-tab="api">
|
<div class="content" data-tab="api">
|
||||||
TODO
|
TODO
|
||||||
@ -132,7 +241,7 @@
|
|||||||
Api
|
Api
|
||||||
</button>
|
</button>
|
||||||
<div class="content" data-tab="create_class">
|
<div class="content" data-tab="create_class">
|
||||||
TODO
|
{{ template "data-model-create-class-table" . }}
|
||||||
</div>
|
</div>
|
||||||
<div class="content" data-tab="api">
|
<div class="content" data-tab="api">
|
||||||
TODO
|
TODO
|
||||||
|
@ -20,6 +20,30 @@ main {
|
|||||||
padding: 20px 15vw;
|
padding: 20px 15vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-center {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-start {
|
||||||
|
justify-content: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-end {
|
||||||
|
justify-content: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grow-1 {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.w100 {
|
.w100 {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: block;
|
display: block;
|
||||||
@ -47,7 +71,7 @@ main {
|
|||||||
button {
|
button {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 2px;
|
padding: 3px 6px;
|
||||||
border: none;
|
border: none;
|
||||||
box-shadow: 0 2px 8px 1px #66666655;
|
box-shadow: 0 2px 8px 1px #66666655;
|
||||||
background: var(--main);
|
background: var(--main);
|
||||||
|
Loading…
Reference in New Issue
Block a user