james 0.1.0-universal-darwin-10 → 0.1.1-universal-darwin-10

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/aux/james/cli.rb CHANGED
@@ -5,6 +5,10 @@ module James
5
5
  class CLI
6
6
 
7
7
  def execute *patterns
8
+ silent = patterns.delete '-s'
9
+ silent_input = patterns.delete '-si'
10
+ silent_output = patterns.delete '-so'
11
+
8
12
  dialogs = find_dialogs_for patterns
9
13
 
10
14
  puts "James: I haven't found anything to talk about (No files found). Exiting." or exit!(1) if dialogs.empty?
@@ -12,7 +16,11 @@ module James
12
16
 
13
17
  load_all dialogs
14
18
 
15
- James.listen
19
+ options = {}
20
+ options[:input] = Inputs::Terminal if silent || silent_input
21
+ options[:output] = Outputs::Terminal if silent || silent_output
22
+
23
+ James.listen options
16
24
  end
17
25
  def find_dialogs_for patterns
18
26
  patterns = ["**/*_dialog{,ue}.rb"] if patterns.empty?
data/bin/james CHANGED
@@ -7,6 +7,11 @@
7
7
  # OR
8
8
  # james # Uses all dialogs it can find in this dir and subdirs.
9
9
  #
10
+ # Options:
11
+ # * -s # Silent input and output (same as "-si -so").
12
+ # * -si # Silent input.
13
+ # * -so # Silent output.
14
+ #
10
15
 
11
16
  begin
12
17
  require 'james/cli'
data/lib/james.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  module James; end
2
2
 
3
- # require File.expand_path '../james/timer', __FILE__
4
-
5
3
  require File.expand_path '../james/state_api', __FILE__
6
4
  require File.expand_path '../james/state_internals', __FILE__
7
5
 
@@ -35,18 +33,18 @@ module James
35
33
  dialogs.each { |dialog| controller.add_dialog dialog }
36
34
  end
37
35
 
38
- # Start a new controller and listen.
36
+ # Start listening.
39
37
  #
40
38
  # Will not listen again if already listening.
41
39
  #
42
- def self.listen
43
- controller.listen unless controller.listening?
40
+ def self.listen options
41
+ controller.listen options
44
42
  end
45
43
 
46
44
  # Controller instance.
47
45
  #
48
46
  def self.controller
49
- @controller ||= Controller.new
47
+ Controller.instance
50
48
  end
51
49
 
52
50
  end
@@ -2,21 +2,34 @@ module James
2
2
 
3
3
  class Controller
4
4
 
5
- attr_reader :visitor
5
+ attr_reader :visitor, :listening
6
+
7
+ # Singleton reader.
8
+ #
9
+ def self.instance
10
+ @controller ||= new
11
+ end
6
12
 
7
13
  # This puts together the core dialog and the user
8
14
  # ones that are hooked into it.
9
15
  #
10
16
  # TODO Rewrite this. Design needs some refactoring.
17
+ # Should the user visitor be created dynamically? (Probably yes.)
11
18
  #
12
19
  def initialize
13
- @user_dialogs = Dialogs.new
14
- system_visitor = Visitor.new CoreDialog.new.state_for(:awake)
15
- @visitor = Visitors.new system_visitor, @user_dialogs.visitor
20
+ @user_dialogs = Dialogs.new
21
+ @visitor = Visitors.new system_visitor, user_visitor
22
+ end
23
+ def system_visitor
24
+ Visitor.new CoreDialog.new.state_for(:awake)
25
+ end
26
+ def user_visitor
27
+ @user_dialogs.visitor
16
28
  end
17
29
 
30
+ # MacRuby callback functions.
31
+ #
18
32
  def applicationDidFinishLaunching notification
19
- load_voices
20
33
  start_output
21
34
  start_input
22
35
  end
@@ -24,12 +37,6 @@ module James
24
37
  exit
25
38
  end
26
39
 
27
- # Load voices from yaml.
28
- #
29
- def load_voices
30
- # TODO
31
- end
32
-
33
40
  # Add a dialog to the current system.
34
41
  #
35
42
  def add_dialog dialog
@@ -39,13 +46,13 @@ module James
39
46
  # Start recognizing words.
40
47
  #
41
48
  def start_input
42
- @input = Inputs::Audio.new self
49
+ @input = @input_class.new self
43
50
  @input.listen
44
51
  end
45
52
  # Start speaking.
46
53
  #
47
54
  def start_output
48
- @output = Outputs::Audio.new
55
+ @output = @output_class.new @output_options
49
56
  end
50
57
 
51
58
  # Callback method from dialog.
@@ -62,38 +69,28 @@ module James
62
69
  visitor.expects
63
70
  end
64
71
 
65
- def listen
72
+ # Start listening using the provided options.
73
+ #
74
+ # Options:
75
+ # * input # Inputs::Terminal or Inputs::Audio (default).
76
+ # * output # Outputs::Terminal or Outputs::Audio (default).
77
+ #
78
+ def listen options = {}
79
+ return if listening
80
+
81
+ @input_class = options[:input] || Inputs::Audio
82
+ @output_class = options[:output] || Outputs::Audio
83
+
84
+ @output_options ||= {}
85
+ @output_options[:voice] = options[:voice] || 'com.apple.speech.synthesis.voice.Alex'
86
+
66
87
  app = NSApplication.sharedApplication
67
88
  app.delegate = self
68
89
 
69
- # window = NSWindow.alloc.initWithContentRect([100, 300, 300, 100],
70
- # styleMask:NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask,
71
- # backing:NSBackingStoreBuffered,
72
- # defer:false)
73
- # window.title = 'James Debug/Info'
74
- # window.level = 3
75
- # window.delegate = app.delegate
76
-
77
- # @button = NSButton.alloc.initWithFrame([10, 10, 400, 10])
78
- # @button.bezelStyle = 4
79
- # @button.title = ''
80
- # @button.target = app.delegate
81
- # @button.action = 'say_hello:'
82
- #
83
- # window.contentView.addSubview(@button)
84
-
85
- # window.display
86
- # window.orderFrontRegardless
87
-
88
90
  @listening = true
89
91
 
90
92
  app.run
91
93
  end
92
- # If listen has been called, it is listening.
93
- #
94
- def listening?
95
- !!@listening
96
- end
97
94
 
98
95
  end
99
96
 
@@ -2,7 +2,7 @@ module James
2
2
 
3
3
  # A dialog can be instantiated in two ways:
4
4
  #
5
- # The simple way, will directly add itself to James.
5
+ # The simple way will directly add itself to James.
6
6
  #
7
7
  # James.use_dialog(optional_args_for_initialize) do
8
8
  # # Your dialog.
@@ -10,12 +10,16 @@ module James
10
10
  # end
11
11
  #
12
12
  # class MyDialog
13
+ #
13
14
  # include James::Dialog
14
15
  #
15
- # # Your dialog.
16
+ # # Your dialog definition.
16
17
  # #
18
+ #
17
19
  # end
18
20
  #
21
+ # # Tell James to use the dialog.
22
+ # #
19
23
  # James.use MyDialog.new
20
24
  #
21
25
  module Dialog; end
@@ -33,7 +33,10 @@ module James
33
33
  end
34
34
  def recognize_new_commands
35
35
  possibilities = controller.expects
36
- puts "Possibilities:\n #{possibilities.join("\n ")}"
36
+ puts "Possibilities:\n"
37
+ possibilities.each_with_index do |possibility, index|
38
+ puts "#{index + 1}) #{possibility}"
39
+ end
37
40
  @recognizer.setCommands possibilities
38
41
  end
39
42
 
@@ -13,11 +13,18 @@ module James
13
13
  # Call this method if you heard something in the subclass.
14
14
  #
15
15
  def heard command
16
- # Call dialog.
17
- #
18
16
  controller.hear command
19
17
  end
20
18
 
19
+ # Shows possible commands in the terminal.
20
+ #
21
+ def show_possibilities possibilities
22
+ puts "Possibilities:\n"
23
+ possibilities.each_with_index do |possibility, index|
24
+ puts "#{index + 1}) #{possibility}"
25
+ end
26
+ end
27
+
21
28
  end
22
29
 
23
30
  end
@@ -6,17 +6,30 @@ module James
6
6
  #
7
7
  class Terminal < Base
8
8
 
9
+ # Start listening to commands by the user.
10
+ #
9
11
  def listen
10
12
  sleep 2
11
13
  loop do
12
14
  possibilities = controller.expects
13
- puts "Possibilities:\n #{possibilities.join("\n ")}"
14
- command = gets.chop
15
+ show_possibilities possibilities
16
+ command = get_command
15
17
  puts "I heard '#{command}'."
18
+ command = possibilities[command.to_i-1] unless command.to_i.zero?
16
19
  heard command if possibilities.include? command
17
20
  end
18
21
  end
19
22
 
23
+ # Get the next command by the user.
24
+ #
25
+ def get_command
26
+ STDIN.gets.chop
27
+ rescue IOError
28
+ puts "Wait a second, please, Sir, I am busy."
29
+ sleep 1
30
+ retry
31
+ end
32
+
20
33
  end
21
34
 
22
35
  end
@@ -4,11 +4,17 @@ module James
4
4
 
5
5
  class Audio
6
6
 
7
-
8
- def initialize voice = nil
9
- @output = NSSpeechSynthesizer.alloc.initWithVoice voice || 'com.apple.speech.synthesis.voice.Alex'
7
+ # Create a new audio output.
8
+ #
9
+ # Options:
10
+ # * voice # Default is 'com.apple.speech.synthesis.voice.Alex'.
11
+ #
12
+ def initialize options = {}
13
+ @output = NSSpeechSynthesizer.alloc.initWithVoice options[:voice] || 'com.apple.speech.synthesis.voice.Alex'
10
14
  end
11
15
 
16
+ # Say the given text out loud.
17
+ #
12
18
  def say text
13
19
  @output.startSpeakingString text
14
20
  end
@@ -6,8 +6,18 @@ module James
6
6
  #
7
7
  class Terminal
8
8
 
9
+ #
10
+ #
11
+ def initialize options = {}
12
+
13
+ end
14
+
15
+ # Say the given text in the terminal.
16
+ #
9
17
  def say text
18
+ puts
10
19
  p text
20
+ puts
11
21
  end
12
22
 
13
23
  end
data/lib/james/visitor.rb CHANGED
@@ -6,10 +6,6 @@ module James
6
6
  # too much time passes without input.
7
7
  #
8
8
  # Note: A visitor should generally be very stupid.
9
- # Note 2: We could call this Hearing, or Ear ;)
10
- #
11
- # TODO Add a timer which resets the state to the
12
- # initial state.
13
9
  #
14
10
  class Visitor
15
11
 
@@ -18,17 +14,15 @@ module James
18
14
 
19
15
  # Pass in an initial state to start from.
20
16
  #
21
- def initialize initial, timer = nil
17
+ def initialize initial
22
18
  @current = initial
23
19
 
24
20
  @initial = initial
25
- # @timer = timer || Timer.new
26
21
  end
27
22
 
28
23
  # Resets the current state back to the initial.
29
24
  #
30
25
  def reset
31
- # timer.stop
32
26
  self.current = initial
33
27
  end
34
28
 
@@ -59,7 +53,6 @@ module James
59
53
  end
60
54
  def hear phrase, &block
61
55
  return unless hears? phrase
62
- # timer.restart
63
56
  exit_text = exit &block
64
57
  transition phrase
65
58
  check &block
@@ -22,10 +22,6 @@ module James
22
22
  @visitors = visitors
23
23
  end
24
24
 
25
- def add_dialog dialog
26
-
27
- end
28
-
29
25
  # Hear tries all visitors in order
30
26
  # until one hears a phrase he knows.
31
27
  #
@@ -38,18 +34,18 @@ module James
38
34
  visitor.hear phrase, &block and break
39
35
  end
40
36
 
41
- while visitor = enumerator.shift
37
+ enumerator.each do |visitor|
42
38
  visitor.reset
43
39
  end
44
40
  end
45
41
 
46
- # Enter enters the first dialog.
42
+ # Enter enters the first visitor.
47
43
  #
48
44
  def enter
49
45
  visitors.first.enter
50
46
  end
51
47
 
52
- # Simply returns the sum of what phrases all dialogs expect.
48
+ # Simply returns the sum of what phrases all dialogs do expect, front-to-back.
53
49
  #
54
50
  # Stops as soon as a visitor is not in a chainable state anymore.
55
51
  #
@@ -7,6 +7,9 @@ require File.expand_path '../../../../lib/james/visitors', __FILE__
7
7
  require File.expand_path '../../../../lib/james/visitor', __FILE__
8
8
  require File.expand_path '../../../../lib/james/state_api', __FILE__
9
9
  require File.expand_path '../../../../lib/james/dialogs', __FILE__
10
+ require File.expand_path '../../../../lib/james/inputs/base', __FILE__
11
+ require File.expand_path '../../../../lib/james/inputs/terminal', __FILE__
12
+ require File.expand_path '../../../../lib/james/inputs/audio', __FILE__
10
13
  require File.expand_path '../../../../lib/james/controller', __FILE__
11
14
 
12
15
  describe James::Controller do
@@ -9,10 +9,6 @@ require File.expand_path '../../../../lib/james/dialogs', __FILE__
9
9
 
10
10
  describe James::Dialog do
11
11
 
12
- it 'can haz merkin spellink' do
13
- James::Dialog.should == James::Dialog
14
- end
15
-
16
12
  context 'units' do
17
13
  let(:dialog) do
18
14
  James.use_dialog do
@@ -89,15 +85,6 @@ describe James::Dialog do
89
85
  end
90
86
  end.to_not raise_error
91
87
  end
92
- it 'can haz merkin spellink' do
93
- expect do
94
- James.dialog do
95
-
96
- hear 'something' => :some_state
97
-
98
- end
99
- end.to_not raise_error
100
- end
101
88
  end
102
89
 
103
90
  end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ #
3
+ require File.expand_path '../../../../../lib/james/inputs/base', __FILE__
4
+ require File.expand_path '../../../../../lib/james/inputs/audio', __FILE__
5
+
6
+ describe James::Inputs::Audio do
7
+
8
+ let(:input) { described_class.new }
9
+
10
+ describe 'speechRecognizer' do
11
+ it 'does something' do
12
+ sender = stub :sender
13
+
14
+ input.speechRecognizer sender
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+ #
3
+ require File.expand_path '../../../../../lib/james/inputs/base', __FILE__
4
+ require File.expand_path '../../../../../lib/james/inputs/terminal', __FILE__
5
+
6
+ describe James::Inputs::Terminal do
7
+
8
+ let(:input) { described_class.new }
9
+
10
+
11
+
12
+ end
metadata CHANGED
@@ -2,14 +2,14 @@
2
2
  name: james
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.0
5
+ version: 0.1.1
6
6
  platform: universal-darwin-10
7
7
  authors:
8
8
  - Florian Hanke
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-05-21 00:00:00 +10:00
12
+ date: 2011-05-29 00:00:00 +10:00
13
13
  default_executable: james
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -49,7 +49,6 @@ files:
49
49
  - lib/james/outputs/terminal.rb
50
50
  - lib/james/state_api.rb
51
51
  - lib/james/state_internals.rb
52
- - lib/james/timer.rb
53
52
  - lib/james/visitor.rb
54
53
  - lib/james/visitors.rb
55
54
  - lib/james.rb
@@ -58,6 +57,8 @@ files:
58
57
  - spec/integration/test_dialogue_spec.rb
59
58
  - spec/lib/james/controller_spec.rb
60
59
  - spec/lib/james/dialog_spec.rb
60
+ - spec/lib/james/inputs/audio_spec.rb
61
+ - spec/lib/james/inputs/terminal_spec.rb
61
62
  - spec/lib/james/state_spec.rb
62
63
  - spec/lib/james/visitor_spec.rb
63
64
  - spec/lib/james/visitors_spec.rb
@@ -92,6 +93,8 @@ test_files:
92
93
  - spec/integration/test_dialogue_spec.rb
93
94
  - spec/lib/james/controller_spec.rb
94
95
  - spec/lib/james/dialog_spec.rb
96
+ - spec/lib/james/inputs/audio_spec.rb
97
+ - spec/lib/james/inputs/terminal_spec.rb
95
98
  - spec/lib/james/state_spec.rb
96
99
  - spec/lib/james/visitor_spec.rb
97
100
  - spec/lib/james/visitors_spec.rb
data/lib/james/timer.rb DELETED
@@ -1,14 +0,0 @@
1
- module James
2
-
3
- class Timer
4
-
5
- def stop
6
-
7
- end
8
- def restart
9
-
10
- end
11
-
12
- end
13
-
14
- end