ecdict 1.2.1 → 1.3.0
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 +4 -4
- data/bin/ecdict +97 -75
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b7ecd655d55d7a4fd69f9f508520cc26537c0d97b9bcc411449963e4fc8b868
|
4
|
+
data.tar.gz: cce06613d92a5550fa54fdd677f54ff9f2435597eddebae545bde391edc93a6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cfc2f765aee2c9e9a9284a6316eb37c548b5da8f3f8b94556a295c0892ed0341a01762bfaf119467397c698bd426e4c4f707d55031a4ed2cc90a82d513f9b81b
|
7
|
+
data.tar.gz: e9bd11e1448f51341bf71f334d6ae210615f04580d3900e9fd971700fa3ee3b7d9eee008b3791a1ac560b5af9f77612698f2d390927cf429e9f1f69f4b26dc82
|
data/bin/ecdict
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# File : ecdict.rb
|
4
4
|
# Authors : ccmywish <ccmywish@qq.com>
|
5
5
|
# Created on : <2020-10-18>
|
6
|
-
# Last modified : <2022-
|
6
|
+
# Last modified : <2022-04-29>
|
7
7
|
#
|
8
8
|
# ecdict:
|
9
9
|
#
|
@@ -27,25 +27,23 @@
|
|
27
27
|
|
28
28
|
require 'sqlite3'
|
29
29
|
|
30
|
-
|
31
|
-
|
30
|
+
ECDict::STORAGE = File.expand_path("~/.local/share/ecdict")
|
31
|
+
ECDict::RAW_DATA = File.join(ECDict::STORAGE, 'ecdict-csv.7z')
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
ECDICT_GEM_VERSION = "1.2.1"
|
33
|
+
ECDict::DB = File.join(ECDict::STORAGE, 'ecdict.db')
|
34
|
+
ECDict::CSV = File.join(ECDict::STORAGE, 'ecdict.csv')
|
37
35
|
|
38
36
|
# 这个版本是我从上游下载的CSV后自己压缩的
|
39
37
|
# 这个文件的实际创建日期(上游作者创建)是2017/06/04
|
40
38
|
# 至2022/03/22,未见更新,估计以后上游维护这个词典的也不会经常更新
|
41
39
|
# 而340万的单词量已经足够,因此我们可以足够长的时间一直停留在此词典版本
|
42
|
-
|
43
|
-
|
40
|
+
ECDict::DICT_DOWNLOAD_LINK = "https://gitee.com/ccmywish/ecdict-data"
|
41
|
+
ECDict::DICT_SHA256 = "86782a0e5d05486b482be5a2e5fa99b1a9b2ae51240c853ecfe181886133818a"
|
44
42
|
|
45
43
|
|
46
44
|
require 'fileutils'
|
47
|
-
FileUtils.mkdir_p(
|
48
|
-
$DB = SQLite3::Database.new
|
45
|
+
FileUtils.mkdir_p(ECDict::STORAGE)
|
46
|
+
$DB = SQLite3::Database.new ECDict::DB
|
49
47
|
|
50
48
|
def close_db
|
51
49
|
$DB.close if $DB
|
@@ -84,9 +82,9 @@ def cyan(str) "\e[36m#{str}\e[0m" end
|
|
84
82
|
|
85
83
|
def check_download_integrity
|
86
84
|
require 'digest'
|
87
|
-
return false if !File.exists?(
|
88
|
-
sha256 = Digest::SHA256.file(
|
89
|
-
if
|
85
|
+
return false if !File.exists?(ECDict::RAW_DATA)
|
86
|
+
sha256 = Digest::SHA256.file(ECDict::RAW_DATA).hexdigest
|
87
|
+
if ECDict::DICT_SHA256 == sha256
|
90
88
|
true
|
91
89
|
else
|
92
90
|
false
|
@@ -96,40 +94,40 @@ end
|
|
96
94
|
|
97
95
|
def download_ecdict_raw_data
|
98
96
|
|
99
|
-
if File.exists?(
|
100
|
-
puts "=> 已存在原始数据文件#{
|
97
|
+
if File.exists?(ECDict::RAW_DATA) && check_download_integrity
|
98
|
+
puts "=> 已存在原始数据文件#{ECDict::RAW_DATA}, 无需再次下载"
|
101
99
|
else
|
102
100
|
|
103
|
-
if File.exists?(
|
101
|
+
if File.exists?(ECDict::RAW_DATA)
|
104
102
|
puts "=> 删除已存在但不完整的原始数据文件"
|
105
|
-
FileUtils.rm
|
103
|
+
FileUtils.rm ECDict::RAW_DATA
|
106
104
|
end
|
107
105
|
|
108
106
|
# 若已经有拉取的仓库,先检查里面的数据是否可用
|
109
|
-
raw_data_git_dir = File.join(
|
107
|
+
raw_data_git_dir = File.join(ECDict::STORAGE, 'ecdict-data')
|
110
108
|
raw_data_git_dir_data = File.join(raw_data_git_dir, 'ecdict-csv.7z')
|
111
109
|
|
112
110
|
if Dir.exists?(raw_data_git_dir)
|
113
111
|
if File.exists?(raw_data_git_dir_data)
|
114
|
-
FileUtils.cp(raw_data_git_dir_data,
|
112
|
+
FileUtils.cp(raw_data_git_dir_data, ECDict::STORAGE)
|
115
113
|
if check_download_integrity
|
116
114
|
puts "=> 从已经Git pull到的仓库中获取原始数据文件"
|
117
115
|
return true
|
118
116
|
else
|
119
|
-
FileUtils.rm
|
117
|
+
FileUtils.rm ECDict::RAW_DATA
|
120
118
|
end
|
121
119
|
end
|
122
120
|
FileUtils.rm_rf(raw_data_git_dir)
|
123
121
|
end
|
124
122
|
|
125
123
|
begin
|
126
|
-
puts "=> 使用Git从#{
|
127
|
-
ret = system("git -C #{
|
128
|
-
FileUtils.cp(File.join(
|
124
|
+
puts "=> 使用Git从#{ECDict::DICT_DOWNLOAD_LINK}获取原始数据库文件"
|
125
|
+
ret = system("git -C #{ECDict::STORAGE} clone #{ECDict::DICT_DOWNLOAD_LINK} ")
|
126
|
+
FileUtils.cp(File.join(ECDict::STORAGE, 'ecdict-data', 'ecdict-csv.7z'), ECDict::STORAGE) rescue nil
|
129
127
|
raise "Git拉取仓库过程失败,原始数据文件不完整!" if (ret != true || !check_download_integrity)
|
130
128
|
rescue StandardError => e
|
131
129
|
puts "=> #{e.message}"
|
132
|
-
FileUtils.rm(
|
130
|
+
FileUtils.rm(ECDict::RAW_DATA) rescue nil
|
133
131
|
return false
|
134
132
|
else
|
135
133
|
puts "=> 下载完成!"
|
@@ -143,10 +141,10 @@ def decompress_7z_to_csv()
|
|
143
141
|
require 'seven_zip_ruby'
|
144
142
|
|
145
143
|
# 正常解压出来的CSV应当至少200MB以上
|
146
|
-
if File.exists?(
|
147
|
-
if File.size(
|
144
|
+
if File.exists?(ECDict::CSV)
|
145
|
+
if File.size(ECDict::CSV) <= 200*1024*1024
|
148
146
|
puts "=> 删除旧有的不完全词典数据"
|
149
|
-
FileUtils.rm(
|
147
|
+
FileUtils.rm(ECDict::CSV)
|
150
148
|
else
|
151
149
|
puts "=> CSV数据已存在,无需再次解压,直接使用"
|
152
150
|
return true
|
@@ -154,12 +152,12 @@ def decompress_7z_to_csv()
|
|
154
152
|
end
|
155
153
|
|
156
154
|
|
157
|
-
File.open(
|
155
|
+
File.open(ECDict::RAW_DATA, "rb") do |file|
|
158
156
|
puts "=> 正在解压ecdict-csv.7z(#{ '%.2f' % (file.size/1024.0/1024) }MB)"
|
159
|
-
SevenZipRuby::Reader.extract_all(file,
|
157
|
+
SevenZipRuby::Reader.extract_all(file, ECDict::STORAGE)
|
160
158
|
end
|
161
159
|
|
162
|
-
puts "=> 已成功解压出ecdict.csv(#{ '%.2f' % (File.size(
|
160
|
+
puts "=> 已成功解压出ecdict.csv(#{ '%.2f' % (File.size(ECDict::CSV)/1024.0/1024) }MB)"
|
163
161
|
true
|
164
162
|
end
|
165
163
|
|
@@ -170,7 +168,7 @@ end
|
|
170
168
|
#
|
171
169
|
def check_db_integrity
|
172
170
|
# 正常从CSV生成出来的数据库应当至少400MB以上
|
173
|
-
if File.size(
|
171
|
+
if File.size(ECDict::DB) <= 400*1024*1024
|
174
172
|
false
|
175
173
|
else
|
176
174
|
true
|
@@ -191,13 +189,13 @@ end
|
|
191
189
|
def generate_sqlite_db()
|
192
190
|
|
193
191
|
# SQLite3::Database.new已经生成了该文件,所以需要提前判断到底是否存在
|
194
|
-
if File.exist?(
|
192
|
+
if File.exist?(ECDict::DB)
|
195
193
|
|
196
194
|
if !check_db_integrity
|
197
195
|
puts "=> 删除旧有的不完整数据库"
|
198
196
|
$DB.close
|
199
|
-
FileUtils.rm(
|
200
|
-
$DB = SQLite3::Database.new
|
197
|
+
FileUtils.rm(ECDict::DB)
|
198
|
+
$DB = SQLite3::Database.new ECDict::DB
|
201
199
|
else
|
202
200
|
puts "=> 完整(可能的)数据库已存在,无需再次从CSV文件生成,直接使用"
|
203
201
|
return true
|
@@ -249,12 +247,12 @@ EOF
|
|
249
247
|
|
250
248
|
begin
|
251
249
|
$DB.execute sql
|
252
|
-
puts "=> 创建数据库文件#{
|
250
|
+
puts "=> 创建数据库文件#{ECDict::DB},并生成表`ecdict`"
|
253
251
|
rescue Exception => e
|
254
252
|
puts "=> #{e.message}"
|
255
|
-
puts "=> 创建数据库文件#{
|
253
|
+
puts "=> 创建数据库文件#{ECDict::DB}失败,或表`ecdict`生成失败"
|
256
254
|
close_db
|
257
|
-
File.delete(
|
255
|
+
File.delete(ECDict::DB)
|
258
256
|
return false
|
259
257
|
end
|
260
258
|
|
@@ -276,7 +274,7 @@ EOF
|
|
276
274
|
puts <<~EOC
|
277
275
|
|
278
276
|
#{blue("gem_name = 'ecdict'")}
|
279
|
-
#{blue("version = '#{
|
277
|
+
#{blue("version = '#{ECDict::VERSION}'")}
|
280
278
|
#{blue("author = 'ccmywish'")}
|
281
279
|
#{blue("bug_track = [ 'https://gitee.com/ccmywish/ecdict/issues'
|
282
280
|
'https://github.com/ccmywish/ecdict/issues ]")}
|
@@ -301,7 +299,7 @@ EOF
|
|
301
299
|
require 'csv'
|
302
300
|
num = 0
|
303
301
|
$DB.transaction
|
304
|
-
CSV.foreach(
|
302
|
+
CSV.foreach(ECDict::CSV) do |row|
|
305
303
|
num = num + 1
|
306
304
|
next if num == 1 # headers不加入
|
307
305
|
row.map! do |n|
|
@@ -319,11 +317,11 @@ EOF
|
|
319
317
|
puts "=> #{e.message}"
|
320
318
|
puts "=> 数据库插入信息失败"
|
321
319
|
close_db
|
322
|
-
File.delete(
|
320
|
+
File.delete(ECDict::DB)
|
323
321
|
return false
|
324
322
|
end
|
325
323
|
puts
|
326
|
-
puts "=> 数据库#{
|
324
|
+
puts "=> 数据库#{ECDict::DB}已完整生成"
|
327
325
|
close_db
|
328
326
|
return true
|
329
327
|
end
|
@@ -350,7 +348,7 @@ end
|
|
350
348
|
#
|
351
349
|
# Error code -1: No db or db not intact
|
352
350
|
# Error code 1: No input
|
353
|
-
# Error code 2:
|
351
|
+
# Error code 2: Doesn't find a result
|
354
352
|
#
|
355
353
|
|
356
354
|
#
|
@@ -423,7 +421,7 @@ end
|
|
423
421
|
#
|
424
422
|
# Search Chinese word to find English words
|
425
423
|
#
|
426
|
-
def
|
424
|
+
def search_chinese(cn_word, support_phrase: false)
|
427
425
|
|
428
426
|
if cn_word.empty?
|
429
427
|
puts "ecdict: 请输入要查询的中文,或使用`ecdict -h`查看帮助"
|
@@ -435,7 +433,7 @@ def chinese_search(cn_word, support_phrase: false)
|
|
435
433
|
end
|
436
434
|
|
437
435
|
if support_phrase
|
438
|
-
puts "ecdict:
|
436
|
+
puts "ecdict: 搜索加强,包含短语"
|
439
437
|
end
|
440
438
|
|
441
439
|
tables = []
|
@@ -510,8 +508,8 @@ def chinese_search(cn_word, support_phrase: false)
|
|
510
508
|
else
|
511
509
|
|
512
510
|
if !support_phrase
|
513
|
-
puts "ecdict:
|
514
|
-
|
511
|
+
puts "ecdict: 扩大搜索范围,再次尝试搜索..."
|
512
|
+
search_chinese(cn_word, support_phrase: true)
|
515
513
|
else
|
516
514
|
puts "ecdict: 抱歉,未找到与之相关的英文"
|
517
515
|
end
|
@@ -600,7 +598,9 @@ def start_ecrepl
|
|
600
598
|
require 'reline'
|
601
599
|
Reline.completion_proc = lambda do |word|
|
602
600
|
if word.strip.empty?
|
603
|
-
|
601
|
+
return %w[1.输入单词并回车查询含义
|
602
|
+
2.输入单词时按一次tab键反馈搜索建议
|
603
|
+
3.输入exit或按Ctrl-C或Ctrl-D退出]
|
604
604
|
end
|
605
605
|
|
606
606
|
max_len = word.length + 4
|
@@ -608,30 +608,54 @@ def start_ecrepl
|
|
608
608
|
|
609
609
|
# $DB.execute "SELECT DISTINCT sw FROM ecdict WHERE sw LIKE '#{word}%' AND length(sw)<#{max_len} LIMIT 12" { |row| puts row }
|
610
610
|
|
611
|
-
# 以word开头的单词
|
612
|
-
ret = $DB.execute "SELECT DISTINCT sw FROM ecdict WHERE sw LIKE '#{word}%'
|
613
|
-
AND length(sw)<#{max_len} LIMIT 64"
|
614
|
-
# [["baba"], ["babe"], ["babn"], ["baby"]]
|
615
|
-
ret = ret.to_a.flatten
|
616
611
|
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
612
|
+
# Display suggestions
|
613
|
+
#
|
614
|
+
# @params word [String] The word we search
|
615
|
+
# @params ret [Array] The suggestions array returned
|
616
|
+
def _display_suggestions(word, ret)
|
617
|
+
return if ret.empty?
|
618
|
+
if word.length <= 7
|
619
|
+
LsTable.ls(ret) { puts blue(_1) }
|
620
|
+
else
|
621
|
+
LsTable.ls(ret, cell_len: 14, cell_num: 6) { puts blue(_1) }
|
622
|
+
end
|
623
|
+
puts
|
621
624
|
end
|
622
625
|
|
623
|
-
|
626
|
+
# Generate suggestions
|
627
|
+
# 1. the words beginning with our search word
|
628
|
+
# 2. the words including our search word
|
629
|
+
#
|
630
|
+
# @params word [String] The word we search
|
631
|
+
# @params max_len [Integer] Suggestion's max length
|
632
|
+
def _gen_suggestion_1(word, max_len)
|
633
|
+
ret = $DB.execute <<-SQL
|
634
|
+
SELECT DISTINCT sw FROM ecdict WHERE sw LIKE '#{word}%'
|
635
|
+
AND length(sw)<#{max_len} LIMIT 64
|
636
|
+
SQL
|
637
|
+
# [["baba"], ["babe"], ["babn"], ["baby"]]
|
638
|
+
ret = ret.to_a.flatten
|
639
|
+
end
|
624
640
|
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
else
|
632
|
-
LsTable.ls(ret, cell_len: 14, cell_num: 6) { puts blue(_1) }
|
641
|
+
def _gen_suggestion_2(word, max_len)
|
642
|
+
ret = $DB.execute <<-SQL
|
643
|
+
SELECT DISTINCT sw FROM ecdict WHERE sw LIKE '_%#{word}%'
|
644
|
+
AND length(sw)<#{max_len} LIMIT 64
|
645
|
+
SQL
|
646
|
+
ret = ret.to_a.flatten
|
633
647
|
end
|
634
648
|
|
649
|
+
suggestions = [
|
650
|
+
Thread.new {
|
651
|
+
_display_suggestions word, _gen_suggestion_1(word, max_len)
|
652
|
+
},
|
653
|
+
Thread.new {
|
654
|
+
_display_suggestions word, _gen_suggestion_2(word, max_len)
|
655
|
+
}
|
656
|
+
].each(&:join)
|
657
|
+
|
658
|
+
""
|
635
659
|
end
|
636
660
|
|
637
661
|
#
|
@@ -662,12 +686,12 @@ end
|
|
662
686
|
|
663
687
|
|
664
688
|
#
|
665
|
-
# remove everything in #{
|
689
|
+
# remove everything in #{ECDict::STORAGE}
|
666
690
|
#
|
667
691
|
def delete_cache
|
668
692
|
close_db
|
669
693
|
begin
|
670
|
-
FileUtils.rm_rf(
|
694
|
+
FileUtils.rm_rf(ECDict::STORAGE)
|
671
695
|
rescue => e
|
672
696
|
puts "ecdict: #{e.message}"
|
673
697
|
puts "ecdict: 清空词典数据失败"
|
@@ -684,7 +708,7 @@ end
|
|
684
708
|
|
685
709
|
def print_version
|
686
710
|
puts <<EOH
|
687
|
-
ecdict (v#{
|
711
|
+
ecdict (v#{ECDict::VERSION}): A courteous cli translator.
|
688
712
|
EOH
|
689
713
|
|
690
714
|
end
|
@@ -692,14 +716,13 @@ end
|
|
692
716
|
|
693
717
|
def help
|
694
718
|
puts <<EOH
|
695
|
-
ecdict (v#{
|
719
|
+
ecdict (v#{ECDict::VERSION}): A courteous cli translator.
|
696
720
|
|
697
721
|
usage:
|
698
722
|
|
699
723
|
ecdict word => 查询单词word
|
700
724
|
ecdict -r => 启动ecdict repl交互式查询,输入exit或Ctrl-C/D退出
|
701
|
-
ecdict -c 中文 =>
|
702
|
-
ecdict -cp 中文 => 搜索中文短语对应的英文短语
|
725
|
+
ecdict -c 中文 => 搜索中文单词对应的英文单词/短语
|
703
726
|
ecdict -i => 下载ecdict词典数据并安装
|
704
727
|
ecdict -v => 打印此Gem版本号
|
705
728
|
ecdict -h => 打印此帮助
|
@@ -730,11 +753,10 @@ when "-h" then help
|
|
730
753
|
when "-i" then download_and_install_ecdict_data
|
731
754
|
when "-r" then start_ecrepl
|
732
755
|
when "-d" then delete_cache
|
733
|
-
when "-c" then
|
734
|
-
when "-cp" then chinese_search(ARGV.join, support_phrase: true)
|
756
|
+
when "-c" then search_chinese(ARGV.join)
|
735
757
|
else
|
736
758
|
reply_once(query)
|
737
759
|
end
|
738
760
|
|
739
761
|
# ensure close db
|
740
|
-
close_db
|
762
|
+
close_db
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ecdict
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ccmywish
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sqlite3
|
@@ -98,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
98
|
- !ruby/object:Gem::Version
|
99
99
|
version: '0'
|
100
100
|
requirements: []
|
101
|
-
rubygems_version: 3.3.
|
101
|
+
rubygems_version: 3.3.12
|
102
102
|
signing_key:
|
103
103
|
specification_version: 4
|
104
104
|
summary: 'ecdict: English-to-Chinese dictionary on the cli.'
|