randrews-toast 0.0.4

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/bin/toastconsole ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'rubygems'
4
+ gem 'toast'
5
+ require 'toast'
6
+
7
+ begin
8
+ bot_class=Toast::ConsoleUtils.get_bot_class_for_name(ARGV[0])
9
+ Toast::ConsoleChannel.run bot_class
10
+ rescue
11
+ puts $!.to_s
12
+ end
@@ -0,0 +1,83 @@
1
+ class HangmanResponder < Toast::Responder
2
+ attr_accessor :word
3
+ attr_accessor :solved_word
4
+ attr_accessor :alphabet
5
+ attr_accessor :body_parts
6
+
7
+ def say_wait msg ; say msg ; wait ; end
8
+
9
+ def respond msg
10
+ say 'Welcome to hangman!'
11
+ @alphabet='abcdefghijklmnopqrstuvwxyz'
12
+ @body_parts=6
13
+ @word=find_word
14
+ @solved_word='_'*word.length
15
+
16
+ say status_msg
17
+
18
+ while(@solved_word!=@word && @body_parts>0)
19
+ letter=get_letter
20
+
21
+ @alphabet[@alphabet.index(letter)]='_'
22
+
23
+ if @word.index(letter)
24
+ @word.split('').each_with_index do |l, i|
25
+ @solved_word[i]=letter if(l==letter)
26
+ end
27
+ else
28
+ @body_parts-= 1
29
+ say "Oops, the word doesn't contain the letter #{letter}"
30
+ end
31
+
32
+ say status_msg
33
+ end
34
+
35
+ if(@body_parts>0)
36
+ "Congratulations, you win! Send any message to play again."
37
+ else
38
+ "Sorry, you were hung. The word was #{@word}. Send any message to play again."
39
+ end
40
+ end
41
+
42
+ def get_letter
43
+ letter=say_wait "Choose a letter"
44
+ letter_good=false
45
+
46
+ loop do
47
+ letter=letter.downcase
48
+
49
+ unless letter=~/^[a-z]$/
50
+ letter=say_wait "That's not a letter, choose again"
51
+ next
52
+ end
53
+ unless @alphabet.index letter
54
+ letter=say_wait "You've already used that letter, choose again"
55
+ next
56
+ end
57
+
58
+ return letter
59
+ end
60
+ end
61
+
62
+ def find_word
63
+ max=(`wc -l /usr/share/dict/words`).split[0].to_i
64
+ line=rand(max)
65
+
66
+ word=nil
67
+ file=File.new('/usr/share/dict/words')
68
+
69
+ line.times do
70
+ word=file.gets
71
+ end
72
+
73
+ word.chomp
74
+ end
75
+
76
+ def status_msg
77
+ "#{@solved_word.split('').join(' ')}\n#{body_part_msg} remaining\n#{@alphabet.split('').join(' ')}"
78
+ end
79
+
80
+ def body_part_msg
81
+ @body_parts==1 ? "#{@body_parts} body part" : "#{@body_parts} body parts"
82
+ end
83
+ end
@@ -0,0 +1,12 @@
1
+ class SimpleResponder < Toast::Responder
2
+ def say_wait msg
3
+ say msg
4
+ wait
5
+ end
6
+
7
+ def respond first
8
+ second = say_wait "first is #{first}"
9
+ third = say_wait "second is #{second}"
10
+ "third is #{third}"
11
+ end
12
+ end
@@ -0,0 +1,6 @@
1
+ class WaitResponder < Toast::Responder
2
+ def respond msg
3
+ say "1: #{msg}"
4
+ "2: #{wait}"
5
+ end
6
+ end
data/lib/channel.rb ADDED
@@ -0,0 +1,31 @@
1
+ module Toast
2
+ class Channel
3
+ attr_accessor :responder_class
4
+ attr_accessor :responders
5
+
6
+ def initialize responder_class
7
+ @responder_class=responder_class
8
+ @responders={}
9
+ end
10
+
11
+ def handle msg
12
+ responder_for(msg.from).handle msg.text
13
+ end
14
+
15
+ def next_msg
16
+ Message.new("Override #{self.class.name}.next_msg",
17
+ 'nobody')
18
+ end
19
+
20
+ def responder_for from
21
+ unless @responders[from]
22
+ @responders[from]= @responder_class.new self, from
23
+ end
24
+ @responders[from]
25
+ end
26
+
27
+ def send msg, to
28
+ puts "#{to}: #{msg.text}"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,96 @@
1
+ module Toast
2
+ class ConsoleChannel < Channel
3
+ def initialize responder_class
4
+ super responder_class
5
+ @hear_commands=true
6
+ @exit_now=false
7
+ end
8
+
9
+ def send msg, to
10
+ puts ""
11
+ puts msg unless msg.nil?
12
+ end
13
+
14
+ def next_line
15
+ line = Readline::readline('> ')
16
+ return nil unless line
17
+ Readline::HISTORY.push(line)
18
+ line
19
+ end
20
+
21
+ def self.run responder_class
22
+ channel=ConsoleChannel.new responder_class
23
+ channel.run
24
+ end
25
+
26
+ def run
27
+ send "Type .exit or ctrl-D to leave",""
28
+ loop do
29
+ msg=next_line
30
+ break unless msg
31
+ handle_line msg
32
+ break if @exit_now
33
+ end
34
+ send nil,nil
35
+ end
36
+
37
+ def handle_line line
38
+ if (line[0,1]=='.' && @hear_commands) ||
39
+ line=~/\.commands\s+on/
40
+
41
+ result=special_cmd line
42
+ return if @exit_now
43
+ send result,'' if result
44
+
45
+ else
46
+ handle Toast::Message.new(line,'console@localhost')
47
+ end
48
+ end
49
+
50
+ def special_cmd cmd
51
+ if cmd=='.exit'
52
+ @exit_now=true
53
+ return nil
54
+
55
+ elsif cmd=~/^\.srand\s+([0-9]+)/
56
+ srand $1.to_i
57
+ return "Random seed is #{$1}"
58
+
59
+ elsif cmd=~/^\.commands\s+(on|off)/
60
+ @hear_commands=($1=='on')
61
+ return "Commands are #{$1}"
62
+
63
+ elsif cmd=~/^.script\s+(\S+)/
64
+ old_dir=@current_dir
65
+
66
+ file=$1
67
+ unless file=~/^\// # if it's a relative path, then tack @current_dir on
68
+ file=File.expand_path(@current_dir+"/"+file)
69
+ end
70
+
71
+ @current_dir=File.dirname(file)
72
+
73
+ File.new(file).each do |line|
74
+ handle_line line.strip unless line.blank? || line=~/^\s*#/
75
+ break if @exit_now
76
+ end
77
+
78
+ @current_dir=old_dir
79
+ return nil
80
+
81
+ elsif cmd=~/^.send\s+(.*)/
82
+ args=$1.strip.split(/\s+/)
83
+ fn=args.shift.to_sym
84
+ begin
85
+ response=responder_for('console@localhost').send(fn, *args)
86
+ rescue
87
+ response=$!.to_s
88
+ end
89
+ return response
90
+ end
91
+
92
+ return "Bad command #{cmd}"
93
+ end
94
+
95
+ end
96
+ end
@@ -0,0 +1,52 @@
1
+ module Toast
2
+ module ConsoleUtils
3
+ def self.get_bot_class_for_name bot_name=nil
4
+
5
+ # If it's nil, show a menu for .
6
+ if bot_name.nil?
7
+ file=show_menu_for_directory '.'
8
+ load file
9
+ return class_for_file_name(file)
10
+ end
11
+
12
+ # If it's a file, then we just use it
13
+ if File.file? bot_name
14
+ load bot_name
15
+ return class_for_file_name(bot_name)
16
+ end
17
+
18
+ # if it's not a .rb file, but is present, it's a directory
19
+ if File.directory? bot_name
20
+ file=show_menu_for_directory(bot_name)
21
+ load file
22
+ return class_for_file_name(file)
23
+ end
24
+
25
+ raise "Can't find #{bot_name}"
26
+ end
27
+
28
+ def self.show_menu_for_directory path
29
+ n=0
30
+ Dir.glob("#{path}/*.rb").each do |file|
31
+ n+=1
32
+ name=File.basename(file,'.rb')
33
+ puts "- #{name}"
34
+ Readline::HISTORY.push(name)
35
+ end
36
+
37
+ if n==0
38
+ path="current directory" if path=='.'
39
+ raise "No .rb files found in #{path}"
40
+ end
41
+
42
+ bot_name=Readline::readline('Which bot: ')
43
+ n.times {Readline::HISTORY.shift}
44
+
45
+ return "#{path}/#{bot_name}.rb"
46
+ end
47
+
48
+ def self.class_for_file_name file
49
+ File.basename(file,'.rb').classify.constantize
50
+ end
51
+ end
52
+ end
data/lib/cont.rb ADDED
@@ -0,0 +1,14 @@
1
+ ##################################################
2
+ ### Pipe: read from stdin, write to stdout #######
3
+ ##################################################
4
+
5
+ # class StdChannel < Channel
6
+ # def initialize responder_class
7
+ # super responder_class
8
+ # end
9
+ #
10
+ # def send msg, to
11
+ # puts StdChannel.escape(to)
12
+ # puts StdChannel.escape(msg)
13
+ # end
14
+ # end
data/lib/responder.rb ADDED
@@ -0,0 +1,43 @@
1
+ module Toast
2
+ class Responder
3
+ attr_accessor :from
4
+
5
+ def initialize channel, from
6
+ @channel=channel
7
+ @from=from
8
+ end
9
+
10
+ def handle msg
11
+ callcc do |back_to_channel|
12
+ @back_to_channel = back_to_channel
13
+
14
+ if @leftoff
15
+ @leftoff.call(msg)
16
+ else
17
+ response=respond(msg)
18
+ say response unless response.nil?
19
+ @leftoff=nil
20
+ @back_to_channel.call
21
+ end
22
+ end
23
+ end
24
+
25
+ ### Override me to handle messages!
26
+ def respond msg
27
+ say "Override #{self.class.name}.respond to have your bot do something."
28
+ nil
29
+ end
30
+
31
+ def wait
32
+ callcc do |cc|
33
+ @leftoff=cc
34
+ @back_to_channel.call
35
+ end
36
+ end
37
+
38
+ def say msg
39
+ @channel.send msg, @from
40
+ nil
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,20 @@
1
+ module Toast
2
+ class TestChannel < Channel
3
+ attr_accessor :output
4
+
5
+ def initialize responder_class
6
+ super responder_class
7
+ self.output=[]
8
+ end
9
+
10
+ def send msg,to
11
+ @output << Message.new(msg,to)
12
+ end
13
+
14
+ def run script
15
+ script.each do |text|
16
+ handle Message.new(text,'test@localhost')
17
+ end
18
+ end
19
+ end
20
+ end
data/lib/toast.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require 'readline'
4
+
5
+ Dir.glob("#{File.dirname(__FILE__)}/**/*.rb").each do |file|
6
+ require file
7
+ end
data/lib/util.rb ADDED
@@ -0,0 +1,35 @@
1
+ module Toast
2
+ Message = Struct.new(:text, :from)
3
+
4
+ class Message
5
+ def to_s ; @text ; end
6
+ end
7
+ end
8
+
9
+ class String
10
+ def escape
11
+ gsub("\\","\\\\").gsub("\n","\\n")
12
+ end
13
+
14
+ def unescape
15
+ gsub("\\n","\n").gsub("\\\\","\\")
16
+ end
17
+ end
18
+
19
+ class Symbol
20
+ def to_proc
21
+ Proc.new {|_| _.send self}
22
+ end
23
+ end
24
+
25
+ def delete_emacs_temp dir="."
26
+ Dir.glob(dir+"/*").each do |file|
27
+ if File.directory? file
28
+ delete_emacs_temp file
29
+ end
30
+ if file=~/~$/
31
+ puts "deleting #{file}"
32
+ File.delete file
33
+ end
34
+ end
35
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: randrews-toast
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Ross Andrews
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-27 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.1.0
24
+ version:
25
+ description: A framework for making Jabber bots
26
+ email: randrews@geekfu.org
27
+ executables:
28
+ - toastconsole
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - lib/channel.rb
35
+ - lib/console_channel.rb
36
+ - lib/console_utils.rb
37
+ - lib/cont.rb
38
+ - lib/responder.rb
39
+ - lib/test_channel.rb
40
+ - lib/toast.rb
41
+ - lib/util.rb
42
+ - bin/toastconsole
43
+ - example/hangman_responder.rb
44
+ - example/simple_responder.rb
45
+ - example/wait_responder.rb
46
+ has_rdoc: false
47
+ homepage: http://toastwiki.yellownote.info
48
+ licenses:
49
+ post_install_message:
50
+ rdoc_options: []
51
+
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.3.5
70
+ signing_key:
71
+ specification_version: 2
72
+ summary: A framework for making Jabber bots
73
+ test_files: []
74
+