all repos

anpi @ e2e6e9e

yaml to anki importer
3 files changed, 65 insertions(+), 70 deletions(-)
implement notes adding
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2025-04-29 23:53:54 +0300
Parent: d5ee330
M anki/anki.go
···
        40
        40
         		DeckName  string            `json:"deckName"`

      
        41
        41
         		ModelName string            `json:"modelName"`

      
        42
        42
         		Fields    map[string]string `json:"fields"`

      
        
        43
        +		Tags      []string          `json:"tags"`

      
        43
        44
         	}

      
        44
        45
         

      
        45
        46
         	internalNote struct {

      ···
        47
        48
         	}

      
        48
        49
         )

      
        49
        50
         

      
        50
        
        -func (a *AnkiClient) AddNote(deckName, modelName string, fields map[string]string) (NoteID, error) {

      
        
        51
        +func (a *AnkiClient) AddNote(

      
        
        52
        +	deckName, modelName string,

      
        
        53
        +	fields map[string]string,

      
        
        54
        +	tags []string,

      
        
        55
        +) (NoteID, error) {

      
        51
        56
         	res, err := request[NoteID]("addNote", internalNote{Note{

      
        52
        57
         		DeckName:  deckName,

      
        53
        58
         		ModelName: modelName,

      
        54
        59
         		Fields:    fields,

      
        
        60
        +		Tags:      tags,

      
        55
        61
         	}})

      
        56
        62
         	if err != nil {

      
        57
        63
         		return 0, err

      
M main.go
···
        1
        1
         package main

      
        2
        2
         

      
        3
        3
         import (

      
        
        4
        +	"fmt"

      
        4
        5
         	"log/slog"

      
        
        6
        +	"os"

      
        5
        7
         

      
        6
        8
         	"github.com/olexsmir/anpi/anki"

      
        
        9
        +	"github.com/olexsmir/anpi/parser"

      
        7
        10
         )

      
        8
        11
         

      
        
        12
        +const importFile = "import.yml"

      
        
        13
        +

      
        9
        14
         func main() {

      
        
        15
        +	if err := run(); err != nil {

      
        
        16
        +		fmt.Fprintf(os.Stderr, "error: %v\n", err)

      
        
        17
        +		os.Exit(1)

      
        
        18
        +	}

      
        
        19
        +}

      
        
        20
        +

      
        
        21
        +func run() error {

      
        10
        22
         	anki := anki.NewAnkiClient()

      
        11
        23
         

      
        12
        
        -	nid, err := anki.AddNote("testing", "Basic", map[string]string{

      
        13
        
        -		"Front": "the thing",

      
        14
        
        -		"Back":  "asdfasfasdf",

      
        15
        
        -	})

      
        16
        
        -	slog.Info("note added", "nid", nid, "err", err)

      
        
        24
        +	f, err := os.ReadFile(importFile)

      
        
        25
        +	if err != nil {

      
        
        26
        +		return err

      
        
        27
        +	}

      
        
        28
        +

      
        
        29
        +	data, err := parser.Parse(f)

      
        
        30
        +	if err != nil {

      
        
        31
        +		return err

      
        
        32
        +	}

      
        
        33
        +

      
        
        34
        +	slog.Info("data", "data", data)

      
        
        35
        +

      
        
        36
        +	for _, deck := range data {

      
        
        37
        +		for _, note := range deck.Notes {

      
        
        38
        +			fields := make(map[string]string)

      
        
        39
        +			for k, v := range note.Fields {

      
        
        40
        +				slog.Info("chicken jokey", "k", k, "v", v, "yep", deck.FieldLookUp(k))

      
        
        41
        +				fields[deck.FieldLookUp(k)] = v

      
        
        42
        +			}

      
        
        43
        +

      
        
        44
        +			slog.Info("got fields", "fields", fields)

      
        
        45
        +

      
        
        46
        +			tags := mergeTags(deck.Tags, note.Tags)

      
        
        47
        +			if _, err := anki.AddNote(deck.Deck, deck.Type, fields, tags); err != nil {

      
        
        48
        +				return err

      
        
        49
        +			}

      
        
        50
        +		}

      
        
        51
        +	}

      
        
        52
        +

      
        
        53
        +	return nil

      
        
        54
        +}

      
        
        55
        +

      
        
        56
        +func mergeTags(global, local []string) []string {

      
        
        57
        +	unique := make(map[string]struct{})

      
        
        58
        +

      
        
        59
        +	for _, tag := range global {

      
        
        60
        +		unique[tag] = struct{}{}

      
        
        61
        +	}

      
        
        62
        +	for _, tag := range local {

      
        
        63
        +		unique[tag] = struct{}{}

      
        
        64
        +	}

      
        17
        65
         

      
        18
        
        -	// decks, err := anki.GetDeckNames()

      
        19
        
        -	// slog.Info("test deck names", "fields", decks, "err", err)

      
        20
        
        -	//

      
        21
        
        -	// fields, err := anki.GetModelFieldNames("Basic")

      
        22
        
        -	// slog.Info("test existent type", "fields", fields, "err", err)

      
        23
        
        -	//

      
        24
        
        -	// fieldsErr, err := anki.GetModelFieldNames("chicked jokey")

      
        25
        
        -	// slog.Info("test non-existent type", "fields", fieldsErr, "err", err)

      
        26
        
        -	//

      
        27
        
        -	// f, _ := os.ReadFile("test.yml")

      
        28
        
        -	// data, err := parser.Parse(f)

      
        29
        
        -	// slog.Info("parsing data", "err", err)

      
        30
        
        -	//

      
        31
        
        -	// lookup := "front"

      
        32
        
        -	// ankiField := data[1].FieldLookUp(lookup)

      
        33
        
        -	// slog.Info("looking up anki note field", "field", ankiField, "lookup", lookup)

      
        
        66
        +	result := make([]string, 0, len(unique))

      
        
        67
        +	for tag := range unique {

      
        
        68
        +		result = append(result, tag)

      
        
        69
        +	}

      
        34
        70
         

      
        35
        
        -	// for _, deck := range data {

      
        36
        
        -	// 	fmt.Printf("\nDeck: %s\n", deck.Deck)

      
        37
        
        -	// 	fmt.Printf("Type: %s\n", deck.Type)

      
        38
        
        -	// 	fmt.Printf("Global Tags: %v\n", deck.Tags)

      
        39
        
        -	// 	fmt.Println("Fields mapping:")

      
        40
        
        -	// 	for internalName, anki := range deck.Fields {

      
        41
        
        -	// 		fmt.Printf("  %s -> %s\n", internalName, anki)

      
        42
        
        -	// 	}

      
        43
        
        -	//

      
        44
        
        -	// 	fmt.Println("Notes:")

      
        45
        
        -	// 	for _, note := range deck.Notes {

      
        46
        
        -	// 		fmt.Println("  Note fields:")

      
        47
        
        -	// 		for internalName, value := range note.Fields {

      
        48
        
        -	// 			fmt.Printf("    %s: %s\n", internalName, value)

      
        49
        
        -	// 		}

      
        50
        
        -	// 		if len(note.Tags) > 0 {

      
        51
        
        -	// 			fmt.Printf("    Local Tags: %v\n", note.Tags)

      
        52
        
        -	// 		}

      
        53
        
        -	// 	}

      
        54
        
        -	// }

      
        
        71
        +	return result

      
        55
        72
         }

      
D test.yml
···
        1
        
        ----

      
        2
        
        -- deck: English

      
        3
        
        -  type: Basic

      
        4
        
        -  fields:

      
        5
        
        -    front: Front

      
        6
        
        -    back: Back

      
        7
        
        -    extra: Extra

      
        8
        
        -  notes:

      
        9
        
        -    - front: The question? asdf asdf

      
        10
        
        -      back: The answer

      
        11
        
        -      extra: Some extra stuff, maybe an explanation

      
        12
        
        -    - front: Some more questions?

      
        13
        
        -      back: Even some more answers

      
        14
        
        -      tags: [english::strange, dck]

      
        15
        
        -- deck: toki pona

      
        16
        
        -  type: Vocab sentence

      
        17
        
        -  fields:

      
        18
        
        -    front: Sentence

      
        19
        
        -    trans: Translatation

      
        20
        
        -    extra: Extra

      
        21
        
        -  notes:

      
        22
        
        -    - front: sina pona ala pona?

      
        23
        
        -      trans: o kokosila ala!

      
        24
        
        -    - front: "how to poop?"

      
        25
        
        -      trans: sina sona ala sone e ni

      
        26
        
        -      extra: jaki. ni li jaki.

      
        27
        
        -      tags: [tokipona:grammar]

      
        28
        
        ----