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 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
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in julius.gemspec
4
+ gemspec
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 [![Build Status](https://travis-ci.org/hadzimme/julius.png)](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
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ Bundler.setup
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc 'run spec'
7
+ RSpec::Core::RakeTask.new(:spec) do |t|
8
+ t.rspec_opts = ["-c", "-fs"]
9
+ end
10
+
11
+ task :default => :spec
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>/){ "&lt;#{$1}s&gt;" })
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
@@ -0,0 +1,3 @@
1
+ class Julius
2
+ VERSION = "0.0.1"
3
+ end
@@ -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