lita-markov 1.1.2 → 1.2.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 +4 -4
- data/README.md +4 -2
- data/lib/lita/handlers/markov/engine.rb +42 -6
- data/lita-markov.gemspec +1 -1
- data/spec/lita/handlers/markov/engine_spec.rb +10 -10
- data/spec/lita/handlers/markov_spec.rb +4 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dbf7aed643189ede40b31e8d9c16ac1640371ed7
|
4
|
+
data.tar.gz: 7d57eadbc324c28c5887b6b7180fe99919051ac7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9775fc10de2164232bc389b44d95d5a7fb0a0e51b70781a382a934f02bc80bf04eac6774a7771edd93a3548d37d80f9b0502e9bbd6f200c996fd93f329b436c8
|
7
|
+
data.tar.gz: 563215674afaf190dac06aafbbf63f4d8208880884d0f5dd0cea867e17d48b984840d2447f0197132c46430ec26359c8ed84be7a83ac3eeb8549f920d58c903e
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
# Markov chains for Lita
|
1
|
+
# Markov chains for [Lita](https://www.lita.io/)
|
2
2
|
|
3
|
-
Listens to your public chat rooms and
|
3
|
+
Listens to your public chat rooms and creates Markov chain databases
|
4
4
|
for each user.
|
5
5
|
|
6
6
|
## Installation
|
@@ -18,6 +18,8 @@ communicating with databases):
|
|
18
18
|
```ruby
|
19
19
|
# lita_config.rb
|
20
20
|
Lita.configure do |config|
|
21
|
+
# For example, using Heroku and their Postgresql addon, the database can be
|
22
|
+
# configured by simply doing:
|
21
23
|
config.handlers.markov.database_url = ENV['DATABASE_URL']
|
22
24
|
end
|
23
25
|
```
|
@@ -105,6 +105,19 @@ class Lita::Handlers::Markov
|
|
105
105
|
.select(:next_state, :frequency)
|
106
106
|
.all
|
107
107
|
|
108
|
+
sample_states(states)
|
109
|
+
end
|
110
|
+
|
111
|
+
def get_random_next_state(user)
|
112
|
+
states = @db[:dictionary]
|
113
|
+
.where(user: user)
|
114
|
+
.select(:next_state, :frequency)
|
115
|
+
.all
|
116
|
+
|
117
|
+
sample_states states
|
118
|
+
end
|
119
|
+
|
120
|
+
def sample_states(states)
|
108
121
|
distribution = states.flat_map do |state|
|
109
122
|
Array.new(state[:frequency]) { state[:next_state] }
|
110
123
|
end
|
@@ -112,26 +125,49 @@ class Lita::Handlers::Markov
|
|
112
125
|
distribution.sample
|
113
126
|
end
|
114
127
|
|
115
|
-
def
|
128
|
+
def start_new_sentence(user, sentence)
|
116
129
|
first_word = random_capitalized_word user
|
117
130
|
second_word = random_second_word user, first_word
|
118
131
|
|
119
|
-
sentence
|
132
|
+
sentence << first_word
|
133
|
+
sentence << second_word
|
134
|
+
end
|
135
|
+
|
136
|
+
def generate_sentence_for(user, length = 30)
|
137
|
+
sentence = []
|
120
138
|
ended_with_punctuation = false
|
121
139
|
|
140
|
+
start_new_sentence user, sentence
|
141
|
+
|
122
142
|
while sentence.length < length
|
123
143
|
current_state = sentence.slice(sentence.length - @depth, @depth).join ' '
|
124
144
|
|
125
145
|
next_state = get_next_state user, current_state
|
126
146
|
|
127
|
-
|
128
|
-
|
147
|
+
if next_state.nil?
|
148
|
+
if sentence.length > (length / 2)
|
149
|
+
# Stop if we failed to find a next state and it's long enough
|
150
|
+
break
|
151
|
+
else
|
152
|
+
# Otherwise pick a completely random next-state from the user
|
153
|
+
# for the lols
|
154
|
+
next_state = get_random_next_state user
|
155
|
+
end
|
156
|
+
end
|
129
157
|
|
130
158
|
sentence << next_state
|
131
159
|
|
132
160
|
if next_state == '.'
|
133
|
-
|
134
|
-
|
161
|
+
if sentence.length > (length / 2)
|
162
|
+
# If it's long enough then we can end on a period
|
163
|
+
ended_with_punctuation = true
|
164
|
+
break
|
165
|
+
else
|
166
|
+
# Otherwise append a period and start a fresh sentence
|
167
|
+
last = sentence.pop
|
168
|
+
sentence.push(sentence.pop + last)
|
169
|
+
start_new_sentence user, sentence
|
170
|
+
end
|
135
171
|
end
|
136
172
|
end
|
137
173
|
|
data/lita-markov.gemspec
CHANGED
@@ -7,27 +7,27 @@ describe Lita::Handlers::Markov::Engine do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it 'will sanitize links from a message' do
|
10
|
-
message = 'hello https://www.example.com world
|
10
|
+
message = 'hello https://www.example.com world'
|
11
11
|
|
12
|
-
expect(subject.sanitize_string(message)).to eql 'hello
|
12
|
+
expect(subject.sanitize_string(message)).to eql 'hello world'
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'will remove code blocks from a message' do
|
16
16
|
message = 'I have `code in` me.'
|
17
17
|
|
18
|
-
expect(subject.sanitize_string(message)).to eql 'I have
|
18
|
+
expect(subject.sanitize_string(message)).to eql 'I have me'
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'will remove illegal characters from a message' do
|
22
22
|
message = 'I have a bad % character.'
|
23
23
|
|
24
|
-
expect(subject.sanitize_string(message)).to eql 'I have a bad
|
24
|
+
expect(subject.sanitize_string(message)).to eql 'I have a bad character'
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'will separate a string into words' do
|
28
|
-
string = "I am\n so totally\tseparated
|
28
|
+
string = "I am\n so totally\tseparated"
|
29
29
|
|
30
|
-
expect(subject.separate_string(string)).to eql ['I', 'am', 'so', 'totally', 'separated'
|
30
|
+
expect(subject.separate_string(string)).to eql ['I', 'am', 'so', 'totally', 'separated']
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'will ingest messages' do
|
@@ -36,19 +36,19 @@ describe Lita::Handlers::Markov::Engine do
|
|
36
36
|
subject.ingest('user', 'hello big, fun world!')
|
37
37
|
|
38
38
|
# Check that the first state made it in and is capitalized
|
39
|
-
expect(dictionary.where(current_state: 'Hello big
|
39
|
+
expect(dictionary.where(current_state: 'Hello big').count).to eql 1
|
40
40
|
# Check that the last state made it in
|
41
|
-
expect(dictionary.where(current_state: 'fun world', next_state: '
|
41
|
+
expect(dictionary.where(current_state: 'fun world', next_state: '.').count).to eql 1
|
42
42
|
|
43
43
|
subject.ingest('user', 'Hello big, fun planet!')
|
44
44
|
|
45
45
|
# Check that the frequency of the "Hello big," -> "fun" state went up
|
46
|
-
expect(dictionary.where(current_state: 'Hello big
|
46
|
+
expect(dictionary.where(current_state: 'Hello big', next_state: 'fun').get(:frequency)).to eql 2
|
47
47
|
end
|
48
48
|
|
49
49
|
it 'will generate a sentence' do
|
50
50
|
subject.ingest('user', 'Hello cruel world.')
|
51
51
|
|
52
|
-
expect(subject.generate_sentence_for 'user').to
|
52
|
+
expect(subject.generate_sentence_for 'user').to include 'Hello cruel world.'
|
53
53
|
end
|
54
54
|
end
|
@@ -21,11 +21,12 @@ describe Lita::Handlers::Markov, lita_handler: true do
|
|
21
21
|
|
22
22
|
expect(replies.count).to eql 1
|
23
23
|
|
24
|
+
reply = replies[0]
|
24
25
|
possible_replies = [
|
25
|
-
'I love cookies
|
26
|
-
'I love pancakes
|
26
|
+
'I love cookies.',
|
27
|
+
'I love pancakes.'
|
27
28
|
]
|
28
|
-
expect(possible_replies).to
|
29
|
+
expect(possible_replies.any? { |r| reply.include?(r) }).to eql true
|
29
30
|
end
|
30
31
|
|
31
32
|
it "will complain if the user hasn't said anything" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lita-markov
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dirk Gadsden
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lita
|