add.go (2171B)
1 package main 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "io" 9 "net/http" 10 "strings" 11 12 tea "github.com/charmbracelet/bubbletea" 13 ) 14 15 const apiVersion = 6 16 17 type addNote struct { 18 Action string `json:"action"` 19 Version int `json:"version"` 20 Params addNoteParams `json:"params"` 21 } 22 23 type addNoteParams struct { 24 Note note `json:"note"` 25 } 26 27 type note struct { 28 DeckName string `json:"deckName"` 29 ModelName string `json:"modelName"` 30 // Fields will not be trivial to generalize 31 Fields fields `json:"fields"` 32 Options options `json:"options"` 33 } 34 35 type fields struct { 36 Front string `json:"Front"` 37 Back string `json:"Back"` 38 } 39 40 type options struct { 41 AllowDuplicate bool `json:"allowDuplicate"` 42 DuplicateScope string `json:"duplicateScope"` 43 } 44 45 func addCard(c *http.Client, apiURL, deckName, modelName, front, back string) tea.Cmd { 46 return func() tea.Msg { 47 front = strings.TrimSpace(front) 48 // Replace apostrophes (possible if copy-pasting) with single quotes 49 front = strings.ReplaceAll(front, `’`, `'`) 50 if back == "" { 51 return errMsg(errors.New("definition is blank")) 52 } 53 if front == "" { 54 return errMsg(errors.New("word is blank")) 55 } 56 57 noteRequest := addNote{ 58 Action: "addNote", 59 Version: apiVersion, 60 Params: addNoteParams{ 61 Note: note{ 62 DeckName: deckName, 63 ModelName: modelName, 64 Fields: fields{ 65 Front: front, 66 Back: back, 67 }, 68 Options: options{ 69 AllowDuplicate: false, 70 DuplicateScope: "deck", 71 }, 72 }, 73 }, 74 } 75 76 jsonBytes, err := json.Marshal(noteRequest) 77 if err != nil { 78 return errMsg(fmt.Errorf("marshaling JSON: %s", err)) 79 } 80 81 req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonBytes)) 82 req.Header.Set("Content-Type", "application/json") 83 84 resp, err := c.Do(req) 85 if err != nil { 86 return errMsg(fmt.Errorf("making request: %s", err)) 87 } 88 defer resp.Body.Close() 89 90 body, _ := io.ReadAll(resp.Body) 91 92 var jsonResp struct { 93 Error string `json:"error"` 94 } 95 96 json.Unmarshal(body, &jsonResp) 97 if jsonResp.Error != "" { 98 return errMsg(fmt.Errorf("creating card: %s", jsonResp.Error)) 99 } 100 101 return wordAddedMsg(front) 102 } 103 }