Files
dmxconnect/project.go

192 lines
7.5 KiB
Go
Raw Normal View History

2024-12-23 17:22:37 +01:00
package main
import (
2025-01-04 00:36:29 +01:00
"dmxconnect/hardware"
2024-12-23 17:22:37 +01:00
"fmt"
2024-12-29 13:09:46 +01:00
"github.com/rs/zerolog/log"
2024-12-23 17:22:37 +01:00
"os"
"path/filepath"
"time"
"github.com/wailsapp/wails/v2/pkg/runtime"
"gopkg.in/yaml.v2"
)
const (
projectsDirectory = "projects" // The directory were are stored all the projects
avatarsDirectory = "frontend/public" // The directory were are stored all the avatars
projectExtension = ".dmxproj" // The extension of a DMX Connect project
)
// GetProjects gets all the projects in the projects directory
func (a *App) GetProjects() ([]ProjectMetaData, error) {
projects := []ProjectMetaData{}
f, err := os.Open(projectsDirectory)
if err != nil {
2024-12-29 13:09:46 +01:00
log.Err(err).Str("file", "project").Msg("unable to open the projects directory")
return nil, fmt.Errorf("unable to open the projects directory: %v", err)
2024-12-23 17:22:37 +01:00
}
2024-12-29 13:09:46 +01:00
log.Trace().Str("file", "project").Str("projectsDirectory", projectsDirectory).Msg("projects directory opened")
2024-12-23 17:22:37 +01:00
files, err := f.Readdir(0)
if err != nil {
2024-12-29 13:09:46 +01:00
log.Err(err).Str("file", "project").Msg("unable to read the projects directory")
return nil, fmt.Errorf("unable to read the projects directory: %v", err)
2024-12-23 17:22:37 +01:00
}
2024-12-29 13:09:46 +01:00
log.Trace().Str("file", "project").Any("projectsFiles", files).Msg("project files got")
2024-12-23 17:22:37 +01:00
for _, fileInfo := range files {
// Open the file and get the show name
fileData, err := os.ReadFile(filepath.Join(projectsDirectory, fileInfo.Name()))
2024-12-29 13:09:46 +01:00
if err != nil {
log.Warn().Str("file", "project").Str("projectFile", fileInfo.Name()).Msg("unable to open the project file")
continue
}
log.Trace().Str("file", "project").Str("projectFile", fileInfo.Name()).Any("fileData", fileData).Msg("project file read")
projectObject := ProjectInfo{}
err = yaml.Unmarshal(fileData, &projectObject)
if err != nil {
log.Warn().Str("file", "project").Str("projectFile", fileInfo.Name()).Msg("project has invalid format")
continue
2024-12-23 17:22:37 +01:00
}
2024-12-29 13:09:46 +01:00
log.Trace().Str("file", "project").Str("projectFile", fileInfo.Name()).Msg("project file unmarshalled")
// Add the SaveFile property
projects = append(projects, ProjectMetaData{
Name: projectObject.ShowInfo.Name,
Save: fileInfo.Name(),
})
2024-12-23 17:22:37 +01:00
}
2024-12-29 13:09:46 +01:00
log.Info().Str("file", "project").Any("projectsList", projects).Msg("got the projects list")
2024-12-23 17:22:37 +01:00
return projects, nil
}
// CreateProject creates a new blank project
func (a *App) CreateProject() ShowInfo {
date := time.Now()
a.projectSave = ""
a.projectInfo.ShowInfo = ShowInfo{
Name: "My new show",
Date: fmt.Sprintf("%04d-%02d-%02dT%02d:%02d", date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute()),
Avatar: "appicon.png",
Comments: "Write your comments here",
}
2024-12-29 13:09:46 +01:00
log.Info().Str("file", "project").Any("showInfo", a.projectInfo.ShowInfo).Msg("project has been created")
2024-12-23 17:22:37 +01:00
return a.projectInfo.ShowInfo
}
// GetProjectInfo returns the information of the saved project
func (a *App) GetProjectInfo(projectFile string) (ProjectInfo, error) {
// Open the project file
projectPath := filepath.Join(projectsDirectory, projectFile)
2024-12-29 13:09:46 +01:00
log.Trace().Str("file", "project").Str("projectPath", projectPath).Msg("project path is created")
2024-12-23 17:22:37 +01:00
content, err := os.ReadFile(projectPath)
if err != nil {
2024-12-29 13:09:46 +01:00
log.Err(err).Str("file", "project").Str("projectFile", projectFile).Msg("Unable to read the project file")
return ProjectInfo{}, fmt.Errorf("unable to read the project file: %v", err)
2024-12-23 17:22:37 +01:00
}
2024-12-29 13:09:46 +01:00
log.Trace().Str("file", "project").Str("projectPath", projectPath).Msg("project file read")
2024-12-23 17:22:37 +01:00
a.projectInfo = ProjectInfo{}
err = yaml.Unmarshal(content, &a.projectInfo)
if err != nil {
2024-12-29 13:09:46 +01:00
log.Err(err).Str("file", "project").Str("projectFile", projectFile).Msg("Unable to get the project information")
return ProjectInfo{}, fmt.Errorf("unable to get the project information: %v", err)
2024-12-23 17:22:37 +01:00
}
2024-12-29 13:09:46 +01:00
log.Trace().Str("file", "project").Str("projectPath", projectPath).Msg("project information got")
2024-12-23 17:22:37 +01:00
// Load it into the app
a.projectSave = projectFile
// Return the show information
2024-12-29 13:09:46 +01:00
log.Info().Str("file", "project").Any("projectInfo", a.projectInfo).Msg("got the project information")
2024-12-23 17:22:37 +01:00
return a.projectInfo, nil
}
// ChooseAvatarPath opens a filedialog to choose the show avatar
func (a *App) ChooseAvatarPath() (string, error) {
// Open the file dialog box
filePath, err := runtime.OpenFileDialog(a.ctx, runtime.OpenDialogOptions{
Title: "Choose your show avatar",
Filters: []runtime.FileFilter{
{
DisplayName: "Images",
Pattern: "*.png;*.jpg;*.jpeg",
},
},
})
if err != nil {
2024-12-29 13:09:46 +01:00
log.Err(err).Str("file", "project").Msg("unable to open the avatar dialog")
2024-12-23 17:22:37 +01:00
return "", err
}
2024-12-29 13:09:46 +01:00
log.Debug().Str("file", "project").Msg("avatar dialog is opened")
2024-12-23 17:22:37 +01:00
// Copy the avatar to the application avatars path
avatarPath := filepath.Join(avatarsDirectory, filepath.Base(filePath))
2024-12-29 13:09:46 +01:00
log.Trace().Str("file", "project").Str("avatarPath", avatarPath).Msg("avatar path is created")
2024-12-23 17:22:37 +01:00
_, err = copy(filePath, avatarPath)
if err != nil {
2024-12-29 13:09:46 +01:00
log.Err(err).Str("file", "project").Str("avatarsDirectory", avatarsDirectory).Str("fileBase", filepath.Base(filePath)).Msg("unable to copy the avatar file")
2024-12-23 17:22:37 +01:00
return "", err
}
2024-12-29 13:09:46 +01:00
log.Info().Str("file", "project").Str("avatarFileName", filepath.Base(filePath)).Msg("got the new avatar file")
2024-12-23 17:22:37 +01:00
return filepath.Base(filePath), nil
}
// UpdateShowInfo updates the show information
func (a *App) UpdateShowInfo(showInfo ShowInfo) {
a.projectInfo.ShowInfo = showInfo
2024-12-29 13:09:46 +01:00
log.Info().Str("file", "project").Any("showInfo", showInfo).Msg("show information was updated")
2024-12-23 17:22:37 +01:00
}
// SaveProject saves the project
func (a *App) SaveProject() (string, error) {
// If there is no save file, create a new one with the show name
if a.projectSave == "" {
date := time.Now()
a.projectSave = fmt.Sprintf("%04d%02d%02d%02d%02d%02d%s", date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), projectExtension)
2024-12-29 13:09:46 +01:00
log.Debug().Str("file", "project").Str("newProjectSave", a.projectSave).Msg("projectSave is null, getting a new one")
2024-12-23 17:22:37 +01:00
}
data, err := yaml.Marshal(a.projectInfo)
if err != nil {
2024-12-29 13:09:46 +01:00
log.Err(err).Str("file", "project").Any("projectInfo", a.projectInfo).Msg("unable to format the project information")
2024-12-23 17:22:37 +01:00
return "", err
}
2024-12-29 13:09:46 +01:00
log.Trace().Str("file", "project").Any("projectInfo", a.projectInfo).Msg("projectInfo has been marshalled")
2024-12-23 17:22:37 +01:00
// Create the project directory if not exists
err = os.MkdirAll(projectsDirectory, os.ModePerm)
if err != nil {
2024-12-29 13:09:46 +01:00
log.Err(err).Str("file", "project").Str("projectsDirectory", projectsDirectory).Msg("unable to create the projects directory")
2024-12-23 17:22:37 +01:00
return "", err
}
2024-12-29 13:09:46 +01:00
log.Trace().Str("file", "project").Str("projectsDirectory", projectsDirectory).Msg("projects directory has been created")
2024-12-23 17:22:37 +01:00
err = os.WriteFile(filepath.Join(projectsDirectory, a.projectSave), data, os.ModePerm)
if err != nil {
2024-12-29 13:09:46 +01:00
log.Err(err).Str("file", "project").Str("projectsDirectory", projectsDirectory).Str("projectSave", a.projectSave).Msg("unable to save the project")
2024-12-23 17:22:37 +01:00
return "", err
}
2024-12-29 13:09:46 +01:00
log.Info().Str("file", "project").Str("projectFileName", a.projectSave).Msg("project has been saved")
2024-12-23 17:22:37 +01:00
return a.projectSave, nil
}
// ShowInfo defines the information of the show
type ShowInfo struct {
Name string `yaml:"name"`
Date string `yaml:"date"`
Avatar string `yaml:"avatar"`
Comments string `yaml:"comments"`
}
// ProjectMetaData defines all the minimum information for a lighting project
type ProjectMetaData struct {
Name string // Show name
Save string // The save file of the project
}
// ProjectInfo defines all the information for a lighting project
type ProjectInfo struct {
ShowInfo ShowInfo `yaml:"show"` // Show information
PeripheralsInfo map[string]hardware.PeripheralInfo `yaml:"peripherals"` // Peripherals information
}