lita-answers 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +20 -0
- data/lib/knowledgebase.rb +2 -7
- data/lib/lita-answers.rb +1 -0
- data/lib/lita/handlers/answers.rb +22 -7
- data/lib/nlp.rb +25 -0
- data/lita-answers.gemspec +2 -2
- data/spec/lita/handlers/answers_spec.rb +8 -1
- data/spec/spec_helper.rb +0 -2
- data/spec/support/contexts/variables.rb +1 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a22ca9edfca01b8a6e308e45d82f90a0cb19800
|
4
|
+
data.tar.gz: 29a4d8ef2bd301b7e4417ec28673dfc82387cd07
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a2d478cfc9403f8ba41598015909e8ab380f5c3d983947335bf8c1b7724f67951e63282ab48b57e8d710adba325d07dddd49feac0b0bb811e364679671ef0b4
|
7
|
+
data.tar.gz: a1e6b0a78062ebf9ae2bf2e4124ce3b1b0e4cc5165ceecb820f7519319fec89601f4b1f97a1ab8898809efb7a532dbb716215ec4d0b792e4fbd3a6a8c5847b11
|
data/Rakefile
CHANGED
@@ -1,6 +1,26 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rspec/core/rake_task"
|
3
|
+
require 'lita-answers'
|
3
4
|
|
4
5
|
RSpec::Core::RakeTask.new(:spec)
|
5
6
|
|
6
7
|
task :default => :spec
|
8
|
+
|
9
|
+
task :seeds do
|
10
|
+
{
|
11
|
+
'What is the w3c?' => 'The World Wide Web Consortium is the main international standards organization for the World Wide Web.',
|
12
|
+
'What is HTTP code 200?' => '200 OK – Standard response for successful HTTP requests. The actual response will depend on the request method used. In a GET request, the response will contain an entity corresponding to the requested resource. In a POST request the response will contain an entity describing or containing the result of the action.',
|
13
|
+
'What is HTTP code 201?' => '201 Created – The request has been fulfilled and resulted in a new resource being created.',
|
14
|
+
'What books should every web developer read?' => "There are few books for old school learners – CSS: The Missing Manual, JavaScript: The Definitive Guide, Agile Web Development => Rails, Python Web Development => Django, Programming PHP.",
|
15
|
+
'What are web programming languages?' => 'There are many programming languages available to Web developers. Some of them are JavaScript, Go, Java, Python, Scala, Ruby.',
|
16
|
+
'What is Ruby?' => 'Ruby is a dynamic, reflective, object-oriented, general-purpose programming language.',
|
17
|
+
'What books should every Ruby/Rails developer read?' => 'The Ruby Programming Language, Agile Web Development => Rails 4, Ruby on Rails Tutorial, The Rails 4 Way, Patterns of Enterprise Application Architecture, Implementation Patterns, Refactoring – Ruby Edition, Rails Antipatterns, Eloquent Ruby, Confident Ruby, Practical object-oriented design in Ruby, Crafting Rails 4 Applications...',
|
18
|
+
'What technology for web-programming to learn?' => 'Python, Java, .NET, Node.js, Ruby on Rails, Coffeescript...',
|
19
|
+
'What is adaptive web design?' => 'Responsive Web design is a Web design approach aimed at crafting sites to provide an optimal viewing experience – easy reading and navigation => a minimum of resizing, panning, and scrolling – across a wide range of devices, from mobile phones to desktop computer monitors.',
|
20
|
+
'What is responsive web design?' => 'Adaptive web design is basically the same as responsive design and shares many of the same ideals and goals. The main difference however is that the changes are made on the server side rather than the client side.',
|
21
|
+
'What is the difference between client-side and server-side?' => 'The Server - This party is responsible for serving pages. The Client - This party requests pages from the Server, and displays them to the user. On most cases, the client is a web browser.',
|
22
|
+
'What are the most popular gems?' => '1. rake, 2. rack, 3. thor, 4. activesupport, 5. activesupport, 6. json, 7. mime-types, 8. rails, 9. activerecord, 10. actionpack'
|
23
|
+
}.each do |question, answer|
|
24
|
+
Knowledgebase.create(question, answer)
|
25
|
+
end
|
26
|
+
end
|
data/lib/knowledgebase.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
class Knowledgebase
|
2
|
+
REDIS_NAMESPACE = 'handlers:answers'
|
2
3
|
REDIS_KEY = 'knowledgebase'
|
3
4
|
|
4
5
|
class << self
|
@@ -27,13 +28,7 @@ class Knowledgebase
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def redis
|
30
|
-
@redis ||= Redis::Namespace.new(
|
31
|
+
@redis ||= Redis::Namespace.new(REDIS_NAMESPACE, redis: Lita.redis)
|
31
32
|
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def redis_namespace
|
36
|
-
ENV['env'] == 'test' ? 'handlers:answers:test' : 'handlers:answers'
|
37
|
-
end
|
38
33
|
end
|
39
34
|
end
|
data/lib/lita-answers.rb
CHANGED
@@ -3,12 +3,12 @@ require 'lita'
|
|
3
3
|
module Lita
|
4
4
|
module Handlers
|
5
5
|
class Answers < Handler
|
6
|
-
TEXT = /[\w\s
|
6
|
+
TEXT = /[\w\s\,\.\-\/:–]+/
|
7
7
|
QUESTION = /(?:'|")(#{TEXT.source}\?)(?:'|")/
|
8
8
|
ANSWER = /(?:'|")(#{TEXT.source}\.?)(?:'|")/
|
9
9
|
|
10
10
|
route(/^all\squestions$/i, :index, command: true, help: {
|
11
|
-
"all questions" => "You could ask me the following questions
|
11
|
+
"all questions" => "You could ask me the following questions: 1) ... 2) ..."
|
12
12
|
})
|
13
13
|
|
14
14
|
route(/^remember\s#{QUESTION.source}\swith\s#{ANSWER.source}$/i, :create, command: true, help: {
|
@@ -36,7 +36,7 @@ module Lita
|
|
36
36
|
end
|
37
37
|
else
|
38
38
|
reply = "There are no questions yet! " \
|
39
|
-
"Use REMEMBER 'question?' WITH 'answer.' syntax for creating questions
|
39
|
+
"Use REMEMBER 'question?' WITH 'answer.' syntax for creating questions.\n" \
|
40
40
|
"For more info see: help remember."
|
41
41
|
end
|
42
42
|
response.reply(reply)
|
@@ -57,8 +57,17 @@ module Lita
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def show(response)
|
60
|
-
question = response.matches.first
|
61
|
-
reply = Knowledgebase.read(question) ||
|
60
|
+
question = response.matches.first[0]
|
61
|
+
reply = Knowledgebase.read(question) || begin
|
62
|
+
closest_question = Nlp.closest_sentence(question, Knowledgebase.all)
|
63
|
+
if closest_question.nil?
|
64
|
+
no_such_question
|
65
|
+
else
|
66
|
+
"Found the closest question to your question: '#{closest_question}'. " \
|
67
|
+
"Use REMEMBER 'question?' WITH 'answer.' syntax for creating questions.\n" \
|
68
|
+
"For more info see: help remember."
|
69
|
+
end
|
70
|
+
end
|
62
71
|
response.reply(reply)
|
63
72
|
end
|
64
73
|
|
@@ -68,7 +77,7 @@ module Lita
|
|
68
77
|
Knowledgebase.update(question, new_answer)
|
69
78
|
reply = "The new answer for '#{question}' is '#{new_answer}'."
|
70
79
|
else
|
71
|
-
reply =
|
80
|
+
reply = no_such_question
|
72
81
|
end
|
73
82
|
response.reply(reply)
|
74
83
|
end
|
@@ -79,10 +88,16 @@ module Lita
|
|
79
88
|
Knowledgebase.destroy(question)
|
80
89
|
reply = "Forgot '#{question}'"
|
81
90
|
else
|
82
|
-
reply =
|
91
|
+
reply = no_such_question
|
83
92
|
end
|
84
93
|
response.reply(reply)
|
85
94
|
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def no_such_question
|
99
|
+
'There is no such a question! Use ALL QUESTIONS command.'
|
100
|
+
end
|
86
101
|
end
|
87
102
|
|
88
103
|
Lita.register_handler(Answers)
|
data/lib/nlp.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
class Nlp
|
2
|
+
class << self
|
3
|
+
# TODO: use real NLP, not this silly chunk of code
|
4
|
+
def closest_sentence(string, sentences)
|
5
|
+
string_tokens = split_into_tokens(string)
|
6
|
+
string_tokens_size = string_tokens.size
|
7
|
+
closest_sentence = nil
|
8
|
+
closest_sentence_size = 0
|
9
|
+
sentences.each do |sentence|
|
10
|
+
sentence_tokens = split_into_tokens(sentence)
|
11
|
+
common_tokens = string_tokens & sentence_tokens
|
12
|
+
bigger_sentence_size = [sentence_tokens.size, string_tokens_size].max
|
13
|
+
if bigger_sentence_size - common_tokens.size == 1 && bigger_sentence_size > closest_sentence_size
|
14
|
+
closest_sentence = sentence
|
15
|
+
closest_sentence_size = bigger_sentence_size
|
16
|
+
end
|
17
|
+
end
|
18
|
+
closest_sentence
|
19
|
+
end
|
20
|
+
|
21
|
+
def split_into_tokens(string)
|
22
|
+
string.gsub('?', '').downcase.split
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lita-answers.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = "lita-answers"
|
3
|
-
spec.version = "0.0.
|
3
|
+
spec.version = "0.0.2"
|
4
4
|
spec.authors = ["Sergey Alekseev"]
|
5
5
|
spec.email = ["sergey.alekseev.minsk@gmail.com"]
|
6
|
-
spec.description = "A Lita handler for a question answering (QA) system. Allows you to use CRUD operations." \
|
6
|
+
spec.description = "A Lita handler for a question answering (QA) system. Allows you to use CRUD operations and simple NLP. " \
|
7
7
|
"More functionality is coming soon..."
|
8
8
|
spec.summary = %q{A Lita handler for a question answering (QA) system}
|
9
9
|
spec.homepage = "https://github.com/sergey-alekseev/lita-answers"
|
@@ -39,7 +39,7 @@ describe Lita::Handlers::Answers, lita_handler: true do
|
|
39
39
|
send_command "forget '#{question}'"
|
40
40
|
send_command 'all questions'
|
41
41
|
expect(replies.last).to eq("There are no questions yet! " \
|
42
|
-
"Use REMEMBER 'question?' WITH 'answer.' syntax for creating questions
|
42
|
+
"Use REMEMBER 'question?' WITH 'answer.' syntax for creating questions.\n" \
|
43
43
|
"For more info see: help remember.")
|
44
44
|
end
|
45
45
|
end
|
@@ -51,6 +51,13 @@ describe Lita::Handlers::Answers, lita_handler: true do
|
|
51
51
|
expect(replies.last).to eq(answer)
|
52
52
|
end
|
53
53
|
|
54
|
+
it 'answers with the suggestion to use the closest question' do
|
55
|
+
send_command "answer '#{close_question}'"
|
56
|
+
expect(replies.last).to eq("Found the closest question to your question: '#{question}'. " \
|
57
|
+
"Use REMEMBER 'question?' WITH 'answer.' syntax for creating questions.\n" \
|
58
|
+
"For more info see: help remember.")
|
59
|
+
end
|
60
|
+
|
54
61
|
it_behaves_like 'absent question', "answer 'abrakadabra?'"
|
55
62
|
end
|
56
63
|
|
data/spec/spec_helper.rb
CHANGED
@@ -2,4 +2,5 @@ shared_context 'variables' do
|
|
2
2
|
let(:question) { 'What is the w3c?' }
|
3
3
|
let(:answer) { 'The World Wide Web Consortium is the main international standards organization for the World Wide Web.' }
|
4
4
|
let(:new_answer) { 'The World Wide Web Consortium' }
|
5
|
+
let(:close_question) { 'What is W3C?' }
|
5
6
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lita-answers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergey Alekseev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lita
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
description: A Lita handler for a question answering (QA) system. Allows you to use
|
112
|
-
CRUD operations.More functionality is coming soon...
|
112
|
+
CRUD operations and simple NLP. More functionality is coming soon...
|
113
113
|
email:
|
114
114
|
- sergey.alekseev.minsk@gmail.com
|
115
115
|
executables: []
|
@@ -124,6 +124,7 @@ files:
|
|
124
124
|
- lib/knowledgebase.rb
|
125
125
|
- lib/lita-answers.rb
|
126
126
|
- lib/lita/handlers/answers.rb
|
127
|
+
- lib/nlp.rb
|
127
128
|
- lita-answers.gemspec
|
128
129
|
- spec/knowledgebase_spec.rb
|
129
130
|
- spec/lita/handlers/answers_spec.rb
|