package main import ( "fmt" "os" "strings" todotxt "github.com/br0xen/go-todotxt" "github.com/br0xen/user-config" ) type AppState struct { Name string Version int config *userConfig.Config directory string fileTodo string fileDone string fileReport string ValidOperations map[string][]string OpFuncs map[string]func([]string) int TaskList *todotxt.TaskList DoneList *todotxt.TaskList screens []Screen } func NewApp() *AppState { app := &AppState{Name: AppName, Version: AppVersion} app.initialize() app.doVersionCheck() if err := app.LoadTaskList(); err != nil { if len(os.Args) > 1 && os.Args[1] != "--reinit" { panic(err) } } return app } func (a *AppState) run(parms []string) int { if len(parms) == 0 || parms[0] == "ui" { // UI Mode return uiLoop() } if fn, ok := a.OpFuncs[parms[0]]; ok { return fn(parms[1:]) } fmt.Println("Unknown Command") return 1 } func (a *AppState) filterList(list *todotxt.TaskList, filter string) *todotxt.TaskList { return list.Filter(a.getFilterPredicate(filter)) } func (a *AppState) getFilteredList(filter string) *todotxt.TaskList { return a.TaskList.Filter(a.getFilterPredicate(filter)) } func (a *AppState) getFilteredDoneList(filter string) *todotxt.TaskList { return a.DoneList.Filter(a.getFilterPredicate(filter)) } func (a *AppState) getTodoFile() string { return a.directory + a.fileTodo } func (a *AppState) getDoneFile() string { return a.directory + a.fileDone } func (a *AppState) getReportFile() string { return a.directory + a.fileReport } func (a *AppState) addOperation(name string, desc []string, fn func([]string) int) { a.ValidOperations[name] = desc a.OpFuncs[name] = fn } func (a *AppState) getTaskString(task todotxt.Task) string { var completed string completed = " " if task.Completed { completed = "X" } return fmt.Sprintf("%d. [%s] %s", task.Id, completed, strings.TrimPrefix(task.String(), "x ")) } func (a *AppState) getDoneTaskString(task todotxt.Task) string { var completed string completed = " " if task.Completed { completed = "X" } return fmt.Sprintf("0. [%s] %s", completed, strings.TrimPrefix(task.String(), "x ")) } func (a *AppState) doVersionCheck() { confVer, _ := a.config.GetInt("version") for confVer < a.Version { confVer = a.migrate(confVer, a.Version) } a.config.SetInt("version", confVer) } func (a *AppState) migrate(from, to int) int { if from == to { return to } switch from { case 0: a.initializeConfig() return 1 } // If we get all the way down here, we _must_ be done. return to } func (a *AppState) initialize() { var err error a.config, err = userConfig.NewConfig(a.Name) if err != nil { panic(err) } a.ValidOperations = make(map[string][]string) a.OpFuncs = make(map[string]func([]string) int) a.addOperation("ls", []string{"ls - List Tasks"}, a.opListTasks, ) a.addOperation("lsa", []string{"lsa - The same as 'ls -a'"}, func(args []string) int { return a.opListTasks(append([]string{"-a"}, args...)) }, ) a.addOperation("add", []string{"add - Add a task"}, a.opAddTask, ) a.addOperation("new", []string{"new - Same as 'add'"}, a.opAddTask, ) a.addOperation("x", []string{"x - Toggle a task's complete flag on/off"}, a.opToggleTaskComplete, ) a.addOperation("done", []string{"done - The same as 'x'"}, a.opToggleTaskComplete, ) a.addOperation("archive", []string{"archive [id1 id2 ...] - Archive completed tasks"}, a.opArchiveTasks, ) a.addOperation("--reinit", []string{"--reinit - Reset all Configuration Settings"}, func(args []string) int { a.initializeConfig() return 0 }, ) a.addOperation("-h", []string{"-h - Print this message"}, a.opPrintUsage, ) a.addOperation("help", []string{"help - Print this message"}, a.opPrintUsage, ) a.addOperation("--h", []string{"--h - Print this message"}, a.opPrintUsage, ) a.directory = a.config.Get("directory") a.fileTodo = a.config.Get("todofile") a.fileDone = a.config.Get("donefile") a.fileReport = a.config.Get("reportfile") } func (a *AppState) initializeConfig() { fmt.Println("Initializing " + a.Name) for { var add string if a.directory != "" { add = " (" + a.directory + ")" } fmt.Println("Path to todo.txt" + add + ":") var resp string fmt.Scanln(&resp) if resp == "" && a.directory != "" { resp = a.directory } if resp != "" { if !strings.HasSuffix(resp, "/") { resp = resp + "/" } fmt.Println("Setting todo.txt directory to: " + resp) a.config.Set("directory", resp) break } } a.config.Set("todofile", "todo.txt") a.config.Set("donefile", "done.txt") a.config.Set("reportfile", "report.txt") }