logstash-input-twitter 2.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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