julius 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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +41 -0
- data/Rakefile +11 -0
- data/julius.gemspec +23 -0
- data/lib/julius.rb +32 -0
- data/lib/julius/command.rb +43 -0
- data/lib/julius/message.rb +116 -0
- data/lib/julius/prompt.rb +16 -0
- data/lib/julius/version.rb +3 -0
- data/spec/julius_spec.rb +119 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8fae0d4d7635d1a147f0e69aebb0f0c8f9b4e9ef
|
4
|
+
data.tar.gz: 6a005282f6f17ee41813f4c230fffd8f627462b2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 56230ef389f291e92898c7358c29ba69acd6c6392312876eeb69ba4847f7d7892d56ae7173f2cba2062fa727ce9c85abeef44492dd2a66e2bc7e1a428982b0f6
|
7
|
+
data.tar.gz: 8097961a9c2c4beb45290aecbac0e58bb20f9e63c863925f13891e61169cab3b21ed3bdd1aa4a761285af42ab8fcb14efd75a3e47300eca3cb64f85da5fa2e3d
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Hajime WAKAHARA
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Julius [](https://travis-ci.org/hadzimme/julius)
|
2
|
+
|
3
|
+
Get results from module mode Julius.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'julius'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install julius
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
require 'julius'
|
23
|
+
|
24
|
+
julius = Julius.new
|
25
|
+
julius.each_message do |message, prompt|
|
26
|
+
prompt.terminate
|
27
|
+
case message.name
|
28
|
+
when :RECOGOUT
|
29
|
+
puts message.sentence
|
30
|
+
end
|
31
|
+
prompt.resume
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
## Contributing
|
36
|
+
|
37
|
+
1. Fork it
|
38
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
39
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
40
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
41
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/julius.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'julius/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "julius"
|
8
|
+
gem.version = Julius::VERSION
|
9
|
+
gem.authors = ["Hajime WAKAHARA"]
|
10
|
+
gem.email = ["hajime.wakahara@gmail.com"]
|
11
|
+
gem.description = %q{Get results from module mode Julius.}
|
12
|
+
gem.summary = %q{A wrapper for Julius, the Open-Source Large Vocabulary CSR Engine}
|
13
|
+
gem.homepage = "https://github.com/hadzimme/julius"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
gem.required_ruby_version = '>= 1.9'
|
20
|
+
|
21
|
+
gem.add_development_dependency 'rake'
|
22
|
+
gem.add_development_dependency 'rspec'
|
23
|
+
end
|
data/lib/julius.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'rexml/document'
|
3
|
+
require 'julius/version'
|
4
|
+
require 'julius/message'
|
5
|
+
require 'julius/command'
|
6
|
+
require 'julius/prompt'
|
7
|
+
|
8
|
+
class Julius
|
9
|
+
def initialize(arg = {})
|
10
|
+
@host = arg[:host] || 'localhost'
|
11
|
+
@port = arg[:port] || 10500
|
12
|
+
end
|
13
|
+
|
14
|
+
def each_message
|
15
|
+
return self.to_enum(__method__) unless block_given?
|
16
|
+
socket = TCPSocket.new(@host, @port)
|
17
|
+
prompt = Prompt.new(socket)
|
18
|
+
xml_enum(socket).each do |xml|
|
19
|
+
yield(Message.init(xml), prompt)
|
20
|
+
end
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def xml_enum(socket)
|
26
|
+
Enumerator.new do |yielder|
|
27
|
+
while line = socket.readline(".\n")
|
28
|
+
yielder << line.force_encoding('UTF-8').sub(/\.\n$/, '')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class Julius
|
2
|
+
class Command
|
3
|
+
class Status < Command; end
|
4
|
+
class Die < Command; end
|
5
|
+
class Version < Command; end
|
6
|
+
class Pause < Command; end
|
7
|
+
class Terminate < Command; end
|
8
|
+
class Resume < Command; end
|
9
|
+
class Currentprocess < Command; end
|
10
|
+
class Shiftprocess < Command; end
|
11
|
+
class Addprocess < Command; end
|
12
|
+
class Delprocess < Command; end
|
13
|
+
class Listprocess < Command; end
|
14
|
+
class Deactivateprocess < Command; end
|
15
|
+
class Activateprocess < Command; end
|
16
|
+
class Graminfo < Command; end
|
17
|
+
class Changegram < Command; end
|
18
|
+
class Addgram < Command; end
|
19
|
+
class Delgram < Command; end
|
20
|
+
class Deactivategram < Command; end
|
21
|
+
class Activategram < Command; end
|
22
|
+
class Inputonchange < Command; end
|
23
|
+
class Syncgram < Command; end
|
24
|
+
class Addword < Command; end
|
25
|
+
|
26
|
+
def initialize(*args)
|
27
|
+
@args = args
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
if @args.size > 0
|
32
|
+
"#{name} #{@args.join(' ')}"
|
33
|
+
else
|
34
|
+
name
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def name
|
40
|
+
self.class.name.upcase[/[A-Z]+$/]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
class Julius
|
2
|
+
class Message
|
3
|
+
class ElementError < StandardError; end
|
4
|
+
|
5
|
+
class Startproc < Message; end
|
6
|
+
class Endproc < Message; end
|
7
|
+
class Startrecog < Message; end
|
8
|
+
class Endrecog < Message; end
|
9
|
+
|
10
|
+
class Input < Message
|
11
|
+
attr_reader :status, :time
|
12
|
+
end
|
13
|
+
|
14
|
+
class Inputparam < Message
|
15
|
+
attr_reader :frames, :msec
|
16
|
+
end
|
17
|
+
|
18
|
+
class GMM < Message
|
19
|
+
attr_reader :result, :cmscore
|
20
|
+
end
|
21
|
+
|
22
|
+
class Recogout < Message
|
23
|
+
include Enumerable
|
24
|
+
class Shypo < Message
|
25
|
+
include Enumerable
|
26
|
+
class Whypo < Message
|
27
|
+
attr_reader :word, :classid, :phone, :cm
|
28
|
+
def to_s
|
29
|
+
@word
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(element)
|
34
|
+
@whypo_list = element.elements.map do |element|
|
35
|
+
Whypo.new(element)
|
36
|
+
end
|
37
|
+
super(element)
|
38
|
+
end
|
39
|
+
attr_reader :rank, :score
|
40
|
+
|
41
|
+
def each(&block)
|
42
|
+
return self.to_enum unless block_given?
|
43
|
+
@whypo_list.each(&block)
|
44
|
+
self
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def initialize(element)
|
49
|
+
@shypo_list = element.elements.map do |element|
|
50
|
+
Shypo.new(element)
|
51
|
+
end
|
52
|
+
super(element)
|
53
|
+
end
|
54
|
+
|
55
|
+
def each(&block)
|
56
|
+
return self.to_enum unless block_given?
|
57
|
+
@shypo_list.each(&block)
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def first
|
62
|
+
@shypo_list.first
|
63
|
+
end
|
64
|
+
|
65
|
+
def [] nth
|
66
|
+
@shypo_list[nth]
|
67
|
+
end
|
68
|
+
|
69
|
+
alias at []
|
70
|
+
|
71
|
+
def sentence
|
72
|
+
self.first.map{|whypo| whypo.to_s }.join
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class Recogfail < Message; end
|
77
|
+
|
78
|
+
class Rejected < Message
|
79
|
+
attr_reader :reason
|
80
|
+
end
|
81
|
+
|
82
|
+
class Graphout < Message; end
|
83
|
+
class Graminfo < Message; end
|
84
|
+
|
85
|
+
class Sysinfo < Message
|
86
|
+
attr_reader :process
|
87
|
+
end
|
88
|
+
|
89
|
+
class Engineinfo < Message
|
90
|
+
attr_reader :type, :version, :conf
|
91
|
+
end
|
92
|
+
|
93
|
+
class Grammar < Message
|
94
|
+
attr_reader :status, :reason
|
95
|
+
end
|
96
|
+
|
97
|
+
class Recogprocess < Message; end
|
98
|
+
|
99
|
+
def self.init(xml)
|
100
|
+
document = REXML::Document.new(xml.gsub(/<(\/?)s>/){ "<#{$1}s>" })
|
101
|
+
eval(document.root.name.capitalize).new(document.root)
|
102
|
+
rescue NameError
|
103
|
+
raise ElementError, "invalid XML element found: #{document.root.name}"
|
104
|
+
end
|
105
|
+
|
106
|
+
def initialize(element)
|
107
|
+
element.attributes.each do |attribute|
|
108
|
+
self.instance_variable_set("@#{attribute[0].downcase}", attribute[1])
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def name
|
113
|
+
self.class.name.upcase[/[A-Z]+$/].intern
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Julius
|
2
|
+
class Prompt
|
3
|
+
class NoCommandError < StandardError; end
|
4
|
+
|
5
|
+
def initialize(socket)
|
6
|
+
@socket = socket
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(name, *args)
|
10
|
+
command = eval("Command::#{name.capitalize}").new(*args)
|
11
|
+
@socket.puts(command.to_s)
|
12
|
+
rescue NameError
|
13
|
+
raise NoCommandError, "the command '#{name}' is not supported."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/spec/julius_spec.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'rspec'
|
4
|
+
require 'julius'
|
5
|
+
|
6
|
+
describe Julius::Message do
|
7
|
+
context 'when initialized with XML "<STARTPROC/>"' do
|
8
|
+
subject { message = Julius::Message.init('<STARTPROC/>') }
|
9
|
+
it { should be_an_instance_of(Julius::Message::Startproc) }
|
10
|
+
it { should respond_to :name }
|
11
|
+
its(:name){ should eq :STARTPROC }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when initialized with unknown XML' do
|
15
|
+
subject { lambda { Julius::Message.init('<FOO/>') } }
|
16
|
+
it { should raise_error Julius::Message::ElementError }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Julius::Message::Recogout do
|
21
|
+
before do
|
22
|
+
@xml = <<EOS # validなXMLでない
|
23
|
+
<RECOGOUT>
|
24
|
+
<SHYPO RANK="1" SCORE="-3214.712891">
|
25
|
+
<WHYPO WORD="" CLASSID="<s>" PHONE="silB" CM="0.244"/>
|
26
|
+
<WHYPO WORD="送れ" CLASSID="送れ:オクレ:送れる:239" PHONE="o k u r e" CM="0.198"/>
|
27
|
+
<WHYPO WORD="ます" CLASSID="ます:マス:ます:146" PHONE="m a s u" CM="0.723"/>
|
28
|
+
<WHYPO WORD="か" CLASSID="か:カ:か:72" PHONE="k a" CM="0.411"/>
|
29
|
+
<WHYPO WORD="?" CLASSID="?:?:?:5" PHONE="sp" CM="0.111"/>
|
30
|
+
<WHYPO WORD="" CLASSID="</s>" PHONE="silE" CM="1.000"/>
|
31
|
+
</SHYPO>
|
32
|
+
</RECOGOUT>
|
33
|
+
EOS
|
34
|
+
@message = Julius::Message.init(@xml)
|
35
|
+
end
|
36
|
+
subject { @message }
|
37
|
+
it { should respond_to :each }
|
38
|
+
it { should respond_to :first }
|
39
|
+
it { should respond_to :sentence }
|
40
|
+
its(:sentence){ should eq '送れますか?' }
|
41
|
+
context 'each' do
|
42
|
+
it do
|
43
|
+
expect {|block| @message.each(&block) }.to yield_control
|
44
|
+
end
|
45
|
+
it do
|
46
|
+
expect {|block| @message.each(&block) }.to yield_with_args(
|
47
|
+
Julius::Message::Recogout::Shypo)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
context 'first' do
|
51
|
+
subject { @message.first }
|
52
|
+
it { should be_an_instance_of Julius::Message::Recogout::Shypo }
|
53
|
+
context 'each' do
|
54
|
+
# it do
|
55
|
+
# expect {|block| @message.first.each(&block) }.to yield_control
|
56
|
+
# end
|
57
|
+
it do
|
58
|
+
expect {|block| @message.first.each(&block) }.to yield_successive_args(
|
59
|
+
Julius::Message::Recogout::Shypo::Whypo,
|
60
|
+
Julius::Message::Recogout::Shypo::Whypo,
|
61
|
+
Julius::Message::Recogout::Shypo::Whypo,
|
62
|
+
Julius::Message::Recogout::Shypo::Whypo,
|
63
|
+
Julius::Message::Recogout::Shypo::Whypo,
|
64
|
+
Julius::Message::Recogout::Shypo::Whypo)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe Julius::Command::Status do
|
71
|
+
subject { @status = Julius::Command::Status.new }
|
72
|
+
its(:to_s){ should eq 'STATUS' }
|
73
|
+
end
|
74
|
+
|
75
|
+
describe Julius::Command::Addprocess do
|
76
|
+
subject { @addprocess = Julius::Command::Addprocess.new('/path/to/jconf') }
|
77
|
+
its(:to_s){ should eq 'ADDPROCESS /path/to/jconf' }
|
78
|
+
end
|
79
|
+
|
80
|
+
describe Julius::Prompt do
|
81
|
+
before do
|
82
|
+
@server_socket, fake_socket = IO.pipe
|
83
|
+
@prompt = Julius::Prompt.new(fake_socket)
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'status' do
|
87
|
+
it 'server should receive command "STATUS"' do
|
88
|
+
@prompt.status
|
89
|
+
@server_socket.gets.chomp.should eq 'STATUS'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'unknown command: foo' do
|
94
|
+
subject { lambda { @prompt.foo } }
|
95
|
+
it { should raise_error Julius::Prompt::NoCommandError }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe Julius do
|
100
|
+
before do
|
101
|
+
allow_message_expectations_on_nil
|
102
|
+
@socket = IO.popen('-')
|
103
|
+
@socket.stub!(:readline).and_return('<STARTPROC/>', nil)
|
104
|
+
TCPSocket.should_receive(:new)
|
105
|
+
.with('localhost', 10501)
|
106
|
+
.and_return(@socket)
|
107
|
+
@julius = Julius.new(port: 10501)
|
108
|
+
end
|
109
|
+
context 'each_message' do
|
110
|
+
it do
|
111
|
+
expect {|block| @julius.each_message(&block) }.to yield_control
|
112
|
+
end
|
113
|
+
it do
|
114
|
+
expect {|block| @julius.each_message(&block) }.to yield_with_args(
|
115
|
+
Julius::Message::Startproc,
|
116
|
+
Julius::Prompt)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: julius
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Hajime WAKAHARA
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-03-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Get results from module mode Julius.
|
42
|
+
email:
|
43
|
+
- hajime.wakahara@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- .gitignore
|
49
|
+
- Gemfile
|
50
|
+
- LICENSE.txt
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- julius.gemspec
|
54
|
+
- lib/julius.rb
|
55
|
+
- lib/julius/command.rb
|
56
|
+
- lib/julius/message.rb
|
57
|
+
- lib/julius/prompt.rb
|
58
|
+
- lib/julius/version.rb
|
59
|
+
- spec/julius_spec.rb
|
60
|
+
homepage: https://github.com/hadzimme/julius
|
61
|
+
licenses: []
|
62
|
+
metadata: {}
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '1.9'
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 2.0.0
|
80
|
+
signing_key:
|
81
|
+
specification_version: 4
|
82
|
+
summary: A wrapper for Julius, the Open-Source Large Vocabulary CSR Engine
|
83
|
+
test_files:
|
84
|
+
- spec/julius_spec.rb
|