all repos

anpi @ 5b11d15

yaml to anki importer
5 files changed, 135 insertions(+), 0 deletions(-)
add basic anki client
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2025-04-29 21:43:10 +0300
Authored at: 2025-04-29 21:42:58 +0300
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.mod
···
        
        1
        +module github.com/olexsmir/anpi

      
        
        2
        +

      
        
        3
        +go 1.24.2

      
        
        4
        +

      
        
        5
        +require (

      
        
        6
        +	golang.org/x/sync v0.13.0

      
        
        7
        +	gopkg.in/yaml.v3 v3.0.1

      
        
        8
        +)

      
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
        +}