colloquy 1.0.0
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 +15 -0
- data/README.md +160 -0
- data/TODO.md +256 -0
- data/bin/colloquy +14 -0
- data/examples/config/flows.yaml +22 -0
- data/examples/config/logger.yaml +2 -0
- data/examples/config/messages.yaml +3 -0
- data/examples/config/mysql.yaml +18 -0
- data/examples/config/redis.yaml +9 -0
- data/examples/config/scribe.yaml +2 -0
- data/examples/config/settings.yaml +2 -0
- data/examples/config/test.yaml +8 -0
- data/examples/config/urls.yaml +18 -0
- data/examples/flows/active_record_flow.rb +42 -0
- data/examples/flows/art_of_war_flow.rb +27 -0
- data/examples/flows/calculator_flow.rb +71 -0
- data/examples/flows/crossover_flow.rb +17 -0
- data/examples/flows/database_flow.rb +33 -0
- data/examples/flows/hangman_flow.rb +82 -0
- data/examples/flows/metadata_flow.rb +11 -0
- data/examples/flows/pagination_flow.rb +23 -0
- data/examples/flows/pass_flow.rb +29 -0
- data/examples/flows/prefix_menu_flow.rb +24 -0
- data/examples/flows/scribe_flow.rb +26 -0
- data/examples/flows/settings_flow.rb +23 -0
- data/examples/flows/special/special_redis_flow.rb +28 -0
- data/examples/flows/url_flow.rb +27 -0
- data/examples/log/renderer.log +198381 -0
- data/examples/log/urls.log +3269 -0
- data/examples/messages/active_record.yaml +2 -0
- data/examples/messages/art_of_war.yaml +1 -0
- data/examples/messages/calculator.yaml +2 -0
- data/examples/messages/database.yaml +1 -0
- data/examples/messages/hangman.yaml +0 -0
- data/examples/messages/prefix_menu.yaml +3 -0
- data/examples/models/activations.rb +5 -0
- data/lib/colloquy.rb +39 -0
- data/lib/colloquy/exceptions.rb +64 -0
- data/lib/colloquy/flow_parser.rb +315 -0
- data/lib/colloquy/flow_pool.rb +21 -0
- data/lib/colloquy/helpers.rb +15 -0
- data/lib/colloquy/helpers/mysql.rb +110 -0
- data/lib/colloquy/helpers/redis.rb +103 -0
- data/lib/colloquy/helpers/scribe.rb +103 -0
- data/lib/colloquy/helpers/settings.rb +111 -0
- data/lib/colloquy/helpers/url.rb +10 -0
- data/lib/colloquy/input.rb +14 -0
- data/lib/colloquy/logger.rb +11 -0
- data/lib/colloquy/menu.rb +128 -0
- data/lib/colloquy/message_builder.rb +54 -0
- data/lib/colloquy/node.rb +67 -0
- data/lib/colloquy/paginator.rb +59 -0
- data/lib/colloquy/paginator/menu.rb +79 -0
- data/lib/colloquy/paginator/prompt.rb +32 -0
- data/lib/colloquy/prompt.rb +35 -0
- data/lib/colloquy/renderer.rb +423 -0
- data/lib/colloquy/response.rb +4 -0
- data/lib/colloquy/runner.rb +93 -0
- data/lib/colloquy/server.rb +157 -0
- data/lib/colloquy/session_store.rb +46 -0
- data/lib/colloquy/session_store/memory.rb +14 -0
- data/lib/colloquy/session_store/redis.rb +24 -0
- data/lib/colloquy/simulator.rb +114 -0
- data/lib/colloquy/spec_helpers.rb +21 -0
- metadata +459 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
testing:
|
2
|
+
host: 'localhost'
|
3
|
+
username: 'root'
|
4
|
+
password: ''
|
5
|
+
reconnect: true
|
6
|
+
database: 'activations'
|
7
|
+
encoding: 'utf8'
|
8
|
+
adapter: 'em_mysql2'
|
9
|
+
|
10
|
+
customer:
|
11
|
+
host: 'localhost'
|
12
|
+
username: 'root'
|
13
|
+
password: ''
|
14
|
+
reconnect: true
|
15
|
+
database: 'activations'
|
16
|
+
encoding: 'utf8'
|
17
|
+
adapter: 'em_mysql2'
|
18
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
log_cancellations:
|
2
|
+
active: http://google.com/?q=hello
|
3
|
+
backup: http://www.google.com/search?q=%%msisdn%%
|
4
|
+
|
5
|
+
pinger:
|
6
|
+
log_cancellations:
|
7
|
+
verb: get
|
8
|
+
params:
|
9
|
+
msisdn: 9745044399
|
10
|
+
tick: 5
|
11
|
+
|
12
|
+
timeouts:
|
13
|
+
connection: 2
|
14
|
+
inactivity: 5
|
15
|
+
|
16
|
+
logger:
|
17
|
+
log_level: debug
|
18
|
+
path: log/urls.log
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
require_relative '../models/activations'
|
5
|
+
|
6
|
+
class ActiveRecordFlow
|
7
|
+
include Colloquy::FlowParser
|
8
|
+
|
9
|
+
index {
|
10
|
+
request {
|
11
|
+
menu << :activate << :cancel
|
12
|
+
}
|
13
|
+
|
14
|
+
process { |input|
|
15
|
+
case menu.key(input)
|
16
|
+
when :activate
|
17
|
+
privileged_user = true
|
18
|
+
if privileged_user
|
19
|
+
if count = activate(headers[:msisdn])
|
20
|
+
notify [:activation_success, :count => count]
|
21
|
+
else
|
22
|
+
notify :activation_failure
|
23
|
+
end
|
24
|
+
else
|
25
|
+
notify :priveleges_required
|
26
|
+
end
|
27
|
+
when :cancel
|
28
|
+
url.call(:log_cancellations, { :msisdn => headers[:msisdn] })
|
29
|
+
notify :canceled
|
30
|
+
end
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
def setup
|
35
|
+
::Activation.establish_connection(mysql.configuration[:customer])
|
36
|
+
end
|
37
|
+
|
38
|
+
def activate(msisdn)
|
39
|
+
logger.info "Activating #{msisdn}!"
|
40
|
+
count = Activation.count
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
class ArtOfWarFlow
|
3
|
+
include Colloquy::FlowParser
|
4
|
+
|
5
|
+
index {
|
6
|
+
request {
|
7
|
+
session[:hello] = "yellow!"
|
8
|
+
menu.push(
|
9
|
+
:calculator, # to test a swtich
|
10
|
+
:special_redis,
|
11
|
+
:estimates, :waging_war, :offensive_strategy, :dispositions, :energy,
|
12
|
+
:weaknesses_and_strengths, :manoeuvre, :nine_variables, :marches,
|
13
|
+
:terrain, :the_nine_varieties_of_ground, :attack_by_fire,
|
14
|
+
:employment_of_secret_agents
|
15
|
+
)
|
16
|
+
}
|
17
|
+
|
18
|
+
process { |input|
|
19
|
+
session[:hello] = "world"
|
20
|
+
switch :index, :flow => :calculator if menu.key(input) == :calculator
|
21
|
+
switch :index, :flow => :special_redis if menu.key(input) == :special_redis
|
22
|
+
switch :index, :flow => :unknown if menu.key(input) == :offensive_strategy
|
23
|
+
|
24
|
+
notify "#{menu.key(input)}_notification".to_sym
|
25
|
+
}
|
26
|
+
}
|
27
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
|
2
|
+
class CalculatorFlow
|
3
|
+
|
4
|
+
include Colloquy::FlowParser
|
5
|
+
|
6
|
+
index {
|
7
|
+
request {
|
8
|
+
menu << "Add" << "Subtract" << "Back"
|
9
|
+
}
|
10
|
+
|
11
|
+
process { |input|
|
12
|
+
session[:operation] = case menu.key(input)
|
13
|
+
when "Add"
|
14
|
+
:add
|
15
|
+
when "Subtract"
|
16
|
+
:subtract
|
17
|
+
when "Back"
|
18
|
+
switch :back
|
19
|
+
else
|
20
|
+
notify :operation_invalid
|
21
|
+
end
|
22
|
+
|
23
|
+
switch :number_first
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
number_first {
|
28
|
+
request {
|
29
|
+
prompt "Enter the first number:"
|
30
|
+
}
|
31
|
+
|
32
|
+
process { |input|
|
33
|
+
if valid_input? input
|
34
|
+
session[:first_number] = input.to_i
|
35
|
+
switch :number_second
|
36
|
+
else
|
37
|
+
notify :number_invalid
|
38
|
+
end
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
number_second {
|
43
|
+
request {
|
44
|
+
prompt "Enter the second number:"
|
45
|
+
}
|
46
|
+
|
47
|
+
process { |number|
|
48
|
+
if valid_input? number
|
49
|
+
value = calculate(session[:operation], session[:first_number], number.to_i)
|
50
|
+
notify "The result is: #{value}"
|
51
|
+
end
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
def calculate(operation, first_number, second_number)
|
56
|
+
case operation
|
57
|
+
when :add
|
58
|
+
first_number + second_number
|
59
|
+
when :subtract
|
60
|
+
first_number - second_number
|
61
|
+
else
|
62
|
+
logger.error "Got an unexpected operation."
|
63
|
+
notify :error
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def valid_input?(number)
|
68
|
+
"#{number.to_i}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
class CrossoverFlow
|
3
|
+
|
4
|
+
include Colloquy::FlowParser
|
5
|
+
|
6
|
+
index {
|
7
|
+
request { |input|
|
8
|
+
session[:calculator_type] = (input == "1") ? :scientific : :normal
|
9
|
+
pass
|
10
|
+
}
|
11
|
+
|
12
|
+
process { |input|
|
13
|
+
switch :index, :flow => :calculator
|
14
|
+
}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
class DatabaseFlow
|
3
|
+
include Colloquy::FlowParser
|
4
|
+
|
5
|
+
index {
|
6
|
+
request {
|
7
|
+
menu << :activate << :cancel
|
8
|
+
}
|
9
|
+
|
10
|
+
process { |input|
|
11
|
+
case menu.key(input)
|
12
|
+
when :activate
|
13
|
+
privileged_user = mysql[:customer].query("select sleep(0.25);")
|
14
|
+
if privileged_user
|
15
|
+
if activate(headers[:msisdn])
|
16
|
+
notify :activation_success
|
17
|
+
else
|
18
|
+
notify :activation_failure
|
19
|
+
end
|
20
|
+
else
|
21
|
+
notify :priveleges_required
|
22
|
+
end
|
23
|
+
when :cancel
|
24
|
+
url.call(:log_cancellations, { :msisdn => headers[:msisdn] })
|
25
|
+
notify :canceled
|
26
|
+
end
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
def activate(msisdn)
|
31
|
+
logger.info "Activating #{msisdn}!"
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'random_word_generator'
|
2
|
+
require 'active_support/inflector'
|
3
|
+
|
4
|
+
class HangmanFlow
|
5
|
+
|
6
|
+
include Colloquy::FlowParser
|
7
|
+
NUMBER_CRYPTEX = "22233344455566677778889999"
|
8
|
+
|
9
|
+
index {
|
10
|
+
request {
|
11
|
+
prompt "Hangman..Ready to die? No escape now!\n" +
|
12
|
+
"Enter any key to start."
|
13
|
+
}
|
14
|
+
|
15
|
+
process { |input|
|
16
|
+
session[:secret] = RandomWordGenerator.word
|
17
|
+
session[:lives] = 9
|
18
|
+
session[:used_letters] = "0"
|
19
|
+
session[:message] = ""
|
20
|
+
|
21
|
+
switch :game_logic
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
game_logic {
|
26
|
+
request {
|
27
|
+
notify "#{session[:secret]}\n You WIN!" if session[:secret] == word_with_user_input
|
28
|
+
notify "You LOSE. The word was #{session[:secret]}" if session[:lives] == 0
|
29
|
+
|
30
|
+
prompt "#{session[:message]}\n #{word_with_user_input} \n" +
|
31
|
+
"You have #{session[:lives]} #{pluralize(session[:lives], 'life')} left.\n" +
|
32
|
+
"Enter letter (A=>2,B=>22,C=>222,D=>3). Enter 0 to quit."
|
33
|
+
}
|
34
|
+
|
35
|
+
process { |input|
|
36
|
+
notify "Exiting application.." if input == "0"
|
37
|
+
|
38
|
+
if valid_input? input
|
39
|
+
letter_entered = translate_letter_code(input)
|
40
|
+
if session[:used_letters].include? letter_entered
|
41
|
+
session[:message] = "You already entered this letter."
|
42
|
+
else
|
43
|
+
session[:used_letters] << letter_entered
|
44
|
+
if session[:secret].include? letter_entered
|
45
|
+
session[:message] = "You entered #{letter_entered}. Aha! Good guess."
|
46
|
+
else
|
47
|
+
session[:lives] -= 1
|
48
|
+
session[:message] = "You entered #{letter_entered}. Bad luck!"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
else
|
52
|
+
session[:message] = "Invalid letter code."
|
53
|
+
end
|
54
|
+
switch :game_logic
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
|
59
|
+
def valid_input?(number)
|
60
|
+
if number.length <= 4 && ["7","9"].include?(number.squeeze)
|
61
|
+
return true
|
62
|
+
elsif number.length <= 3 && ["2","3","4","5","6","8"].include?(number.squeeze)
|
63
|
+
return true
|
64
|
+
else
|
65
|
+
return false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def translate_letter_code(letter_code)
|
70
|
+
("a".."z").to_a[NUMBER_CRYPTEX.index(letter_code) + letter_code.length - 1]
|
71
|
+
end
|
72
|
+
|
73
|
+
def word_with_user_input
|
74
|
+
regex = Regexp.new("[^#{session[:used_letters]}]")
|
75
|
+
session[:secret].gsub(regex,'-')
|
76
|
+
end
|
77
|
+
|
78
|
+
def pluralize(number, text)
|
79
|
+
return text.pluralize if number != 1
|
80
|
+
text
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
class PaginationFlow
|
3
|
+
|
4
|
+
include Colloquy::FlowParser
|
5
|
+
|
6
|
+
index {
|
7
|
+
request {
|
8
|
+
menu.prefix {
|
9
|
+
if headers[:page] == 1
|
10
|
+
"Welcome to Some new application. Please choose from one of the packs below to get latest news from Some new application"
|
11
|
+
end
|
12
|
+
}
|
13
|
+
1.upto(10).each do |item|
|
14
|
+
menu << "Pack #{item}"
|
15
|
+
end
|
16
|
+
}
|
17
|
+
|
18
|
+
process { |input|
|
19
|
+
|
20
|
+
}
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
class PassFlow
|
3
|
+
include Colloquy::FlowParser
|
4
|
+
|
5
|
+
index {
|
6
|
+
request { |input|
|
7
|
+
pass unless input.blank?
|
8
|
+
menu << :activate << :cancel
|
9
|
+
}
|
10
|
+
|
11
|
+
process { |input|
|
12
|
+
notify :direct if input.direct?
|
13
|
+
|
14
|
+
case menu.key(input)
|
15
|
+
when :activate
|
16
|
+
notify :activation_success
|
17
|
+
when :cancel
|
18
|
+
cancelation = url[:log_cancellations].call(:msisdn => headers[:msisdn])
|
19
|
+
notify cancelation.response
|
20
|
+
else
|
21
|
+
notif "Hello World!" #Deliberate error!
|
22
|
+
end
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
def activate
|
27
|
+
logger.info "Activating!"
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
class PrefixMenuFlow
|
3
|
+
include Colloquy::FlowParser
|
4
|
+
|
5
|
+
index {
|
6
|
+
request { |input|
|
7
|
+
menu.push(headers[:msisdn])
|
8
|
+
menu.push(*('a'..'z').to_a)
|
9
|
+
menu.prefix { "Hello #{headers[:session_id]}" }
|
10
|
+
menu.suffix do
|
11
|
+
logger.info "Headers: #{headers.inspect}"
|
12
|
+
"Your world is my oyster! And there's nothing better than beer! Or a touch of lemonade." if headers[:page] == 1
|
13
|
+
end
|
14
|
+
|
15
|
+
menu.before_page do
|
16
|
+
session[:wonker] = "Page: #{headers[:page]}"
|
17
|
+
end
|
18
|
+
}
|
19
|
+
|
20
|
+
process { |input|
|
21
|
+
notify menu.key(input)
|
22
|
+
}
|
23
|
+
}
|
24
|
+
end
|