ecdict 1.2.alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/ecdict +701 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6e1996ba567e038df6a09192d756555cc6d412dba27768a1ba8a14e7c7f5b86e
|
4
|
+
data.tar.gz: 9f629889962c28cbf083aa15a72dbbbe043c8f20f0dd4d222067a44a30af2dfb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: abc14275deab49f24f5500af11872096273d7993370429243dcf5bd6b150ceef2c3052abb1bb6698469f65a81bc378fa3b9fc2a383056e8b43f1b4f5d307290a
|
7
|
+
data.tar.gz: ca19a7ece452d4f1ac8dd4514d8660dd7284bd7c5cd06a8e9b053f3d19839a76495c8a62218cfc3f551b63a1e60bbc60db3f02c3b51185c13d0c4bb540b2d2c9
|
data/bin/ecdict
ADDED
@@ -0,0 +1,701 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# ------------------------------------------------------
|
3
|
+
# File : ecdict.rb
|
4
|
+
# Authors : ccmywish <ccmywish@qq.com>
|
5
|
+
# Created on : <2020-10-18>
|
6
|
+
# Last modified : <2022-03-23>
|
7
|
+
#
|
8
|
+
# ecdict:
|
9
|
+
#
|
10
|
+
# The command line dict using ECDICT.
|
11
|
+
#
|
12
|
+
# ECDICT: https://github.com/skywind3000/ECDICT
|
13
|
+
#
|
14
|
+
# This gem consists of:
|
15
|
+
# 1. ecdict installer
|
16
|
+
# 2. ecdict cmd
|
17
|
+
# 3. ecdict repl
|
18
|
+
# ------------------------------------------------------
|
19
|
+
|
20
|
+
require 'sqlite3'
|
21
|
+
|
22
|
+
ECDICT_STORAGE = File.expand_path("~/.local/share/ecdict")
|
23
|
+
ECDictRAWDATA = File.join(ECDICT_STORAGE, 'ecdict-csv.7z')
|
24
|
+
ECDictDB = File.join(ECDICT_STORAGE, 'ecdict.db')
|
25
|
+
ECDictCSV = File.join(ECDICT_STORAGE, 'ecdict.csv')
|
26
|
+
|
27
|
+
ECDICT_GEM_VERSION = "1.2.alpha"
|
28
|
+
|
29
|
+
# 这个版本是我从上游下载的CSV后自己压缩的
|
30
|
+
# 这个文件的实际创建日期(上游作者创建)是2017/06/04
|
31
|
+
# 至2022/03/22,未见更新,估计以后上游维护这个词典的也不会经常更新
|
32
|
+
# 而340万的单词量已经足够,因此我们可以足够长的时间一直停留在此词典版本
|
33
|
+
ECDICT_DICT_VERSION = "2020.10.19"
|
34
|
+
ECDICT_DICT_DOWNLOAD_LINK = "https://gitee.com/ccmywish/ecdict/attach_files/1004013/download/ecdict-csv.7z"
|
35
|
+
ECDICT_DICT_SHA256 = "86782a0e5d05486b482be5a2e5fa99b1a9b2ae51240c853ecfe181886133818a"
|
36
|
+
|
37
|
+
|
38
|
+
require 'fileutils'
|
39
|
+
FileUtils.mkdir_p(ECDICT_STORAGE)
|
40
|
+
$DB = SQLite3::Database.new ECDictDB
|
41
|
+
|
42
|
+
|
43
|
+
####################
|
44
|
+
# helper: for color
|
45
|
+
####################
|
46
|
+
|
47
|
+
def bold(str) "\e[1m#{str}\e[0m" end
|
48
|
+
def underline(str) "\e[4m#{str}\e[0m" end
|
49
|
+
def red(str) "\e[31m#{str}\e[0m" end
|
50
|
+
def green(str) "\e[32m#{str}\e[0m" end
|
51
|
+
def yellow(str) "\e[33m#{str}\e[0m" end
|
52
|
+
def blue(str) "\e[34m#{str}\e[0m" end
|
53
|
+
def purple(str) "\e[35m#{str}\e[0m" end
|
54
|
+
def cyan(str) "\e[36m#{str}\e[0m" end
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
##########################
|
59
|
+
# db download and install
|
60
|
+
##########################
|
61
|
+
#
|
62
|
+
# 1. Download .7z file from Gitee
|
63
|
+
# 2. Decompress the .7z file to CSV file
|
64
|
+
# 3. Transform CSV file into database
|
65
|
+
#
|
66
|
+
|
67
|
+
def check_download_integrity
|
68
|
+
require 'digest'
|
69
|
+
cont = File.read(ECDictRAWDATA)
|
70
|
+
sha256 = Digest::SHA256.hexdigest(cont)
|
71
|
+
if ECDICT_DICT_SHA256 == sha256
|
72
|
+
true
|
73
|
+
else
|
74
|
+
false
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
def download_ecdict_data
|
80
|
+
|
81
|
+
if File.exists?(ECDictRAWDATA) && check_download_integrity
|
82
|
+
puts "=> 已存在原始数据文件#{ECDictRAWDATA}, 无需再次下载"
|
83
|
+
else
|
84
|
+
|
85
|
+
if File.exists?(ECDictRAWDATA)
|
86
|
+
puts "=> 删除已存在但不完整的数据"
|
87
|
+
FileUtils.rm ECDictRAWDATA
|
88
|
+
end
|
89
|
+
|
90
|
+
begin
|
91
|
+
puts "=> 正在从#{ECDICT_DICT_DOWNLOAD_LINK}"
|
92
|
+
puts "=> 下载原始数据库文件(v#{ECDICT_DICT_VERSION})"
|
93
|
+
system("curl -L #{ECDICT_DICT_DOWNLOAD_LINK} -o #{ECDictRAWDATA}")
|
94
|
+
raise "=> 下载数据不完整!" if !check_download_integrity
|
95
|
+
rescue StandardError => e
|
96
|
+
puts "=> #{e.message}"
|
97
|
+
puts "=> 下载失败,请检查网络连接(使用国内网络即可,不需要外网)"
|
98
|
+
FileUtils.rm(ECDictRAWDATA)
|
99
|
+
else
|
100
|
+
puts "=> 下载完成!"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
true
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
def decompress_7z_to_csv()
|
109
|
+
require 'seven_zip_ruby'
|
110
|
+
|
111
|
+
# 正常解压出来的CSV应当至少200MB以上
|
112
|
+
if File.exists?(ECDictCSV)
|
113
|
+
if File.size(ECDictCSV) <= 200*1024*1024
|
114
|
+
puts "=> 删除旧有的不完全词典数据"
|
115
|
+
FileUtils.rm(ECDictCSV)
|
116
|
+
else
|
117
|
+
puts "=> CSV数据已存在,无需再次解压,直接使用"
|
118
|
+
return true
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
File.open(ECDictRAWDATA, "rb") do |file|
|
124
|
+
puts "=> 正在解压ecdict-csv.7z(#{file.size/1024/1024}MB)"
|
125
|
+
SevenZipRuby::Reader.extract_all(file, ECDICT_STORAGE)
|
126
|
+
end
|
127
|
+
|
128
|
+
puts "=> 已成功解压出ecdict.csv(#{File.size(ECDictCSV)/1024/1024}MB)"
|
129
|
+
true
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
#
|
134
|
+
# 检查生成出来的db的完整性
|
135
|
+
# 不太方便检查,只能粗略的查看大小
|
136
|
+
#
|
137
|
+
def check_db_integrity
|
138
|
+
# 正常从CSV生成出来的数据库应当至少400MB以上
|
139
|
+
if File.size(ECDictDB) <= 400*1024*1024
|
140
|
+
false
|
141
|
+
else
|
142
|
+
true
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
#
|
148
|
+
# This is the Ruby versioned [stardict.py] from
|
149
|
+
# https://github.com/skywind3000/ECDICT
|
150
|
+
#
|
151
|
+
# It generates [ecdict.db] in 3 steps:
|
152
|
+
#
|
153
|
+
# 1. create new and empty db file
|
154
|
+
# 2. create table in the db
|
155
|
+
# 3. insert data from CSV into the table
|
156
|
+
#
|
157
|
+
# exit 1 : create db failed
|
158
|
+
# exit 2 : insert data failed
|
159
|
+
#
|
160
|
+
def generate_sqlite_db()
|
161
|
+
|
162
|
+
# SQLite3::Database.new已经生成了该文件,所以需要提前判断到底是否存在
|
163
|
+
if File.exist?(ECDictDB)
|
164
|
+
|
165
|
+
if !check_db_integrity
|
166
|
+
puts "=> 删除旧有的不完整数据库"
|
167
|
+
$DB.close
|
168
|
+
FileUtils.rm(ECDictDB)
|
169
|
+
$DB = SQLite3::Database.new ECDictDB
|
170
|
+
else
|
171
|
+
puts "=> 完整(可能的)数据库已存在,无需再次从CSV文件生成,直接使用"
|
172
|
+
return true
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def db_close
|
177
|
+
$DB.close if $DB
|
178
|
+
end
|
179
|
+
|
180
|
+
# 共15个字段,存的时候只需要14个
|
181
|
+
# 1.id 主键,自增
|
182
|
+
# 2.sw strip word(删除非alnum字符)
|
183
|
+
# 3.word 单词名称
|
184
|
+
# 4.phonetic 音标,以英语英标为主
|
185
|
+
# 5.definition 单词释义(英文),每行一个释义
|
186
|
+
# 6.translation 单词释义(中文),每行一个释义
|
187
|
+
# 7.pos 词语位置,用 "/" 分割不同位置
|
188
|
+
# 8.collins 柯林斯星级
|
189
|
+
# 9.oxford 是否是牛津三千核心词汇
|
190
|
+
# 10.tag 字符串标签:zk/中考,gk/高考,cet4/四级 等等标签,空格分割
|
191
|
+
# 11.bnc 英国国家语料库词频顺序
|
192
|
+
# 12.frq 当代语料库词频顺序
|
193
|
+
# 13.exchange 时态复数等变换,使用 "/" 分割不同项目
|
194
|
+
# 14.detail json 扩展信息,字典形式保存例句(待添加)
|
195
|
+
# 15.audio 读音音频 url (待添加)
|
196
|
+
|
197
|
+
sql = <<-EOF
|
198
|
+
CREATE TABLE IF NOT EXISTS "ecdict" (
|
199
|
+
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
|
200
|
+
"word" VARCHAR(64) COLLATE NOCASE NOT NULL UNIQUE,
|
201
|
+
"sw" VARCHAR(64) COLLATE NOCASE NOT NULL,
|
202
|
+
"phonetic" VARCHAR(64),
|
203
|
+
"definition" TEXT,
|
204
|
+
"translation" TEXT,
|
205
|
+
"pos" VARCHAR(16),
|
206
|
+
"collins" INTEGER DEFAULT(0),
|
207
|
+
"oxford" INTEGER DEFAULT(0),
|
208
|
+
"tag" VARCHAR(64),
|
209
|
+
"bnc" INTEGER DEFAULT(NULL),
|
210
|
+
"frq" INTEGER DEFAULT(NULL),
|
211
|
+
"exchange" TEXT,
|
212
|
+
"detail" TEXT,
|
213
|
+
"audio" TEXT
|
214
|
+
);
|
215
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "ecdict_1" ON ecdict (id);
|
216
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "ecdict_2" ON ecdict (word);
|
217
|
+
CREATE INDEX IF NOT EXISTS "ecdict_3" ON ecdict (sw, word collate nocase);
|
218
|
+
CREATE INDEX IF NOT EXISTS "ecd_1" ON ecdict (word collate nocase);
|
219
|
+
EOF
|
220
|
+
|
221
|
+
|
222
|
+
begin
|
223
|
+
$DB.execute sql
|
224
|
+
puts "=> 创建数据库文件#{ECDictDB},并生成表`ecdict`"
|
225
|
+
rescue Exception => e
|
226
|
+
puts "=> #{e.message}"
|
227
|
+
puts "=> 创建数据库文件#{ECDictDB}失败,或表`ecdict`生成失败"
|
228
|
+
db_close
|
229
|
+
File.delete(ECDictDB)
|
230
|
+
exit 1
|
231
|
+
end
|
232
|
+
|
233
|
+
|
234
|
+
# 这是生成数据库中sw字段的函数,用于模糊匹配,csv中并不包含此字段
|
235
|
+
def strip_word(word)
|
236
|
+
word.gsub(/\W/,'').downcase
|
237
|
+
end
|
238
|
+
|
239
|
+
your_machine = case RUBY_PLATFORM
|
240
|
+
when /linux/i then "linux"
|
241
|
+
when /ucrt/i, /mingw/i then "windows"
|
242
|
+
when /mac/i then "mac"
|
243
|
+
when /bsd/i then "bsd"
|
244
|
+
else "machine"
|
245
|
+
end
|
246
|
+
|
247
|
+
begin
|
248
|
+
puts <<~EOC
|
249
|
+
|
250
|
+
#{blue("gem_name = 'ecdict'")}
|
251
|
+
#{blue("version = '#{ECDICT_GEM_VERSION}'")}
|
252
|
+
#{blue("author = 'ccmywish'")}
|
253
|
+
#{blue("bug_track = [ 'https://gitee.com/ccmywish/ecdict/issues'
|
254
|
+
'https://github.com/ccmywish/ecdict/issues ]")}
|
255
|
+
|
256
|
+
#{green("if")} #{purple("your_#{your_machine}_is_good")}
|
257
|
+
wait n =~ #{red('3min or less')}
|
258
|
+
#{green("end")}
|
259
|
+
|
260
|
+
#{blue(bold("the_\#{author}_is_busily_inserting_data_for_you(...)"))}
|
261
|
+
|
262
|
+
EOC
|
263
|
+
|
264
|
+
require 'progress_bar'
|
265
|
+
# progress_bar的bar在Windows上显示有问题
|
266
|
+
progress = ProgressBar.new(3402560,:counter,:percentage,:elapsed)
|
267
|
+
|
268
|
+
columns = %w{word sw phonetic definition translation pos collins oxford
|
269
|
+
tag bnc frq exchange detail audio}.join(',')
|
270
|
+
|
271
|
+
insert = "INSERT INTO ecdict (#{columns}) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?) "
|
272
|
+
|
273
|
+
require 'csv'
|
274
|
+
num = 0
|
275
|
+
$DB.transaction
|
276
|
+
CSV.foreach(ECDictCSV) do |row|
|
277
|
+
num = num + 1
|
278
|
+
next if num == 1 # headers不加入
|
279
|
+
row.map! do |n|
|
280
|
+
r = n.nil?? '' : n
|
281
|
+
r.gsub('\n',"\n") # 插入数据库时应直接转换为真的换行符
|
282
|
+
end
|
283
|
+
sw = strip_word(row[0])
|
284
|
+
row.insert(1,sw)
|
285
|
+
$DB.execute(insert,row)
|
286
|
+
progress.increment!
|
287
|
+
end
|
288
|
+
$DB.commit
|
289
|
+
|
290
|
+
rescue Exception => e
|
291
|
+
puts "=> #{e.message}"
|
292
|
+
puts "=> 数据库插入信息失败"
|
293
|
+
File.delete(ECDictDB)
|
294
|
+
db_close
|
295
|
+
exit 2
|
296
|
+
end
|
297
|
+
puts
|
298
|
+
puts "=> 数据库#{ECDictDB}已完整生成"
|
299
|
+
db_close
|
300
|
+
end
|
301
|
+
|
302
|
+
|
303
|
+
def download_and_install_ecdict_data
|
304
|
+
download_ecdict_data || ( puts("\e[31m=> 下载失败,安装取消!\e[0m") || exit(-1) )
|
305
|
+
decompress_7z_to_csv || ( puts("\e[31m=> 解压失败,安装取消!\e[0m") || exit(-2) )
|
306
|
+
generate_sqlite_db || ( puts("\e[31m=> 生成数据库失败,安装取消!\e[0m") || exit(-3) )
|
307
|
+
puts
|
308
|
+
puts "=> Hooray! 词典数据下载安装完成! 请尝试使用:"
|
309
|
+
puts "=> 1. ecdict word 查询单词 "
|
310
|
+
puts "=> 2. ecdict -r 进入交互式查询REPL"
|
311
|
+
puts
|
312
|
+
end
|
313
|
+
|
314
|
+
|
315
|
+
|
316
|
+
####################
|
317
|
+
# ecdict cmd
|
318
|
+
####################
|
319
|
+
#
|
320
|
+
# Error code -1: No db or db not intact
|
321
|
+
# Error code 1: No input
|
322
|
+
# Error code 2: Don't find a result
|
323
|
+
#
|
324
|
+
|
325
|
+
#
|
326
|
+
# Look up the dictionary db once a call
|
327
|
+
#
|
328
|
+
def reply_once(query)
|
329
|
+
|
330
|
+
if !check_db_integrity
|
331
|
+
puts "=> 数据库不存在或数据库不完整,请使用ecdict -i来下载安装词典数据",""
|
332
|
+
exit -1
|
333
|
+
end
|
334
|
+
|
335
|
+
tables = []
|
336
|
+
$DB.execute "SELECT name FROM sqlite_master WHERE TYPE = 'table' AND name != 'sqlite_sequence'; " do |tbl|
|
337
|
+
tables << tbl
|
338
|
+
end
|
339
|
+
# 每个表自己被数组包裹, [["gnuutils"], ["ruby"]]
|
340
|
+
tables.flatten!
|
341
|
+
|
342
|
+
|
343
|
+
rows = []
|
344
|
+
tables.each do |t|
|
345
|
+
$DB.execute "SELECT phonetic,translation,definition,exchange FROM #{t} WHERE word = '#{query}'" do |row|
|
346
|
+
rows << row
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
if rows.empty?
|
351
|
+
puts "ecdict: 未找到结果,请检查单词拼写是否正确",""
|
352
|
+
exit 2
|
353
|
+
else
|
354
|
+
line = rows[0]
|
355
|
+
phonetic,trans,definition,exchange = line[0],line[1],line[2],line[3]
|
356
|
+
puts "#{query} [#{phonetic.strip.empty?? :nil : phonetic}]"
|
357
|
+
puts
|
358
|
+
puts "* 中文翻译"
|
359
|
+
trans.split("\n").each {|t| puts "- #{t}"}
|
360
|
+
puts
|
361
|
+
if !definition.nil? && definition.strip != ""
|
362
|
+
puts "* 英文释义"
|
363
|
+
definition.split("\n").each {|t| puts "- #{t}"}
|
364
|
+
puts
|
365
|
+
end
|
366
|
+
if !exchange.nil? && !exchange.strip.empty?
|
367
|
+
puts "* 变化形式"
|
368
|
+
exchange.split("/").each do |e|
|
369
|
+
print "- "
|
370
|
+
type,word = e.split(":")
|
371
|
+
case type
|
372
|
+
when ?p then print "过去式 : "
|
373
|
+
when ?d then print "过去分词: "
|
374
|
+
when ?i then print "现在分词: "
|
375
|
+
when ?3 then print "第三人称: "
|
376
|
+
when ?r then print "比较级 : "
|
377
|
+
when ?t then print "最高级 : "
|
378
|
+
when ?s then print "名词复数: "
|
379
|
+
when ?0 then print "词根来源: "
|
380
|
+
when ?1 then print "词根变化: "
|
381
|
+
end
|
382
|
+
puts word
|
383
|
+
end
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
$DB.close if $DB
|
388
|
+
end
|
389
|
+
|
390
|
+
|
391
|
+
#
|
392
|
+
# Search Chinese word to find English words
|
393
|
+
#
|
394
|
+
def chinese_search(cn_word, support_phrase: false)
|
395
|
+
|
396
|
+
if cn_word.empty?
|
397
|
+
puts "ecdict: 请输入要查询的中文,或使用`ecdict -h`查看帮助", ""
|
398
|
+
exit 1
|
399
|
+
end
|
400
|
+
if !check_db_integrity
|
401
|
+
puts "=> 数据库不存在或数据库不完整,请使用`ecdict -i`来下载安装词典数据", ""
|
402
|
+
exit -1
|
403
|
+
end
|
404
|
+
|
405
|
+
if support_phrase
|
406
|
+
puts "ecdict: 搜索加强,支持短语"
|
407
|
+
end
|
408
|
+
|
409
|
+
tables = []
|
410
|
+
$DB.execute "SELECT name FROM sqlite_master WHERE TYPE = 'table' AND name != 'sqlite_sequence'; " do |tbl|
|
411
|
+
tables << tbl
|
412
|
+
end
|
413
|
+
tables.flatten!
|
414
|
+
|
415
|
+
rows = []
|
416
|
+
tables.each do |t|
|
417
|
+
$DB.execute "SELECT word, translation FROM #{t} WHERE translation LIKE '%#{cn_word}%' " do |row|
|
418
|
+
rows << row
|
419
|
+
end
|
420
|
+
end
|
421
|
+
if rows.empty?
|
422
|
+
puts "ecdict: 未找到相关英文,请不要输入中文短语或短句,仅支持词的搜索",""
|
423
|
+
exit 2
|
424
|
+
else
|
425
|
+
# 有的时候并不是没有结果,而是被我们过滤掉了,对此确认一下
|
426
|
+
found_a_word = false
|
427
|
+
|
428
|
+
rows.each do |line|
|
429
|
+
en_word,trans = line[0],line[1]
|
430
|
+
|
431
|
+
# 过长的直接跳过
|
432
|
+
next if trans.length > 35
|
433
|
+
# 有换行符的太长,直接跳过
|
434
|
+
next if trans.include?("\r\n")
|
435
|
+
next if trans.include?("\n")
|
436
|
+
|
437
|
+
# 不要搜索词组
|
438
|
+
if !support_phrase
|
439
|
+
next if en_word.include?(' ')
|
440
|
+
end
|
441
|
+
# 不要搜索连字词
|
442
|
+
next if en_word.include?('-')
|
443
|
+
|
444
|
+
# filter
|
445
|
+
# "[网络] 微软,认证专家;微软认证产品专家;微软专家认证"
|
446
|
+
trans_words1 = trans.split(',') # 英文逗号!!!
|
447
|
+
|
448
|
+
trans_words = []
|
449
|
+
trans_words1.each do |w|
|
450
|
+
trans_words << w.split(';') # 中文分号!!!
|
451
|
+
end
|
452
|
+
# [ [] [] [] ]
|
453
|
+
trans_words = trans_words.flatten
|
454
|
+
|
455
|
+
ret = nil
|
456
|
+
trans_words.each do |t|
|
457
|
+
ret = t.split.index do
|
458
|
+
# 必须以搜索的中文开头,最多容纳两个字符
|
459
|
+
# _1 =~ /^#{cn_word}.{0,2}$/
|
460
|
+
|
461
|
+
# 往往中文都是精确搜索
|
462
|
+
_1 == cn_word
|
463
|
+
end
|
464
|
+
break if ret
|
465
|
+
end
|
466
|
+
|
467
|
+
if !ret.nil?
|
468
|
+
found_a_word = true
|
469
|
+
puts "#{blue(en_word)}: #{trans}"
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
if found_a_word
|
474
|
+
puts
|
475
|
+
else
|
476
|
+
puts "ecdict: 抱歉,为了防止显示内容过多,已将可能的答案过滤了",""
|
477
|
+
end
|
478
|
+
# end of else
|
479
|
+
end
|
480
|
+
|
481
|
+
end
|
482
|
+
|
483
|
+
|
484
|
+
####################
|
485
|
+
# ecdict REPL
|
486
|
+
####################
|
487
|
+
|
488
|
+
#
|
489
|
+
# Look up the dictionary db all the time in a not ending way,
|
490
|
+
# that is, interactively as a REPL does.
|
491
|
+
#
|
492
|
+
# Notice the similar function `reply_once` above,
|
493
|
+
# which only answer once.
|
494
|
+
#
|
495
|
+
def replying(query)
|
496
|
+
|
497
|
+
answer = nil
|
498
|
+
$DB.execute "SELECT phonetic,translation,definition,exchange FROM ecdict WHERE word = '#{query}'" do |row|
|
499
|
+
answer = row
|
500
|
+
end
|
501
|
+
if answer.nil?
|
502
|
+
puts "未找到结果,请检查单词拼写是否正确"
|
503
|
+
else
|
504
|
+
line = answer
|
505
|
+
phonetic,trans,definition,exchange = line[0],line[1],line[2],line[3]
|
506
|
+
puts "#{query} [#{phonetic.strip.empty?? :nil : phonetic}]"
|
507
|
+
puts
|
508
|
+
puts "* 中文翻译"
|
509
|
+
trans.split("\n").each {|t| puts "- #{t}"}
|
510
|
+
puts
|
511
|
+
if !definition.nil? && definition.strip != ""
|
512
|
+
puts "* 英文释义"
|
513
|
+
definition.split("\n").each {|t| puts "- #{t}"}
|
514
|
+
puts
|
515
|
+
end
|
516
|
+
if !exchange.nil? && !exchange.strip.empty?
|
517
|
+
puts "* 变化形式"
|
518
|
+
exchange.split("/").each do |e|
|
519
|
+
print "- "
|
520
|
+
type,word = e.split(":")
|
521
|
+
case type
|
522
|
+
when ?p then print "过去式 : "
|
523
|
+
when ?d then print "过去分词: "
|
524
|
+
when ?i then print "现在分词: "
|
525
|
+
when ?3 then print "第三人称: "
|
526
|
+
when ?r then print "比较级 : "
|
527
|
+
when ?t then print "最高级 : "
|
528
|
+
when ?s then print "名词复数: "
|
529
|
+
when ?0 then print "词根来源: "
|
530
|
+
when ?1 then print "词根变化: "
|
531
|
+
end
|
532
|
+
puts word
|
533
|
+
end
|
534
|
+
end
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
|
539
|
+
#
|
540
|
+
# Start ecrepl
|
541
|
+
#
|
542
|
+
def start_ecrepl
|
543
|
+
|
544
|
+
if !check_db_integrity
|
545
|
+
puts "=> 数据库不存在或数据库不完整,请使用`ecdict -i`来下载安装词典数据",""
|
546
|
+
exit -1
|
547
|
+
end
|
548
|
+
|
549
|
+
def db_close_and_exit
|
550
|
+
$DB.close if $DB
|
551
|
+
exit 0
|
552
|
+
end
|
553
|
+
|
554
|
+
begin
|
555
|
+
stty_save = `stty -g`.chomp
|
556
|
+
rescue
|
557
|
+
end
|
558
|
+
|
559
|
+
#
|
560
|
+
# completion
|
561
|
+
#
|
562
|
+
require 'ls_table'
|
563
|
+
require 'reline'
|
564
|
+
Reline.completion_proc = lambda do |word|
|
565
|
+
if word.strip.empty?
|
566
|
+
return %w{1.输入单词查询 2.输入exit或按Ctrl-C退出}
|
567
|
+
end
|
568
|
+
|
569
|
+
max_len = word.length + 4
|
570
|
+
puts
|
571
|
+
|
572
|
+
# $DB.execute "SELECT DISTINCT sw FROM ecdict WHERE sw LIKE '#{word}%' AND length(sw)<#{max_len} LIMIT 12" { |row| puts row }
|
573
|
+
|
574
|
+
# 以word开头的单词
|
575
|
+
ret = $DB.execute "SELECT DISTINCT sw FROM ecdict WHERE sw LIKE '#{word}%'
|
576
|
+
AND length(sw)<#{max_len} LIMIT 64"
|
577
|
+
# [["baba"], ["babe"], ["babn"], ["baby"]]
|
578
|
+
ret = ret.to_a.flatten
|
579
|
+
|
580
|
+
if word.length <= 7
|
581
|
+
LsTable.ls(ret) { puts blue(_1) }
|
582
|
+
else
|
583
|
+
LsTable.ls(ret, cell_len: 14, cell_num: 6) { puts blue(_1) }
|
584
|
+
end
|
585
|
+
|
586
|
+
puts
|
587
|
+
|
588
|
+
# 前面至少有一个字符
|
589
|
+
ret = $DB.execute "SELECT DISTINCT sw FROM ecdict WHERE sw LIKE '_%#{word}%'
|
590
|
+
AND length(sw)<#{max_len} LIMIT 64"
|
591
|
+
ret = ret.to_a.flatten
|
592
|
+
if word.length <= 7
|
593
|
+
LsTable.ls(ret) { puts blue(_1) }
|
594
|
+
else
|
595
|
+
LsTable.ls(ret, cell_len: 14, cell_num: 6) { puts blue(_1) }
|
596
|
+
end
|
597
|
+
|
598
|
+
end
|
599
|
+
|
600
|
+
#
|
601
|
+
# main query
|
602
|
+
#
|
603
|
+
begin
|
604
|
+
puts red("ECDict REPL (Ruby #{RUBY_VERSION} Powered)")
|
605
|
+
|
606
|
+
while line = Reline.readline("\e[32mecdict> \e[0m", true)
|
607
|
+
case word = line.chomp
|
608
|
+
when 'exit'
|
609
|
+
db_close_and_exit
|
610
|
+
when ''
|
611
|
+
# NOOP
|
612
|
+
else
|
613
|
+
replying(word)
|
614
|
+
end
|
615
|
+
end
|
616
|
+
rescue Interrupt
|
617
|
+
puts '^C'
|
618
|
+
`stty #{stty_save}` if stty_save
|
619
|
+
db_close_and_exit
|
620
|
+
end
|
621
|
+
|
622
|
+
end
|
623
|
+
|
624
|
+
|
625
|
+
#
|
626
|
+
# remove everything in #{ECDICT_STORAGE}
|
627
|
+
#
|
628
|
+
def delete_cache
|
629
|
+
|
630
|
+
begin
|
631
|
+
FileUtils.rm_rf(ECDICT_STORAGE)
|
632
|
+
rescue => e
|
633
|
+
puts "=> #{e.message}"
|
634
|
+
puts "=> 清空词典数据失败"
|
635
|
+
else
|
636
|
+
puts "=> 清空词典数据完成"
|
637
|
+
end
|
638
|
+
puts
|
639
|
+
end
|
640
|
+
|
641
|
+
|
642
|
+
####################
|
643
|
+
# others
|
644
|
+
####################
|
645
|
+
|
646
|
+
def print_version
|
647
|
+
puts <<EOH
|
648
|
+
ecdict (v#{ECDICT_GEM_VERSION}): A courteous cli translator.
|
649
|
+
|
650
|
+
|
651
|
+
EOH
|
652
|
+
|
653
|
+
end
|
654
|
+
|
655
|
+
|
656
|
+
def help
|
657
|
+
puts <<EOH
|
658
|
+
ecdict (v#{ECDICT_GEM_VERSION}): A courteous cli translator.
|
659
|
+
|
660
|
+
usage:
|
661
|
+
|
662
|
+
ecdict word => 查询单词 word
|
663
|
+
ecdict -r => 启动ecdict repl交互式查询,输入exit或Ctrl-C退出
|
664
|
+
ecdict -c 中文 => 搜索中文对应的英文单词
|
665
|
+
ecdict -cp 中文 => 搜索中文对应的英文单词以及短语(结果可能很多)
|
666
|
+
ecdict -i => 下载ecdict词典数据并安装
|
667
|
+
ecdict -v => 打印此Gem与词典版本号
|
668
|
+
ecdict -h => 打印此帮助
|
669
|
+
ecdict -d => 清空词典数据
|
670
|
+
|
671
|
+
EOH
|
672
|
+
|
673
|
+
end
|
674
|
+
|
675
|
+
|
676
|
+
####################
|
677
|
+
# main
|
678
|
+
####################
|
679
|
+
|
680
|
+
if ARGV.empty?
|
681
|
+
if !check_db_integrity
|
682
|
+
puts "=> 数据库不存在或数据库不完整,请使用`ecdict -i`来下载安装词典数据",""
|
683
|
+
exit -1
|
684
|
+
end
|
685
|
+
puts "ecdict: 请输入要查询的词/词组 或使用`ecdict -h`查看帮助",""
|
686
|
+
exit 1
|
687
|
+
end
|
688
|
+
|
689
|
+
query = ARGV.shift
|
690
|
+
case query
|
691
|
+
when "-v" then print_version
|
692
|
+
when "-h" then help
|
693
|
+
when "-i" then download_and_install_ecdict_data
|
694
|
+
when "-r" then start_ecrepl
|
695
|
+
when "-d" then delete_cache
|
696
|
+
when "-c" then chinese_search(ARGV.join)
|
697
|
+
when "-cp" then chinese_search(ARGV.join, support_phrase: true)
|
698
|
+
else
|
699
|
+
reply_once(query)
|
700
|
+
end
|
701
|
+
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ecdict
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.2.alpha
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- ccmywish
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-03-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: sqlite3
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: progress_bar
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: seven_zip_ruby
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: ls_table
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.1'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.1'
|
69
|
+
description: 'This command line tool `ecdict` is used to translate English to Chinese
|
70
|
+
using a huge dictionary called `ECDICT` which include 3.4 million words.
|
71
|
+
|
72
|
+
'
|
73
|
+
email: ccmywish@qq.com
|
74
|
+
executables:
|
75
|
+
- ecdict
|
76
|
+
extensions: []
|
77
|
+
extra_rdoc_files: []
|
78
|
+
files:
|
79
|
+
- bin/ecdict
|
80
|
+
homepage: https://gitee.com/ccmywish/ecdict
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata:
|
84
|
+
bug_tracker_uri: https://gitee.com/ccmywish/ecdict/issues
|
85
|
+
source_code_uri: https://gitee.com/ccmywish/ecdict
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">"
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: 1.3.1
|
100
|
+
requirements: []
|
101
|
+
rubygems_version: 3.3.7
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: 'ecdict: English-to-Chinese dictionary on the cli.'
|
105
|
+
test_files: []
|