-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathyt
executable file
·134 lines (111 loc) · 3.26 KB
/
yt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/bin/bash
exe=$(readlink -f "$0")
ui=en
API='https://translate.yandex.net/api/v1.5/tr.json'
say() { echo "$@" >&2; }
error() {
local -i rc="$1"
shift
say "$@"
exit $rc
}
[ -d ~/.yt/. ] || { mkdir -p ~/.yt; error 1 "No API key."; }
[ -e ~/.yt/key ] || { mkdir -p ~/.yt; error 1 "No API key file."; }
declare -a wants=(
curl sed jq
tr cat mktemp rm od
)
for p in "${wants[@]}"; do
x=$(type -P "$p")
[ -z "$x" -o ! -x "$x" ] || continue
error 1 "No '$p' available."
done
temp="$(mktemp -p /tmp)"
[ -f "$temp" ] || error 1 "Cannot write to /tmp/."
trap "rm -f '${temp}'" EXIT
_fetch() { curl -Ssk "$@"; }
fetch() {
_fetch "$@" > "$temp"
local code=$(jq .code < "$temp")
if [ "$code" = 200 ]; then
: # that's ok
elif [ "$code" != null ]; then
local msg=$(jq .message < "$temp")
local -A rcx=(
[401]='Bad API key'
[402]='API key banned'
[404]='Daily limit exceeded'
[413]='Text size exceeded'
[422]='Cannot translate text'
[501]='Unsupported lang pair'
)
[ -n "$msg" ] || msg="= ${rcx[$code]}"
error 1 "Error #${code}: ${msg}"
fi
cat "$temp"
}
api_call() {
local fn="$1" ; shift
local tail=$(echo -n "$@" | tr -s '[:space:]' ' ' | sed -e 's/\s\+\(\w\+=\)/\&\1/g')
local url="${API}/${fn}?key=${APIKEY}${tail:+&}${tail}"
fetch "${url}"
}
lang_list() {
api_call getLangs ui=$ui
# &callback=<имя callback-функции>
# {
# "dirs": [
# "az-ru",
# "be-bg",
# "be-cs",
# "be-de",
# ...
# ],
# "langs": {
# "af": "Afrikaans",
# "am": "Amharic",
# "ar": "Arabic",
# "az": "Azerbaijani",
# ...
# }
# }
}
c2x() {
echo -n "$*" |
od -vtxC -Anone | # space prefixed, charwise, 2-hex per char
tr -d '\n' | # join lines
tr '[:lower:]' '[:upper:]' # uppercase hex
}
urlencode() { c2x "$@" | tr ' ' '%'; } # 'A' -> '%41' for all, easy way
detect_lang() {
local hint='en,ru'
api_call detect "text=$(urlencode "$@")" "hint=${hint}"
# { "code": 200, "lang": "en" }
}
whereto() {
local s="$(echo -n "$@" | tr -s '[:space:]' ' ')"
local l="$(echo -n "$s" | tr -dc '[:alpha:]')"
# say "#l=${#l} #s=${#s} $(( ${#s} / 2 ))"
(( ${#l} < ( ${#s} / 2 ) )) && echo 'ru-en' || echo 'ru'
}
translate() {
local to=ru # where to translate to ('ru') or lang pair (like 'en-ru')
if [[ "$1" =~ ^[a-z]{2,2}(-[a-z]{2,2})?$ ]]; then
to="$1"
shift
else
to=$(whereto "$@")
fi
local fm=plain # text format ('plain' or 'html')
api_call translate "text=$(urlencode "$@")" "lang=${to}" "format=${fm}"
# &options= ?????
# { "code": 200, "lang": "en-ru", "text": [ "Здравствуй, Мир!" ] }
}
output() { if [ -t 1 ]; then jq ${1:-.}; else cat; fi; }
# see https://translate.yandex.ru/developers/keys
source ~/.yt/key
[ "$1" != -l ] || { lang_list | output; exit; }
[ "$1" != -L ] || { shift; detect_lang "$@" | output; exit; }
[ $# -gt 0 ] && { translate "$@" | output .text[]; } ||
error 1 "Usage: $(basename ${exe}) [-l|-L] [<lang1>[-<lang2>]] text"
# EOF #