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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9c2bed6ab0bed5b885e19baf626242cdc70a7b57
4
- data.tar.gz: b0e92d4d149ff726d58f91f9bf189e9a96cbf89e
3
+ metadata.gz: dbf7aed643189ede40b31e8d9c16ac1640371ed7
4
+ data.tar.gz: 7d57eadbc324c28c5887b6b7180fe99919051ac7
5
5
  SHA512:
6
- metadata.gz: 55cd5aaa1b42b657b52cdc765d56872c6fdf02b030060bfb17bf0e48068670db9ae72ec8629ef85cbce17d615bb69cf2c1fbdb19673e27d06ff275539b54f916
7
- data.tar.gz: 146947b211fc0c85790a3bf27ece618ad2e6b37eb4eb37d54313678455cf9bc35fdf3b675c5525da26afc857049694051e8b2f78fbc0ed295ae4fc65ed41e86b
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 generates Markov chain databases
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 generate_sentence_for(user, length = 30)
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 = [first_word, second_word]
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
- # Stop if we failed to find a next state
128
- break if next_state.nil?
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
- ended_with_punctuation = true
134
- break
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
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "lita-markov"
3
- spec.version = "1.1.2"
3
+ spec.version = "1.2.0"
4
4
  spec.authors = ["Dirk Gadsden"]
5
5
  spec.email = ["dirk@dirk.to"]
6
6
  spec.description = "Markov chains for Lita."
@@ -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 world!'
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 me.'
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 character.'
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,').count).to eql 1
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: '!').count).to eql 1
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,', next_state: 'fun').get(:frequency)).to eql 2
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 eql 'Hello cruel world.'
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 include replies[0]
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.1.2
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-24 00:00:00.000000000 Z
11
+ date: 2015-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lita