Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 82 additions & 4 deletions backend/handle_tw.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ func ExportTasks(tempDir string) ([]Task, error) {

// add task to the user's tw client
func AddTaskToTaskwarrior(email, encryptionSecret, uuid, description, project, priority, dueDate string) error {
cmd := exec.Command("rm", "-rf", "/root/.task")
if err := cmd.Run(); err != nil {
return fmt.Errorf("error deleting Taskwarrior data: %v", err)
}

tempDir, err := os.MkdirTemp("", "taskwarrior-"+email)
if err != nil {
return fmt.Errorf("failed to create temporary directory: %v", err)
Expand All @@ -144,7 +149,7 @@ func AddTaskToTaskwarrior(email, encryptionSecret, uuid, description, project, p
cmdArgs = append(cmdArgs, "due:"+dueDate)
}

cmd := exec.Command("task", cmdArgs...)
cmd = exec.Command("task", cmdArgs...)
cmd.Dir = tempDir
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to add task: %v", err)
Expand All @@ -159,6 +164,10 @@ func AddTaskToTaskwarrior(email, encryptionSecret, uuid, description, project, p
}

func EditTaskInTaskwarrior(uuid, description, email, encryptionSecret, taskuuid string) error {
cmd := exec.Command("rm", "-rf", "/root/.task")
if err := cmd.Run(); err != nil {
return fmt.Errorf("error deleting Taskwarrior data: %v", err)
}
tempDir, err := os.MkdirTemp("", "taskwarrior-"+email)
if err != nil {
return fmt.Errorf("failed to create temporary directory: %v", err)
Expand All @@ -177,7 +186,7 @@ func EditTaskInTaskwarrior(uuid, description, email, encryptionSecret, taskuuid
// Escape the double quotes in the description and format it
escapedDescription := fmt.Sprintf(`description:"%s"`, strings.ReplaceAll(description, `"`, `\"`))

cmd := exec.Command("task", taskuuid, "modify", escapedDescription)
cmd = exec.Command("task", taskuuid, "modify", escapedDescription)
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to edit task: %v", err)
}
Expand All @@ -189,7 +198,72 @@ func EditTaskInTaskwarrior(uuid, description, email, encryptionSecret, taskuuid
return nil
}

func ModifyTaskInTaskwarrior(uuid, description, project, priority, status, due, email, encryptionSecret, taskuuid string) error {
cmd := exec.Command("rm", "-rf", "/root/.task")
if err := cmd.Run(); err != nil {
return fmt.Errorf("error deleting Taskwarrior data: %v", err)
}
tempDir, err := os.MkdirTemp("", "taskwarrior-"+email)
if err != nil {
return fmt.Errorf("failed to create temporary directory: %v", err)
}
defer os.RemoveAll(tempDir)

origin := os.Getenv("CONTAINER_ORIGIN")
if err := SetTaskwarriorConfig(tempDir, encryptionSecret, origin, uuid); err != nil {
return err
}

if err := SyncTaskwarrior(tempDir); err != nil {
return err
}

escapedDescription := fmt.Sprintf(`description:"%s"`, strings.ReplaceAll(description, `"`, `\"`))

cmd = exec.Command("task", taskuuid, "modify", escapedDescription)
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to edit task: %v", err)
}

escapedProject := fmt.Sprintf(`project:%s`, strings.ReplaceAll(project, `"`, `\"`))
cmd = exec.Command("task", taskuuid, "modify", escapedProject)
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to edit task project: %v", err)
}

escapedPriority := fmt.Sprintf(`priority:%s`, strings.ReplaceAll(priority, `"`, `\"`))
cmd = exec.Command("task", taskuuid, "modify", escapedPriority)
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to edit task priority: %v", cmd)
}

escapedDue := fmt.Sprintf(`due:%s`, strings.ReplaceAll(due, `"`, `\"`))
cmd = exec.Command("task", taskuuid, "modify", escapedDue)
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to edit task due: %v", err)
}

escapedStatus := fmt.Sprintf(`status:%s`, strings.ReplaceAll(status, `"`, `\"`))
if escapedStatus == "completed" {
cmd = exec.Command("task", taskuuid, "done", "rc.confirmation=off")
cmd.Run()
} else if escapedStatus == "deleted" {
cmd = exec.Command("task", taskuuid, "delete", "rc.confirmation=off")
cmd.Run()
}

// Sync Taskwarrior again
if err := SyncTaskwarrior(tempDir); err != nil {
return err
}
return nil
}

func DeleteTaskInTaskwarrior(email, encryptionSecret, uuid, taskuuid string) error {
cmd := exec.Command("rm", "-rf", "/root/.task")
if err := cmd.Run(); err != nil {
return fmt.Errorf("error deleting Taskwarrior data: %v", err)
}
tempDir, err := os.MkdirTemp("", "taskwarrior-"+email)
if err != nil {
return fmt.Errorf("failed to create temporary directory: %v", err)
Expand All @@ -206,7 +280,7 @@ func DeleteTaskInTaskwarrior(email, encryptionSecret, uuid, taskuuid string) err
}

// Mark the task as deleted
cmd := exec.Command("task", taskuuid, "delete", "rc.confirmation=off")
cmd = exec.Command("task", taskuuid, "delete", "rc.confirmation=off")
cmd.Dir = tempDir
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to mark task as deleted: %v", err)
Expand All @@ -221,6 +295,10 @@ func DeleteTaskInTaskwarrior(email, encryptionSecret, uuid, taskuuid string) err
}

func CompleteTaskInTaskwarrior(email, encryptionSecret, uuid, taskuuid string) error {
cmd := exec.Command("rm", "-rf", "/root/.task")
if err := cmd.Run(); err != nil {
return fmt.Errorf("error deleting Taskwarrior data: %v", err)
}
tempDir, err := os.MkdirTemp("", "taskwarrior-"+email)
if err != nil {
return fmt.Errorf("failed to create temporary directory: %v", err)
Expand All @@ -237,7 +315,7 @@ func CompleteTaskInTaskwarrior(email, encryptionSecret, uuid, taskuuid string) e
}

// Mark the task as done
cmd := exec.Command("task", taskuuid, "done", "rc.confirmation=off")
cmd = exec.Command("task", taskuuid, "done", "rc.confirmation=off")
cmd.Dir = tempDir
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to mark task as done: %v", err)
Expand Down
56 changes: 56 additions & 0 deletions backend/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func main() {
mux.HandleFunc("/tasks", app.TasksHandler)
mux.HandleFunc("/add-task", AddTaskHandler)
mux.HandleFunc("/edit-task", EditTaskHandler)
mux.HandleFunc("/modify-task", ModifyTaskHandler)
mux.HandleFunc("/complete-task", CompleteTaskHandler)
mux.HandleFunc("/delete-task", DeleteTaskHandler)

Expand Down Expand Up @@ -313,6 +314,61 @@ func EditTaskHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
}

func ModifyTaskHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, fmt.Sprintf("error reading request body: %v", err), http.StatusBadRequest)
return
}
defer r.Body.Close()

fmt.Printf("Raw request body: %s\n", string(body))

var requestBody struct {
Email string `json:"email"`
EncryptionSecret string `json:"encryptionSecret"`
UUID string `json:"UUID"`
TaskUUID string `json:"taskuuid"`
Description string `json:"description"`
Project string `json:"project"`
Priority string `json:"priority"`
Status string `json:"status"`
Due string `json:"due"`
}

err = json.Unmarshal(body, &requestBody)
if err != nil {
http.Error(w, fmt.Sprintf("error decoding request body: %v", err), http.StatusBadRequest)
return
}

email := requestBody.Email
encryptionSecret := requestBody.EncryptionSecret
uuid := requestBody.UUID
taskuuid := requestBody.TaskUUID
description := requestBody.Description
project := requestBody.Project
priority := requestBody.Priority
status := requestBody.Status
due := requestBody.Due

if taskuuid == "" {
http.Error(w, "taskuuid is required", http.StatusBadRequest)
return
}

if err := ModifyTaskInTaskwarrior(uuid, description, project, priority, status, due, email, encryptionSecret, taskuuid); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

http.Redirect(w, r, "/tasks", http.StatusSeeOther)
return
}
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
}

func AddTaskHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
body, err := io.ReadAll(r.Body)
Expand Down