137 lines
3.6 KiB
Go
137 lines
3.6 KiB
Go
package client
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
const baseURL = "http://localhost:8080"
|
|
|
|
var httpClient = &http.Client{}
|
|
|
|
func doRequest(method, url string, body any) []byte {
|
|
var reqBody io.Reader
|
|
if body != nil {
|
|
data, err := json.Marshal(body)
|
|
if err != nil {
|
|
fmt.Println("Failed to marshal request body")
|
|
os.Exit(1)
|
|
}
|
|
reqBody = bytes.NewReader(data)
|
|
}
|
|
|
|
req, err := http.NewRequest(method, url, reqBody)
|
|
if err != nil {
|
|
fmt.Println("Failed to create request")
|
|
os.Exit(1)
|
|
}
|
|
if body != nil {
|
|
req.Header.Set("Content-Type", "application/json")
|
|
}
|
|
|
|
resp, err := httpClient.Do(req)
|
|
if err != nil {
|
|
fmt.Println("Failed to send request is the server running?")
|
|
os.Exit(1)
|
|
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
respBody, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
log.Fatalf("Failed to read response body: %v", err)
|
|
}
|
|
return respBody
|
|
}
|
|
|
|
func ListNotes() {
|
|
body := doRequest(http.MethodGet, baseURL+"/notes", nil)
|
|
var notes []struct {
|
|
ID int `json:"id"`
|
|
Content string `json:"content"`
|
|
LastUpdate time.Time `json:"last_update"`
|
|
}
|
|
if err := json.Unmarshal(body, ¬es); err != nil {
|
|
log.Fatalf("Failed to parse notes: %v", err)
|
|
}
|
|
if len(notes) == 0 {
|
|
fmt.Println("No notes found.")
|
|
return
|
|
}
|
|
|
|
// Calculate column widths from headers and content
|
|
idW, updatedW, contentW := 2, 7, 7 // minimums: "ID", "Updated", "Content"
|
|
for _, n := range notes {
|
|
if w := len(fmt.Sprintf("%d", n.ID)); w > idW {
|
|
idW = w
|
|
}
|
|
if w := len(n.LastUpdate.Format("2006-01-02 15:04:05")); w > updatedW {
|
|
updatedW = w
|
|
}
|
|
if w := len(n.Content); w > contentW {
|
|
contentW = w
|
|
}
|
|
}
|
|
|
|
row := func(id, updated, content string) {
|
|
fmt.Printf("| %-*s | %-*s | %-*s |\n", idW, id, updatedW, updated, contentW, content)
|
|
}
|
|
sep := fmt.Sprintf("|-%s-|-%s-|-%s-|", strings.Repeat("-", idW), strings.Repeat("-", updatedW), strings.Repeat("-", contentW))
|
|
fmt.Println(strings.Repeat("-", idW+updatedW+contentW+10))
|
|
row("ID", "Updated", "Content")
|
|
fmt.Println(sep)
|
|
for _, n := range notes {
|
|
row(fmt.Sprintf("%d", n.ID), n.LastUpdate.Format("2006-01-02 15:04:05"), n.Content)
|
|
}
|
|
fmt.Println(strings.Repeat("-", idW+updatedW+contentW+10))
|
|
}
|
|
|
|
func CreateNote(content string) {
|
|
body := doRequest(http.MethodPost, baseURL+"/notes", map[string]string{"content": content})
|
|
var note struct {
|
|
ID int `json:"id"`
|
|
Content string `json:"content"`
|
|
}
|
|
if err := json.Unmarshal(body, ¬e); err != nil {
|
|
log.Fatalf("Failed to parse note: %v", err)
|
|
}
|
|
fmt.Printf("Created note #%d: %s\n", note.ID, note.Content)
|
|
}
|
|
|
|
func GetNoteByID(id int) {
|
|
body := doRequest(http.MethodGet, fmt.Sprintf("%s/note/%d", baseURL, id), nil)
|
|
var note struct {
|
|
ID int `json:"id"`
|
|
Content string `json:"content"`
|
|
LastUpdate time.Time `json:"last_update"`
|
|
}
|
|
if err := json.Unmarshal(body, ¬e); err != nil {
|
|
log.Fatalf("Failed to parse note: %v", err)
|
|
}
|
|
fmt.Printf("Note #%d (updated %s):\n %s\n", note.ID, note.LastUpdate.Format("2006-01-02 15:04:05"), note.Content)
|
|
}
|
|
|
|
func UpdateNoteByID(id int, content string) {
|
|
body := doRequest(http.MethodPut, fmt.Sprintf("%s/note/%d", baseURL, id), map[string]string{"content": content})
|
|
var note struct {
|
|
ID int `json:"id"`
|
|
Content string `json:"content"`
|
|
}
|
|
if err := json.Unmarshal(body, ¬e); err != nil {
|
|
log.Fatalf("Failed to parse note: %v", err)
|
|
}
|
|
fmt.Printf("Updated note #%d: %s\n", note.ID, note.Content)
|
|
}
|
|
|
|
func DeleteNoteByID(id int) {
|
|
doRequest(http.MethodDelete, fmt.Sprintf("%s/note/%d", baseURL, id), nil)
|
|
fmt.Printf("Deleted note #%d\n", id)
|
|
}
|