logaling-command 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in logaling-command.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler/gem_tasks'
2
+ require "rspec/core/rake_task"
3
+
4
+ desc "Run all specs"
5
+ RSpec::Core::RakeTask.new(:spec) do |t|
6
+ t.verbose = true
7
+ end
8
+
9
+ task :default => :spec
data/bin/loga ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+ LOGALING_HOME = File.expand_path("~/.logaling.d")
6
+
7
+ require "logaling"
8
+
9
+ Logaling::Command.start
10
+
@@ -0,0 +1,135 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'thor'
4
+ require "logaling/glossary"
5
+ require "logaling/glossary_db"
6
+
7
+ class Logaling::Command < Thor
8
+ VERSION = "0.0.1"
9
+
10
+ map '-c' => :create,
11
+ '-a' => :add,
12
+ '-d' => :delete,
13
+ '-u' => :update,
14
+ '-l' => :lookup
15
+
16
+ class_option :glossary, type: :string, aliases: "-g"
17
+ class_option :source_language, type: :string, aliases: "-S"
18
+ class_option :target_language, type: :string, aliases: "-T"
19
+ class_option :logaling_home, type: :string, required: false, aliases: "-h"
20
+
21
+ def initialize(*args)
22
+ super
23
+ @dot_options = Hash.new
24
+ end
25
+
26
+ desc 'create', 'Create glossary.'
27
+ def create
28
+ load_config
29
+ glossary.create
30
+ rescue Logaling::CommandFailed => e
31
+ error(e.message)
32
+ end
33
+
34
+ desc 'add', 'Add term to glossary.'
35
+ method_option :source_term, type: :string, required: true, aliases: "-s"
36
+ method_option :target_term, type: :string, required: true, aliases: "-t"
37
+ method_option :note, type: :string, aliases: "-n"
38
+ def add
39
+ load_config
40
+ glossary.add(options[:source_term], options[:target_term], options[:note])
41
+ rescue Logaling::CommandFailed => e
42
+ error(e.message)
43
+ end
44
+
45
+ desc 'delete', 'Delete term.'
46
+ method_option :source_term, type: :string, required: true, aliases: "-s"
47
+ method_option :target_term, type: :string, required: true, aliases: "-t"
48
+ def delete
49
+ load_config
50
+ glossary.delete(options[:source_term], options[:target_term])
51
+ rescue Logaling::CommandFailed => e
52
+ error(e.message)
53
+ end
54
+
55
+ desc 'update', 'Update term.'
56
+ method_option :source_term, type: :string, required: true, aliases: "-s"
57
+ method_option :target_term, type: :string, required: true, aliases: "-t"
58
+ method_option :new_target_term, type: :string, required: true, aliases: "-nt"
59
+ method_option :note, type: :string, required: true, aliases: "-n"
60
+ def update
61
+ load_config
62
+ glossary.update(options[:source_term], options[:target_term], options[:new_target_term], options[:note])
63
+ rescue Logaling::CommandFailed => e
64
+ error(e.message)
65
+ end
66
+
67
+ desc 'lookup', 'Lookup terms.'
68
+ method_option :source_term, type: :string, required: true, aliases: "-s"
69
+ def lookup
70
+ load_config
71
+ glossary.lookup(options[:source_term])
72
+ rescue Logaling::CommandFailed => e
73
+ error(e.message)
74
+ end
75
+
76
+ desc 'index', 'Index glossaries to groonga DB.'
77
+ def index
78
+ load_config
79
+ home = find_option("logaling_home") || LOGALING_HOME
80
+ db_home = File.join(home, ".logadb")
81
+ glossarydb = Logaling::GlossaryDB.new
82
+ glossarydb.open(db_home, "utf8") do |db|
83
+ db.recreate_table(db_home)
84
+ db.load_glossaries(home)
85
+ end
86
+ end
87
+
88
+ private
89
+ def glossary
90
+ glossary = find_option("glossary")
91
+ raise(Logaling::CommandFailed, "input glossary name '-g <glossary name>'") unless glossary
92
+
93
+ source_language = find_option("source_language")
94
+ raise(Logaling::CommandFailed, "input source-language code '-S <source-language code>'") unless source_language
95
+
96
+ target_language = find_option("target_language")
97
+ raise(Logaling::CommandFailed, "input target-language code '-T <target-language code>'") unless target_language
98
+
99
+ logaling_home = find_option("logaling_home")
100
+
101
+ Logaling::Glossary.new(glossary, source_language, target_language, logaling_home)
102
+ end
103
+
104
+ def error(msg)
105
+ STDERR.puts(msg)
106
+ exit 1
107
+ end
108
+
109
+ def find_option(key)
110
+ options[key] || @dot_options[key]
111
+ end
112
+
113
+ def load_config
114
+ if path = find_dotfile
115
+ tmp_options = File.readlines(path).map {|l| l.chomp.split " "}
116
+ tmp_options.each do |option|
117
+ key = option[0].sub(/^[\-]{2}/, "")
118
+ value = option[1]
119
+ @dot_options[key] = value
120
+ end
121
+ end
122
+ end
123
+
124
+ def find_dotfile
125
+ dir = Dir.pwd
126
+ while(dir) do
127
+ path = File.join(dir, '.logaling')
128
+ if File.exist?(path)
129
+ return path
130
+ break
131
+ end
132
+ dir = (dir != "/") ? File.dirname(dir) : nil
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,175 @@
1
+ # -*- coding: utf-8 -*-
2
+ #require "logaling-command/version"
3
+
4
+ require 'psych'
5
+ require "yaml"
6
+ require "fileutils"
7
+
8
+ module Logaling
9
+ class Glossary
10
+ def self.build_path(glossary, source_language, target_language, logaling_home)
11
+ dir, file = File::split(glossary)
12
+ if dir == "."
13
+ fname = [glossary, source_language, target_language].join(".")
14
+ return File.join(logaling_home, "#{fname}.yml")
15
+ else
16
+ return glossary
17
+ end
18
+ end
19
+
20
+ def initialize(glossary, source_language, target_language, logaling_home)
21
+ logaling_home ||= LOGALING_HOME
22
+ @path = Glossary.build_path(glossary, source_language, target_language, logaling_home)
23
+ @glossary = glossary
24
+ @source_language = source_language
25
+ @target_language = target_language
26
+ @logaling_home = logaling_home
27
+ end
28
+
29
+ def create
30
+ check_glossary_unexists
31
+
32
+ dirname = File::dirname(@path)
33
+ FileUtils.mkdir_p(dirname)
34
+ FileUtils.touch(@path)
35
+ end
36
+
37
+ def add(source_term, target_term, note)
38
+ check_glossary_exists
39
+
40
+ if bilingual_pair_exists?(source_term, target_term)
41
+ puts "[#{source_term}] [#{target_term}] pair already exists"
42
+ return
43
+ end
44
+
45
+ glossary = load_glossary_yml
46
+ glossary << build_term(source_term, target_term, note)
47
+
48
+ dump_glossary(glossary)
49
+ end
50
+
51
+ def update(source_term, target_term, new_target_term, note)
52
+ check_glossary_exists
53
+
54
+ if bilingual_pair_exists?(source_term, new_target_term)
55
+ puts "[#{source_term}] [#{new_target_term}] pair already exists"
56
+ return
57
+ end
58
+
59
+ glossary = load_glossary_yml
60
+ target_index = find_term_index(glossary, source_term, target_term)
61
+ if target_index
62
+ glossary[target_index] = rebuild_term(glossary[target_index], source_term, new_target_term, note)
63
+ dump_glossary(glossary)
64
+ else
65
+ puts "source_term:#{source_term} target_term:#{target_term} not found in glossary #{@path}"
66
+ end
67
+ end
68
+
69
+ def delete(source_term, target_term)
70
+ check_glossary_exists
71
+
72
+ glossary = load_glossary_yml
73
+ target_index = find_term_index(glossary, source_term, target_term)
74
+ if target_index
75
+ glossary.delete_at(target_index)
76
+ dump_glossary(glossary)
77
+ else
78
+ puts "source_term:#{source_term} target_term:#{target_term} not found in glossary #{@path}"
79
+ end
80
+ end
81
+
82
+ def lookup(source_term)
83
+ check_glossary_exists
84
+
85
+ glossarydb = Logaling::GlossaryDB.new
86
+ glossarydb.open(logaling_db_home, "utf8") do |db|
87
+ glossaries = db.lookup(source_term)
88
+ glossaries.reject! do |term|
89
+ term[:source_language] != @source_language || term[:target_language] != @target_language
90
+ end
91
+ if glossaries.empty?
92
+ puts "source_term <#{source_term}> not found"
93
+ return
94
+ end
95
+ # order by glossary
96
+ specified = glossaries.select{|term| term[:name] == @glossary}
97
+ other = glossaries.select{|term| term[:name] != @glossary}
98
+ glossaries = specified.concat(other)
99
+
100
+ puts "\nlookup word : #{source_term}"
101
+ glossaries.each do |term|
102
+ puts "\n #{term[:source_term]}\n"
103
+ puts " #{term[:target_term]}\n"
104
+ puts " note:#{term[:note]}"
105
+ puts " glossary:#{term[:name]}"
106
+ end
107
+ end
108
+ end
109
+
110
+ private
111
+ def load_glossary_yml
112
+ YAML::load_file(@path) || []
113
+ end
114
+
115
+ def logaling_db_home
116
+ File.join(@logaling_home, ".logadb")
117
+ end
118
+
119
+ def build_term(source_term, target_term, note)
120
+ {'source_term' => source_term, 'target_term' => target_term, 'note' => note}
121
+ end
122
+
123
+ def rebuild_term(current, source_term, target_term, note)
124
+ note = current['note'] if note == ""
125
+ target_term = current['target_term'] if target_term == ""
126
+ build_term(source_term, target_term, note)
127
+ end
128
+
129
+ def find_term_index(glossary_yml, source_term, target_term)
130
+ glossary_yml.find_index do |term|
131
+ term['source_term'] == source_term && term['target_term'] == target_term
132
+ end
133
+ end
134
+
135
+ def bilingual_pair_exists?(source_term, target_term)
136
+ target_terms(source_term).any?{|data| data['target_term'] == target_term }
137
+ end
138
+
139
+ def exist?
140
+ File.exists?(@path)
141
+ end
142
+
143
+ def check_glossary_unexists
144
+ raise CommandFailed, "glossary #{@path} already exists" if exist?
145
+ end
146
+
147
+ def check_glossary_exists
148
+ raise CommandFailed, "glossary #{@path} not found" unless exist?
149
+ end
150
+
151
+ def target_terms(source_term, path=@path)
152
+ target_terms = []
153
+ glossaly = YAML::load_file(path) || []
154
+ glossaly.each do |term|
155
+ target_terms << term if term['source_term'] == source_term
156
+ end
157
+ target_terms
158
+ end
159
+
160
+ def lookup_files
161
+ file_list = Dir.glob("#{@logaling_home}/*.#{@source_language}.#{@target_language}.yml")
162
+ if glossary_index = file_list.index(@path)
163
+ file_list.delete_at(glossary_index)
164
+ end
165
+ file_list.unshift(@path)
166
+ return file_list
167
+ end
168
+
169
+ def dump_glossary(glossary)
170
+ File.open(@path, "w") do |f|
171
+ f.puts(glossary.to_yaml)
172
+ end
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,132 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'psych'
4
+ require "yaml"
5
+ require "fileutils"
6
+ require 'groonga'
7
+
8
+ module Logaling
9
+ class GlossaryDB
10
+ def initialize()
11
+ @database = nil
12
+ end
13
+
14
+ def open(base_path, encoding)
15
+ reset_context(encoding)
16
+ path = File.join(base_path, "logaling.db")
17
+ if File.exist?(path)
18
+ @database = Groonga::Database.open(path)
19
+ else
20
+ FileUtils.mkdir_p(base_path)
21
+ populate(path)
22
+ end
23
+ if block_given?
24
+ begin
25
+ yield(self)
26
+ ensure
27
+ close unless closed?
28
+ end
29
+ end
30
+ end
31
+
32
+ def recreate_table(base_path)
33
+ path = File.join(base_path, "logaling.db.tables")
34
+ if File.exist?(path)
35
+ remove_schema
36
+ end
37
+ populate_schema
38
+ end
39
+
40
+ def close
41
+ @database.close
42
+ @database = nil
43
+ end
44
+
45
+ def closed?
46
+ @database.nil? or @database.closed?
47
+ end
48
+
49
+ def load_glossaries(path)
50
+ file_list = Dir.glob("#{path}/*.yml")
51
+ file_list.each do |file|
52
+ name, source_language, target_language = File::basename(file, "yml").split(".")
53
+ glossary = YAML::load_file(file)
54
+ next if !glossary
55
+ glossary.each do |term|
56
+ source_term = term['source_term']
57
+ target_term = term['target_term']
58
+ note = term['note']
59
+ add_glossary(name, source_language, target_language, source_term, target_term, note)
60
+ end
61
+ end
62
+ end
63
+
64
+ def lookup(source_term)
65
+ records_raw = Groonga["glossaries"].select do |record|
66
+ record.source_term =~ source_term
67
+ end
68
+ records = records_raw.sort([
69
+ {:key=>"name", :order=>'ascending'},
70
+ {:key=>"source_term", :order=>'ascending'},
71
+ {:key=>"target_term", :order=>'ascending'}])
72
+
73
+ records.map do |record|
74
+ term = record.key
75
+ {:name => term.name,
76
+ :source_language => term.source_language,
77
+ :target_language => term.target_language,
78
+ :source_term => term.source_term,
79
+ :target_term => term.target_term,
80
+ :note => term.note,}
81
+ end
82
+ end
83
+
84
+ private
85
+ def add_glossary(name, source_language, target_language, source_term, target_term, note)
86
+ Groonga["glossaries"].add(:name => name,
87
+ :source_language => source_language,
88
+ :target_language => target_language,
89
+ :source_term => source_term,
90
+ :target_term => target_term,
91
+ :note => note,
92
+ )
93
+ end
94
+
95
+ def reset_context(encoding)
96
+ Groonga::Context.default_options = {:encoding => encoding}
97
+ Groonga::Context.default = nil
98
+ end
99
+
100
+ def populate(path)
101
+ @database = Groonga::Database.create(:path => path)
102
+ end
103
+
104
+ def populate_schema
105
+ Groonga::Schema.define do |schema|
106
+ schema.create_table("glossaries") do |table|
107
+ table.short_text("name")
108
+ table.short_text("source_language")
109
+ table.short_text("target_language")
110
+ table.short_text("source_term")
111
+ table.text("target_term")
112
+ table.text("note")
113
+ end
114
+
115
+ schema.create_table("terms",
116
+ :type => :patricia_trie,
117
+ :key_type => "ShortText",
118
+ :key_normalize => true,
119
+ :default_tokenizer => "TokenBigram") do |table|
120
+ table.index("glossaries.source_term")
121
+ end
122
+ end
123
+ end
124
+
125
+ def remove_schema
126
+ Groonga::Schema.define do |schema|
127
+ schema.remove_table("glossaries")
128
+ schema.remove_table("terms")
129
+ end
130
+ end
131
+ end
132
+ end
data/lib/logaling.rb ADDED
@@ -0,0 +1,7 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require "logaling/command"
4
+
5
+ module Logaling
6
+ class CommandFailed < RuntimeError; end
7
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "logaling/command.rb"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "logaling-command"
7
+ s.version = Logaling::Command::VERSION
8
+ s.authors = ["SHIMADA Koji", "SHIDARA Yoji", "Kouhei Sutou", "Daijiro MORI", "SUZUKI Miho"]
9
+ s.email = ["koji.shimada@enishi-tech.com", "dara@shidara.net", "kou@clear-code.com", "daijiro.mori@gmail.com", "adzuki34@gmail.com"]
10
+ s.homepage = "http://logaling.github.com/"
11
+ s.summary = %q{A command line interface for logaling.}
12
+ s.description = %q{A command line interface for logaling.}
13
+
14
+ s.rubyforge_project = "logaling-command"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency 'rake'
22
+ s.add_development_dependency 'rspec'
23
+ end
@@ -0,0 +1,8 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+
4
+ require 'rspec'
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
6
+
7
+ require 'logaling_command'
8
+
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logaling-command
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - SHIMADA Koji
9
+ - SHIDARA Yoji
10
+ - Kouhei Sutou
11
+ - Daijiro MORI
12
+ - SUZUKI Miho
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+ date: 2011-11-09 00:00:00.000000000Z
17
+ dependencies:
18
+ - !ruby/object:Gem::Dependency
19
+ name: rake
20
+ requirement: &2151902900 !ruby/object:Gem::Requirement
21
+ none: false
22
+ requirements:
23
+ - - ! '>='
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ type: :development
27
+ prerelease: false
28
+ version_requirements: *2151902900
29
+ - !ruby/object:Gem::Dependency
30
+ name: rspec
31
+ requirement: &2151901960 !ruby/object:Gem::Requirement
32
+ none: false
33
+ requirements:
34
+ - - ! '>='
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: *2151901960
40
+ description: A command line interface for logaling.
41
+ email:
42
+ - koji.shimada@enishi-tech.com
43
+ - dara@shidara.net
44
+ - kou@clear-code.com
45
+ - daijiro.mori@gmail.com
46
+ - adzuki34@gmail.com
47
+ executables:
48
+ - loga
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - .gitignore
53
+ - .rspec
54
+ - Gemfile
55
+ - Rakefile
56
+ - bin/loga
57
+ - lib/logaling.rb
58
+ - lib/logaling/command.rb
59
+ - lib/logaling/glossary.rb
60
+ - lib/logaling/glossary_db.rb
61
+ - logaling-command.gemspec
62
+ - spec/spec_helper.rb
63
+ homepage: http://logaling.github.com/
64
+ licenses: []
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project: logaling-command
83
+ rubygems_version: 1.8.6
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: A command line interface for logaling.
87
+ test_files:
88
+ - spec/spec_helper.rb