Add basic library code to manage projects, activities and times.
This commit is contained in:
parent
529efb3668
commit
fb576f3d51
7 changed files with 663 additions and 0 deletions
142
lib/projects.go
Normal file
142
lib/projects.go
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
package lib
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// Project entity. In addition to the JSON properties as defined by the specification, it holds activities of the
|
||||
// project organized by title and by ID in a map.
|
||||
type Project struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
activitiesByTitle map[string]*Activity
|
||||
activitiesByID map[string]*Activity
|
||||
activitiesLoaded bool
|
||||
}
|
||||
|
||||
// NewProject creates a new project instance.
|
||||
func NewProject() *Project {
|
||||
return &Project{
|
||||
activitiesByID: make(map[string]*Activity),
|
||||
activitiesByTitle: make(map[string]*Activity),
|
||||
}
|
||||
}
|
||||
|
||||
// GetProjects retrieves all stored project instances. It does not load related data like activities or times.
|
||||
func GetProjects() ([]*Project, error) {
|
||||
folder, folderErr := getProjectFolder()
|
||||
if folderErr != nil {
|
||||
return nil, folderErr
|
||||
}
|
||||
|
||||
dirErr := os.MkdirAll(folder, 0o750)
|
||||
if dirErr != nil {
|
||||
return nil, dirErr
|
||||
}
|
||||
|
||||
files, filesErr := os.ReadDir(folder)
|
||||
if filesErr != nil {
|
||||
return nil, filesErr
|
||||
}
|
||||
|
||||
projects := []*Project{}
|
||||
for _, file := range files {
|
||||
project, fileErr := readProject(filepath.Join(folder, file.Name()))
|
||||
if fileErr != nil {
|
||||
return nil, fileErr
|
||||
}
|
||||
projects = append(projects, project)
|
||||
}
|
||||
|
||||
return projects, nil
|
||||
}
|
||||
|
||||
// GetProject retrieves a single project by its ID. It does not load related data like activities or times.
|
||||
func GetProject(id string) (*Project, error) {
|
||||
file, fileErr := getProjectFile(id)
|
||||
if fileErr != nil {
|
||||
return nil, fileErr
|
||||
}
|
||||
project, err := readProject(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
project.ID = id
|
||||
|
||||
return project, nil
|
||||
}
|
||||
|
||||
// SetProject persists a project.
|
||||
func SetProject(project *Project) error {
|
||||
uuid, uuidErr := newUUID()
|
||||
if uuidErr != nil {
|
||||
return uuidErr
|
||||
}
|
||||
|
||||
project.ID = uuid
|
||||
|
||||
file, fileErr := getProjectFile(uuid)
|
||||
if fileErr != nil {
|
||||
return fileErr
|
||||
}
|
||||
|
||||
return writeProject(file, project)
|
||||
}
|
||||
|
||||
// readProject reads a project from a file and converts it into an entity instance.
|
||||
func readProject(filename string) (*Project, error) {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
project := NewProject()
|
||||
if err := json.NewDecoder(file).Decode(&project); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return project, nil
|
||||
}
|
||||
|
||||
// writeProject writes a project instance to a file.
|
||||
func writeProject(filename string, project *Project) error {
|
||||
dirErr := os.MkdirAll(filepath.Dir(filename), 0o750)
|
||||
if dirErr != nil {
|
||||
return dirErr
|
||||
}
|
||||
|
||||
file, fileErr := os.Create(filename)
|
||||
if fileErr != nil {
|
||||
return fileErr
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
encoder := json.NewEncoder(file)
|
||||
encoder.SetIndent("", " ")
|
||||
|
||||
jsonErr := encoder.Encode(project)
|
||||
if jsonErr != nil {
|
||||
return jsonErr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getProjectFolder returns the folder to store project entity files in.
|
||||
func getProjectFolder() (string, error) {
|
||||
return getDataDir("projects")
|
||||
}
|
||||
|
||||
// getProjectFile returns the file name for a project entity instance.
|
||||
func getProjectFile(name string) (string, error) {
|
||||
folder, err := getProjectFolder()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return filepath.Join(folder, name+".json"), nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue