pangdudu-robots 0.2.0 → 0.2.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/funky-examples/memory-agent/memory_agent.rb +250 -0
- data/funky-examples/memory-agent/memory_generator_agent.rb +59 -0
- data/funky-examples/talking-swift-agent/README +14 -0
- data/funky-examples/talking-swift-agent/talking_swift_agent.rb +44 -0
- data/funky-examples/talking-swift-agent/text_generator.rb +38 -0
- metadata +7 -2
@@ -0,0 +1,250 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'dm-core' #sudo gem install datamapper
|
3
|
+
require 'do_mysql' #sudo gem install do_mysql
|
4
|
+
require 'dm-timestamps' #sudo gem install dm-timestamps
|
5
|
+
require 'rofl' #sudo gem install pangdudu-rofl --source=http://gems.github.com
|
6
|
+
require 'robots' #sudo gem install pangdudu-robots --source=http://gems.github.com
|
7
|
+
require 'robots_xml'
|
8
|
+
|
9
|
+
#the RobotsXml module supplies nice methods for xml handling
|
10
|
+
#create xml messages like this: xml_msg = create_xml_msg { |b| b.body("test"); b.info("timestamp" => "#{Time.now}") }
|
11
|
+
#send them like this: send_msg xml_msg
|
12
|
+
#parse them like this: parse_xml_msg xml_msg,xpath
|
13
|
+
|
14
|
+
#do the mysql datamapper setup
|
15
|
+
DataMapper.setup(:default,{:adapter => 'mysql',:host => 'localhost',:username => 'robots',:password => 'robots!secret',:database => 'robots'})
|
16
|
+
|
17
|
+
#if you don't want to use a mysql database, or just need raw speed, check this out
|
18
|
+
#DataMapper.setup(:in_memory, :adapter => 'in_memory')
|
19
|
+
|
20
|
+
#and define a memory class
|
21
|
+
class Memory
|
22
|
+
include DataMapper::Resource
|
23
|
+
property :index, Serial
|
24
|
+
property :value, Text
|
25
|
+
property :created_at, DateTime
|
26
|
+
property :created_on, Date
|
27
|
+
property :updated_at, DateTime
|
28
|
+
property :updated_on, Date
|
29
|
+
#property :deleted_at, ParanoidDateTime
|
30
|
+
has n, :questions, :through => Resource
|
31
|
+
has n, :keywords, :through => Resource
|
32
|
+
end
|
33
|
+
|
34
|
+
#and define a memory class
|
35
|
+
class Question
|
36
|
+
include DataMapper::Resource
|
37
|
+
property :index, Serial
|
38
|
+
property :value, Text
|
39
|
+
property :created_at, DateTime
|
40
|
+
property :created_on, Date
|
41
|
+
property :updated_at, DateTime
|
42
|
+
property :updated_on, Date
|
43
|
+
#property :deleted_at, ParanoidDateTime
|
44
|
+
has n, :memories, :through => Resource
|
45
|
+
end
|
46
|
+
|
47
|
+
#memories may have keywords
|
48
|
+
class Keyword
|
49
|
+
include DataMapper::Resource
|
50
|
+
property :index, Serial
|
51
|
+
property :value, String
|
52
|
+
property :created_at, DateTime
|
53
|
+
property :created_on, Date
|
54
|
+
property :updated_at, DateTime
|
55
|
+
property :updated_on, Date
|
56
|
+
#property :deleted_at, ParanoidDateTime
|
57
|
+
has n, :memories, :through => Resource
|
58
|
+
end
|
59
|
+
|
60
|
+
#if your records aren't persistent, try removing the migrate statements
|
61
|
+
DataMapper.auto_migrate!
|
62
|
+
#Memory.auto_migrate!
|
63
|
+
#Question.auto_migrate!
|
64
|
+
#Keyword.auto_migrate!
|
65
|
+
|
66
|
+
class MemoryAgent
|
67
|
+
include Robots
|
68
|
+
include RobotsXml
|
69
|
+
|
70
|
+
def initialize
|
71
|
+
ilog "RobotsProto initialized"
|
72
|
+
end
|
73
|
+
|
74
|
+
#process an incoming memory message
|
75
|
+
def process_memory_msg xml_msg
|
76
|
+
memories = get_memories xml_msg
|
77
|
+
questions = get_questions xml_msg
|
78
|
+
keywords = get_keywords xml_msg
|
79
|
+
#remember a memory
|
80
|
+
#rather check for Array class here, lazy...
|
81
|
+
unless (memories.eql? "question") || (memories.eql? "keywords") || (memories.eql? "memories")
|
82
|
+
memories.each {|m| process_memory m,questions,keywords}
|
83
|
+
end
|
84
|
+
#ask a question and return memories
|
85
|
+
if memories.eql? "question"
|
86
|
+
questions.each {|q| process_question q}
|
87
|
+
end
|
88
|
+
#retrieve memories for keywords
|
89
|
+
if memories.eql? "memories"
|
90
|
+
process_keywords keywords
|
91
|
+
end
|
92
|
+
#retrieve keywords for a memory
|
93
|
+
#if memories.eql? "keywords"
|
94
|
+
#end
|
95
|
+
end
|
96
|
+
|
97
|
+
#process a single memory
|
98
|
+
def process_memory memory,questions,keywords
|
99
|
+
questions.each {|q| memory.questions << q}
|
100
|
+
keywords.each {|k| memory.keywords << k}
|
101
|
+
#finally save the updated memory to the storage
|
102
|
+
memory.save
|
103
|
+
end
|
104
|
+
|
105
|
+
#process a question
|
106
|
+
def process_question question
|
107
|
+
qval = question.value
|
108
|
+
#get all question with that value from storage
|
109
|
+
questions = Question.all(:value => qval)
|
110
|
+
memories = {} #single values behind key, so only newest memory will be returned
|
111
|
+
#get all associated memories from storage
|
112
|
+
questions.each { |q| q.memories.each { |m| memories[m.value] = m } }
|
113
|
+
memories.each do |n,m|
|
114
|
+
#create a response message
|
115
|
+
msg = create_xml_msg { |b| b.memory_response(m.value,"action"=>"question-response","question"=>qval,"timestamp" => "#{Time.now}") }
|
116
|
+
#send response message to system
|
117
|
+
send_msg msg
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
#process keywords, and return matching memories to system
|
122
|
+
def process_keywords keywords
|
123
|
+
memories = {}
|
124
|
+
keys = []
|
125
|
+
#the following could be a super nasty oneliner :)
|
126
|
+
keywords.each do |keyword|
|
127
|
+
keys << keyword.value #use that later for sorting
|
128
|
+
(Keyword.all(:value => keyword.value)).each do |k|
|
129
|
+
k.memories.each do |m|
|
130
|
+
if memories.has_key? m.value
|
131
|
+
memories[m.value][k.value] = "key" #add another keyword
|
132
|
+
else
|
133
|
+
memories[m.value] = {k.value => "key"} #it's a new entry
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
#oki, we now know which memories have what keywords, now we sort out the good ones
|
139
|
+
cinderella = {}
|
140
|
+
memories.each do |value,keywords|
|
141
|
+
good = true
|
142
|
+
keys.each { |key| good = false unless keywords.has_key? key }
|
143
|
+
#send message if we're good
|
144
|
+
if good
|
145
|
+
keys_string = ""
|
146
|
+
keys.each { |k| keys_string += "#{k} " }
|
147
|
+
msg = create_xml_msg { |b| b.memory_response(value,"action"=>"keywords-response","keywords"=>keys_string,"timestamp" => "#{Time.now}") }
|
148
|
+
end
|
149
|
+
end
|
150
|
+
#ok, there probably would have been a more datamapperish way to do this, tell me if you know one :)
|
151
|
+
#dlog cinderella.inspect
|
152
|
+
end
|
153
|
+
|
154
|
+
#get the memories from an xml_msg
|
155
|
+
def get_memories xml_msg
|
156
|
+
memories = []
|
157
|
+
mems = parse_xml_msg xml_msg,"//memory"
|
158
|
+
mems.each do |m|
|
159
|
+
if m.attributes["action"].eql? "remember"
|
160
|
+
memory = Memory.new(:value => m.inner_text)
|
161
|
+
memory.save
|
162
|
+
memories << memory
|
163
|
+
end
|
164
|
+
return "question" if m.attributes["action"].eql? "question" #ask a question, retrieve memory
|
165
|
+
return "keywords" if m.attributes["action"].eql? "keywords" #retrieve keywords for memory - not implemented yet
|
166
|
+
return "memories" if m.attributes["action"].eql? "memories" #retrieve memories for keywords
|
167
|
+
end
|
168
|
+
return memories
|
169
|
+
end
|
170
|
+
|
171
|
+
#get the keywords from an xml_msg
|
172
|
+
def get_keywords xml_msg
|
173
|
+
keywords = []
|
174
|
+
keys = parse_xml_msg xml_msg,"//keyword"
|
175
|
+
keys.each do |k|
|
176
|
+
keyword = Keyword.new(:value => k.inner_text)
|
177
|
+
keyword.save
|
178
|
+
keywords << keyword
|
179
|
+
end
|
180
|
+
return keywords
|
181
|
+
end
|
182
|
+
|
183
|
+
#get the questions from an xml_msg
|
184
|
+
def get_questions xml_msg
|
185
|
+
questions = []
|
186
|
+
quests = parse_xml_msg xml_msg,"//question"
|
187
|
+
quests.each do |q|
|
188
|
+
question = Question.new(:value => q.inner_text)
|
189
|
+
questions << question
|
190
|
+
question.save if q.attributes["action"].eql? "remember"
|
191
|
+
end
|
192
|
+
return questions
|
193
|
+
end
|
194
|
+
|
195
|
+
#ROBOTS message parsing stuff
|
196
|
+
|
197
|
+
#method that gets called when a new message arrives
|
198
|
+
def receive_msg msg
|
199
|
+
check_for_interests msg
|
200
|
+
end
|
201
|
+
|
202
|
+
#check if this msg interests us
|
203
|
+
def check_for_interests xml_msg
|
204
|
+
#message filter callback looks like this now
|
205
|
+
memory = parse_xml_msg xml_msg,"//memory"
|
206
|
+
process_memory_msg xml_msg unless memory.empty?
|
207
|
+
end
|
208
|
+
=begin
|
209
|
+
memory messages:
|
210
|
+
|
211
|
+
remember a memory:
|
212
|
+
<msg>
|
213
|
+
<memory action="remember">something happened</memory>
|
214
|
+
<question action="remember">what happened?</question>
|
215
|
+
<keyword>stuff</keyword>
|
216
|
+
<keyword>happening</keyword>
|
217
|
+
</msg>
|
218
|
+
|
219
|
+
ask a question:
|
220
|
+
<msg>
|
221
|
+
<memory action="question"></memory>
|
222
|
+
<question action="ask">what happened?</question>
|
223
|
+
</msg>
|
224
|
+
|
225
|
+
retrieve memories matching keywords:
|
226
|
+
<msg>
|
227
|
+
<memory action="memories"></memory>
|
228
|
+
<keyword>stuff</keyword>
|
229
|
+
<keyword>happening</keyword>
|
230
|
+
</msg>
|
231
|
+
|
232
|
+
not yet implemented, to lazy, retrieve keywords:
|
233
|
+
<msg>
|
234
|
+
<memory action="keywords">something happened</memory>
|
235
|
+
</msg>
|
236
|
+
=end
|
237
|
+
end
|
238
|
+
|
239
|
+
#start the app
|
240
|
+
ma = MemoryAgent.new
|
241
|
+
#=begin
|
242
|
+
ma.release_robots #start the robot agent module
|
243
|
+
|
244
|
+
#build you own loop if you need one
|
245
|
+
loop do
|
246
|
+
sleep 1
|
247
|
+
#send an xml message over the system
|
248
|
+
ma.send_msg ma.create_xml_msg { |b| b.info("memory agent alive","timestamp" => "#{Time.now}") }
|
249
|
+
end
|
250
|
+
#=end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rofl' #sudo gem install pangdudu-rofl --source=http://gems.github.com
|
3
|
+
require 'robots' #sudo gem install pangdudu-robots --source=http://gems.github.com
|
4
|
+
require 'robots_xml'
|
5
|
+
|
6
|
+
#the RobotsXml module supplies nice methods for xml handling
|
7
|
+
#create xml messages like this: xml_msg = create_xml_msg { |b| b.body("test"); b.info("timestamp" => "#{Time.now}") }
|
8
|
+
#send them like this: send_msg xml_msg
|
9
|
+
#parse them like this: parse_xml_msg xml_msg,xpath
|
10
|
+
|
11
|
+
class MemoryGeneratorAgent
|
12
|
+
include Robots
|
13
|
+
include RobotsXml
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
ilog "MemoryGeneratorAgent initialized"
|
17
|
+
end
|
18
|
+
|
19
|
+
#ROBOTS message parsing stuff
|
20
|
+
|
21
|
+
#method that gets called when a new message arrives
|
22
|
+
def receive_msg msg
|
23
|
+
check_for_interests msg
|
24
|
+
end
|
25
|
+
|
26
|
+
#check if this msg interests us
|
27
|
+
def check_for_interests xml_msg
|
28
|
+
#message filter callback looks like this now
|
29
|
+
memory = parse_xml_msg xml_msg,"//memory"
|
30
|
+
dlog memory unless memory.empty?
|
31
|
+
#message filter callback looks like this now
|
32
|
+
info = parse_xml_msg xml_msg,"//info"
|
33
|
+
dlog info unless info.empty?
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
#start the app
|
39
|
+
mga = MemoryGeneratorAgent.new
|
40
|
+
#begin
|
41
|
+
|
42
|
+
mga.release_robots #start the robot agent module
|
43
|
+
|
44
|
+
#build you own loop if you need one
|
45
|
+
loop do
|
46
|
+
sleep 3
|
47
|
+
#send an xml message over the system
|
48
|
+
mga.send_msg mga.create_xml_msg { |b| b.info("memory generator agent alive","timestamp" => "#{Time.now}") }
|
49
|
+
#generate some bogus memory remember
|
50
|
+
mga.send_msg mga.create_xml_msg { |b| b.memory("something happened","action" => "remember");b.question("what happened?","action"=>"remember");b.keyword("stuff");b.keyword("happening") }
|
51
|
+
#generate bogus ask question
|
52
|
+
mga.send_msg mga.create_xml_msg { |b| b.memory("action" => "question");b.question("what happened?","action"=>"ask") }
|
53
|
+
#generate bogus retrieve keywords
|
54
|
+
mga.send_msg mga.create_xml_msg { |b| b.memory("something happened","action" => "keywords");}
|
55
|
+
#generate bogus retrieve memories from keywords
|
56
|
+
mga.send_msg mga.create_xml_msg { |b| b.memory("action" => "memories");b.keyword("stuff");b.keyword("happening") }
|
57
|
+
end
|
58
|
+
|
59
|
+
#end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Hello!
|
2
|
+
|
3
|
+
in order to use swift, you need a cepstral swift voice: http://cepstral.com/downloads/
|
4
|
+
|
5
|
+
they are industry standard unit selection voices, and come with an api, i think it's
|
6
|
+
worth the bugs.
|
7
|
+
|
8
|
+
if you have a voice checkout and build: http://github.com/pangdudu/swiftly/tree/master
|
9
|
+
|
10
|
+
FREE ALTERNATIVE:
|
11
|
+
|
12
|
+
a free alternative that is easy to use, would be libflite: sudo gem install flite4r
|
13
|
+
|
14
|
+
have fun.
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'swiftly' #have a look at: http://github.com/pangdudu/swiftly/tree/master
|
3
|
+
require 'rofl' #sudo gem install pangdudu-rofl --source=http://gems.github.com
|
4
|
+
require 'robots' #sudo gem install pangdudu-robots --source=http://gems.github.com
|
5
|
+
require 'robots_xml'
|
6
|
+
|
7
|
+
#the RobotsXml module supplies nice methods for xml handling
|
8
|
+
#create xml messages like this: xml_msg = create_xml_msg { |b| b.body("test"); b.info("timestamp" => "#{Time.now}") }
|
9
|
+
#send them like this: send_msg xml_msg
|
10
|
+
#parse them like this: parse_xml_msg xml_msg,xpath
|
11
|
+
|
12
|
+
class SwiftAgent
|
13
|
+
include Swiftly
|
14
|
+
include Robots
|
15
|
+
include RobotsXml
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
ilog "SwiftAgent initialized"
|
19
|
+
end
|
20
|
+
|
21
|
+
#method that gets called when a new message arrives
|
22
|
+
def receive_msg msg
|
23
|
+
check_for_interests msg
|
24
|
+
end
|
25
|
+
|
26
|
+
#check if this msg interests us
|
27
|
+
def check_for_interests xml_msg
|
28
|
+
#message filter callback looks like this now
|
29
|
+
text = parse_xml_msg xml_msg,"//speak"
|
30
|
+
speak text.inner_text unless text.empty?
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
#start the app
|
36
|
+
sa = SwiftAgent.new
|
37
|
+
sa.release_robots #start the robot agent module
|
38
|
+
|
39
|
+
#build you own loop if you need one
|
40
|
+
loop do
|
41
|
+
sleep 1
|
42
|
+
#send an xml message over the system
|
43
|
+
sa.send_msg sa.create_xml_msg { |b| b.body("swift alive"); b.info("timestamp" => "#{Time.now}") }
|
44
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rofl' #sudo gem install pangdudu-rofl --source=http://gems.github.com
|
3
|
+
require 'robots' #sudo gem install pangdudu-robots --source=http://gems.github.com
|
4
|
+
require 'robots_xml'
|
5
|
+
|
6
|
+
#the RobotsXml module supplies nice methods for xml handling
|
7
|
+
#create xml messages like this: xml_msg = create_xml_msg { |b| b.body("test"); b.info("timestamp" => "#{Time.now}") }
|
8
|
+
#send them like this: send_msg xml_msg
|
9
|
+
#parse them like this: parse_xml_msg xml_msg,xpath
|
10
|
+
|
11
|
+
class TextGenerator
|
12
|
+
include Robots
|
13
|
+
include RobotsXml
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
ilog "TextGenerator initialized"
|
17
|
+
end
|
18
|
+
|
19
|
+
#method that gets called when a new message arrives
|
20
|
+
def receive_msg msg
|
21
|
+
end
|
22
|
+
|
23
|
+
#check if this msg interests us
|
24
|
+
def check_for_interests xml_msg
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
#start the app
|
30
|
+
tg = TextGenerator.new
|
31
|
+
tg.release_robots #start the robot agent module
|
32
|
+
|
33
|
+
#build you own loop if you need one
|
34
|
+
loop do
|
35
|
+
sleep 5
|
36
|
+
#send an xml message over the system
|
37
|
+
tg.send_msg tg.create_xml_msg { |b| b.speak("the robots say hello!"); b.info("timestamp" => "#{Time.now}") }
|
38
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pangdudu-robots
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- pangdudu
|
@@ -13,7 +13,7 @@ date: 2009-07-17 00:00:00 -07:00
|
|
13
13
|
default_executable: robots
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name: dbus
|
16
|
+
name: pangdudu-ruby-dbus
|
17
17
|
type: :runtime
|
18
18
|
version_requirement:
|
19
19
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -39,6 +39,11 @@ files:
|
|
39
39
|
- lib/robots_xml.rb
|
40
40
|
- lib/robots_prototype.rb
|
41
41
|
- config/org.robots.service.conf
|
42
|
+
- funky-examples/talking-swift-agent/README
|
43
|
+
- funky-examples/talking-swift-agent/talking_swift_agent.rb
|
44
|
+
- funky-examples/talking-swift-agent/text_generator.rb
|
45
|
+
- funky-examples/memory-agent/memory_agent.rb
|
46
|
+
- funky-examples/memory-agent/memory_generator_agent.rb
|
42
47
|
has_rdoc: true
|
43
48
|
homepage: http://github.com/pangdudu/robots
|
44
49
|
post_install_message:
|