add db models, refactor json models, add references in migrations

This commit is contained in:
lbenedar
2026-04-06 16:40:49 +03:00
parent a16edb9b61
commit 095dac5db7
28 changed files with 709 additions and 259 deletions

View File

@@ -2,8 +2,6 @@ package main
import ( import (
"net/http" "net/http"
"gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry/models"
) )
func (app *application) ShowText(w http.ResponseWriter, r *http.Request) { func (app *application) ShowText(w http.ResponseWriter, r *http.Request) {
@@ -27,27 +25,28 @@ func (app *application) ShowText(w http.ResponseWriter, r *http.Request) {
} }
func (app *application) WhenNextSession(w http.ResponseWriter, r *http.Request) { func (app *application) WhenNextSession(w http.ResponseWriter, r *http.Request) {
data, err := app.foundryApp.HandleWSRequest("/setup") // data, err := app.foundryApp.HandleWSRequest("/setup")
if err != nil { // if err != nil {
app.slogger.Error("", "error", err) // app.slogger.Error("", "error", err)
w.Write([]byte(err.Error())) // w.Write([]byte(err.Error()))
// return
// }
// setupData, err := json_model.ParseSetupModel(data)
// if err != nil {
// app.slogger.Error("", "error", err)
// w.Write([]byte(err.Error()))
// return
// }
// // nextSession, err := setupData.GetWorlds().GetSessionTime("")
// // if err != nil {
// // app.slogger.Error("", "error", err)
// // w.Write([]byte(err.Error()))
// // return
// // }
// app.slogger.Info("Next session data is ready to send", "sessionTime", nextSession)
// w.Write([]byte(nextSession.Local().String()))
return return
} }
setupData, err := models.ParseSetupModel(data)
if err != nil {
app.slogger.Error("", "error", err)
w.Write([]byte(err.Error()))
return
}
nextSession, err := setupData.GetWorlds().GetSessionTime("")
if err != nil {
app.slogger.Error("", "error", err)
w.Write([]byte(err.Error()))
return
}
app.slogger.Info("Next session data is ready to send", "sessionTime", nextSession)
w.Write([]byte(nextSession.Local().String()))
}

View File

@@ -150,6 +150,8 @@ func main() {
defer db.Close() defer db.Close()
app.slogger.Info("Database connection pool established") app.slogger.Info("Database connection pool established")
app.foundryApp.CreateNewDataModels(db)
go app.StartListenFoundry() go app.StartListenFoundry()
errLog := slog.NewLogLogger(app.slogger.Handler(), slog.LevelError) errLog := slog.NewLogLogger(app.slogger.Handler(), slog.LevelError)

View File

@@ -1,13 +1,14 @@
CREATE TABLE IF NOT EXISTS modules ( CREATE TABLE IF NOT EXISTS modules (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
state_id INTEGER NOT NULL,
text_id VARCHAR(256) NOT NULL, text_id VARCHAR(256) NOT NULL,
title VARCHAR(256) NOT NULL, title VARCHAR(256) NOT NULL,
description TEXT NOT NULL, description TEXT NOT NULL,
url VARCHAR(256) NOT NULL, url VARCHAR(256) NOT NULL,
version VARCHAR(64) NOT NULL, version VARCHAR(64) NOT NULL,
availability INTEGER NOT NULL, availability INTEGER NOT NULL,
created_at DATETIME NOT NULL DEFAULT current_timestamp,
created_at DATETIME NOT NULL DEFAULT current_timestamp FOREIGN KEY (state_id) REFERENCES foundry_state(id) ON DELETE CASCADE
); );
CREATE TABLE IF NOT EXISTS modules_compatibility ( CREATE TABLE IF NOT EXISTS modules_compatibility (

View File

@@ -1,12 +1,13 @@
CREATE TABLE IF NOT EXISTS systems ( CREATE TABLE IF NOT EXISTS systems (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
state_id INTEGER NOT NULL,
text_id VARCHAR(256) NOT NULL, text_id VARCHAR(256) NOT NULL,
title VARCHAR(256) NOT NULL, title VARCHAR(256) NOT NULL,
description TEXT NOT NULL, description TEXT NOT NULL,
url VARCHAR(256) NOT NULL, url VARCHAR(256) NOT NULL,
download VARCHAR(256) NOT NULL, download VARCHAR(256) NOT NULL,
created_at DATETIME NOT NULL DEFAULT current_timestamp,
created_at DATETIME NOT NULL DEFAULT current_timestamp FOREIGN KEY (state_id) REFERENCES foundry_state(id) ON DELETE CASCADE
); );
CREATE TABLE IF NOT EXISTS systems_compatibility ( CREATE TABLE IF NOT EXISTS systems_compatibility (

View File

@@ -1,5 +1,6 @@
CREATE TABLE IF NOT EXISTS worlds ( CREATE TABLE IF NOT EXISTS worlds (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
state_id INTEGER NOT NULL,
text_id VARCHAR(256) NOT NULL, text_id VARCHAR(256) NOT NULL,
title VARCHAR(256) NOT NULL, title VARCHAR(256) NOT NULL,
description TEXT NOT NULL, description TEXT NOT NULL,
@@ -8,8 +9,8 @@ CREATE TABLE IF NOT EXISTS worlds (
system_version VARCHAR(256) NOT NULL, system_version VARCHAR(256) NOT NULL,
playtime INTEGER NOT NULL, playtime INTEGER NOT NULL,
next_session DATETIME NOT NULL, next_session DATETIME NOT NULL,
created_at DATETIME NOT NULL DEFAULT current_timestamp,
created_at DATETIME NOT NULL DEFAULT current_timestamp FOREIGN KEY (state_id) REFERENCES foundry_state(id) ON DELETE CASCADE
); );
CREATE TABLE IF NOT EXISTS worlds_compatibility ( CREATE TABLE IF NOT EXISTS worlds_compatibility (

View File

@@ -1,12 +1,13 @@
CREATE TABLE IF NOT EXISTS users ( CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
state_id INTEGER NOT NULL,
name VARCHAR(256) NOT NULL, name VARCHAR(256) NOT NULL,
role INTEGER NOT NULL, role INTEGER NOT NULL,
character VARCHAR(128) NOT NULL, character VARCHAR(128) NOT NULL,
color VARCHAR(128) NOT NULL, color VARCHAR(128) NOT NULL,
pronouns VARCHAR(128) NOT NULL, pronouns VARCHAR(128) NOT NULL,
created_at DATETIME NOT NULL DEFAULT current_timestamp,
created_at DATETIME NOT NULL DEFAULT current_timestamp FOREIGN KEY (state_id) REFERENCES foundry_state(id) ON DELETE CASCADE
); );
CREATE TABLE IF NOT EXISTS users_hotbar ( CREATE TABLE IF NOT EXISTS users_hotbar (

View File

@@ -1,6 +1,7 @@
package foundry package foundry
import ( import (
"database/sql"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@@ -10,6 +11,7 @@ import (
"strconv" "strconv"
"strings" "strings"
data "gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry/models/db"
"gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry/requests" "gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry/requests"
"gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry/types" "gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry/types"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
@@ -47,8 +49,7 @@ type Foundry struct {
isAuth bool isAuth bool
logger *slog.Logger logger *slog.Logger
// db db.DB models data.Models
config requests.Config config requests.Config
ws *webSocketUtil ws *webSocketUtil
} }
@@ -110,6 +111,17 @@ func (foundry *Foundry) StartListen() error {
var err error var err error
for { for {
select { select {
// case msg, ok := <-foundry.ws.channels.Msg():
// if !ok {
// time.Sleep(5 * time.Microsecond)
// continue
// }
// var foundryState *json_model.FoundryState
// foundryState, err = json_model.ParseSetupModel(msg.ToByteSlice())
// if err != nil {
// return nil
// }
// foundry.models.FoundryState.Insert(foundryState)
case err = <-wsChannels.Err(): case err = <-wsChannels.Err():
var foundryErr *FoundryError var foundryErr *FoundryError
if errors.As(err, &foundryErr) { if errors.As(err, &foundryErr) {
@@ -205,6 +217,10 @@ func (foundry *Foundry) SetLogger(slogger *slog.Logger) {
foundry.ws.logger = slogger foundry.ws.logger = slogger
} }
func (foundry *Foundry) CreateNewDataModels(db *sql.DB) {
foundry.models = data.NewModels(db)
}
// /** // /**
// * Poll the server to see if a World has become active, and automatically refresh if so. // * Poll the server to see if a World has become active, and automatically refresh if so.
// * @returns {Promise<void>} // * @returns {Promise<void>}

View File

@@ -1,44 +0,0 @@
package models
import (
"encoding/json"
)
type FoundryState struct {
IsAdmin bool `json:"isAdmin,omitempty"`
IsSetup bool `json:"isSetup,omitempty"`
Languages []Language `json:"languages,omitempty"`
Modules []DataTemplate `json:"modules"`
Release Release `json:"release"`
Systems []DataTemplate `json:"systems,omitempty"`
Worlds []DataTemplate `json:"worlds,omitempty"`
World *DataTemplate `json:"world,omitempty"`
Users Users `json:"users,omitempty"`
Options struct {
Language string `json:"language,omitempty"`
} `json:"options,omitempty"`
//coreUpdate struct{}
//featuredContent struct{}
//files struct{}
//news struct{}
//packageWarnings struct{} think about it
}
func (state FoundryState) GetRelease() Release {
return state.Release
}
func ParseSetupModel(data []byte) (*FoundryState, error) {
var modelSetup []FoundryState
err := json.Unmarshal(data, &modelSetup)
if err != nil {
return nil, err
}
if len(modelSetup) > 1 {
return nil, ErrorSetupMoreThanOne
}
return &modelSetup[0], nil
}

View File

@@ -1,4 +1,4 @@
package models package db
import "errors" import "errors"

View File

@@ -0,0 +1,113 @@
package db
import (
"context"
"database/sql"
"time"
)
type StateType int
const (
AuthState = StateType(0)
SetupState = StateType(1)
JoinState = StateType(2)
PlayersState = StateType(3)
UpdateState = StateType(4)
LicenseState = StateType(5)
)
type FoundryState struct {
Id int
IsAdmin bool
IsSetup bool
Type StateType
CreatedAt time.Time
Options Options
Modules Modules
Systems Systems
Worlds Worlds
Users Users
}
type Compatibility struct {
Id int
Minimum string
Verified string
Maximum string
}
type Options struct {
Id int
Language string
}
type FoundryStateModel struct {
DB *sql.DB
}
func (m FoundryStateModel) Insert(state *FoundryState) error {
query := `
INSERT INTO foundry_state (is_admin, is_setup, state_type)
VALUES ($1, $2, $3)
RETURNING id, created_at`
args := []any{state.IsAdmin, state.IsSetup, state.Type}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
err := m.DB.QueryRowContext(ctx, query, args...).Scan(&state.Id, &state.CreatedAt)
if err != nil {
return err
}
err = m.InsertOptions(&state.Options, state.Id)
if err != nil {
return err
}
for i := range state.Modules {
err = m.InsertModule(&state.Modules[i], state.Id)
if err != nil {
return err
}
}
for i := range state.Systems {
err = m.InsertSystem(&state.Systems[i], state.Id)
if err != nil {
return err
}
}
for i := range state.Worlds {
err = m.InsertWorld(&state.Worlds[i], state.Id)
if err != nil {
return err
}
}
for i := range state.Users {
err = m.InsertUser(&state.Users[i], state.Id)
if err != nil {
return err
}
}
return nil
}
func (m FoundryStateModel) InsertOptions(options *Options, stateId int) error {
query := `
INSERT INTO options (state_id, lang)
VALUES ($1, $2)
RETURNING id`
args := []any{stateId, options.Language}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
return m.DB.QueryRowContext(ctx, query, args...).Scan(&options.Id)
}

View File

@@ -0,0 +1,35 @@
package db
import "database/sql"
// var (
// ErrRecordNotFound = errors.New("record not found")
// ErrEditConflict = errors.New("edit conflict")
// )
type Models struct {
FoundryState FoundryStateModel
}
// type Models struct {
// Movies interface {
// Insert(movie *Movie) error
// Get(id int64) (*Movie, error)
// Update(movie *Movie) error
// Delete(id int64) error
// GetAll(title string, genres []string, filter Filters) ([]*Movie, Metadata, error)
// }
// }
func NewModels(db *sql.DB) Models {
return Models{
FoundryState: FoundryStateModel{DB: db},
}
}
// func NewMockModels() Models {
// return Models{
// Movies: MockMovieModel{},
// Users: MockMovieModel{},
// }
// }

View File

@@ -0,0 +1,84 @@
package db
import (
"context"
"time"
)
type Module struct {
Id int
TextId string
Title string
Description string
Url string
Version string
Availability int
CreatedAt time.Time
Languages []Language
Compatibility Compatibility
}
type Language struct {
Id string
Lang string
Name string
Path string
}
type Modules []Module
func (modules Modules) GetById(id int) *Module {
return &modules[id]
}
func (m FoundryStateModel) InsertModule(module *Module, stateId int) error {
query := `
INSERT INTO modules (state_id, text_id, title, description, url, version, availability)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING id, created_at`
args := []any{stateId, module.TextId, module.Title, module.Description, module.Url, module.Version, module.Availability}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
err := m.DB.QueryRowContext(ctx, query, args...).Scan(&module.Id, &module.CreatedAt)
if err != nil {
return err
}
for i := range module.Languages {
err = m.InsertModuleLanguages(&module.Languages[i], module.Id)
if err != nil {
return err
}
}
return m.InsertModuleCompatibility(&module.Compatibility, module.Id)
}
func (m FoundryStateModel) InsertModuleCompatibility(compatibility *Compatibility, moduleId int) error {
query := `
INSERT INTO modules_compatibility (model_id, minumum, verified, maximum)
VALUES ($1, $2, $3, $4)
RETURNING id`
args := []any{moduleId, compatibility.Minimum, compatibility.Verified, compatibility.Maximum}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
return m.DB.QueryRowContext(ctx, query, args...).Scan(&compatibility.Id)
}
func (m FoundryStateModel) InsertModuleLanguages(lang *Language, moduleId int) error {
query := `
INSERT INTO modules_compatibility (model_id, language, name, path)
VALUES ($1, $2, $3, $4)
RETURNING id`
args := []any{moduleId, lang.Lang, lang.Name, lang.Path}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
return m.DB.QueryRowContext(ctx, query, args...).Scan(&lang.Id)
}

View File

@@ -0,0 +1,53 @@
package db
import (
"context"
"time"
)
type System struct {
Id int
TextId string
Title string
Description string
Url string
Download string
CreatedAt time.Time
Compatibility Compatibility
}
type Systems []System
func (systems Systems) GetById(id int) *System {
return &systems[id]
}
func (m FoundryStateModel) InsertSystem(system *System, stateId int) error {
query := `
INSERT INTO systems (state_id, text_id, title, description, url, download)
VALUES ($1, $2, $3, $4, $5, $6)`
args := []any{stateId, system.TextId, system.Title, system.Description, system.Url, system.Download}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
err := m.DB.QueryRowContext(ctx, query, args...).Scan(&system.Id)
if err != nil {
return err
}
return m.InsertModuleCompatibility(&system.Compatibility, system.Id)
}
func (m FoundryStateModel) InsertSystenCompatibility(compatibility *Compatibility, systemId int) error {
query := `
INSERT INTO systems_compatibility (system_id, minumum, verified, maximum)
VALUES ($1, $2, $3, $4)`
args := []any{systemId, compatibility.Minimum, compatibility.Verified, compatibility.Maximum}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
return m.DB.QueryRowContext(ctx, query, args...).Scan(&compatibility.Id)
}

View File

@@ -0,0 +1,91 @@
package db
import (
"context"
"time"
)
type User struct {
Id int
Name string
Role int
Character string
Color string
Pronouns string
CreatedAt time.Time
Hotbar map[string]string
Stats UserStats
}
type UserStats struct {
Id int
CoreVersion string
SystemId string
SystemVersion string
CreatedTime int64
ModifiedTime int64
LastModifiedBy string
}
type Users []User
func (users Users) GetById(id int) *User {
return &users[id]
}
func (m FoundryStateModel) InsertUser(user *User, stateId int) error {
query := `
INSERT INTO users (state_id, name, role, character, color, pronouns)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING id, created_at`
args := []any{stateId, user.Name, user.Role, user.Character, user.Color, user.Pronouns}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
err := m.DB.QueryRowContext(ctx, query, args...).Scan(&user.Id, &user.CreatedAt)
if err != nil {
return err
}
for k, v := range user.Hotbar {
err = m.InsertUserHotbar(k, v, user.Id)
if err != nil {
return err
}
}
return m.InsertUserStats(&user.Stats, user.Id)
}
func (m FoundryStateModel) InsertUserHotbar(key string, value string, userId int) error {
query := `
INSERT INTO users_hotbar (user_id, key, value)
VALUES ($1, $2, $3)`
args := []any{userId, key, value}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
_, err := m.DB.ExecContext(ctx, query, args...)
if err != nil {
return err
}
return nil
}
func (m FoundryStateModel) InsertUserStats(stats *UserStats, userId int) error {
query := `
INSERT INTO users_stats (user_id, core_version, system_id, system_version, created_time, modified_time, last_modified_by)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING id`
args := []any{userId, stats.CoreVersion, stats.SystemId, stats.SystemVersion, stats.CreatedTime, stats.ModifiedTime, stats.LastModifiedBy}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
return m.DB.QueryRowContext(ctx, query, args...).Scan(&stats.Id)
}

View File

@@ -0,0 +1,81 @@
package db
import (
"context"
"time"
)
type World struct {
Id int
TextId string
Title string
Description string
System string
CoreVersion string
SystemVersion string
LastPlayed string
PlayTime int64
NextSession time.Time
CreatedAt time.Time
Compatibility Compatibility
}
type Worlds []World
func (worlds Worlds) GetById(id int) *World {
return &worlds[id]
}
func (m FoundryStateModel) InsertWorld(world *World, stateId int) error {
query := `
INSERT INTO worlds (state_id, text_id, title, description, system, core_version, system_version, playtime, next_session)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
RETURNING id, created_at`
args := []any{stateId, world.TextId, world.Title, world.Description, world.System, world.System, world.CoreVersion, world.SystemVersion, world.PlayTime, world.NextSession}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
err := m.DB.QueryRowContext(ctx, query, args...).Scan(&world.Id, &world.CreatedAt)
if err != nil {
return err
}
return m.InsertWorldCompatibility(&world.Compatibility, world.Id)
}
func (m FoundryStateModel) InsertWorldCompatibility(compatibility *Compatibility, worldId int) error {
query := `
INSERT INTO worlds_compatibility (world_id, minumum, verified, maximum)
VALUES ($1, $2, $3, $4)
RETURNING id`
args := []any{worldId, compatibility.Minimum, compatibility.Verified, compatibility.Maximum}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
return m.DB.QueryRowContext(ctx, query, args...).Scan(&compatibility.Id)
}
// func (worlds Worlds) GetSessionTime(worldName string) (*time.Time, error) {
// if worldName == "" && len(worlds) != 1 {
// return nil, ErrorSetupNotFound
// }
// if worldName == "" {
// return &worlds.GetById(0).NextSession, nil
// } else {
// for i := range worlds {
// if worlds[i].Id == worldName {
// return &worlds.GetById(0).NextSession, nil
// }
// }
// }
// return nil, ErrorSetupNotFound
// }
// func (world World) GetSessionTime() *time.Time {
// return &world.NextSession
// }

View File

@@ -0,0 +1,181 @@
package json
import (
"encoding/json"
"gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry/models/db"
)
type FoundryState struct {
IsAdmin bool `json:"isAdmin,omitempty"`
IsSetup bool `json:"isSetup,omitempty"`
Languages []Language `json:"languages,omitempty"`
Modules []DataTemplate `json:"modules"`
Release Release `json:"release"`
Systems []DataTemplate `json:"systems,omitempty"`
Worlds []DataTemplate `json:"worlds,omitempty"`
World *DataTemplate `json:"world,omitempty"`
Users Users `json:"users,omitempty"`
Options Options `json:"options,omitempty"`
//coreUpdate struct{}
//featuredContent struct{}
//files struct{}
//news struct{}
//packageWarnings struct{} think about it
}
type Options struct {
Language string `json:"language,omitempty"`
}
func (state FoundryState) GetRelease() Release {
return state.Release
}
func (state FoundryState) GetFoundryStateDB(stateType db.StateType) *db.FoundryState {
dbFoundryState := db.FoundryState{
IsAdmin: state.IsAdmin,
IsSetup: state.IsSetup,
Type: stateType,
Options: db.Options{Language: state.Options.Language},
}
dbFoundryState.Modules = state.GetModules()
dbFoundryState.Systems = state.GetSystems()
dbFoundryState.Worlds = state.GetWorlds()
dbFoundryState.Users = state.GetUsers()
return &dbFoundryState
}
func (state *FoundryState) GetModules() db.Modules {
modulesCopy := make([]db.Module, 0, 8)
for i := range state.Modules {
module := &(state.Modules[i])
moduleCopy := db.Module{
TextId: module.Id,
Title: module.Title,
Description: module.Description,
Compatibility: db.Compatibility{
Minimum: module.Compatibility.Minimum,
Maximum: module.Compatibility.Maximum,
},
Url: module.Url,
Version: module.CoreVersion,
Availability: module.Availability,
}
for j := range module.Languages {
lang := db.Language{
Lang: module.Languages[j].Lang,
Name: module.Languages[j].Name,
Path: module.Languages[j].Path,
}
moduleCopy.Languages = append(moduleCopy.Languages, lang)
}
modulesCopy = append(modulesCopy, moduleCopy)
}
return modulesCopy
}
func (state *FoundryState) GetSystems() db.Systems {
systemsCopy := make([]db.System, 0, 8)
for i := range state.Systems {
system := &(state.Systems[i])
systemCopy := db.System{
TextId: system.Id,
Title: system.Title,
Description: system.Description,
Url: system.Url,
Compatibility: db.Compatibility{
Minimum: system.Compatibility.Minimum,
Maximum: system.Compatibility.Maximum,
},
Download: system.Download,
}
systemsCopy = append(systemsCopy, systemCopy)
}
return systemsCopy
}
func (state *FoundryState) GetWorld() *db.World {
return &db.World{
TextId: state.World.Id,
Title: state.World.Title,
Description: state.World.Description,
Compatibility: db.Compatibility{
Minimum: state.World.Compatibility.Minimum,
Maximum: state.World.Compatibility.Maximum,
},
System: state.World.System,
CoreVersion: state.World.CoreVersion,
SystemVersion: state.World.SystemVersion,
LastPlayed: state.World.LastPlayed,
PlayTime: state.World.PlayTime,
NextSession: state.World.NextSession,
}
}
func (state *FoundryState) GetWorlds() db.Worlds {
worldsCopy := make([]db.World, 0, 8)
for i := range state.Worlds {
world := &(state.Worlds[i])
worldCopy := db.World{
TextId: world.Id,
Title: world.Title,
Description: world.Description,
Compatibility: db.Compatibility{
Minimum: world.Compatibility.Minimum,
Maximum: world.Compatibility.Maximum,
},
System: world.System,
CoreVersion: world.CoreVersion,
SystemVersion: world.SystemVersion,
LastPlayed: world.LastPlayed,
PlayTime: world.PlayTime,
NextSession: world.NextSession,
}
worldsCopy = append(worldsCopy, worldCopy)
}
return worldsCopy
}
func (state *FoundryState) GetUsers() db.Users {
usersCopy := make(db.Users, 0, 8)
for i := range state.Users {
user := &(state.Users[i])
userCopy := db.User{
Name: user.Name,
Role: user.Role,
Character: user.Character,
Color: user.Color,
Pronouns: user.Pronouns,
Hotbar: user.Hotbar,
Stats: db.UserStats{
CoreVersion: user.Stats.CoreVersion,
SystemId: user.Stats.SystemId,
SystemVersion: user.Stats.SystemVersion,
CreatedTime: user.Stats.CreatedTime,
ModifiedTime: user.Stats.ModifiedTime,
LastModifiedBy: user.Stats.LastModifiedBy,
},
}
usersCopy = append(usersCopy, userCopy)
}
return usersCopy
}
func ParseSetupModel(data []byte) (*FoundryState, error) {
var modelSetup []FoundryState
err := json.Unmarshal(data, &modelSetup)
if err != nil {
return nil, err
}
if len(modelSetup) > 1 {
return nil, ErrorSetupMoreThanOne
}
return &modelSetup[0], nil
}

View File

@@ -0,0 +1,8 @@
package json
import "errors"
var (
ErrorSetupMoreThanOne = errors.New("Passed more than one setupData")
ErrorSetupNotFound = errors.New("Not found setup data from your request")
)

View File

@@ -1,4 +1,4 @@
package models package json
type Language struct { type Language struct {
Id string `json:"id"` Id string `json:"id"`

View File

@@ -1,4 +1,4 @@
package models package json
type Release struct { type Release struct {
Generation int `json:"generation"` Generation int `json:"generation"`

View File

@@ -1,4 +1,4 @@
package models package json
type Status struct { type Status struct {
Active bool `json:"active"` Active bool `json:"active"`

View File

@@ -1,4 +1,4 @@
package models package json
import "time" import "time"

View File

@@ -1,6 +1,6 @@
package models package json
import "gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry/models/modules" import "gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry/models/json/modules"
type User struct { type User struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`

View File

@@ -1,49 +0,0 @@
package models
type Module struct {
Id string
Title string
Description string
Url string
Version string
Compatibility Compatibility
Languages []DataLanguage
Availability int
}
type Modules []Module
func (modules Modules) GetById(id int) *Module {
return &modules[id]
}
func (state *FoundryState) GetModules() Modules {
modulesCopy := make([]Module, 0, 8)
for i := range state.Modules {
module := &(state.Modules[i])
moduleCopy := Module{
Id: module.Id,
Title: module.Title,
Description: module.Description,
Compatibility: Compatibility{
Minimum: module.Compatibility.Minimum,
Maximum: module.Compatibility.Maximum,
},
Url: module.Url,
Version: module.CoreVersion,
Availability: module.Availability,
}
for j := range module.Languages {
lang := DataLanguage{
Lang: module.Languages[j].Lang,
Name: module.Languages[j].Name,
Path: module.Languages[j].Path,
Flags: module.Languages[j].Flags,
}
moduleCopy.Languages = append(moduleCopy.Languages, lang)
}
modulesCopy = append(modulesCopy, moduleCopy)
}
return modulesCopy
}

View File

@@ -1,36 +0,0 @@
package models
type System struct {
Id string
Title string
Description string
Url string
Compatibility Compatibility
Download string
}
type Systems []System
func (systems Systems) GetById(id int) *System {
return &systems[id]
}
func (state *FoundryState) GetSystems() Systems {
systemsCopy := make([]System, 0, 8)
for i := range state.Systems {
system := &(state.Systems[i])
systemCopy := System{
Id: system.Id,
Title: system.Title,
Description: system.Description,
Url: system.Url,
Compatibility: Compatibility{
Minimum: system.Compatibility.Minimum,
Maximum: system.Compatibility.Maximum,
},
Download: system.Download,
}
systemsCopy = append(systemsCopy, systemCopy)
}
return systemsCopy
}

View File

@@ -1,88 +0,0 @@
package models
import (
"time"
)
type World struct {
Id string
Title string
Description string
Compatibility Compatibility
System string
CoreVersion string
SystemVersion string
LastPlayed string
PlayTime int64
NextSession time.Time
}
type Worlds []World
func (worlds Worlds) GetById(id int) *World {
return &worlds[id]
}
func (state *FoundryState) GetWorld() World {
return World{
Id: state.World.Id,
Title: state.World.Title,
Description: state.World.Description,
Compatibility: Compatibility{
Minimum: state.World.Compatibility.Minimum,
Maximum: state.World.Compatibility.Maximum,
},
System: state.World.System,
CoreVersion: state.World.CoreVersion,
SystemVersion: state.World.SystemVersion,
LastPlayed: state.World.LastPlayed,
PlayTime: state.World.PlayTime,
NextSession: state.World.NextSession,
}
}
func (state *FoundryState) GetWorlds() Worlds {
worldsCopy := make([]World, 0, 8)
for i := range state.Worlds {
world := &(state.Worlds[i])
worldCopy := World{
Id: world.Id,
Title: world.Title,
Description: world.Description,
Compatibility: Compatibility{
Minimum: world.Compatibility.Minimum,
Maximum: world.Compatibility.Maximum,
},
System: world.System,
CoreVersion: world.CoreVersion,
SystemVersion: world.SystemVersion,
LastPlayed: world.LastPlayed,
PlayTime: world.PlayTime,
NextSession: world.NextSession,
}
worldsCopy = append(worldsCopy, worldCopy)
}
return worldsCopy
}
func (worlds Worlds) GetSessionTime(worldName string) (*time.Time, error) {
if worldName == "" && len(worlds) != 1 {
return nil, ErrorSetupNotFound
}
if worldName == "" {
return &worlds.GetById(0).NextSession, nil
} else {
for i := range worlds {
if worlds[i].Id == worldName {
return &worlds.GetById(0).NextSession, nil
}
}
}
return nil, ErrorSetupNotFound
}
func (world World) GetSessionTime() *time.Time {
return &world.NextSession
}

View File

@@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry/models" json_model "gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry/models/json"
) )
func (conf *Config) GetSessionId() error { func (conf *Config) GetSessionId() error {
@@ -42,7 +42,7 @@ func (conf *Config) GetSessionToken() (bool, error) {
return conf.SetSessionTokenFromHeader(resp.Header) return conf.SetSessionTokenFromHeader(resp.Header)
} }
func (conf *Config) GetStatus() (*models.Status, error) { func (conf *Config) GetStatus() (*json_model.Status, error) {
getResp, err := http.Get(fmt.Sprintf("http://%s/api/status", conf.Host)) getResp, err := http.Get(fmt.Sprintf("http://%s/api/status", conf.Host))
if err != nil { if err != nil {
return nil, err return nil, err
@@ -55,7 +55,7 @@ func (conf *Config) GetStatus() (*models.Status, error) {
return nil, err return nil, err
} }
var status models.Status var status json_model.Status
err = json.Unmarshal(statusByte, &status) err = json.Unmarshal(statusByte, &status)
if err != nil { if err != nil {
return nil, err return nil, err