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
13 changes: 6 additions & 7 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ import (
)

func main() {
go func() {
err := db.InitDB()
if err != nil {
log.Fatalf("Failed to initialize database: %v", err)
}
}()

err := db.InitDB()
if err != nil {
log.Fatalf("Failed to initialize database: %v", err)
}
defer db.Close()

server.Run()
}
34 changes: 22 additions & 12 deletions pkg/api/addtask.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ package api

import (
"fmt"
"log"
"net/http"
"strconv"
"time"

"github.com/ArtyomGaribyan/Task-Scheduler/pkg/db"
)

func checkTask (task *db.Task) error {
if task == nil {
return fmt.Errorf("task is nil")
}
func checkTask(task *db.Task) error {
if task.Title == "" {
return fmt.Errorf("title is required")
}
Expand All @@ -21,7 +21,7 @@ if task == nil {
} else {
_, err := time.Parse(db.DateLayout, task.Date)
if err != nil {
return fmt.Errorf("invalid date format: %v", err)
return fmt.Errorf("invalid date format: %w", err)
}
}

Expand All @@ -30,7 +30,7 @@ if task == nil {
if task.Repeat != "" {
task.Date, err = db.NextDate(now, task.Date, task.Repeat)
if err != nil {
return err
return fmt.Errorf("next date calculation error: %w", err)
}
} else {
task.Date = today
Expand All @@ -39,16 +39,26 @@ if task == nil {
return nil
}

func addTaskHandler(task *db.Task) (int64, error) {
err := checkTask(task)
func AddTaskHandler(w http.ResponseWriter, task db.Task) {
log.Println("Adding task:", task)
err := checkTask(&task)
if err != nil {
return 0, err
Error := db.Task{Error: "Validation error for adding task: " + err.Error()}
log.Println(Error)
w.WriteHeader(http.StatusBadRequest)
writeJson(w, Error)
return
}

id, err := db.AddTask(task)
if err != nil {
return 0, err
Error := db.Task{Error: "Error for adding task: " + err.Error()}
log.Println(Error)
w.WriteHeader(http.StatusInternalServerError)
writeJson(w, Error)
return
}

return id, nil
task.ID = strconv.Itoa(int(id))
log.Println("Added task ID:", task.ID)
writeJson(w, task)
}
214 changes: 94 additions & 120 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,35 @@ import (
"fmt"
"log"
"net/http"
"strconv"
"time"

"github.com/ArtyomGaribyan/Task-Scheduler/pkg/db"
)

func writeJson(w http.ResponseWriter, data any) {
fmt.Printf("\n")
fmt.Printf("\n") // for better readability in logs
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
jsonData, err := json.Marshal(data)
if err != nil {
http.Error(w, "Error encoding JSON", http.StatusInternalServerError)
log.Println("Error encoding JSON:", err)
http.Error(w, "Error encoding JSON: "+err.Error(), http.StatusInternalServerError)
return
}
w.Write(jsonData)
}

func getTaskBody (w http.ResponseWriter, r *http.Request, task *db.Task) {
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(task)
if err != nil {
Error := "Invalid request body: " + err.Error()
log.Println(Error)
w.WriteHeader(http.StatusBadRequest)
writeJson(w, Error)
}
log.Println("Received task:", task)
}

func HandleNextDate(w http.ResponseWriter, r *http.Request) {
now := r.URL.Query().Get("now")
date := r.URL.Query().Get("date")
Expand All @@ -34,14 +46,20 @@ func HandleNextDate(w http.ResponseWriter, r *http.Request) {
} else {
parsedNow, err = time.Parse(db.DateLayout, now)
if err != nil {
w.Write([]byte(""))
Error := "Next date parse error: " + err.Error()
log.Println(Error)
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(Error))
return
}
}

nextDate, err := db.NextDate(parsedNow, date, repeat)
if err != nil {
w.Write([]byte(""))
Error := "Next date calculation error: " + err.Error()
log.Println(Error)
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(Error))
return
}

Expand All @@ -50,115 +68,27 @@ func HandleNextDate(w http.ResponseWriter, r *http.Request) {

func HandleTask(w http.ResponseWriter, r *http.Request) {
var task db.Task
task.ID = r.URL.Query().Get("id")

method := r.Method
log.Println("Method:", method)

decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&task)
if err != nil {
task.ID = r.URL.Query().Get("id")
task.Title = r.URL.Query().Get("title")
task.Date = r.URL.Query().Get("date")
task.Comment = r.URL.Query().Get("comment")
task.Repeat = r.URL.Query().Get("repeat")
if task != (db.Task{}) {
goto If_close
}

task.Error = "Invalid request body: " + err.Error()
log.Println(task.Error)
w.WriteHeader(http.StatusInternalServerError)
writeJson(w, task)
return
}
If_close:

log.Println("Received task:", task)

switch method {
case http.MethodGet:
if task.ID == "" {
task.Error = "Error getting task: missing ID"
log.Println(task.Error)
w.WriteHeader(http.StatusInternalServerError)
writeJson(w, task)
return
}

taskResieved, err := db.GetTask(task.ID)
log.Println("Task received:", taskResieved.ID, taskResieved.Title, taskResieved.Date, taskResieved.Comment, taskResieved.Repeat)
if err != nil {
task.Error = "Error getting task: " + err.Error()
log.Println(task.Error)
w.WriteHeader(http.StatusInternalServerError)
writeJson(w, task)
return
}
writeJson(w, taskResieved)
return

GetTaskHandler(w, task.ID)
case http.MethodPost:
log.Println("Adding task:", task)
id, err := addTaskHandler(&task)
if err != nil {
task.Error = "Error adding task: " + err.Error()
log.Println(task.Error)
w.WriteHeader(http.StatusInternalServerError)
writeJson(w, task)
return
}
task.ID = strconv.Itoa(int(id))
log.Println("Added task ID:", task.ID)
writeJson(w, task)
return

getTaskBody(w, r, &task)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Было хорошо сделано, что все в одном месте, а тут у тебя если ошибка в декодировании, то ты все равно пытаешься добавить задачу, а это плохо, вот как у тебя получается. что две ошибки склеивается

Нужно либо делать в одной функции, либо возвращать и проверять ошибку

image

AddTaskHandler(w, task)
case http.MethodPut:
if task.ID == "" {
task.Error = "Error updating task: missing ID"
log.Println(task.Error)
w.WriteHeader(http.StatusInternalServerError)
writeJson(w, task)
return
}

log.Println("Updating task:", task.ID, "\n", task.Title, task.Date, task.Comment, task.Repeat)
err := UpdateTaskHandler(&task)
if err != nil {
task.Error = "Error updating task: " + err.Error()
log.Println(task.Error)
w.WriteHeader(http.StatusInternalServerError)
writeJson(w, task)
return
}
writeJson(w, db.Task{})
getTaskBody(w, r, &task)
UpdateTaskHandler(w, task)
case http.MethodDelete:
if task.ID == "" {
task.Error = "Error deleting task: missing ID"
log.Println(task.Error)
w.WriteHeader(http.StatusInternalServerError)
writeJson(w, task)
return
}

err := db.DeleteTask(task.ID)
if err != nil {
task.Error = "Error deleting task: " + err.Error()
log.Println(task.Error)
w.WriteHeader(http.StatusInternalServerError)
writeJson(w, task)
return
}

log.Printf("Successfully deleted task: %s\n", task.ID)
writeJson(w, db.Task{})

DeleteTaskHandler(w, task.ID)
default:
task.Error = "Method not allowed"
log.Println(task.Error)
w.WriteHeader(http.StatusInternalServerError)
writeJson(w, task)
return
Error := db.Task{Error: "Method not allowed"}
log.Println(Error)
w.WriteHeader(http.StatusMethodNotAllowed)
writeJson(w, Error)
}
}

Expand All @@ -168,44 +98,88 @@ func HandleTaskDone(w http.ResponseWriter, r *http.Request) {
method := r.Method
log.Println("Method:", method)
if method != http.MethodPost {
log.Println("Method not allowed")
w.WriteHeader(http.StatusInternalServerError)
task.Error = "Method not allowed"
writeJson(w, task)
Error := db.Task{Error: "Method not allowed"}
log.Println(Error)
w.WriteHeader(http.StatusMethodNotAllowed)
writeJson(w, Error)
return
}

task.ID = r.URL.Query().Get("id")
if task.ID == "" {
task.Error = "Error marking task as done: missing ID"
log.Println(task.Error)
w.WriteHeader(http.StatusInternalServerError)
writeJson(w, task)
Error := db.Task{Error: "Validation error for marking task as done: missing ID"}
log.Println(Error)
w.WriteHeader(http.StatusBadRequest)
writeJson(w, Error)
return
}
log.Println("Marking task as done", task.ID)

err := TaskDoneHandler(task.ID)
task, err := db.GetTask(task.ID)
if err != nil {
task.Error = "Error marking task as done: " + err.Error()
log.Println(task.Error)
Error := db.Task{Error: "Error for marking task as done: " + err.Error()}
log.Println(Error)
w.WriteHeader(http.StatusInternalServerError)
writeJson(w, task)
writeJson(w, Error)
return
}

if task.Repeat == "" {
err = db.DeleteTask(task.ID)
if err != nil {
if err.Error() == "incorrect id for deleting task" {
Error := db.Task{Error: "Error for marking task as done: " + err.Error()}
log.Println(Error)
w.WriteHeader(http.StatusBadRequest)
writeJson(w, Error)
return
}
Error := db.Task{Error: "Error for marking task as done: " + err.Error()}
log.Println(Error)
w.WriteHeader(http.StatusInternalServerError)
writeJson(w, Error)
return
}
log.Println("Task", task.ID, "was successfully removed")
writeJson(w, db.Task{})
return
}

log.Println("Calculating next date for task:", task)
task.Date, err = db.NextDate(time.Now(), task.Date, task.Repeat)
if err != nil {
Error := db.Task{Error: "Error for calculating next date: " + err.Error()}
log.Println(Error)
w.WriteHeader(http.StatusInternalServerError)
writeJson(w, Error)
return
}
log.Println("Next date for task:", task.Date)

err = db.UpdateDate(&task)
if err != nil {
if err.Error() == "incorrect id for updating date" {
Error := db.Task{Error: "Error for marking task as done: " + err.Error()}
log.Println(Error)
w.WriteHeader(http.StatusBadRequest)
writeJson(w, Error)
return
}
Error := db.Task{Error: "Error for marking task as done: " + err.Error()}
log.Println(Error)
w.WriteHeader(http.StatusBadRequest)
writeJson(w, Error)
return
}

log.Println("Successfully marked as done: ", task.ID)
writeJson(w, db.Task{})
}

func Init() {
http.Handle("/", http.FileServer(http.Dir("web")))
http.HandleFunc("/api/nextdate", HandleNextDate)
http.HandleFunc("api/nextdate", HandleNextDate)
http.HandleFunc("/api/task", HandleTask)
http.HandleFunc("api/task", HandleTask)
http.HandleFunc("/api/tasks", HandleTasks)
http.HandleFunc("api/tasks", HandleTasks)
http.HandleFunc("/api/task/done", HandleTaskDone)
http.HandleFunc("api/task/done", HandleTaskDone)
}
Loading