package main import ( "changeme/hardware" "fmt" "log" "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 { log.Fatalf("Unable to open the projects directory: %v", err) return nil, err } files, err := f.Readdir(0) if err != nil { log.Fatalf("Unable to read the projects directory: %v", err) return nil, err } for _, fileInfo := range files { // Open the file and get the show name fileData, err := os.ReadFile(filepath.Join(projectsDirectory, fileInfo.Name())) if err == nil { projectObject := ProjectInfo{} err = yaml.Unmarshal(fileData, &projectObject) if err == nil { // Add the SaveFile property projects = append(projects, ProjectMetaData{ Name: projectObject.ShowInfo.Name, Save: fileInfo.Name(), }) } } } 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", } 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) content, err := os.ReadFile(projectPath) if err != nil { log.Fatalf("Unable to read the project file: %v", err) return ProjectInfo{}, err } a.projectInfo = ProjectInfo{} err = yaml.Unmarshal(content, &a.projectInfo) if err != nil { log.Fatalf("Unable to get the project information: %v", err) return ProjectInfo{}, err } // Load it into the app a.projectSave = projectFile // Return the show information 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 { return "", err } // Copy the avatar to the application avatars path avatarPath := filepath.Join(avatarsDirectory, filepath.Base(filePath)) _, err = copy(filePath, avatarPath) if err != nil { return "", err } return filepath.Base(filePath), nil } // UpdateShowInfo updates the show information func (a *App) UpdateShowInfo(showInfo ShowInfo) { fmt.Printf("%s\n", showInfo) a.projectInfo.ShowInfo = showInfo } // SaveProject saves the project func (a *App) SaveProject() (string, error) { log.Printf("Saving the project %s to %s", a.projectInfo.ShowInfo.Name, a.projectSave) // 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) } data, err := yaml.Marshal(a.projectInfo) if err != nil { return "", err } // Create the project directory if not exists err = os.MkdirAll(projectsDirectory, os.ModePerm) if err != nil { return "", err } err = os.WriteFile(filepath.Join(projectsDirectory, a.projectSave), data, os.ModePerm) if err != nil { return "", err } 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 }