ruboty-twitter_search 0.0.4 → 0.1.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/.rspec +2 -0
- data/.rubocop.yml +68 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +1 -2
- data/README.md +9 -18
- data/Rakefile +5 -0
- data/lib/ruboty/handlers/twitter_search.rb +113 -2
- data/lib/ruboty/twitter_search/version.rb +1 -1
- data/ruboty-twitter_search.gemspec +2 -0
- data/spec/ruboty/handlers/twitter_search/query_spec.rb +165 -0
- data/spec/spec_helper.rb +16 -0
- metadata +38 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a101873c2cb41d5d728cf61262f77bf2a5e3d890
|
4
|
+
data.tar.gz: c29ce2d0503b71933e1e92edcdc549684afebb8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9725086905c97364564ffda709cb6ef96827771755e5b4e597d45d5efac9c8f46c3e5a403e7fe7803656142730cc1581914354dd244dbe738a010cffc4b43190
|
7
|
+
data.tar.gz: 239e4ae74c634f5fa15653e977f69f766cfeb2768a8b3112d867428014e989c7ac79ce6f0b2f26c7da17403cb71f65db809649201a4e752bb3de42fd45aefde3
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
Lint/AssignmentInCondition:
|
2
|
+
Enabled: false
|
3
|
+
|
4
|
+
Lint/EnsureReturn:
|
5
|
+
Enabled: false
|
6
|
+
|
7
|
+
Lint/UnusedBlockArgument:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
Lint/UnusedMethodArgument:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Metrics/AbcSize:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Metrics/ClassLength:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
Metrics/CyclomaticComplexity:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Metrics/LineLength:
|
23
|
+
Max: 120
|
24
|
+
|
25
|
+
Metrics/MethodLength:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
Metrics/PerceivedComplexity:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
Style/Documentation:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
Style/DoubleNegation:
|
35
|
+
Enabled: false
|
36
|
+
|
37
|
+
Style/FormatString:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
Style/GuardClause:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
Style/IfUnlessModifier:
|
44
|
+
Enabled: false
|
45
|
+
|
46
|
+
Style/MultilineBlockChain:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
Style/PercentLiteralDelimiters:
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
Style/PredicateName:
|
53
|
+
Enabled: false
|
54
|
+
|
55
|
+
Style/RegexpLiteral:
|
56
|
+
MaxSlashes: 0
|
57
|
+
|
58
|
+
Style/SignalException:
|
59
|
+
Enabled: false
|
60
|
+
|
61
|
+
Style/StringLiterals:
|
62
|
+
EnforcedStyle: double_quotes
|
63
|
+
|
64
|
+
Style/TrailingComma:
|
65
|
+
Enabled: false
|
66
|
+
|
67
|
+
Style/TrivialAccessors:
|
68
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,30 +1,21 @@
|
|
1
|
-
# Ruboty::TwitterSearch
|
1
|
+
# Ruboty::TwitterSearch [](https://travis-ci.org/r7kamura/ruboty-twitter_search)
|
2
2
|
[Ruboty](https://github.com/r7kamura/ruboty-twitter_search) plug-in to search twitter.
|
3
3
|
|
4
4
|
## Usage
|
5
|
+
Search with given query and show tweet URLs.
|
6
|
+
(Note: `since_id` will be stored in ruboty's brain to same query by default)
|
7
|
+
|
5
8
|
```
|
6
9
|
@ruboty search twitter by <query>
|
7
10
|
```
|
8
11
|
|
9
12
|
### Example
|
10
13
|
```
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
https://twitter.com/bone_sushi/status/573806877340893184
|
17
|
-
https://twitter.com/namaakubi_/status/573806888015388672
|
18
|
-
https://twitter.com/NIGIRE_sushi/status/573806891211452416
|
19
|
-
https://twitter.com/Rymdensbarn/status/573806901722488832
|
20
|
-
https://twitter.com/SmaltimoreMD/status/573806917316968448
|
21
|
-
https://twitter.com/ornat/status/573806982852968448
|
22
|
-
https://twitter.com/kelZoom/status/573806985805754368
|
23
|
-
https://twitter.com/DT_Hanmer/status/573807032286973952
|
24
|
-
> @ruboty search twitter by sushi
|
25
|
-
https://twitter.com/Sushi_sweetegg/status/573807039224279040
|
26
|
-
> @ruboty search twitter by sushi
|
27
|
-
>
|
14
|
+
@ruboty search twitter by sushi
|
15
|
+
@ruboty search twitter by sushi fav:10
|
16
|
+
@ruboty search twitter by sushi retweet:20
|
17
|
+
@ruboty search twitter by sushi result_type:popular
|
18
|
+
@ruboty search twitter by sushi result_type:mixed
|
28
19
|
```
|
29
20
|
|
30
21
|
## ENV
|
data/Rakefile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
require "ruboty"
|
2
2
|
require "twitter"
|
3
|
-
require "yaml"
|
4
3
|
|
5
4
|
module Ruboty
|
6
5
|
module Handlers
|
7
6
|
class TwitterSearch < Base
|
8
7
|
NAMESPACE = "twitter-search"
|
8
|
+
TWEETS_COUNT = 10
|
9
9
|
|
10
10
|
env :TWITTER_ACCESS_TOKEN, "Twitter access token"
|
11
11
|
env :TWITTER_ACCESS_TOKEN_SECRET, "Twitter access token secret"
|
@@ -21,7 +21,22 @@ module Ruboty
|
|
21
21
|
|
22
22
|
# @return [true] to prevent running missing handlers.
|
23
23
|
def search(message)
|
24
|
-
|
24
|
+
query = Query.new(message[:query])
|
25
|
+
|
26
|
+
statuses = client.search(
|
27
|
+
query.query_string,
|
28
|
+
result_type: query.result_type,
|
29
|
+
since_id: fetch_since_id_for(message[:query]),
|
30
|
+
).take(TWEETS_COUNT)
|
31
|
+
|
32
|
+
statuses.select! do |status|
|
33
|
+
status.retweet_count >= query.minimum_retweet_count
|
34
|
+
end
|
35
|
+
|
36
|
+
statuses.select! do |status|
|
37
|
+
status.favorite_count >= query.minimum_favorite_count
|
38
|
+
end
|
39
|
+
|
25
40
|
if statuses.any?
|
26
41
|
message.reply(StatusesView.new(statuses).to_s)
|
27
42
|
store_since_id(query: message[:query], since_id: statuses.first.id)
|
@@ -66,6 +81,55 @@ module Ruboty
|
|
66
81
|
end
|
67
82
|
end
|
68
83
|
|
84
|
+
class Query
|
85
|
+
DEFAULT_MINIMUM_FAVORITE_COUNT = 0
|
86
|
+
DEFAULT_MINIMUM_RETWEET_COUNT = 0
|
87
|
+
|
88
|
+
# @param [String] original_query_string
|
89
|
+
def initialize(original_query_string)
|
90
|
+
@original_query_string = original_query_string
|
91
|
+
end
|
92
|
+
|
93
|
+
# @return [Fixnum]
|
94
|
+
def minimum_favorite_count
|
95
|
+
if token = tokens.find(&:favorite_count_filter?)
|
96
|
+
token.favorite_count
|
97
|
+
else
|
98
|
+
DEFAULT_MINIMUM_FAVORITE_COUNT
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# @return [Fixnum]
|
103
|
+
def minimum_retweet_count
|
104
|
+
if token = tokens.find(&:retweet_count_filter?)
|
105
|
+
token.retweet_count
|
106
|
+
else
|
107
|
+
DEFAULT_MINIMUM_RETWEET_COUNT
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# @return [String]
|
112
|
+
def query_string
|
113
|
+
tokens.reject(&:filter?).join(" ")
|
114
|
+
end
|
115
|
+
|
116
|
+
# @return [String, nil]
|
117
|
+
def result_type
|
118
|
+
if token = tokens.find(&:result_type_filter?)
|
119
|
+
token.result_type
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
# @return [Array<Ruboty::Handlers::TwitterSearch::Token>]
|
126
|
+
def tokens
|
127
|
+
@tokens ||= @original_query_string.split.map do |token_string|
|
128
|
+
Token.new(token_string)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
69
133
|
class StatusesView
|
70
134
|
def initialize(statuses)
|
71
135
|
@statuses = statuses
|
@@ -83,6 +147,53 @@ module Ruboty
|
|
83
147
|
end
|
84
148
|
end
|
85
149
|
end
|
150
|
+
|
151
|
+
class Token
|
152
|
+
def initialize(token_string)
|
153
|
+
@token_string = token_string
|
154
|
+
end
|
155
|
+
|
156
|
+
# @return [Fixnum, nil]
|
157
|
+
def favorite_count
|
158
|
+
if @token_string.match(/\Afav:(?<count>\d+)\z/)
|
159
|
+
Regexp.last_match(:count).to_i
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def favorite_count_filter?
|
164
|
+
!favorite_count.nil?
|
165
|
+
end
|
166
|
+
|
167
|
+
def filter?
|
168
|
+
favorite_count_filter? || result_type_filter? || retweet_count_filter?
|
169
|
+
end
|
170
|
+
|
171
|
+
# @return [String, nil]
|
172
|
+
def result_type
|
173
|
+
if @token_string.match(/\Aresult_type:(?<type>\w+)\z/)
|
174
|
+
Regexp.last_match(:type)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def result_type_filter?
|
179
|
+
!result_type.nil?
|
180
|
+
end
|
181
|
+
|
182
|
+
# @return [Fixnum, nil]
|
183
|
+
def retweet_count
|
184
|
+
if @token_string.match(/\Aretweet:(?<count>\d+)\z/)
|
185
|
+
Regexp.last_match(:count).to_i
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def retweet_count_filter?
|
190
|
+
!retweet_count.nil?
|
191
|
+
end
|
192
|
+
|
193
|
+
def to_s
|
194
|
+
@token_string
|
195
|
+
end
|
196
|
+
end
|
86
197
|
end
|
87
198
|
end
|
88
199
|
end
|
@@ -20,4 +20,6 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.add_dependency "twitter"
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.7"
|
22
22
|
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "rspec", "3.2.0"
|
24
|
+
spec.add_development_dependency "rubocop", "0.29.1"
|
23
25
|
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
RSpec.describe Ruboty::Handlers::TwitterSearch::Query do
|
2
|
+
let(:query) do
|
3
|
+
described_class.new(original_string)
|
4
|
+
end
|
5
|
+
|
6
|
+
describe "#minimum_favorite_count" do
|
7
|
+
subject do
|
8
|
+
query.minimum_favorite_count
|
9
|
+
end
|
10
|
+
|
11
|
+
context "with favorite count filter" do
|
12
|
+
let(:original_string) do
|
13
|
+
"a fav:10"
|
14
|
+
end
|
15
|
+
|
16
|
+
it { is_expected.to eq 10 }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "without favorite count filter" do
|
20
|
+
let(:original_string) do
|
21
|
+
"a"
|
22
|
+
end
|
23
|
+
|
24
|
+
it { is_expected.to eq 0 }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#minimum_retweet_count" do
|
29
|
+
subject do
|
30
|
+
query.minimum_retweet_count
|
31
|
+
end
|
32
|
+
|
33
|
+
context "with retweet count filter" do
|
34
|
+
let(:original_string) do
|
35
|
+
"a retweet:10"
|
36
|
+
end
|
37
|
+
|
38
|
+
it { is_expected.to eq 10 }
|
39
|
+
end
|
40
|
+
|
41
|
+
context "without retweet count filter" do
|
42
|
+
let(:original_string) do
|
43
|
+
"a"
|
44
|
+
end
|
45
|
+
|
46
|
+
it { is_expected.to eq 0 }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#query_string" do
|
51
|
+
subject do
|
52
|
+
query.query_string
|
53
|
+
end
|
54
|
+
|
55
|
+
context "with simple string" do
|
56
|
+
let(:original_string) do
|
57
|
+
"a"
|
58
|
+
end
|
59
|
+
|
60
|
+
it { is_expected.to eq "a" }
|
61
|
+
end
|
62
|
+
|
63
|
+
context "with empty string" do
|
64
|
+
let(:original_string) do
|
65
|
+
""
|
66
|
+
end
|
67
|
+
|
68
|
+
it { is_expected.to eq "" }
|
69
|
+
end
|
70
|
+
|
71
|
+
context "with space-separated string" do
|
72
|
+
let(:original_string) do
|
73
|
+
"a b"
|
74
|
+
end
|
75
|
+
|
76
|
+
it { is_expected.to eq "a b" }
|
77
|
+
end
|
78
|
+
|
79
|
+
context "with spaces-separated string" do
|
80
|
+
let(:original_string) do
|
81
|
+
"a b"
|
82
|
+
end
|
83
|
+
|
84
|
+
it { is_expected.to eq "a b" }
|
85
|
+
end
|
86
|
+
|
87
|
+
context "with tab-separated string" do
|
88
|
+
let(:original_string) do
|
89
|
+
"a\tb"
|
90
|
+
end
|
91
|
+
|
92
|
+
it { is_expected.to eq "a b" }
|
93
|
+
end
|
94
|
+
|
95
|
+
context "with favorite count filter" do
|
96
|
+
let(:original_string) do
|
97
|
+
"a fav:10"
|
98
|
+
end
|
99
|
+
|
100
|
+
it { is_expected.to eq "a" }
|
101
|
+
end
|
102
|
+
|
103
|
+
context "with invalid favorite count filter" do
|
104
|
+
let(:original_string) do
|
105
|
+
"a fav:b"
|
106
|
+
end
|
107
|
+
|
108
|
+
it { is_expected.to eq "a fav:b" }
|
109
|
+
end
|
110
|
+
|
111
|
+
context "with retweet count filter" do
|
112
|
+
let(:original_string) do
|
113
|
+
"a retweet:10"
|
114
|
+
end
|
115
|
+
|
116
|
+
it { is_expected.to eq "a" }
|
117
|
+
end
|
118
|
+
|
119
|
+
context "with invalid retweet count filter" do
|
120
|
+
let(:original_string) do
|
121
|
+
"a retweet:b"
|
122
|
+
end
|
123
|
+
|
124
|
+
it { is_expected.to eq "a retweet:b" }
|
125
|
+
end
|
126
|
+
|
127
|
+
context "with result type filter" do
|
128
|
+
let(:original_string) do
|
129
|
+
"a result_type:popular"
|
130
|
+
end
|
131
|
+
|
132
|
+
it { is_expected.to eq "a" }
|
133
|
+
end
|
134
|
+
|
135
|
+
context "with invalid retweet count filter" do
|
136
|
+
let(:original_string) do
|
137
|
+
"a result_type:b-c"
|
138
|
+
end
|
139
|
+
|
140
|
+
it { is_expected.to eq "a result_type:b-c" }
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe "#result_type" do
|
145
|
+
subject do
|
146
|
+
query.result_type
|
147
|
+
end
|
148
|
+
|
149
|
+
context "with result type filter" do
|
150
|
+
let(:original_string) do
|
151
|
+
"a result_type:popular"
|
152
|
+
end
|
153
|
+
|
154
|
+
it { is_expected.to eq "popular" }
|
155
|
+
end
|
156
|
+
|
157
|
+
context "without result type filter" do
|
158
|
+
let(:original_string) do
|
159
|
+
"a"
|
160
|
+
end
|
161
|
+
|
162
|
+
it { is_expected.to be_nil }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "ruboty/twitter_search"
|
2
|
+
|
3
|
+
RSpec.configure do |config|
|
4
|
+
config.expect_with :rspec do |expectations|
|
5
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
6
|
+
end
|
7
|
+
|
8
|
+
config.mock_with :rspec do |mocks|
|
9
|
+
mocks.verify_partial_doubles = true
|
10
|
+
end
|
11
|
+
|
12
|
+
config.disable_monkey_patching!
|
13
|
+
config.filter_run :focus
|
14
|
+
config.run_all_when_everything_filtered = true
|
15
|
+
config.warnings = true
|
16
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruboty-twitter_search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruboty
|
@@ -66,6 +66,34 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 3.2.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 3.2.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.29.1
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.29.1
|
69
97
|
description:
|
70
98
|
email:
|
71
99
|
- r7kamura@gmail.com
|
@@ -74,6 +102,9 @@ extensions: []
|
|
74
102
|
extra_rdoc_files: []
|
75
103
|
files:
|
76
104
|
- ".gitignore"
|
105
|
+
- ".rspec"
|
106
|
+
- ".rubocop.yml"
|
107
|
+
- ".travis.yml"
|
77
108
|
- CHANGELOG.md
|
78
109
|
- Gemfile
|
79
110
|
- LICENSE.txt
|
@@ -83,6 +114,8 @@ files:
|
|
83
114
|
- lib/ruboty/twitter_search.rb
|
84
115
|
- lib/ruboty/twitter_search/version.rb
|
85
116
|
- ruboty-twitter_search.gemspec
|
117
|
+
- spec/ruboty/handlers/twitter_search/query_spec.rb
|
118
|
+
- spec/spec_helper.rb
|
86
119
|
homepage: https://github.com/r7kamura/ruboty-twitter_search
|
87
120
|
licenses:
|
88
121
|
- MIT
|
@@ -107,5 +140,7 @@ rubygems_version: 2.4.5
|
|
107
140
|
signing_key:
|
108
141
|
specification_version: 4
|
109
142
|
summary: Ruboty plug-in to search twitter.
|
110
|
-
test_files:
|
143
|
+
test_files:
|
144
|
+
- spec/ruboty/handlers/twitter_search/query_spec.rb
|
145
|
+
- spec/spec_helper.rb
|
111
146
|
has_rdoc:
|