logstash-input-twitter 2.0.2 → 2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b1bd1d74096af15b0ef43608ed517bfc467226ce
4
- data.tar.gz: 2aa4525b43079c40b9e9a43d3910ae17af2a895f
3
+ metadata.gz: c2c82687f3ddd3386c346f11cead1cd3a6bbc485
4
+ data.tar.gz: 8ba300f93af4f14852047a19f1187fc72f0cda80
5
5
  SHA512:
6
- metadata.gz: d7b58f15425e2d5b9f87e762a6b03abd586396622fe18318cb9369776d00b590ad61a77a597e12cc28d17703401a2ccea0ffff7211b6710cc38f3e92e60bf4f8
7
- data.tar.gz: 1aaf36fd17ca13f983cd1f80a2cd9e87bd9e5693603d337a6986d4ce918490facd45d421382985c707606854dde34e33f77dd456fc024afe90176b3e3d29626e
6
+ metadata.gz: b5f37dde1ba6376d57f4d4064b7f9ddcadaa7ada41449f6abfd80dc9a51b852981bbee2fc9566d38ad3bdc0badba1689ec6520bc801d90353fc55e22a1569fe4
7
+ data.tar.gz: f7bd667faadaa77c6e41f53785dc807e2764ae20c65276023ca7297d1108cf6479326501d248e778a463df89372db55a5d2dc648f3ab41795fe56c633e3f62cd
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 2.1.0
2
+ - Add an option to fetch data from the sample endpoint.
3
+ - Add hashtags, symbols and user_mentions as data for the non extended tweet event.
4
+ - Add an option to filter per location and language.
5
+ - Add an option to stream data from a list of users.
6
+ - Add integration and unit tests for this and previous features.
7
+ - Add an ignore_retweet flag to filter them.
8
+ - Small code reorg and refactoring.
9
+ - Fixes #22 #21 #20 #11 #9
10
+
1
11
  ## 2.0.0
2
12
  - Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
3
13
  instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Logstash Plugin
2
2
 
3
+ [![Build
4
+ Status](http://build-eu-00.elastic.co/view/LS%20Plugins/view/LS%20Inputs/job/logstash-plugin-input-twitter-unit/badge/icon)](http://build-eu-00.elastic.co/view/LS%20Plugins/view/LS%20Inputs/job/logstash-plugin-input-twitter-unit/)
5
+
3
6
  This is a plugin for [Logstash](https://github.com/elastic/logstash).
4
7
 
5
8
  It is fully free and fully open source. The license is Apache 2.0, meaning you are pretty much free to use it however you want in whatever way.
@@ -6,27 +6,29 @@ require "logstash/util"
6
6
  require "logstash/json"
7
7
  require "stud/interval"
8
8
 
9
- # Read events from the twitter streaming api.
9
+ # Ingest events from the Twitter Streaming API.
10
10
  class LogStash::Inputs::Twitter < LogStash::Inputs::Base
11
11
 
12
+ attr_reader :filter_options
13
+
12
14
  config_name "twitter"
13
15
 
14
- # Your twitter app's consumer key
16
+ # Your Twitter App's consumer key
15
17
  #
16
18
  # Don't know what this is? You need to create an "application"
17
- # on twitter, see this url: <https://dev.twitter.com/apps/new>
19
+ # on Twitter, see this url: <https://dev.twitter.com/apps/new>
18
20
  config :consumer_key, :validate => :string, :required => true
19
21
 
20
- # Your twitter app's consumer secret
22
+ # Your Twitter App's consumer secret
21
23
  #
22
24
  # If you don't have one of these, you can create one by
23
- # registering a new application with twitter:
25
+ # registering a new application with Twitter:
24
26
  # <https://dev.twitter.com/apps/new>
25
27
  config :consumer_secret, :validate => :password, :required => true
26
28
 
27
29
  # Your oauth token.
28
30
  #
29
- # To get this, login to twitter with whatever account you want,
31
+ # To get this, login to Twitter with whatever account you want,
30
32
  # then visit <https://dev.twitter.com/apps>
31
33
  #
32
34
  # Click on your app (used with the consumer_key and consumer_secret settings)
@@ -37,7 +39,7 @@ class LogStash::Inputs::Twitter < LogStash::Inputs::Base
37
39
 
38
40
  # Your oauth token secret.
39
41
  #
40
- # To get this, login to twitter with whatever account you want,
42
+ # To get this, login to Twitter with whatever account you want,
41
43
  # then visit <https://dev.twitter.com/apps>
42
44
  #
43
45
  # Click on your app (used with the consumer_key and consumer_secret settings)
@@ -46,20 +48,57 @@ class LogStash::Inputs::Twitter < LogStash::Inputs::Base
46
48
  # application.
47
49
  config :oauth_token_secret, :validate => :password, :required => true
48
50
 
49
- # Any keywords to track in the twitter stream
50
- config :keywords, :validate => :array, :required => true
51
+ # Any keywords to track in the Twitter stream. For multiple keywords, use
52
+ # the syntax ["foo", "bar"]. There's a logical OR between each keyword
53
+ # string listed and a logical AND between words separated by spaces per
54
+ # keyword string.
55
+ # See https://dev.twitter.com/streaming/overview/request-parameters#track
56
+ # for more details.
57
+ #
58
+ # The wildcard "*" option is not supported. To ingest a sample stream of
59
+ # all tweets, the use_samples option is recommended.
60
+ config :keywords, :validate => :array
51
61
 
52
- # Record full tweet object as given to us by the Twitter stream api.
62
+ # Record full tweet object as given to us by the Twitter Streaming API.
53
63
  config :full_tweet, :validate => :boolean, :default => false
54
64
 
55
- public
65
+ # A comma separated list of user IDs, indicating the users to
66
+ # return statuses for in the Twitter stream.
67
+ # See https://dev.twitter.com/streaming/overview/request-parameters#follow
68
+ # for more details.
69
+ config :follows, :validate => :array
70
+
71
+ # A comma-separated list of longitude, latitude pairs specifying a set
72
+ # of bounding boxes to filter tweets by.
73
+ # See https://dev.twitter.com/streaming/overview/request-parameters#locations
74
+ # for more details.
75
+ config :locations, :validate => :string
76
+
77
+ # A list of BCP 47 language identifiers corresponding to any of the languages listed
78
+ # on Twitter’s advanced search page will only return tweets that have been detected
79
+ # as being written in the specified languages.
80
+ config :languages, :validate => :array
81
+
82
+ # Returns a small random sample of all public statuses. The tweets returned
83
+ # by the default access level are the same, so if two different clients connect
84
+ # to this endpoint, they will see the same tweets. If set to true, the keywords,
85
+ # follows, locations, and languages options will be ignored. Default => false
86
+ config :use_samples, :validate => :boolean, :default => false
87
+
88
+ # Lets you ingore the retweets coming out of the Twitter API. Default => false
89
+ config :ignore_retweets, :validate => :boolean, :default => false
90
+
56
91
  def register
57
92
  require "twitter"
58
93
 
94
+ if !@use_samples && ( @keywords.nil? && @follows.nil? && @locations.nil? )
95
+ raise LogStash::ConfigurationError.new("At least one parameter (follows, locations or keywords) must be specified.")
96
+ end
97
+
59
98
  # monkey patch twitter gem to ignore json parsing error.
60
99
  # at the same time, use our own json parser
61
100
  # this has been tested with a specific gem version, raise if not the same
62
- raise("Incompatible Twitter gem version and the LogStash::Json.load") unless Twitter::Version.to_s == "5.12.0"
101
+ raise("Incompatible Twitter gem version and the LogStash::Json.load") unless Twitter::Version.to_s == "5.14.0"
63
102
 
64
103
  Twitter::Streaming::Response.module_eval do
65
104
  def on_body(data)
@@ -74,51 +113,83 @@ class LogStash::Inputs::Twitter < LogStash::Inputs::Base
74
113
  end
75
114
  end
76
115
 
77
- @client = Twitter::Streaming::Client.new do |c|
78
- c.consumer_key = @consumer_key
79
- c.consumer_secret = @consumer_secret.value
80
- c.access_token = @oauth_token
81
- c.access_token_secret = @oauth_token_secret.value
82
- end
116
+ @rest_client = Twitter::REST::Client.new { |c| configure(c) }
117
+ @stream_client = Twitter::Streaming::Client.new { |c| configure(c) }
118
+ @twitter_options = build_options
83
119
  end
84
120
 
85
- public
86
121
  def run(queue)
87
- @logger.info("Starting twitter tracking", :keywords => @keywords)
122
+ @logger.info("Starting twitter tracking", twitter_options.clone) # need to pass a clone as it modify this var otherwise
88
123
  begin
89
- @client.filter(:track => @keywords.join(",")) do |tweet|
90
- return if stop?
91
- if tweet.is_a?(Twitter::Tweet)
92
- event = from_tweet(tweet)
93
- decorate(event)
94
- queue << event
124
+ if @use_samples
125
+ @stream_client.sample do |tweet|
126
+ return if stop?
127
+ tweet_processor(queue, tweet)
95
128
  end
96
- end # client.filter
129
+ else
130
+ @stream_client.filter(twitter_options) do |tweet|
131
+ return if stop?
132
+ tweet_processor(queue, tweet)
133
+ end
134
+ end
97
135
  rescue Twitter::Error::TooManyRequests => e
98
136
  @logger.warn("Twitter too many requests error, sleeping for #{e.rate_limit.reset_in}s")
99
137
  Stud.stoppable_sleep(e.rate_limit.reset_in) { stop? }
100
138
  retry
101
139
  rescue => e
102
- @logger.warn("Twitter client error", :message => e.message, :exception => e, :backtrace => e.backtrace)
140
+ @logger.warn("Twitter client error", :message => e.message, :exception => e, :backtrace => e.backtrace, :options => @filter_options)
103
141
  retry
104
142
  end
105
143
  end # def run
106
144
 
145
+ def stop
146
+ @stream_client = nil
147
+ end
148
+
149
+ def twitter_options
150
+ @twitter_options
151
+ end
152
+
153
+ def set_stream_client(client)
154
+ @stream_client = client
155
+ end
156
+
107
157
  private
158
+
159
+ def tweet_processor(queue, tweet)
160
+ if tweet.is_a?(Twitter::Tweet)
161
+ return if ignore?(tweet)
162
+ event = from_tweet(tweet)
163
+ decorate(event)
164
+ queue << event
165
+ end
166
+ end
167
+
168
+ def ignore?(tweet)
169
+ @ignore_retweets && tweet.retweet?
170
+ end
171
+
108
172
  def from_tweet(tweet)
109
173
  @logger.debug? && @logger.debug("Got tweet", :user => tweet.user.screen_name, :text => tweet.text)
110
174
  if @full_tweet
111
175
  event = LogStash::Event.new(LogStash::Util.stringify_symbols(tweet.to_hash))
112
176
  event.timestamp = LogStash::Timestamp.new(tweet.created_at)
113
177
  else
114
- event = LogStash::Event.new(
178
+
179
+ attributes = {
115
180
  LogStash::Event::TIMESTAMP => LogStash::Timestamp.new(tweet.created_at),
116
181
  "message" => tweet.full_text,
117
182
  "user" => tweet.user.screen_name,
118
183
  "client" => tweet.source,
119
184
  "retweeted" => tweet.retweeted?,
120
185
  "source" => "http://twitter.com/#{tweet.user.screen_name}/status/#{tweet.id}"
121
- )
186
+ }
187
+
188
+ attributes["hashtags"] = tweet.hashtags
189
+ attributes["symbols"] = tweet.symbols
190
+ attributes["user_mentions"] = tweet.user_mentions
191
+
192
+ event = LogStash::Event.new(attributes)
122
193
  event["in-reply-to"] = tweet.in_reply_to_status_id if tweet.reply?
123
194
  unless tweet.urls.empty?
124
195
  event["urls"] = tweet.urls.map(&:expanded_url).map(&:to_s)
@@ -130,4 +201,33 @@ class LogStash::Inputs::Twitter < LogStash::Inputs::Base
130
201
 
131
202
  event
132
203
  end
204
+
205
+ def configure(c)
206
+ c.consumer_key = @consumer_key
207
+ c.consumer_secret = @consumer_secret.value
208
+ c.access_token = @oauth_token
209
+ c.access_token_secret = @oauth_token_secret.value
210
+ end
211
+
212
+ def build_options
213
+ build_options = {}
214
+ build_options[:track] = @keywords.join(",") if @keywords && !@keywords.empty?
215
+ build_options[:locations] = @locations if @locations && !@locations.empty?
216
+ build_options[:language] = @languages.join(",") if @languages && !@languages.empty?
217
+
218
+ if @follows && @follows.length > 0
219
+ build_options[:follow] = @follows.map do |username|
220
+ ( !is_number?(username) ? find_user(username) : username )
221
+ end.join(",")
222
+ end
223
+ build_options
224
+ end
225
+
226
+ def find_user(username)
227
+ @rest_client.user(:user => username)
228
+ end
229
+
230
+ def is_number?(string)
231
+ /^(\d+)$/.match(string) ? true : false
232
+ end
133
233
  end # class LogStash::Inputs::Twitter
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-input-twitter'
4
- s.version = '2.0.2'
4
+ s.version = '2.1.0'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "Read events from the twitter streaming api."
7
7
  s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
21
21
 
22
22
  # Gem dependencies
23
23
  s.add_runtime_dependency "logstash-core", ">= 2.0.0.beta2", "< 3.0.0"
24
- s.add_runtime_dependency 'twitter', ['5.12.0']
24
+ s.add_runtime_dependency 'twitter', '5.14.0'
25
25
  s.add_runtime_dependency 'stud', '>= 0.0.22', '< 0.1'
26
26
 
27
27
  s.add_development_dependency 'logstash-devutils'
@@ -1,29 +1,193 @@
1
- require "logstash/devutils/rspec/spec_helper"
2
- require 'logstash/inputs/twitter'
3
- require 'twitter'
1
+ require_relative "../spec_helper"
4
2
 
5
- class MockClient
6
- def filter(options)
7
- loop { yield }
3
+ describe LogStash::Inputs::Twitter do
4
+
5
+ let(:config) do
6
+ {
7
+ 'consumer_key' => 'foo',
8
+ 'consumer_secret' => 'foo',
9
+ 'oauth_token' => 'foo',
10
+ 'oauth_token_secret' => 'foo',
11
+ 'keywords' => ['foo', 'bar']
12
+ }
8
13
  end
9
- end
10
14
 
11
- describe LogStash::Inputs::Twitter do
12
- context "when told to shutdown" do
13
- before :each do
15
+ let(:plugin) { LogStash::Inputs::Twitter.new(config) }
16
+
17
+ describe "registration" do
18
+
19
+ it "not raise error" do
20
+ expect {plugin.register}.to_not raise_error
21
+ end
22
+
23
+ context "with no required configuration fields" do
24
+ let(:config) do
25
+ {
26
+ 'consumer_key' => 'foo',
27
+ 'consumer_secret' => 'foo',
28
+ 'oauth_token' => 'foo',
29
+ 'oauth_token_secret' => 'foo',
30
+ }
31
+ end
32
+
33
+ it "raise an error if no required fields are specified" do
34
+ expect {plugin.register}.to raise_error(LogStash::ConfigurationError)
35
+ end
36
+ end
37
+ end
38
+
39
+ describe "when told to shutdown" do
40
+ before(:each) do
14
41
  allow(Twitter::Streaming::Client).to receive(:new).and_return(MockClient.new)
15
42
  end
43
+ it_behaves_like "an interruptible input plugin"
44
+ end
45
+
46
+ describe "fetching from sample" do
47
+
48
+ let(:input) { LogStash::Inputs::Twitter.new(config) }
49
+ let(:queue) { Queue.new }
50
+
51
+ let(:config) do
52
+ {
53
+ 'consumer_key' => 'foo',
54
+ 'consumer_secret' => 'foo',
55
+ 'oauth_token' => 'foo',
56
+ 'oauth_token_secret' => 'foo',
57
+ 'use_samples' => true
58
+ }
59
+ end
60
+
61
+ let(:stream_client) { double("stream-client") }
62
+
63
+ before(:each) do
64
+ input.register
65
+ input.set_stream_client(stream_client)
66
+ end
67
+
68
+ it "uses the sample endpoint" do
69
+ expect(stream_client).to receive(:sample).once
70
+ run_input_with(input, queue)
71
+ end
72
+
73
+ end
74
+
75
+ describe "stream filter" do
76
+
77
+ describe "options parsing" do
78
+
79
+ let(:plugin) { LogStash::Inputs::Twitter.new(config) }
16
80
 
17
- it_behaves_like "an interruptible input plugin" do
18
81
  let(:config) do
19
82
  {
20
83
  'consumer_key' => 'foo',
21
84
  'consumer_secret' => 'foo',
22
85
  'oauth_token' => 'foo',
23
86
  'oauth_token_secret' => 'foo',
24
- 'keywords' => ['foo', 'bar']
87
+ 'keywords' => ['foo'],
88
+ 'languages' => ['en', 'fr'],
89
+ 'locations' => "1234,2343",
90
+ 'follows' => [ '1234', '4321' ]
25
91
  }
26
92
  end
93
+
94
+ before(:each) do
95
+ plugin.register
96
+ end
97
+
98
+ let(:options) { plugin.twitter_options }
99
+
100
+ it "include the track filter in options" do
101
+ expect(options).to include(:track=>"foo")
102
+ end
103
+
104
+ it "include the language filter in options" do
105
+ expect(options).to include(:language=>"en,fr")
106
+ end
107
+
108
+ it "include the locations filter in options" do
109
+ expect(options).to include(:locations=>"1234,2343")
110
+ end
111
+
112
+ it "include the follows filter in options" do
113
+ expect(options).to include(:follow=>"1234,4321")
114
+ end
27
115
  end
116
+
117
+ describe "run" do
118
+
119
+ let(:input) { LogStash::Inputs::Twitter.new(config) }
120
+
121
+ let(:queue) { Queue.new }
122
+
123
+ let(:stream_client) { double("stream-client") }
124
+
125
+ let(:options) do
126
+ {:track=>"foo,bar"}
127
+ end
128
+
129
+ before(:each) do
130
+ input.register
131
+ input.set_stream_client(stream_client)
132
+ end
133
+
134
+ it "using the filter endpoint" do
135
+ expect(stream_client).to receive(:filter).with(options).once
136
+ run_input_with(input, queue)
137
+ end
138
+
139
+ context "when not filtering retweets" do
140
+
141
+ let(:tweet) { Twitter::Tweet.new(id: 1) }
142
+
143
+ let(:config) do
144
+ {
145
+ 'consumer_key' => 'foo',
146
+ 'consumer_secret' => 'foo',
147
+ 'oauth_token' => 'foo',
148
+ 'oauth_token_secret' => 'foo',
149
+ 'keywords' => ['foo'],
150
+ 'languages' => ['en', 'fr'],
151
+ 'locations' => "1234,2343",
152
+ 'ignore_retweets' => false
153
+ }
154
+ end
155
+
156
+ it "not exclude retweets" do
157
+ allow(tweet).to receive(:retweet?).and_return(true)
158
+ expect(input).to receive(:from_tweet).with(tweet)
159
+ expect(stream_client).to receive(:filter).at_least(:once).and_yield(tweet)
160
+ expect(queue).to receive(:<<)
161
+ run_input_with(input, queue)
162
+ end
163
+ end
164
+
165
+ context "when filtering retweets" do
166
+
167
+ let(:tweet) { Twitter::Tweet.new(id: 1) }
168
+
169
+ let(:config) do
170
+ {
171
+ 'consumer_key' => 'foo',
172
+ 'consumer_secret' => 'foo',
173
+ 'oauth_token' => 'foo',
174
+ 'oauth_token_secret' => 'foo',
175
+ 'keywords' => ['foo'],
176
+ 'languages' => ['en', 'fr'],
177
+ 'locations' => "1234,2343",
178
+ 'ignore_retweets' => true
179
+ }
180
+ end
181
+
182
+ it "exclude retweets" do
183
+ allow(tweet).to receive(:retweet?).and_return(true)
184
+ expect(stream_client).to receive(:filter).at_least(:once).and_yield(tweet)
185
+ expect(queue).not_to receive(:<<)
186
+ run_input_with(input, queue)
187
+ end
188
+ end
189
+
190
+ end
191
+
28
192
  end
29
193
  end
@@ -0,0 +1,75 @@
1
+ require_relative "../spec_helper"
2
+
3
+ describe LogStash::Inputs::Twitter do
4
+
5
+ describe "#receive", :integration => true do
6
+
7
+ context "keyword search" do
8
+ let(:config) do
9
+ <<-CONFIG
10
+ input {
11
+ twitter {
12
+ consumer_key => '#{ENV['TWITTER_CONSUMER_KEY']}'
13
+ consumer_secret => '#{ENV['TWITTER_CONSUMER_SECRET']}'
14
+ oauth_token => '#{ENV['TWITTER_OAUTH_TOKEN']}'
15
+ oauth_token_secret => '#{ENV['TWITTER_OAUTH_TOKEN_SECRET']}'
16
+ keywords => [ 'Barcelona' ]
17
+ full_tweet => true
18
+ }
19
+ }
20
+ CONFIG
21
+ end
22
+
23
+ let(:events) do
24
+ input(config) do |pipeline, queue|
25
+ 3.times.collect { queue.pop }
26
+ end
27
+ end
28
+
29
+ it "receive a list of events from the twitter stream" do
30
+ expect(events.count).to eq(3)
31
+ end
32
+ end
33
+
34
+ context "pulling from sample" do
35
+ let(:config) do
36
+ <<-CONFIG
37
+ input {
38
+ twitter {
39
+ consumer_key => '#{ENV['TWITTER_CONSUMER_KEY']}'
40
+ consumer_secret => '#{ENV['TWITTER_CONSUMER_SECRET']}'
41
+ oauth_token => '#{ENV['TWITTER_OAUTH_TOKEN']}'
42
+ oauth_token_secret => '#{ENV['TWITTER_OAUTH_TOKEN_SECRET']}'
43
+ use_samples => true
44
+ }
45
+ }
46
+ CONFIG
47
+ end
48
+
49
+ let(:events) do
50
+ input(config) do |pipeline, queue|
51
+ 3.times.collect { queue.pop }
52
+ end
53
+ end
54
+
55
+ let(:event) { events.first }
56
+
57
+ it "receive a list of events from the twitter stream" do
58
+ expect(events.count).to eq(3)
59
+ end
60
+
61
+ it "contains the hashtags" do
62
+ expect(event["hashtags"]).to be_truthy
63
+ end
64
+
65
+ it "contains the symbols" do
66
+ expect(event["symbols"]).to be_truthy
67
+ end
68
+
69
+ it "contains the user_mentions" do
70
+ expect(event["user_mentions"]).to be_truthy
71
+ end
72
+
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,19 @@
1
+ require "logstash/devutils/rspec/spec_helper"
2
+ require 'logstash/inputs/twitter'
3
+ require 'twitter'
4
+
5
+ class MockClient
6
+ def filter(options)
7
+ loop { yield }
8
+ end
9
+
10
+ alias_method :sample, :filter
11
+ end
12
+
13
+ def run_input_with(input, queue)
14
+ t = Thread.new(input, queue) do |_input, _queue|
15
+ _input.run(_queue)
16
+ end
17
+ sleep 0.1
18
+ t.kill
19
+ end
metadata CHANGED
@@ -1,17 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-input-twitter
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-14 00:00:00.000000000 Z
11
+ date: 2015-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- requirement: !ruby/object:Gem::Requirement
14
+ name: logstash-core
15
+ version_requirements: !ruby/object:Gem::Requirement
15
16
  requirements:
16
17
  - - '>='
17
18
  - !ruby/object:Gem::Version
@@ -19,10 +20,7 @@ dependencies:
19
20
  - - <
20
21
  - !ruby/object:Gem::Version
21
22
  version: 3.0.0
22
- name: logstash-core
23
- prerelease: false
24
- type: :runtime
25
- version_requirements: !ruby/object:Gem::Requirement
23
+ requirement: !ruby/object:Gem::Requirement
26
24
  requirements:
27
25
  - - '>='
28
26
  - !ruby/object:Gem::Version
@@ -30,21 +28,32 @@ dependencies:
30
28
  - - <
31
29
  - !ruby/object:Gem::Version
32
30
  version: 3.0.0
31
+ prerelease: false
32
+ type: :runtime
33
33
  - !ruby/object:Gem::Dependency
34
+ name: twitter
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - '='
38
+ - !ruby/object:Gem::Version
39
+ version: 5.14.0
34
40
  requirement: !ruby/object:Gem::Requirement
35
41
  requirements:
36
42
  - - '='
37
43
  - !ruby/object:Gem::Version
38
- version: 5.12.0
39
- name: twitter
44
+ version: 5.14.0
40
45
  prerelease: false
41
46
  type: :runtime
47
+ - !ruby/object:Gem::Dependency
48
+ name: stud
42
49
  version_requirements: !ruby/object:Gem::Requirement
43
50
  requirements:
44
- - - '='
51
+ - - '>='
45
52
  - !ruby/object:Gem::Version
46
- version: 5.12.0
47
- - !ruby/object:Gem::Dependency
53
+ version: 0.0.22
54
+ - - <
55
+ - !ruby/object:Gem::Version
56
+ version: '0.1'
48
57
  requirement: !ruby/object:Gem::Requirement
49
58
  requirements:
50
59
  - - '>='
@@ -53,60 +62,53 @@ dependencies:
53
62
  - - <
54
63
  - !ruby/object:Gem::Version
55
64
  version: '0.1'
56
- name: stud
57
65
  prerelease: false
58
66
  type: :runtime
67
+ - !ruby/object:Gem::Dependency
68
+ name: logstash-devutils
59
69
  version_requirements: !ruby/object:Gem::Requirement
60
70
  requirements:
61
71
  - - '>='
62
72
  - !ruby/object:Gem::Version
63
- version: 0.0.22
64
- - - <
65
- - !ruby/object:Gem::Version
66
- version: '0.1'
67
- - !ruby/object:Gem::Dependency
73
+ version: '0'
68
74
  requirement: !ruby/object:Gem::Requirement
69
75
  requirements:
70
76
  - - '>='
71
77
  - !ruby/object:Gem::Version
72
78
  version: '0'
73
- name: logstash-devutils
74
79
  prerelease: false
75
80
  type: :development
81
+ - !ruby/object:Gem::Dependency
82
+ name: logstash-codec-plain
76
83
  version_requirements: !ruby/object:Gem::Requirement
77
84
  requirements:
78
85
  - - '>='
79
86
  - !ruby/object:Gem::Version
80
87
  version: '0'
81
- - !ruby/object:Gem::Dependency
82
88
  requirement: !ruby/object:Gem::Requirement
83
89
  requirements:
84
90
  - - '>='
85
91
  - !ruby/object:Gem::Version
86
92
  version: '0'
87
- name: logstash-codec-plain
88
93
  prerelease: false
89
94
  type: :development
90
- version_requirements: !ruby/object:Gem::Requirement
91
- requirements:
92
- - - '>='
93
- - !ruby/object:Gem::Version
94
- version: '0'
95
95
  description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
96
96
  email: info@elastic.co
97
97
  executables: []
98
98
  extensions: []
99
99
  extra_rdoc_files: []
100
100
  files:
101
+ - lib/logstash/inputs/twitter.rb
102
+ - spec/spec_helper.rb
103
+ - spec/inputs/twitter_spec.rb
104
+ - spec/integration/twitter_spec.rb
105
+ - logstash-input-twitter.gemspec
101
106
  - CHANGELOG.md
107
+ - README.md
102
108
  - CONTRIBUTORS
103
109
  - Gemfile
104
110
  - LICENSE
105
111
  - NOTICE.TXT
106
- - README.md
107
- - lib/logstash/inputs/twitter.rb
108
- - logstash-input-twitter.gemspec
109
- - spec/inputs/twitter_spec.rb
110
112
  homepage: http://www.elastic.co/guide/en/logstash/current/index.html
111
113
  licenses:
112
114
  - Apache License (2.0)
@@ -129,9 +131,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
131
  version: '0'
130
132
  requirements: []
131
133
  rubyforge_project:
132
- rubygems_version: 2.4.8
134
+ rubygems_version: 2.1.9
133
135
  signing_key:
134
136
  specification_version: 4
135
137
  summary: Read events from the twitter streaming api.
136
138
  test_files:
139
+ - spec/spec_helper.rb
137
140
  - spec/inputs/twitter_spec.rb
141
+ - spec/integration/twitter_spec.rb