todo-server/server/ajax/ajax.go

145 lines
3.4 KiB
Go
Executable File

package ajax
import (
"local/storage"
"local/todo-server/config"
"local/todo-server/server/ajax/task"
"log"
"net/http"
"net/url"
"time"
)
type Ajax struct {
DB storage.DB
ListCnt int
}
func New() (*Ajax, error) {
db, err := storage.New(storage.TypeFromString(config.StoreType), config.StoreAddr, config.StoreUser, config.StorePass)
return &Ajax{
DB: db,
}, err
}
func (a *Ajax) HandleAjax(w http.ResponseWriter, r *http.Request) {
params := r.URL.Query()
var foo func(http.ResponseWriter, *http.Request) error
if has(params, "loadLists") {
foo = a.loadLists
} else if has(params, "loadTasks") {
foo = a.loadTasks
} else if has(params, "newTask") {
foo = a.newTask
} else if has(params, "fullNewTask") {
foo = a.newTask
} else if has(params, "deleteTask") {
foo = a.deleteTask
} else if has(params, "completeTask") {
foo = a.completeTask
} else if has(params, "editNote") {
foo = a.editNote
} else if has(params, "editTask") {
foo = a.editTask
} else if has(params, "changeOrder") {
foo = a.changeOrder
} else if has(params, "suggestTags") {
foo = a.suggestTags
} else if has(params, "setPrio") {
foo = a.setPrio
} else if has(params, "tagCloud") {
foo = a.tagCloud
} else if has(params, "addList") {
foo = a.addList
} else if has(params, "renameList") {
foo = a.renameList
} else if has(params, "deleteList") {
foo = a.deleteList
} else if has(params, "setSort") {
foo = a.setSort
} else if has(params, "publishList") {
foo = a.publishList
} else if has(params, "moveTask") {
foo = a.moveTask
} else if has(params, "changeListOrder") {
foo = a.changeListOrder
} else if has(params, "parseTaskStr") {
foo = a.parseTaskStr
} else if has(params, "clearCompletedInList") {
foo = a.clearCompletedInList
} else if has(params, "setShowNotesInList") {
foo = a.setShowNotesInList
} else if has(params, "setHideList") {
foo = a.setHideList
}
if foo == nil {
http.NotFound(w, r)
} else if err := foo(w, r); err == storage.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func has(params url.Values, k string) bool {
_, ok := params[k]
return ok
}
func (a *Ajax) Async() {
var err error
nextDue := time.Now().Add(config.Loop)
c := time.NewTicker(config.Loop)
for {
select {
case <-c.C:
case <-time.After(time.Until(nextDue)):
}
log.Println("loop tasks")
nextDue, err = a.loopTasks()
if err != nil {
log.Println("failed to loop tasks", err)
}
}
}
func (a *Ajax) loopTasks() (time.Time, error) {
nextDue := time.Now().Add(time.Hour * 240)
lists, err := a.storageListLists()
if err != nil {
return nextDue, err
}
for _, list := range lists {
tasks, err := a.storageListTasks(list.UUID, func(t *task.Task) bool {
return t.Complete
})
if err != nil {
return nextDue, err
}
for _, task := range tasks {
if !task.Complete {
continue
}
if task.Loop == 0 && task.Cron == "" {
continue
}
nextLoopTrigger := task.Completed.Add(task.Loop)
if task.Loop == 0 {
nextLoopTrigger = task.Cron.Next()
}
if time.Now().Before(nextLoopTrigger) {
if nextLoopTrigger.Before(nextDue) {
nextDue = nextLoopTrigger
}
continue
}
task.Complete = false
task.Completed = time.Time{}
if err := a.storageSetTask(list.UUID, task); err != nil {
return nextDue, err
}
}
}
return nextDue, nil
}