all repos

anpi @ 2122b1be1ed91cb8a550a8dc7769f20305662943

yaml to anki importer

anpi/main.go (view raw)

Olexandr Smirnov Olexandr Smirnov
olexsmir@gmail.com
repurpose of the tool, 8 days ago
1
package main
2
3
import (
4
	"bufio"
5
	"errors"
6
	"flag"
7
	"fmt"
8
	"os"
9
	"strings"
10
)
11
12
type Sense struct {
13
	Definition string
14
	Examples   []string
15
}
16
17
type POSBlock struct {
18
	POS    string
19
	IPA    string
20
	Senses []Sense
21
}
22
23
type Entry struct {
24
	Word         string
25
	RedirectWord string
26
	POSBlocks    []POSBlock
27
}
28
29
func isPiped() bool {
30
	fi, _ := os.Stdin.Stat()
31
	return (fi.Mode() & os.ModeCharDevice) == 0
32
}
33
34
func readStdinWord() (string, error) {
35
	s := bufio.NewScanner(os.Stdin)
36
	if s.Scan() {
37
		return strings.TrimSpace(s.Text()), nil
38
	}
39
	return "", s.Err()
40
}
41
42
func main() {
43
	all := flag.Bool("all", false, "print all senses to stderr")
44
	aFlag := flag.Bool("a", false, "shorthand for --all")
45
	pos := flag.String("pos", "", "filter by part of speech")
46
	clearCacheFlag := flag.Bool("clear-cache", false, "clear cache for word")
47
48
	flag.Parse()
49
50
	args := flag.Args()
51
52
	var word string
53
	switch {
54
	case len(args) > 0:
55
		word = args[0]
56
	case isPiped():
57
		var err error
58
		word, err = readStdinWord()
59
		if err != nil {
60
			fmt.Fprintf(os.Stderr, "anpi: %v\n", err)
61
			os.Exit(1)
62
		}
63
		if word == "" {
64
			fmt.Fprintln(os.Stderr, "usage: anpi [flags] <word>")
65
			os.Exit(1)
66
		}
67
	default:
68
		fmt.Fprintln(os.Stderr, "usage: anpi [flags] <word>")
69
		os.Exit(1)
70
	}
71
72
	if len(args) > 1 {
73
		for _, arg := range args[1:] {
74
			if arg == "--all" || arg == "-a" {
75
				*all = true
76
			}
77
			if arg == "--clear-cache" {
78
				*clearCacheFlag = true
79
			}
80
		}
81
	}
82
83
	if *all || *aFlag {
84
		*all = true
85
	}
86
87
	cache, err := NewCache()
88
	if err != nil {
89
		fmt.Fprintln(os.Stderr, err)
90
		os.Exit(1)
91
	}
92
93
	if *clearCacheFlag {
94
		_ = cache.Clear(word)
95
	}
96
97
	entry, err := cache.Read(word)
98
	if errors.Is(err, ErrNotFound) {
99
		_, _ = fmt.Fprintf(os.Stderr, "anpi: %v\n", err)
100
		os.Exit(1)
101
	}
102
	if err != nil {
103
		dict := NewCambridgeDictionary()
104
		entry, err = dict.Lookup(word)
105
		if err != nil {
106
			if werr := cache.Write(word, nil, false); werr != nil {
107
				fmt.Fprintf(os.Stderr, "cache write error: %v\n", werr)
108
			}
109
			_, _ = fmt.Fprintf(os.Stderr, "anpi: %v\n", err)
110
			os.Exit(1)
111
		}
112
		if err := cache.Write(word, entry, true); err != nil {
113
			fmt.Fprintf(os.Stderr, "cache write error: %v\n", err)
114
		}
115
	}
116
117
	if *pos != "" {
118
		var filtered []POSBlock
119
		for _, b := range entry.POSBlocks {
120
			if strings.EqualFold(b.POS, *pos) {
121
				filtered = append(filtered, b)
122
			}
123
		}
124
		if len(filtered) == 0 {
125
			_, _ = fmt.Fprintf(os.Stderr, "warning: no %q sense found, showing all\n", *pos)
126
		} else {
127
			entry.POSBlocks = filtered
128
		}
129
	}
130
131
	if *all {
132
		writeAll(entry, os.Stderr)
133
		return
134
	}
135
136
	fmt.Print(toTSV(entry))
137
}