logaling-command 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +18 -0
- data/lib/logaling/command.rb +98 -5
- data/lib/logaling/external_glossaries/debian_project.rb +8 -8
- data/lib/logaling/external_glossaries/edict.rb +50 -0
- data/lib/logaling/external_glossaries/gene95.rb +60 -0
- data/lib/logaling/external_glossaries/gnome_project.rb +7 -7
- data/lib/logaling/external_glossaries/postgresql_manual.rb +8 -8
- data/lib/logaling/external_glossary.rb +21 -3
- data/lib/logaling/glossary.rb +4 -12
- data/lib/logaling/glossary_db.rb +232 -24
- data/lib/logaling/repository.rb +63 -39
- data/lib/logaling.rb +3 -1
- data/spec/logaling/command_spec.rb +91 -16
- data/spec/logaling/glossary_spec.rb +20 -17
- metadata +21 -18
data/CHANGES
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
= 0.1.2 / 2012-01-30
|
2
|
+
|
3
|
+
* 英和 / 和英 辞書のインポートができるようになりました。他プロジェクトの用語集をインポートする `loga import` と同じ手順でインポートすることができます。
|
4
|
+
|
5
|
+
* 出力結果が長くなった場合に、ページングが出来るようになりました。
|
6
|
+
|
7
|
+
* `loga show` コマンドが追加されました。指定した用語集内の用語を一覧する為のコマンドです。
|
8
|
+
|
9
|
+
* `loga list` コマンドが追加されました。登録されている用語集を一覧するためのコマンドです。
|
10
|
+
|
11
|
+
* `loga update` コマンド利用時に備考のみの変更ができるようになりました。(KitaitiMakoto さん)
|
12
|
+
|
13
|
+
* インデックスのタイミングと方式を変更したので、 `loga lookup` の結果表示速度が改善されました。
|
14
|
+
|
15
|
+
* 用語の登録 / 更新時の重複チェックを 用語集ファイルではなくインデックスしたものでチェックするように修正しました。
|
16
|
+
|
17
|
+
* loga lookup 時に自分のプロジェクトの用語集名が、より分かり易くなるように色付けを改良しました。
|
18
|
+
|
data/lib/logaling/command.rb
CHANGED
@@ -19,10 +19,9 @@ require 'thor'
|
|
19
19
|
require 'rainbow'
|
20
20
|
require "logaling/repository"
|
21
21
|
require "logaling/glossary"
|
22
|
-
require "logaling/external_glossary"
|
23
22
|
|
24
23
|
class Logaling::Command < Thor
|
25
|
-
VERSION = "0.1.
|
24
|
+
VERSION = "0.1.2"
|
26
25
|
LOGALING_CONFIG = '.logaling'
|
27
26
|
|
28
27
|
map '-a' => :add,
|
@@ -33,6 +32,8 @@ class Logaling::Command < Thor
|
|
33
32
|
'-n' => :new,
|
34
33
|
'-r' => :register,
|
35
34
|
'-U' => :unregister,
|
35
|
+
'-L' => :list,
|
36
|
+
'-s' => :show,
|
36
37
|
'-v' => :version
|
37
38
|
|
38
39
|
class_option "glossary", type: :string, aliases: "-g"
|
@@ -59,6 +60,7 @@ class Logaling::Command < Thor
|
|
59
60
|
desc 'import', 'Import external glossary'
|
60
61
|
method_option "list", type: :boolean, default: false
|
61
62
|
def import(external_glossary=nil)
|
63
|
+
require "logaling/external_glossary"
|
62
64
|
Logaling::ExternalGlossary.load
|
63
65
|
if options["list"]
|
64
66
|
Logaling::ExternalGlossary.list.each {|glossary| say "#{glossary.name.bright} : #{glossary.description}" }
|
@@ -118,6 +120,13 @@ class Logaling::Command < Thor
|
|
118
120
|
|
119
121
|
desc 'add [SOURCE TERM] [TARGET TERM] [NOTE(optional)]', 'Add term to glossary.'
|
120
122
|
def add(source_term, target_term, note='')
|
123
|
+
config = load_config_and_merge_options
|
124
|
+
repository.index
|
125
|
+
|
126
|
+
if repository.bilingual_pair_exists?(source_term, target_term, config["glossary"])
|
127
|
+
raise Logaling::TermError, "term '#{source_term}: #{target_term}' already exists in '#{config["glossary"]}'"
|
128
|
+
end
|
129
|
+
|
121
130
|
glossary.add(source_term, target_term, note)
|
122
131
|
rescue Logaling::CommandFailed, Logaling::TermError => e
|
123
132
|
say e.message
|
@@ -139,6 +148,13 @@ class Logaling::Command < Thor
|
|
139
148
|
|
140
149
|
desc 'update [SOURCE TERM] [TARGET TERM] [NEW TARGET TERM], [NOTE(optional)]', 'Update term.'
|
141
150
|
def update(source_term, target_term, new_target_term, note='')
|
151
|
+
config = load_config_and_merge_options
|
152
|
+
repository.index
|
153
|
+
|
154
|
+
if repository.bilingual_pair_exists_and_has_same_note?(source_term, new_target_term, note, config["glossary"])
|
155
|
+
raise Logaling::TermError, "term '#{source_term}: #{new_target_term}' already exists in '#{config["glossary"]}'"
|
156
|
+
end
|
157
|
+
|
142
158
|
glossary.update(source_term, target_term, new_target_term, note)
|
143
159
|
rescue Logaling::CommandFailed, Logaling::TermError => e
|
144
160
|
say e.message
|
@@ -154,14 +170,20 @@ class Logaling::Command < Thor
|
|
154
170
|
|
155
171
|
unless terms.empty?
|
156
172
|
max_str_size = terms.map{|term| term[:source_term].size}.sort.last
|
173
|
+
run_pager
|
157
174
|
terms.each do |term|
|
158
175
|
target_string = "#{term[:target_term].bright}"
|
159
176
|
target_string << "\t# #{term[:note]}" unless term[:note].empty?
|
160
177
|
if repository.glossary_counts > 1
|
161
|
-
|
162
|
-
|
178
|
+
target_string << "\t"
|
179
|
+
glossary_name = "(#{term[:glossary_name]})"
|
180
|
+
if term[:glossary_name] == config["glossary"]
|
181
|
+
target_string << glossary_name.foreground(:white).background(:green)
|
182
|
+
else
|
183
|
+
target_string << glossary_name
|
184
|
+
end
|
163
185
|
end
|
164
|
-
source_string = term[:
|
186
|
+
source_string = term[:snipped_source_term].map{|word| word.is_a?(Hash) ? word[:keyword].bright : word }.join
|
165
187
|
printf(" %-#{max_str_size+10}s %s\n", source_string, target_string)
|
166
188
|
end
|
167
189
|
else
|
@@ -176,6 +198,49 @@ class Logaling::Command < Thor
|
|
176
198
|
say "logaling-command version #{Logaling::Command::VERSION}"
|
177
199
|
end
|
178
200
|
|
201
|
+
desc 'show', 'Show terms in glossary.'
|
202
|
+
def show
|
203
|
+
required_options = {
|
204
|
+
"glossary" => "input glossary name '-g <glossary name>'",
|
205
|
+
"source-language" => "input source-language code '-S <source-language code>'",
|
206
|
+
"target-language" => "input target-language code '-T <target-language code>'"
|
207
|
+
}
|
208
|
+
config = load_config_and_merge_options(required_options)
|
209
|
+
repository.index
|
210
|
+
terms = repository.show_glossary(config["glossary"], config["source-language"], config["target-language"])
|
211
|
+
unless terms.empty?
|
212
|
+
run_pager
|
213
|
+
max_str_size = terms.map{|term| term[:source_term].size}.sort.last
|
214
|
+
terms.each do |term|
|
215
|
+
target_string = "#{term[:target_term]}"
|
216
|
+
target_string << "\t# #{term[:note]}" unless term[:note].empty?
|
217
|
+
printf(" %-#{max_str_size+10}s %s\n", term[:source_term], target_string)
|
218
|
+
end
|
219
|
+
else
|
220
|
+
"glossary <#{config['glossary']}> not found"
|
221
|
+
end
|
222
|
+
|
223
|
+
rescue Logaling::CommandFailed, Logaling::GlossaryDBNotFound => e
|
224
|
+
say e.message
|
225
|
+
end
|
226
|
+
|
227
|
+
desc 'list', 'Show glossary list.'
|
228
|
+
def list
|
229
|
+
repository.index
|
230
|
+
glossaries = repository.list
|
231
|
+
unless glossaries.empty?
|
232
|
+
run_pager
|
233
|
+
glossaries.each do |glossary|
|
234
|
+
printf(" %s\n", glossary)
|
235
|
+
end
|
236
|
+
else
|
237
|
+
"There is no registered glossary."
|
238
|
+
end
|
239
|
+
|
240
|
+
rescue Logaling::CommandFailed, Logaling::GlossaryDBNotFound => e
|
241
|
+
say e.message
|
242
|
+
end
|
243
|
+
|
179
244
|
private
|
180
245
|
def repository
|
181
246
|
@repository ||= Logaling::Repository.new(LOGALING_HOME)
|
@@ -278,4 +343,32 @@ class Logaling::Command < Thor
|
|
278
343
|
fp.puts "--target-language #{config['target-language']}" if config['target-language']
|
279
344
|
end
|
280
345
|
end
|
346
|
+
|
347
|
+
# http://nex-3.com/posts/73-git-style-automatic-paging-in-ruby
|
348
|
+
def run_pager
|
349
|
+
return if ::RUBY_PLATFORM =~ /win32/
|
350
|
+
return unless STDOUT.tty?
|
351
|
+
|
352
|
+
read, write = IO.pipe
|
353
|
+
|
354
|
+
unless Kernel.fork # Child process
|
355
|
+
STDOUT.reopen(write)
|
356
|
+
STDERR.reopen(write) if STDERR.tty?
|
357
|
+
read.close
|
358
|
+
write.close
|
359
|
+
return
|
360
|
+
end
|
361
|
+
|
362
|
+
# Parent process, become pager
|
363
|
+
STDIN.reopen(read)
|
364
|
+
read.close
|
365
|
+
write.close
|
366
|
+
|
367
|
+
ENV['LESS'] = 'FSRX' # Don't page if the input is short enough
|
368
|
+
|
369
|
+
# wait until we have input before we start the pager
|
370
|
+
Kernel.select [STDIN]
|
371
|
+
pager = ENV['PAGER'] || 'less'
|
372
|
+
exec pager rescue exec "/bin/sh", "-c", pager
|
373
|
+
end
|
281
374
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# Copyright (C) 2011 Miho SUZUKI
|
2
|
+
# Copyright (C) 2012 Kouhei Sutou <kou@clear-code.com>
|
2
3
|
#
|
3
4
|
# This program is free software: you can redistribute it and/or modify
|
4
5
|
# it under the terms of the GNU General Public License as published by
|
@@ -21,15 +22,14 @@ module Logaling
|
|
21
22
|
description 'Debian JP Project (http://www.debian.or.jp/community/translate/)'
|
22
23
|
source_language 'en'
|
23
24
|
target_language 'ja'
|
25
|
+
output_format 'csv'
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
csv << [dt.text, dd.text.gsub(/(^\/|\/$)/,'')]
|
32
|
-
end
|
27
|
+
private
|
28
|
+
def convert_to_csv(csv)
|
29
|
+
doc = ::Nokogiri::HTML(open("http://www.debian.or.jp/community/translate/trans_table.html", "r"))
|
30
|
+
doc.css('dl').each do |dl|
|
31
|
+
dl.children.each_slice(3) do |dt, dd, _|
|
32
|
+
csv << [dt.text, dd.text.gsub(/(^\/|\/$)/,'')]
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Copyright (C) 2012 Koji SHIMADA <koji.shimada@enishi-tech.com>
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
require 'open-uri'
|
17
|
+
require 'zlib'
|
18
|
+
require 'stringio'
|
19
|
+
|
20
|
+
module Logaling
|
21
|
+
class Edict < ExternalGlossary
|
22
|
+
description 'The EDICT Dictionary File (http://www.csse.monash.edu.au/~jwb/edict.html)'
|
23
|
+
source_language 'ja'
|
24
|
+
target_language 'en'
|
25
|
+
output_format 'csv'
|
26
|
+
|
27
|
+
private
|
28
|
+
def convert_to_csv(csv)
|
29
|
+
puts "downloading edict file..."
|
30
|
+
url = 'http://ftp.monash.edu.au/pub/nihongo/edict.gz'
|
31
|
+
Zlib::GzipReader.open(open(url)) do |gz|
|
32
|
+
puts "importing edict file..."
|
33
|
+
|
34
|
+
lines = StringIO.new(gz.read).each_line
|
35
|
+
|
36
|
+
lines.next # skip header
|
37
|
+
|
38
|
+
preprocessed_lines = lines.map do |line|
|
39
|
+
line.encode("UTF-8", "EUC-JP").chomp
|
40
|
+
end
|
41
|
+
|
42
|
+
preprocessed_lines.each do |line|
|
43
|
+
source, target = line.split('/', 2)
|
44
|
+
source = source.strip
|
45
|
+
csv << [source, target]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Copyright (C) 2012 Koji SHIMADA
|
2
|
+
# Copyright (C) 2012 Kouhei Sutou <kou@clear-code.com>
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
require 'open-uri'
|
18
|
+
require 'zlib'
|
19
|
+
require 'stringio'
|
20
|
+
require 'rubygems/package'
|
21
|
+
|
22
|
+
module Logaling
|
23
|
+
class Gene95 < ExternalGlossary
|
24
|
+
description 'GENE95 Dictionary (http://www.namazu.org/~tsuchiya/sdic/data/gene.html)'
|
25
|
+
source_language 'en'
|
26
|
+
target_language 'ja'
|
27
|
+
output_format 'csv'
|
28
|
+
|
29
|
+
private
|
30
|
+
def convert_to_csv(csv)
|
31
|
+
puts "downloading gene95 dictionary..."
|
32
|
+
url = 'http://www.namazu.org/~tsuchiya/sdic/data/gene95.tar.gz'
|
33
|
+
Zlib::GzipReader.open(open(url)) do |gz|
|
34
|
+
puts "importing gene95 dictionary..."
|
35
|
+
|
36
|
+
Gem::Package::TarReader.new(gz) do |tar|
|
37
|
+
tar.each do |entry|
|
38
|
+
case entry.full_name
|
39
|
+
when "gene.txt"
|
40
|
+
lines = StringIO.new(entry.read).each_line
|
41
|
+
|
42
|
+
2.times { lines.next } # skip header
|
43
|
+
|
44
|
+
preprocessed_lines = lines.map.map do |line|
|
45
|
+
line.encode("UTF-8", "CP932",
|
46
|
+
undef: :replace, replace: '').chomp
|
47
|
+
end
|
48
|
+
|
49
|
+
preprocessed_lines.each_slice(2) do |source, target|
|
50
|
+
csv << [source.sub(/( .*)/, ''), target]
|
51
|
+
end
|
52
|
+
else
|
53
|
+
# ignore
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# Copyright (C) 2011 Miho SUZUKI
|
2
|
+
# Copyright (C) 2012 Kouhei Sutou <kou@clear-code.com>
|
2
3
|
#
|
3
4
|
# This program is free software: you can redistribute it and/or modify
|
4
5
|
# it under the terms of the GNU General Public License as published by
|
@@ -21,14 +22,13 @@ module Logaling
|
|
21
22
|
description 'GNOME Translation Project Ja (http://live.gnome.org/TranslationProjectJa)'
|
22
23
|
source_language 'en'
|
23
24
|
target_language 'ja'
|
25
|
+
output_format 'csv'
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
csv << [tr.children[0].text, tr.children[1].text]
|
31
|
-
end
|
27
|
+
private
|
28
|
+
def convert_to_csv(csv)
|
29
|
+
doc = ::Nokogiri::HTML(open("http://www.gnome.gr.jp/l10n/trans-terms.html", "r"))
|
30
|
+
doc.css('table tr')[1..-1].each do |tr|
|
31
|
+
csv << [tr.children[0].text, tr.children[1].text]
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# Copyright (C) 2011 Miho SUZUKI
|
2
|
+
# Copyright (C) 2012 Kouhei Sutou <kou@clear-code.com>
|
2
3
|
#
|
3
4
|
# This program is free software: you can redistribute it and/or modify
|
4
5
|
# it under the terms of the GNU General Public License as published by
|
@@ -21,15 +22,14 @@ module Logaling
|
|
21
22
|
description 'PostgreSQL7.1 Manual (http://osb.sraoss.co.jp/PostgreSQL/Manual/)'
|
22
23
|
source_language 'en'
|
23
24
|
target_language 'ja'
|
25
|
+
output_format 'csv'
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
csv << [tr.children[2].text, tr.children[4].text]
|
32
|
-
end
|
27
|
+
private
|
28
|
+
def convert_to_csv(csv)
|
29
|
+
doc = ::Nokogiri::HTML(open("http://osb.sraoss.co.jp/PostgreSQL/Manual/word.html", "r:iso-2022-jp").read.encode("utf-8"))
|
30
|
+
doc.css('table table tr')[2..-1].each do |tr|
|
31
|
+
if tr.children[2]
|
32
|
+
csv << [tr.children[2].text, tr.children[4].text]
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -42,7 +42,7 @@ class Logaling::ExternalGlossary
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def name
|
45
|
-
self.
|
45
|
+
self.to_s.underscore.gsub(/.*\//,'')
|
46
46
|
end
|
47
47
|
|
48
48
|
def description val=nil
|
@@ -56,14 +56,32 @@ class Logaling::ExternalGlossary
|
|
56
56
|
def target_language val=nil
|
57
57
|
@target_language ||= val
|
58
58
|
end
|
59
|
+
|
60
|
+
def output_format(*args)
|
61
|
+
if args.empty?
|
62
|
+
@output_format ||= "csv"
|
63
|
+
else
|
64
|
+
@output_format = args.first
|
65
|
+
end
|
66
|
+
end
|
59
67
|
end
|
60
68
|
|
61
69
|
def import
|
62
|
-
File.open(import_file_name, "w")
|
70
|
+
File.open(import_file_name, "w") do |output|
|
71
|
+
output_format = self.class.output_format
|
72
|
+
output_format = output_format.to_s if output_format.is_a?(Symbol)
|
73
|
+
case output_format
|
74
|
+
when "csv"
|
75
|
+
convert_to_csv(CSV.new(output))
|
76
|
+
else
|
77
|
+
raise UnsupportedFormat, "unsupported format: <#{output_format}>"
|
78
|
+
end
|
79
|
+
end
|
63
80
|
end
|
64
81
|
|
65
82
|
private
|
66
83
|
def import_file_name
|
67
|
-
[self.class.name, self.class.source_language,
|
84
|
+
[self.class.name, self.class.source_language,
|
85
|
+
self.class.target_language, self.class.output_format].join('.')
|
68
86
|
end
|
69
87
|
end
|
data/lib/logaling/glossary.rb
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
|
18
18
|
require 'psych'
|
19
19
|
require "yaml"
|
20
|
+
require "csv"
|
20
21
|
require "fileutils"
|
21
22
|
|
22
23
|
module Logaling
|
@@ -72,10 +73,6 @@ module Logaling
|
|
72
73
|
FileUtils.touch(@path) unless File.exist?(@path)
|
73
74
|
|
74
75
|
glossary = Glossary.load_glossary(@path)
|
75
|
-
if bilingual_pair_exists?(glossary, source_term, target_term)
|
76
|
-
raise TermError, "term '#{source_term}: #{target_term}' already exists in '#{@glossary}'"
|
77
|
-
end
|
78
|
-
|
79
76
|
glossary << build_term(source_term, target_term, note)
|
80
77
|
dump_glossary(glossary)
|
81
78
|
end
|
@@ -84,9 +81,6 @@ module Logaling
|
|
84
81
|
raise GlossaryNotFound unless File.exist?(@path)
|
85
82
|
|
86
83
|
glossary = Glossary.load_glossary(@path)
|
87
|
-
if bilingual_pair_exists?(glossary, source_term, new_target_term)
|
88
|
-
raise TermError, "term '#{source_term}: #{target_term}' already exists in '#{@glossary}'"
|
89
|
-
end
|
90
84
|
|
91
85
|
target_index = find_term_index(glossary, source_term, target_term)
|
92
86
|
if target_index
|
@@ -136,7 +130,9 @@ module Logaling
|
|
136
130
|
end
|
137
131
|
|
138
132
|
def rebuild_term(current, source_term, target_term, note)
|
139
|
-
|
133
|
+
if current['target_term'] != target_term && (note.nil? || note == "")
|
134
|
+
note = current['note']
|
135
|
+
end
|
140
136
|
target_term = current['target_term'] if target_term == ""
|
141
137
|
build_term(source_term, target_term, note)
|
142
138
|
end
|
@@ -151,10 +147,6 @@ module Logaling
|
|
151
147
|
end
|
152
148
|
end
|
153
149
|
|
154
|
-
def bilingual_pair_exists?(glossary, source_term, target_term)
|
155
|
-
target_terms(glossary, source_term).any?{|data| data['target_term'] == target_term }
|
156
|
-
end
|
157
|
-
|
158
150
|
def target_terms(glossary, source_term)
|
159
151
|
glossary.select {|term| term['source_term'] == source_term }
|
160
152
|
end
|
data/lib/logaling/glossary_db.rb
CHANGED
@@ -15,14 +15,13 @@
|
|
15
15
|
# You should have received a copy of the GNU General Public License
|
16
16
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
17
|
|
18
|
-
require 'psych'
|
19
|
-
require "yaml"
|
20
|
-
require "fileutils"
|
21
18
|
require 'groonga'
|
22
|
-
require '
|
19
|
+
require 'cgi'
|
23
20
|
|
24
21
|
module Logaling
|
25
22
|
class GlossaryDB
|
23
|
+
VERSION = 1
|
24
|
+
|
26
25
|
def self.open(base_path, encoding, &blk)
|
27
26
|
blk ? GlossaryDB.new.open(base_path, encoding, &blk) : GlossaryDB.new.open(base_path, encoding)
|
28
27
|
end
|
@@ -50,8 +49,12 @@ module Logaling
|
|
50
49
|
end
|
51
50
|
|
52
51
|
def recreate_table
|
53
|
-
|
54
|
-
|
52
|
+
version = Groonga["configurations"] ? get_config("version") : 0
|
53
|
+
if version.to_i != VERSION
|
54
|
+
remove_schema
|
55
|
+
populate_schema
|
56
|
+
add_config("version", VERSION.to_s)
|
57
|
+
end
|
55
58
|
end
|
56
59
|
|
57
60
|
def close
|
@@ -59,27 +62,80 @@ module Logaling
|
|
59
62
|
@database = nil
|
60
63
|
end
|
61
64
|
|
62
|
-
def
|
65
|
+
def deindex_glossary(glossary_name, glossary_source)
|
66
|
+
delete_translations_by_glossary_source(glossary_source)
|
67
|
+
delete_glossary(glossary_name)
|
68
|
+
delete_glossary_source(glossary_source)
|
69
|
+
end
|
70
|
+
|
71
|
+
def index_glossary(glossary, glossary_name, glossary_source, source_language, target_language, indexed_at)
|
72
|
+
deindex_glossary(glossary_name, glossary_source)
|
73
|
+
|
74
|
+
add_glossary_source(glossary_source, indexed_at)
|
75
|
+
add_glossary(glossary_name)
|
63
76
|
glossary.each do |term|
|
64
77
|
source_term = term['source_term']
|
65
78
|
target_term = term['target_term']
|
66
79
|
note = term['note']
|
67
|
-
|
80
|
+
add_translation(glossary_name, glossary_source, source_language, target_language, source_term, target_term, note)
|
68
81
|
end
|
69
82
|
end
|
70
83
|
|
71
|
-
def lookup(source_term)
|
72
|
-
|
73
|
-
record.source_term =~ source_term
|
84
|
+
def lookup(source_term, source_language, target_language, glossary)
|
85
|
+
records_selected = Groonga["translations"].select do |record|
|
86
|
+
conditions = [record.source_term =~ source_term]
|
87
|
+
conditions << (record.source_language =~ source_language) if source_language
|
88
|
+
conditions << (record.target_language =~ target_language) if target_language
|
89
|
+
conditions
|
90
|
+
end
|
91
|
+
specified_glossary = records_selected.select do |record|
|
92
|
+
record.glossary == glossary
|
74
93
|
end
|
94
|
+
specified_glossary.each do |record|
|
95
|
+
record.key._score += 10
|
96
|
+
end
|
97
|
+
records = records_selected.sort([
|
98
|
+
{:key=>"_score", :order=>'descending'},
|
99
|
+
{:key=>"glossary", :order=>'ascending'},
|
100
|
+
{:key=>"source_term", :order=>'ascending'},
|
101
|
+
{:key=>"target_term", :order=>'ascending'}])
|
102
|
+
|
103
|
+
options = {:width => 100,
|
104
|
+
:html_escape => true,
|
105
|
+
:normalize => true}
|
106
|
+
snippet = records_selected.expression.snippet(["<snippet>", "</snippet>"], options)
|
107
|
+
|
108
|
+
snipped_source_term = []
|
109
|
+
records.map do |record|
|
110
|
+
term = record.key
|
111
|
+
snipped_text = snippet.execute(term.source_term).join
|
112
|
+
{:glossary_name => term.glossary.key,
|
113
|
+
:source_language => term.source_language,
|
114
|
+
:target_language => term.target_language,
|
115
|
+
:source_term => term.source_term,
|
116
|
+
:snipped_source_term => struct_snipped_text(snipped_text),
|
117
|
+
:target_term => term.target_term,
|
118
|
+
:note => term.note || ''}
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def translation_list(glossary, source_language, target_language)
|
123
|
+
records_raw = Groonga["translations"].select do |record|
|
124
|
+
[
|
125
|
+
record.glossary == glossary,
|
126
|
+
record.source_language == source_language,
|
127
|
+
record.target_language == target_language
|
128
|
+
]
|
129
|
+
end
|
130
|
+
|
75
131
|
records = records_raw.sort([
|
76
|
-
{:key=>"name", :order=>'ascending'},
|
77
132
|
{:key=>"source_term", :order=>'ascending'},
|
78
133
|
{:key=>"target_term", :order=>'ascending'}])
|
79
134
|
|
80
135
|
records.map do |record|
|
81
136
|
term = record.key
|
82
|
-
|
137
|
+
|
138
|
+
{:glossary_name => term.glossary.key,
|
83
139
|
:source_language => term.source_language,
|
84
140
|
:target_language => term.target_language,
|
85
141
|
:source_term => term.source_term,
|
@@ -88,15 +144,119 @@ module Logaling
|
|
88
144
|
end
|
89
145
|
end
|
90
146
|
|
147
|
+
def get_bilingual_pair(source_term, target_term, glossary)
|
148
|
+
records = Groonga["translations"].select do |record|
|
149
|
+
[
|
150
|
+
record.glossary == glossary,
|
151
|
+
record.source_term == source_term,
|
152
|
+
record.target_term == target_term
|
153
|
+
]
|
154
|
+
end
|
155
|
+
|
156
|
+
records.map do |record|
|
157
|
+
term = record.key
|
158
|
+
|
159
|
+
{:glossary_name => term.glossary,
|
160
|
+
:source_language => term.source_language,
|
161
|
+
:target_language => term.target_language,
|
162
|
+
:source_term => term.source_term,
|
163
|
+
:target_term => term.target_term,
|
164
|
+
:note => term.note || ''}
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def get_bilingual_pair_with_note(source_term, target_term, note, glossary)
|
169
|
+
records = Groonga["translations"].select do |record|
|
170
|
+
[
|
171
|
+
record.glossary == glossary,
|
172
|
+
record.source_term == source_term,
|
173
|
+
record.target_term == target_term,
|
174
|
+
record.note == note
|
175
|
+
]
|
176
|
+
end
|
177
|
+
|
178
|
+
records.map do |record|
|
179
|
+
term = record.key
|
180
|
+
|
181
|
+
{:glossary_name => term.glossary,
|
182
|
+
:source_language => term.source_language,
|
183
|
+
:target_language => term.target_language,
|
184
|
+
:source_term => term.source_term,
|
185
|
+
:target_term => term.target_term,
|
186
|
+
:note => term.note || ''}
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def glossary_source_exist?(glossary_source, indexed_at)
|
191
|
+
glossary = Groonga["glossary_sources"].select do |record|
|
192
|
+
[
|
193
|
+
record.key == glossary_source,
|
194
|
+
record.indexed_at == indexed_at
|
195
|
+
]
|
196
|
+
end
|
197
|
+
!glossary.size.zero?
|
198
|
+
end
|
199
|
+
|
200
|
+
def get_all_glossary_source
|
201
|
+
Groonga["glossary_sources"].sort([
|
202
|
+
{:key=>"_key", :order=>'ascending'}
|
203
|
+
]).map{|record| record.key}
|
204
|
+
end
|
205
|
+
|
206
|
+
def get_all_glossary
|
207
|
+
Groonga["glossaries"].sort([
|
208
|
+
{:key=>"_key", :order=>'ascending'}
|
209
|
+
]).map{|record| record.key}
|
210
|
+
end
|
211
|
+
|
91
212
|
private
|
92
|
-
def
|
93
|
-
Groonga["
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
213
|
+
def delete_glossary_source(glossary_source)
|
214
|
+
records = Groonga["glossary_sources"].select do |record|
|
215
|
+
record.key == glossary_source
|
216
|
+
end
|
217
|
+
|
218
|
+
records.each do |record|
|
219
|
+
record.key.delete
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def add_glossary_source(glossary_source, indexed_at)
|
224
|
+
Groonga["glossary_sources"].add(glossary_source, :indexed_at => indexed_at)
|
225
|
+
end
|
226
|
+
|
227
|
+
def delete_glossary(glossary_name)
|
228
|
+
records = Groonga["glossaries"].select do |record|
|
229
|
+
record.key == glossary_name
|
230
|
+
end
|
231
|
+
|
232
|
+
records.each do |record|
|
233
|
+
record.key.delete
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def add_glossary(glossary_name)
|
238
|
+
Groonga["glossaries"].add(glossary_name)
|
239
|
+
end
|
240
|
+
|
241
|
+
def delete_translations_by_glossary_source(glossary_source)
|
242
|
+
records = Groonga["translations"].select do |record|
|
243
|
+
record.glossary_source == glossary_source
|
244
|
+
end
|
245
|
+
|
246
|
+
records.each do |record|
|
247
|
+
record.key.delete
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
def add_translation(glossary_name, glossary_source, source_language, target_language, source_term, target_term, note)
|
252
|
+
Groonga["translations"].add(:glossary => glossary_name,
|
253
|
+
:glossary_source => glossary_source,
|
254
|
+
:source_language => source_language,
|
255
|
+
:target_language => target_language,
|
256
|
+
:source_term => source_term,
|
257
|
+
:target_term => target_term,
|
258
|
+
:note => note,
|
259
|
+
)
|
100
260
|
end
|
101
261
|
|
102
262
|
def reset_context(encoding)
|
@@ -110,8 +270,25 @@ module Logaling
|
|
110
270
|
|
111
271
|
def populate_schema
|
112
272
|
Groonga::Schema.define do |schema|
|
113
|
-
schema.create_table("
|
114
|
-
table.short_text("
|
273
|
+
schema.create_table("configurations") do |table|
|
274
|
+
table.short_text("conf_key")
|
275
|
+
table.text("conf_value")
|
276
|
+
end
|
277
|
+
|
278
|
+
schema.create_table("glossary_sources",
|
279
|
+
:type => :hash,
|
280
|
+
:key_type => "ShortText") do |table|
|
281
|
+
table.time("indexed_at")
|
282
|
+
end
|
283
|
+
|
284
|
+
schema.create_table("glossaries",
|
285
|
+
:type => :hash,
|
286
|
+
:key_type => "ShortText") do |table|
|
287
|
+
end
|
288
|
+
|
289
|
+
schema.create_table("translations") do |table|
|
290
|
+
table.reference("glossary", "glossaries")
|
291
|
+
table.reference("glossary_source", "glossary_sources")
|
115
292
|
table.short_text("source_language")
|
116
293
|
table.short_text("target_language")
|
117
294
|
table.short_text("source_term")
|
@@ -124,14 +301,17 @@ module Logaling
|
|
124
301
|
:key_type => "ShortText",
|
125
302
|
:key_normalize => true,
|
126
303
|
:default_tokenizer => "TokenBigram") do |table|
|
127
|
-
table.index("
|
304
|
+
table.index("translations.source_term")
|
128
305
|
end
|
129
306
|
end
|
130
307
|
end
|
131
308
|
|
132
309
|
def remove_schema
|
133
310
|
Groonga::Schema.define do |schema|
|
311
|
+
schema.remove_table("configurations") if Groonga["configurations"]
|
312
|
+
schema.remove_table("translations") if Groonga["translations"]
|
134
313
|
schema.remove_table("glossaries") if Groonga["glossaries"]
|
314
|
+
schema.remove_table("glossary_sources") if Groonga["glossary_sources"]
|
135
315
|
schema.remove_table("terms") if Groonga["terms"]
|
136
316
|
end
|
137
317
|
end
|
@@ -139,5 +319,33 @@ module Logaling
|
|
139
319
|
def closed?
|
140
320
|
@database.nil? or @database.closed?
|
141
321
|
end
|
322
|
+
|
323
|
+
def struct_snipped_text(snipped_text)
|
324
|
+
word_list = snipped_text.split(/(<snippet>[^<]*<\/snippet>)/)
|
325
|
+
structed_source_term = word_list.map{|word|
|
326
|
+
replaced_word = word.sub(/<snippet>([^<]*)<\/snippet>/){|match| $1}
|
327
|
+
if replaced_word == word
|
328
|
+
CGI.unescapeHTML(word)
|
329
|
+
else
|
330
|
+
{:keyword => CGI.unescapeHTML(replaced_word)}
|
331
|
+
end
|
332
|
+
}
|
333
|
+
structed_source_term
|
334
|
+
end
|
335
|
+
|
336
|
+
def get_config(conf_key)
|
337
|
+
records = Groonga["configurations"].select do |record|
|
338
|
+
record.conf_key == conf_key
|
339
|
+
end
|
340
|
+
value = records.map do |record|
|
341
|
+
config = record.key
|
342
|
+
config.conf_value
|
343
|
+
end
|
344
|
+
value.size > 0 ? value[0] : ""
|
345
|
+
end
|
346
|
+
|
347
|
+
def add_config(conf_key, conf_value)
|
348
|
+
Groonga["configurations"].add(:conf_key => conf_key, :conf_value => conf_value)
|
349
|
+
end
|
142
350
|
end
|
143
351
|
end
|
data/lib/logaling/repository.rb
CHANGED
@@ -55,36 +55,54 @@ module Logaling
|
|
55
55
|
|
56
56
|
terms = []
|
57
57
|
Logaling::GlossaryDB.open(logaling_db_home, "utf8") do |db|
|
58
|
-
terms = db.lookup(source_term)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
58
|
+
terms = db.lookup(source_term, source_language, target_language, glossary)
|
59
|
+
end
|
60
|
+
terms
|
61
|
+
end
|
62
|
+
|
63
|
+
def show_glossary(glossary, source_language, target_language)
|
64
|
+
raise GlossaryDBNotFound unless File.exist?(logaling_db_home)
|
65
|
+
|
66
|
+
terms = []
|
67
|
+
Logaling::GlossaryDB.open(logaling_db_home, "utf8") do |db|
|
68
|
+
terms = db.translation_list(glossary, source_language, target_language)
|
67
69
|
end
|
68
70
|
terms
|
69
71
|
end
|
70
72
|
|
73
|
+
def list
|
74
|
+
raise GlossaryDBNotFound unless File.exist?(logaling_db_home)
|
75
|
+
|
76
|
+
glossaries = []
|
77
|
+
Logaling::GlossaryDB.open(logaling_db_home, "utf8") do |db|
|
78
|
+
glossaries = db.get_all_glossary
|
79
|
+
end
|
80
|
+
glossaries
|
81
|
+
end
|
82
|
+
|
71
83
|
def index
|
72
|
-
|
73
|
-
|
84
|
+
project_glossaries = Dir[File.join(@path, "projects", "*")].map do |project|
|
85
|
+
Dir.glob(get_all_glossary_sources(File.join(project, "glossary")))
|
86
|
+
end
|
87
|
+
imported_glossaries = Dir.glob(get_all_glossary_sources(cache_path))
|
88
|
+
all_glossaries = project_glossaries.flatten + imported_glossaries
|
74
89
|
|
75
90
|
Logaling::GlossaryDB.open(logaling_db_home, "utf8") do |db|
|
76
91
|
db.recreate_table
|
77
|
-
|
78
|
-
|
79
|
-
|
92
|
+
all_glossaries.each do |glossary_source|
|
93
|
+
indexed_at = File.mtime(glossary_source)
|
94
|
+
unless db.glossary_source_exist?(glossary_source, indexed_at)
|
95
|
+
glossary_name, source_language, target_language = get_glossary(glossary_source)
|
96
|
+
puts "now index #{glossary_name}..."
|
97
|
+
db.index_glossary(Glossary.load(glossary_source), glossary_name, glossary_source, source_language, target_language, indexed_at)
|
80
98
|
end
|
81
99
|
end
|
82
|
-
|
83
|
-
|
100
|
+
(db.get_all_glossary_source - all_glossaries).each do |glossary_source|
|
101
|
+
glossary_name, source_language, target_language = get_glossary(glossary_source)
|
102
|
+
puts "now deindex #{glossary_name}..."
|
103
|
+
db.deindex_glossary(glossary_name, glossary_source)
|
84
104
|
end
|
85
105
|
end
|
86
|
-
|
87
|
-
FileUtils.touch(index_at_file)
|
88
106
|
end
|
89
107
|
|
90
108
|
def glossary_counts
|
@@ -96,33 +114,43 @@ module Logaling
|
|
96
114
|
File.exist?(path) ? path : nil
|
97
115
|
end
|
98
116
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
117
|
+
def bilingual_pair_exists?(source_term, target_term, glossary)
|
118
|
+
raise GlossaryDBNotFound unless File.exist?(logaling_db_home)
|
119
|
+
|
120
|
+
terms = []
|
121
|
+
Logaling::GlossaryDB.open(logaling_db_home, "utf8") do |db|
|
122
|
+
terms = db.get_bilingual_pair(source_term, target_term, glossary)
|
123
|
+
end
|
124
|
+
|
125
|
+
if terms.size > 0
|
126
|
+
true
|
109
127
|
else
|
110
128
|
false
|
111
129
|
end
|
112
130
|
end
|
113
131
|
|
114
|
-
def
|
115
|
-
|
116
|
-
|
117
|
-
|
132
|
+
def bilingual_pair_exists_and_has_same_note?(source_term, target_term, note, glossary)
|
133
|
+
raise GlossaryDBNotFound unless File.exist?(logaling_db_home)
|
134
|
+
|
135
|
+
terms = []
|
136
|
+
Logaling::GlossaryDB.open(logaling_db_home, "utf8") do |db|
|
137
|
+
terms = db.get_bilingual_pair_with_note(source_term, target_term, note, glossary)
|
138
|
+
end
|
139
|
+
|
140
|
+
if terms.size > 0
|
141
|
+
true
|
142
|
+
else
|
143
|
+
false
|
118
144
|
end
|
119
145
|
end
|
120
146
|
|
121
|
-
|
122
|
-
|
147
|
+
private
|
148
|
+
def get_glossary(path)
|
149
|
+
glossary_name, source_language, target_language = File::basename(path, ".*").split(".")
|
150
|
+
[glossary_name, source_language, target_language]
|
123
151
|
end
|
124
152
|
|
125
|
-
def
|
153
|
+
def get_all_glossary_sources(path)
|
126
154
|
%w(yml tsv csv).map{|type| File.join(path, "*.#{type}") }
|
127
155
|
end
|
128
156
|
|
@@ -145,9 +173,5 @@ module Logaling
|
|
145
173
|
def imported_glossaries
|
146
174
|
Dir[File.join(cache_path, "*")]
|
147
175
|
end
|
148
|
-
|
149
|
-
def index_at_file
|
150
|
-
File.join(logaling_db_home, "index_at")
|
151
|
-
end
|
152
176
|
end
|
153
177
|
end
|
data/lib/logaling.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
# -*-
|
1
|
+
# -*- coding: utf-8 -*-
|
2
2
|
#
|
3
3
|
# Copyright (C) 2011 Miho SUZUKI
|
4
|
+
# Copyright (C) 2011 Kouhei Sutou <kou@clear-code.com>
|
4
5
|
#
|
5
6
|
# This program is free software: you can redistribute it and/or modify
|
6
7
|
# it under the terms of the GNU General Public License as published by
|
@@ -25,4 +26,5 @@ module Logaling
|
|
25
26
|
class GlossaryNotFound < LogalingError; end
|
26
27
|
class GlossaryDBNotFound < LogalingError; end
|
27
28
|
class ExternalGlossaryNotFound < LogalingError; end
|
29
|
+
class UnsupportedFormat < LogalingError; end
|
28
30
|
end
|
@@ -22,6 +22,7 @@ describe Logaling::Command do
|
|
22
22
|
let(:command) { Logaling::Command.new([], base_options) }
|
23
23
|
let(:glossary_path) { Logaling::Glossary.build_path('spec', 'en', 'ja') }
|
24
24
|
let(:target_project_path) { File.join(LOGALING_HOME, "projects", "spec") }
|
25
|
+
let(:repository) { Logaling::Repository.new(LOGALING_HOME) }
|
25
26
|
|
26
27
|
before do
|
27
28
|
FileUtils.remove_entry_secure(Logaling::Command::LOGALING_CONFIG, true)
|
@@ -80,6 +81,7 @@ describe Logaling::Command do
|
|
80
81
|
|
81
82
|
describe '#register' do
|
82
83
|
before do
|
84
|
+
sleep(1)
|
83
85
|
@project_counts = Dir[File.join(LOGALING_HOME, "projects", "*")].size
|
84
86
|
end
|
85
87
|
|
@@ -293,35 +295,40 @@ describe Logaling::Command do
|
|
293
295
|
|
294
296
|
describe "#update" do
|
295
297
|
before do
|
298
|
+
FileUtils.remove_entry_secure(File.join(LOGALING_HOME, "db", "index_at"), true)
|
296
299
|
command.new('spec', 'en', 'ja')
|
297
300
|
command.add("spec", "テスト", "備考")
|
298
301
|
end
|
299
302
|
|
300
|
-
context "
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
#should show err
|
306
|
-
end
|
303
|
+
context "with arguments except note" do
|
304
|
+
before do
|
305
|
+
command.update("spec", "テスト", "スペック")
|
306
|
+
@yaml = YAML::load_file(glossary_path).find{|h| h["source_term"] == "spec" }
|
307
|
+
end
|
307
308
|
|
308
|
-
|
309
|
-
|
309
|
+
it "term's target_term should be updated" do
|
310
|
+
@yaml.should == {"source_term"=>"spec", "target_term"=>"スペック", "note"=>"備考"}
|
311
|
+
end
|
310
312
|
end
|
311
313
|
|
312
|
-
context
|
314
|
+
context 'with exisiting bilingual pair and note' do
|
313
315
|
before do
|
314
|
-
command.update("spec", "テスト", "
|
316
|
+
@stdout = capture(:stdout) { command.update("spec", "テスト", "テスト", "備考") }
|
315
317
|
end
|
316
318
|
|
317
|
-
|
319
|
+
it 'should show error message' do
|
320
|
+
@stdout.should include "already exists"
|
321
|
+
end
|
322
|
+
end
|
318
323
|
|
319
|
-
|
320
|
-
|
324
|
+
context 'with existing bilingual pair and different note' do
|
325
|
+
before do
|
326
|
+
command.update("spec", "テスト", "テスト", "備考だけ書き換え")
|
327
|
+
@yaml = YAML::load_file(glossary_path).find{|h| h["source_term"] == "spec" }
|
321
328
|
end
|
322
329
|
|
323
|
-
it "
|
324
|
-
|
330
|
+
it "should update note" do
|
331
|
+
@yaml.should == {"source_term"=>"spec", "target_term"=>"テスト", "note"=>"備考だけ書き換え"}
|
325
332
|
end
|
326
333
|
end
|
327
334
|
end
|
@@ -409,6 +416,74 @@ describe Logaling::Command do
|
|
409
416
|
end
|
410
417
|
end
|
411
418
|
|
419
|
+
describe "#show" do
|
420
|
+
let(:csv_path) { File.join(File.dirname(glossary_path), "spec.ja.en.csv") }
|
421
|
+
before do
|
422
|
+
command.new('spec', 'en', 'ja')
|
423
|
+
command.add("spec", "スペック", "備考")
|
424
|
+
command.add("spec-test", "スペックてすと", "備考")
|
425
|
+
command.add("spec-test-test", "スペックてすとてすと", "備考")
|
426
|
+
|
427
|
+
FileUtils.mkdir_p(File.dirname(glossary_path))
|
428
|
+
FileUtils.touch(csv_path)
|
429
|
+
File.open(csv_path, "w"){|f| f.puts "test_logaling,テスト"}
|
430
|
+
end
|
431
|
+
|
432
|
+
context 'when .logaling exists' do
|
433
|
+
before do
|
434
|
+
@stdout = capture(:stdout) {command.show}
|
435
|
+
end
|
436
|
+
|
437
|
+
it 'should show translation list' do
|
438
|
+
@stdout.should include "spec"
|
439
|
+
@stdout.should include "spec-test"
|
440
|
+
@stdout.should include "spec-test-test"
|
441
|
+
@stdout.should_not include "test_logaling"
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
context 'with arguments glossary' do
|
446
|
+
before do
|
447
|
+
command.options = base_options.merge("glossary" => "spec", "source-language" => "ja", "target-language" => "en")
|
448
|
+
@stdout = capture(:stdout) {command.show}
|
449
|
+
end
|
450
|
+
|
451
|
+
it 'should show translation list' do
|
452
|
+
@stdout.should include "test_logaling"
|
453
|
+
@stdout.should_not include "spec-test-test"
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
after do
|
458
|
+
FileUtils.remove_entry_secure(csv_path, true)
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
describe '#list' do
|
463
|
+
context 'when some glossaries are registered' do
|
464
|
+
before do
|
465
|
+
command.new('spec', 'en', 'ja')
|
466
|
+
@stdout = capture(:stdout) {command.list}
|
467
|
+
end
|
468
|
+
|
469
|
+
it 'should list glossaries' do
|
470
|
+
@stdout.should include "spec"
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
context 'when a glossary is unregistered' do
|
475
|
+
before do
|
476
|
+
command.new('spec', 'en', 'ja')
|
477
|
+
repository.unregister('spec')
|
478
|
+
@stdout = capture(:stdout) {command.list}
|
479
|
+
end
|
480
|
+
|
481
|
+
it 'should not include unregistered glossary' do
|
482
|
+
@stdout.should_not include "spec"
|
483
|
+
end
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
412
487
|
after do
|
413
488
|
FileUtils.remove_entry_secure(Logaling::Command::LOGALING_CONFIG, true)
|
414
489
|
FileUtils.remove_entry_secure(File.join(LOGALING_HOME, 'projects', 'spec'), true)
|
@@ -43,16 +43,6 @@ module Logaling
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
context 'with arguments show existing bilingual pair' do
|
47
|
-
before do
|
48
|
-
glossary.add("user", "ユーザ", "ユーザーではない")
|
49
|
-
end
|
50
|
-
|
51
|
-
it {
|
52
|
-
-> { glossary.add("user", "ユーザ", "ユーザーではない") }.should raise_error(Logaling::TermError)
|
53
|
-
}
|
54
|
-
end
|
55
|
-
|
56
46
|
context "when the glossary not found" do
|
57
47
|
before do
|
58
48
|
glossary.add("test", "テスト", "テスト")
|
@@ -77,17 +67,30 @@ module Logaling
|
|
77
67
|
}
|
78
68
|
end
|
79
69
|
|
80
|
-
context 'with source-term
|
70
|
+
context 'with source-term show not existing bilingual pair' do
|
81
71
|
it {
|
82
72
|
-> { glossary.update("use", "ユーザ", "ユーザー", "やっぱりユーザー") }.should raise_error(Logaling::TermError)
|
83
73
|
}
|
84
74
|
end
|
85
75
|
|
86
|
-
context 'with target-term
|
76
|
+
context 'with target-term show not existing bilingual pair' do
|
87
77
|
it {
|
88
78
|
-> { glossary.update("user", "ユー", "ユーザー", "やっぱりユーザー") }.should raise_error(Logaling::TermError)
|
89
79
|
}
|
90
80
|
end
|
81
|
+
|
82
|
+
context 'with same target-term and empty note' do
|
83
|
+
before do
|
84
|
+
glossary.update("user", "ユーザ", "ユーザ", "")
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should clear note' do
|
88
|
+
yaml = YAML::load_file(glossary_path)
|
89
|
+
term = yaml.index({"source_term"=>"user", "target_term"=>"ユーザ", "note"=>""})
|
90
|
+
term.should_not be_nil
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
91
94
|
end
|
92
95
|
|
93
96
|
describe '#delete' do
|
@@ -101,8 +104,8 @@ module Logaling
|
|
101
104
|
end
|
102
105
|
|
103
106
|
it 'should delete the bilingual pair' do
|
104
|
-
@result.
|
105
|
-
@result.
|
107
|
+
@result.any?{|term| term[:source_term] == "delete_logaling" && term[:target_term] == "てすと2"}.should be_true
|
108
|
+
@result.any?{|term| term[:source_term] == "delete_logaling" && term[:target_term] == "てすと1"}.should be_false
|
106
109
|
end
|
107
110
|
end
|
108
111
|
|
@@ -138,7 +141,7 @@ module Logaling
|
|
138
141
|
end
|
139
142
|
|
140
143
|
it 'should delete the term' do
|
141
|
-
@result.
|
144
|
+
@result.any?{|term| term[:source_term] == "user_logaling" && term[:target_term] == "ユーザ"}.should be_false
|
142
145
|
end
|
143
146
|
end
|
144
147
|
|
@@ -158,8 +161,8 @@ module Logaling
|
|
158
161
|
}
|
159
162
|
|
160
163
|
it "should delete terms when force option is true" do
|
161
|
-
@result.
|
162
|
-
@result.
|
164
|
+
@result.any?{|term| term[:source_term] == "delete_logaling" && term[:target_term] == "てすと1"}.should be_false
|
165
|
+
@result.any?{|term| term[:source_term] == "delete_logaling" && term[:target_term] == "てすと2"}.should be_false
|
163
166
|
end
|
164
167
|
end
|
165
168
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logaling-command
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,11 +13,11 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date:
|
16
|
+
date: 2012-01-30 00:00:00.000000000Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: thor
|
20
|
-
requirement: &
|
20
|
+
requirement: &2153162840 !ruby/object:Gem::Requirement
|
21
21
|
none: false
|
22
22
|
requirements:
|
23
23
|
- - ! '>='
|
@@ -25,10 +25,10 @@ dependencies:
|
|
25
25
|
version: 0.14.6
|
26
26
|
type: :runtime
|
27
27
|
prerelease: false
|
28
|
-
version_requirements: *
|
28
|
+
version_requirements: *2153162840
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: bundler
|
31
|
-
requirement: &
|
31
|
+
requirement: &2153162000 !ruby/object:Gem::Requirement
|
32
32
|
none: false
|
33
33
|
requirements:
|
34
34
|
- - ! '>='
|
@@ -36,10 +36,10 @@ dependencies:
|
|
36
36
|
version: '1.0'
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
|
-
version_requirements: *
|
39
|
+
version_requirements: *2153162000
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: rroonga
|
42
|
-
requirement: &
|
42
|
+
requirement: &2153155300 !ruby/object:Gem::Requirement
|
43
43
|
none: false
|
44
44
|
requirements:
|
45
45
|
- - ! '>='
|
@@ -47,10 +47,10 @@ dependencies:
|
|
47
47
|
version: 1.3.0
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
|
-
version_requirements: *
|
50
|
+
version_requirements: *2153155300
|
51
51
|
- !ruby/object:Gem::Dependency
|
52
52
|
name: rainbow
|
53
|
-
requirement: &
|
53
|
+
requirement: &2153154740 !ruby/object:Gem::Requirement
|
54
54
|
none: false
|
55
55
|
requirements:
|
56
56
|
- - ! '>='
|
@@ -58,10 +58,10 @@ dependencies:
|
|
58
58
|
version: '0'
|
59
59
|
type: :runtime
|
60
60
|
prerelease: false
|
61
|
-
version_requirements: *
|
61
|
+
version_requirements: *2153154740
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: nokogiri
|
64
|
-
requirement: &
|
64
|
+
requirement: &2153153780 !ruby/object:Gem::Requirement
|
65
65
|
none: false
|
66
66
|
requirements:
|
67
67
|
- - ! '>='
|
@@ -69,10 +69,10 @@ dependencies:
|
|
69
69
|
version: '0'
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
72
|
-
version_requirements: *
|
72
|
+
version_requirements: *2153153780
|
73
73
|
- !ruby/object:Gem::Dependency
|
74
74
|
name: active_support
|
75
|
-
requirement: &
|
75
|
+
requirement: &2153152800 !ruby/object:Gem::Requirement
|
76
76
|
none: false
|
77
77
|
requirements:
|
78
78
|
- - ! '>='
|
@@ -80,10 +80,10 @@ dependencies:
|
|
80
80
|
version: '0'
|
81
81
|
type: :runtime
|
82
82
|
prerelease: false
|
83
|
-
version_requirements: *
|
83
|
+
version_requirements: *2153152800
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
85
|
name: rake
|
86
|
-
requirement: &
|
86
|
+
requirement: &2153151540 !ruby/object:Gem::Requirement
|
87
87
|
none: false
|
88
88
|
requirements:
|
89
89
|
- - ! '>='
|
@@ -91,10 +91,10 @@ dependencies:
|
|
91
91
|
version: '0'
|
92
92
|
type: :development
|
93
93
|
prerelease: false
|
94
|
-
version_requirements: *
|
94
|
+
version_requirements: *2153151540
|
95
95
|
- !ruby/object:Gem::Dependency
|
96
96
|
name: rspec
|
97
|
-
requirement: &
|
97
|
+
requirement: &2153150900 !ruby/object:Gem::Requirement
|
98
98
|
none: false
|
99
99
|
requirements:
|
100
100
|
- - ! '>='
|
@@ -102,7 +102,7 @@ dependencies:
|
|
102
102
|
version: '0'
|
103
103
|
type: :development
|
104
104
|
prerelease: false
|
105
|
-
version_requirements: *
|
105
|
+
version_requirements: *2153150900
|
106
106
|
description: A command line interface for logaling.
|
107
107
|
email:
|
108
108
|
- koji.shimada@enishi-tech.com
|
@@ -117,6 +117,7 @@ extra_rdoc_files: []
|
|
117
117
|
files:
|
118
118
|
- .gitignore
|
119
119
|
- .rspec
|
120
|
+
- CHANGES
|
120
121
|
- COPYING
|
121
122
|
- Gemfile
|
122
123
|
- README.md
|
@@ -125,6 +126,8 @@ files:
|
|
125
126
|
- lib/logaling.rb
|
126
127
|
- lib/logaling/command.rb
|
127
128
|
- lib/logaling/external_glossaries/debian_project.rb
|
129
|
+
- lib/logaling/external_glossaries/edict.rb
|
130
|
+
- lib/logaling/external_glossaries/gene95.rb
|
128
131
|
- lib/logaling/external_glossaries/gnome_project.rb
|
129
132
|
- lib/logaling/external_glossaries/postgresql_manual.rb
|
130
133
|
- lib/logaling/external_glossary.rb
|