5 files changed,
135 insertions(+),
0 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed at:
2025-04-29 21:43:10 +0300
Authored at:
2025-04-29 21:42:58 +0300
jump to
| A | anki/anki.go |
| A | anki/http.go |
| A | go.mod |
| A | go.sum |
| A | main.go |
A
anki/anki.go
··· 1 +package anki 2 + 3 +type AnkiClient struct{} 4 + 5 +func NewAnkiClient() AnkiClient { 6 + return AnkiClient{} 7 +} 8 + 9 +type ModelFieldNames []string 10 + 11 +type ModelFieldNamesParams struct { 12 + ModelName string `json:"modelName"` 13 +} 14 + 15 +func (a *AnkiClient) GetModelFieldNames(modelName string) (ModelFieldNames, error) { 16 + res, err := request[ModelFieldNames]("modelFieldNames", ModelFieldNamesParams{ 17 + ModelName: modelName, 18 + }) 19 + if err != nil { 20 + return ModelFieldNames{}, err 21 + } 22 + 23 + return res.Result, nil 24 +} 25 + 26 +type DeckNames []string 27 + 28 +func (a *AnkiClient) GetDeckNames() (DeckNames, error) { 29 + res, err := request[DeckNames]("deckNames", paramsDefault{}) 30 + if err != nil { 31 + return DeckNames{}, err 32 + } 33 + 34 + return res.Result, nil 35 +}
A
anki/http.go
··· 1 +package anki 2 + 3 +import ( 4 + "bytes" 5 + "encoding/json" 6 + "fmt" 7 + "net/http" 8 +) 9 + 10 +const ( 11 + ankiURL = "http://localhost:8765" 12 + ankiConnectVersion = 6 13 +) 14 + 15 +type AnkiResponse[T any] struct { 16 + Result T `json:"result,omitempty"` 17 + Error string `json:"error,omitempty"` 18 +} 19 + 20 +func (r AnkiResponse[T]) CheckErrors() error { 21 + if r.Error != "" { 22 + return fmt.Errorf("%s", r.Error) 23 + } 24 + return nil 25 +} 26 + 27 +type AnkiRequest[T any] struct { 28 + Action string `json:"action"` 29 + Version int `json:"version"` 30 + Params T `json:"params"` 31 +} 32 + 33 +type paramsDefault struct{} 34 + 35 +func request[R any, P any](action string, params P) (AnkiResponse[R], error) { 36 + bodyReq, err := json.Marshal(AnkiRequest[P]{ 37 + Action: action, 38 + Version: ankiConnectVersion, 39 + Params: params, 40 + }) 41 + if err != nil { 42 + return AnkiResponse[R]{}, err 43 + } 44 + 45 + req, err := http.NewRequest(http.MethodGet, ankiURL, bytes.NewBuffer(bodyReq)) 46 + if err != nil { 47 + return AnkiResponse[R]{}, err 48 + } 49 + 50 + req.Header.Set("Content-type", "application/json") 51 + 52 + client := &http.Client{} 53 + resp, err := client.Do(req) 54 + if err != nil { 55 + return AnkiResponse[R]{}, err 56 + } 57 + 58 + defer resp.Body.Close() //nolint 59 + 60 + var ankiResp AnkiResponse[R] 61 + if err := json.NewDecoder(resp.Body).Decode(&ankiResp); err != nil { 62 + return AnkiResponse[R]{}, err 63 + } 64 + 65 + return ankiResp, ankiResp.CheckErrors() 66 +}
A
go.sum
··· 1 +golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= 2 +golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 3 +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 4 +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 5 +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 6 +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
A
main.go
··· 1 +package main 2 + 3 +import ( 4 + "log/slog" 5 + 6 + "github.com/olexsmir/anpi/anki" 7 +) 8 + 9 +func main() { 10 + anki := anki.NewAnkiClient() 11 + 12 + decks, err := anki.GetDeckNames() 13 + slog.Info("test deck names", "fields", decks, "err", err) 14 + 15 + fields, err := anki.GetModelFieldNames("Basic") 16 + slog.Info("test existent type", "fields", fields, "err", err) 17 + 18 + fieldsErr, err := anki.GetModelFieldNames("chicked jokey") 19 + slog.Info("test non-existent type", "fields", fieldsErr, "err", err) 20 +}