lita-markov 0.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 80906c8495bb1dcbbc33b970047390e606b429c8
4
+ data.tar.gz: 85f84a17b45289e6c86334318322eebba6724b8f
5
+ SHA512:
6
+ metadata.gz: f7c18adeba628b7e6cc48a22922fd745595104ce6846c919b773ab475e7c22b4d2e852d747055adadaec74b0dc881cab36254b305ab4c2df179c6a77e1b118e3
7
+ data.tar.gz: e4fce6fb0f3d70d04d2153fb202d1740c223abadc475a18a6629ba5080f211219dc58a0817bd36d58d6529801b8da7a2eaeb700585b7bb69d7ff1c20daf45145
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ Gemfile.lock
2
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2015 Dirk Gadsden
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ * Neither the name of Roost nor the names of its contributors may be used to
15
+ endorse or promote products derived from this software without specific
16
+ prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # Markov chains for Lita
2
+
3
+ Listens to your public chat rooms and generates Markov chain databases
4
+ for each user.
5
+
6
+ ## Installation
7
+
8
+ Add `lita-markov` to your Lita instance's Gemfile:
9
+
10
+ ``` ruby
11
+ gem 'lita-markov'
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ The bot will automatically ingest all messages into the Redis-backed Markov
17
+ chain database. You can then query the bot for a generated chain:
18
+
19
+ ```
20
+ user> mybot markov dirk
21
+ mybot> I love cookies!
22
+ ```
23
+
24
+ ## License
25
+
26
+ Licensed under the 3-clause BSD license. See [LICENSE](LICENSE) for details.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,13 @@
1
+ require "lita"
2
+
3
+ Lita.load_locales Dir[File.expand_path(
4
+ File.join("..", "..", "locales", "*.yml"), __FILE__
5
+ )]
6
+
7
+ require 'marky_markov/persistent_json_dictionary'
8
+ require 'lita/handlers/markov'
9
+
10
+ # Lita::Handlers::Markov.template_root File.expand_path(
11
+ # File.join("..", "..", "templates"),
12
+ # __FILE__
13
+ # )
@@ -0,0 +1,64 @@
1
+ module Lita::Handlers
2
+ class Markov < Lita::Handler
3
+ Dictionary = MarkyMarkov::PersistentJSONDictionary
4
+
5
+ REDIS_KEY_PREFIX = 'lita-markov:'
6
+
7
+ route(/.+/, :ingest, command: false)
8
+
9
+ route(/markov (.+)/, :generate, command: true, help: {
10
+ 'markov USER' => 'Generate a markov chain from the given user.'
11
+ })
12
+
13
+ def ingest(chat)
14
+ # Don't ingest messages addressed to ourselves
15
+ return if chat.command?
16
+
17
+ message = chat.matches[0].strip
18
+
19
+ # Get the mention name (ie. 'dirk') of the user
20
+ name = chat.user.mention_name
21
+ dictionary = dictionary_for_user name
22
+
23
+ # Passing `false` to indicate it's a string and not a file name
24
+ dictionary.parse_source message, false
25
+
26
+ save_dictionary name, dictionary
27
+ end
28
+
29
+ def generate(chat)
30
+ name = chat.matches[0][0].strip
31
+
32
+ dictionary = dictionary_for_user name
33
+ generator = MarkovSentenceGenerator.new dictionary
34
+
35
+ begin
36
+ sentence = generator.generate_sentence 1
37
+
38
+ chat.reply sentence
39
+ rescue EmptyDictionaryError
40
+ chat.reply "Looks like #{name} hasn't said anything!"
41
+ end
42
+ end
43
+
44
+ def save_dictionary(name, dictionary)
45
+ redis.set key_for_user(name), dictionary.to_json
46
+ end
47
+
48
+ def dictionary_for_user(name)
49
+ key = key_for_user name
50
+ dictionary = Dictionary.new name
51
+ json = redis.get key
52
+
53
+ dictionary.load_json(json) if json
54
+
55
+ dictionary
56
+ end
57
+
58
+ def key_for_user(name)
59
+ REDIS_KEY_PREFIX+name.downcase
60
+ end
61
+
62
+ Lita.register_handler self
63
+ end
64
+ end
@@ -0,0 +1,34 @@
1
+ require 'marky_markov'
2
+ require 'oj'
3
+
4
+ module MarkyMarkov
5
+ class PersistentJSONDictionary < ::PersistentDictionary
6
+ def initialize(*args)
7
+ super(*args)
8
+
9
+ @dictionary = {}
10
+ @capitalized_words = []
11
+ end
12
+
13
+ # No-op instead of reading from the filesystem
14
+ def open_dictionary
15
+ nil
16
+ end
17
+
18
+ def load_json(json)
19
+ data = Oj.load json
20
+
21
+ @depth = data['depth']
22
+ @dictionary = data['dictionary']
23
+ @capitalized_words = data['capitalized_words']
24
+ end
25
+
26
+ def to_json
27
+ Oj.dump(
28
+ 'depth' => @depth,
29
+ 'dictionary' => @dictionary,
30
+ 'capitalized_words' => @capitalized_words
31
+ )
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,25 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "lita-markov"
3
+ spec.version = "0.0.1"
4
+ spec.authors = ["Dirk Gadsden"]
5
+ spec.email = ["dirk@dirk.to"]
6
+ spec.description = "Markov chains for Lita."
7
+ spec.summary = spec.description
8
+ spec.homepage = "http://github.com/dirk/lita-markov"
9
+ spec.metadata = { "lita_plugin_type" => "handler" }
10
+
11
+ spec.files = `git ls-files`.split($/)
12
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
13
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
14
+ spec.require_paths = ["lib"]
15
+
16
+ spec.add_runtime_dependency "lita", ">= 4.6"
17
+ spec.add_runtime_dependency "marky_markov", "~> 0.3.5"
18
+ spec.add_runtime_dependency "oj", "~> 2.13.1"
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "pry-byebug"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rack-test"
24
+ spec.add_development_dependency "rspec", ">= 3.0.0"
25
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,4 @@
1
+ en:
2
+ lita:
3
+ handlers:
4
+ whoami:
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+ require 'pry'
3
+
4
+ describe Lita::Handlers::Markov, lita_handler: true do
5
+ before(:each) do
6
+ Lita.redis.flushall
7
+ end
8
+
9
+ it "won't call #ingest for non-command messages" do
10
+ expect(subject).to_not receive(:ingest)
11
+
12
+ send_message "#{robot.name} foo"
13
+ send_command 'bar'
14
+ end
15
+
16
+ it "will ingest a message into that person's dictionary" do
17
+ send_message 'hello markov world'
18
+ send_message 'hello markov planet'
19
+
20
+ dictionary = subject.dictionary_for_user user.mention_name
21
+
22
+ # Check that the messages made it into the dictionary
23
+ expect(dictionary.dictionary[['hello', 'markov']]).to eql ['world', 'planet']
24
+ end
25
+
26
+ it 'will build a sentence' do
27
+ send_message 'I love cookies!'
28
+ send_message 'I love pancakes!'
29
+
30
+ send_command "#{robot.name} markov #{user.mention_name}"
31
+
32
+ expect(replies.count).to eql 1
33
+
34
+ possible_replies = [
35
+ 'I love cookies!',
36
+ 'I love pancakes!'
37
+ ]
38
+ expect(possible_replies).to include replies[0]
39
+ end
40
+
41
+ it "will complain if the user hasn't said anything" do
42
+ send_command "#{robot.name} markov #{user.mention_name}"
43
+
44
+ expect(replies.count).to eql 1
45
+ expect(replies[0]).to eql "Looks like Test User hasn't said anything!"
46
+ end
47
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe MarkyMarkov::PersistentJSONDictionary do
4
+ subject { MarkyMarkov::PersistentJSONDictionary.new 'whoa' }
5
+
6
+ it 'initializes with sensible defaults' do
7
+ expect(subject.dictionary).to eq({})
8
+ end
9
+
10
+ it 'saves a dictionary' do
11
+ subject.add_word ['a', 'b'], 'c'
12
+
13
+ json = subject.to_json
14
+
15
+ expect(json).to eql '{"depth":2,"dictionary":{"^#1":[["a","b"],["c"]]},"capitalized_words":[]}'
16
+ end
17
+
18
+ it 'saves and loads a dictionary' do
19
+ subject.add_word ['a', 'b'], 'c'
20
+
21
+ json = subject.to_json
22
+
23
+ new_dictionary = MarkyMarkov::PersistentJSONDictionary.new 'whoa-another-one'
24
+ new_dictionary.load_json json
25
+
26
+ expect(new_dictionary.dictionary).to eql(['a', 'b'] => ['c'])
27
+ end
28
+ end
@@ -0,0 +1,6 @@
1
+ require 'lita-markov'
2
+ require 'lita/rspec'
3
+
4
+ # A compatibility mode is provided for older plugins upgrading from Lita 3. Since this plugin
5
+ # was generated with Lita 4, the compatibility mode should be left disabled.
6
+ Lita.version_3_compatibility_mode = false
File without changes
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lita-markov
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Dirk Gadsden
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-11-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: lita
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '4.6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '4.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: marky_markov
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.3.5
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.3.5
41
+ - !ruby/object:Gem::Dependency
42
+ name: oj
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.13.1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.13.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rack-test
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: 3.0.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: 3.0.0
125
+ description: Markov chains for Lita.
126
+ email:
127
+ - dirk@dirk.to
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - Gemfile
134
+ - LICENSE
135
+ - README.md
136
+ - Rakefile
137
+ - lib/lita-markov.rb
138
+ - lib/lita/handlers/markov.rb
139
+ - lib/marky_markov/persistent_json_dictionary.rb
140
+ - lita-markov.gemspec
141
+ - locales/en.yml
142
+ - spec/lita/handlers/markov_spec.rb
143
+ - spec/marky_markov/persistent_json_dictionary_spec.rb
144
+ - spec/spec_helper.rb
145
+ - templates/.gitkeep
146
+ homepage: http://github.com/dirk/lita-markov
147
+ licenses: []
148
+ metadata:
149
+ lita_plugin_type: handler
150
+ post_install_message:
151
+ rdoc_options: []
152
+ require_paths:
153
+ - lib
154
+ required_ruby_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ required_rubygems_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ requirements: []
165
+ rubyforge_project:
166
+ rubygems_version: 2.4.5.1
167
+ signing_key:
168
+ specification_version: 4
169
+ summary: Markov chains for Lita.
170
+ test_files:
171
+ - spec/lita/handlers/markov_spec.rb
172
+ - spec/marky_markov/persistent_json_dictionary_spec.rb
173
+ - spec/spec_helper.rb