weeter 0.9.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.
- data/.gitignore +8 -0
- data/Gemfile +4 -0
- data/LICENSE +9 -0
- data/README.md +98 -0
- data/Rakefile +2 -0
- data/bin/weeter +6 -0
- data/bin/weeter_control +7 -0
- data/lib/weeter/.DS_Store +0 -0
- data/lib/weeter/cli.rb +24 -0
- data/lib/weeter/configuration/client_app_config.rb +12 -0
- data/lib/weeter/configuration/twitter_config.rb +21 -0
- data/lib/weeter/configuration.rb +22 -0
- data/lib/weeter/plugins/lib/oauth_http.rb +40 -0
- data/lib/weeter/plugins/lib/redis.rb +17 -0
- data/lib/weeter/plugins/notification/http.rb +26 -0
- data/lib/weeter/plugins/notification/resque.rb +39 -0
- data/lib/weeter/plugins/notification_plugin.rb +26 -0
- data/lib/weeter/plugins/subscription/http.rb +45 -0
- data/lib/weeter/plugins/subscription/redis.rb +46 -0
- data/lib/weeter/plugins/subscription_plugin.rb +26 -0
- data/lib/weeter/plugins.rb +4 -0
- data/lib/weeter/runner.rb +40 -0
- data/lib/weeter/tasks.rb +16 -0
- data/lib/weeter/twitter/tweet_consumer.rb +67 -0
- data/lib/weeter/twitter/tweet_item.rb +35 -0
- data/lib/weeter/twitter.rb +2 -0
- data/lib/weeter/version.rb +3 -0
- data/lib/weeter.rb +29 -0
- data/log/.gitignore +0 -0
- data/spec/.DS_Store +0 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/weeter/configuration/client_app_config_spec.rb +18 -0
- data/spec/weeter/configuration/twitter_config_spec.rb +39 -0
- data/spec/weeter/configuration_spec.rb +15 -0
- data/spec/weeter/plugins/notification_plugin_spec.rb +22 -0
- data/spec/weeter/plugins/subscription/update_server_spec.rb +30 -0
- data/spec/weeter/plugins/subscription_plugin_spec.rb +23 -0
- data/spec/weeter/runner_spec.rb +7 -0
- data/spec/weeter/twitter/tweet_consumer_spec.rb +64 -0
- data/spec/weeter/twitter/tweet_item_spec.rb +66 -0
- data/weeter.conf.example +51 -0
- data/weeter.gemspec +34 -0
- metadata +228 -0
data/lib/weeter.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'json'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
require 'weeter/configuration'
|
6
|
+
require 'weeter/cli'
|
7
|
+
require 'weeter/plugins'
|
8
|
+
require 'weeter/runner'
|
9
|
+
require 'weeter/twitter'
|
10
|
+
|
11
|
+
|
12
|
+
module Weeter
|
13
|
+
|
14
|
+
def self.configure
|
15
|
+
yield Configuration.instance
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.logger
|
19
|
+
@logger ||= begin
|
20
|
+
if Configuration.instance.log_path == false
|
21
|
+
nil
|
22
|
+
elsif Configuration.instance.log_path
|
23
|
+
Logger.new(Configuration.instance.log_path)
|
24
|
+
else
|
25
|
+
Logger.new(STDOUT)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/log/.gitignore
ADDED
File without changes
|
data/spec/.DS_Store
ADDED
Binary file
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Weeter::Configuration::ClientAppConfig do
|
4
|
+
%w{delete_url subscriptions_url oauth}.each do |setting|
|
5
|
+
it "should accept setting for #{setting}" do
|
6
|
+
Weeter.configure do |conf|
|
7
|
+
conf.client_app do |app|
|
8
|
+
app.send("#{setting}=", "testvalue")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
Weeter::Configuration.instance.client_app.send(setting).should == "testvalue"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should default subscription_updates_port" do
|
16
|
+
Weeter::Configuration.instance.client_app.subscription_updates_port.should == 7337
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Weeter::Configuration::TwitterConfig do
|
4
|
+
%w{basic_auth oauth}.each do |setting|
|
5
|
+
it "should accept setting for #{setting}" do
|
6
|
+
Weeter.configure do |conf|
|
7
|
+
conf.twitter do |app|
|
8
|
+
app.send("#{setting}=", "testvalue")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
Weeter::Configuration::TwitterConfig.instance.send(setting).should == "testvalue"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "auth_options" do
|
16
|
+
|
17
|
+
before do
|
18
|
+
Weeter::Configuration::TwitterConfig.instance.oauth = nil
|
19
|
+
Weeter::Configuration::TwitterConfig.instance.basic_auth = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should return the oauth settings with a oauth credentials" do
|
23
|
+
Weeter::Configuration::TwitterConfig.instance.oauth = {:consumer_key => 'consumer_key', :consumer_secret => 'consumer_secret', :access_key => 'acces_key', :access_secret => 'access_secret'}
|
24
|
+
Weeter::Configuration::TwitterConfig.instance.auth_options.should == {:oauth => {:consumer_key => 'consumer_key', :consumer_secret => 'consumer_secret', :access_key => 'acces_key', :access_secret => 'access_secret'}}
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return the basic auth settings separated by a colon" do
|
28
|
+
Weeter::Configuration::TwitterConfig.instance.basic_auth = {:username => "bob", :password => "s3cr3t"}
|
29
|
+
Weeter::Configuration::TwitterConfig.instance.auth_options.should == {:auth => "bob:s3cr3t"}
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should prefer oauth over basic auth" do
|
33
|
+
Weeter::Configuration::TwitterConfig.instance.basic_auth = {:username => "bob", :password => "s3cr3t"}
|
34
|
+
Weeter::Configuration::TwitterConfig.instance.oauth = {:consumer_key => 'consumer_key', :consumer_secret => 'consumer_secret', :access_key => 'acces_key', :access_secret => 'access_secret'}
|
35
|
+
Weeter::Configuration::TwitterConfig.instance.auth_options.should == {:oauth => {:consumer_key => 'consumer_key', :consumer_secret => 'consumer_secret', :access_key => 'acces_key', :access_secret => 'access_secret'}}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Weeter::Configuration do
|
4
|
+
describe "#twitter" do
|
5
|
+
it "should return the instance" do
|
6
|
+
Weeter::Configuration.instance.twitter.should == Weeter::Configuration::TwitterConfig.instance
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should yield the instance when a block is provided" do
|
10
|
+
Weeter::Configuration.instance.twitter do |twitter_config|
|
11
|
+
twitter_config.should == Weeter::Configuration::TwitterConfig.instance
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Weeter
|
4
|
+
module Plugins
|
5
|
+
describe NotificationPlugin do
|
6
|
+
describe "#publish_tweet" do
|
7
|
+
it "should delegate to the configured plugin" do
|
8
|
+
client_app_config = Hashie::Mash.new(:notification_plugin => :http)
|
9
|
+
tweet_item = TweetItem.new({})
|
10
|
+
|
11
|
+
mock_plugin = mock(Notification::Http)
|
12
|
+
Notification::Http.should_receive(:new).and_return(mock_plugin)
|
13
|
+
|
14
|
+
mock_plugin.should_receive(:publish_tweet).with(tweet_item)
|
15
|
+
|
16
|
+
plugin = NotificationPlugin.new(client_app_config)
|
17
|
+
plugin.publish_tweet(tweet_item)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Weeter
|
3
|
+
module Plugins
|
4
|
+
module Subscription
|
5
|
+
describe Http::UpdateServer do
|
6
|
+
before(:each) do
|
7
|
+
@new_ids = [1,2,3]
|
8
|
+
@tweet_consumer = mock('TweetConsumer', :reconnect => nil)
|
9
|
+
@tweet_server = Http::UpdateServer.new(nil)
|
10
|
+
@tweet_server.instance_variable_set('@http_post_content', MultiJson.encode(@new_ids))
|
11
|
+
@tweet_server.tweet_consumer = @tweet_consumer
|
12
|
+
@response = mock('DelegatedHttpResponse', :send_response => nil)
|
13
|
+
EM::DelegatedHttpResponse.stub!(:new).and_return(@response)
|
14
|
+
end
|
15
|
+
|
16
|
+
after(:each) do
|
17
|
+
@tweet_server.process_http_request
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should process http request" do
|
21
|
+
@tweet_consumer.should_receive(:reconnect).with(@new_ids)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should send response" do
|
25
|
+
@response.should_receive(:send_response)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Weeter
|
4
|
+
module Plugins
|
5
|
+
describe SubscriptionPlugin do
|
6
|
+
describe "#get_initial_filters" do
|
7
|
+
it "should delegate to the configured plugin" do
|
8
|
+
client_app_config = Hashie::Mash.new(:subscription_plugin => :http)
|
9
|
+
|
10
|
+
mock_plugin = mock(Subscription::Http)
|
11
|
+
Subscription::Http.should_receive(:new).and_return(mock_plugin)
|
12
|
+
|
13
|
+
mock_plugin.should_receive(:get_initial_filters).and_yield([{'foo' => 'bar'}])
|
14
|
+
|
15
|
+
plugin = SubscriptionPlugin.new(client_app_config)
|
16
|
+
plugin.get_initial_filters do |filter_params|
|
17
|
+
filter_params.should == [{'foo' => 'bar'}]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Weeter::Twitter::TweetConsumer do
|
4
|
+
|
5
|
+
|
6
|
+
describe "auth" do
|
7
|
+
it 'should use connect to JSON stream with auth options for the configuration' do
|
8
|
+
@mock_stream = mock('JSONStream', :each_item => nil, :on_error => nil, :on_max_reconnects => nil)
|
9
|
+
Twitter::JSONStream.stub!(:connect).and_return(@mock_stream)
|
10
|
+
|
11
|
+
Weeter::Configuration::TwitterConfig.instance.stub!(:auth_options).and_return(:foo => :bar)
|
12
|
+
consumer = Weeter::Twitter::TweetConsumer.new(Weeter::Configuration::TwitterConfig.instance, mock('NotificationPlugin'))
|
13
|
+
Twitter::JSONStream.should_receive(:connect).with(hash_including(:foo => :bar))
|
14
|
+
consumer.connect({'follow' => ['1','2']})
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "connecting to twitter" do
|
19
|
+
|
20
|
+
before(:each) do
|
21
|
+
@filter_params = {'follow' => ['1','2','3']}
|
22
|
+
Weeter::Configuration::TwitterConfig.instance.stub!(:auth_options).and_return(:foo => :bar)
|
23
|
+
@tweet_values = {'text' => "Hey", 'id_str' => "123", 'user' => {'id_str' => "1"}}
|
24
|
+
@mock_stream = mock('JSONStream', :on_error => nil, :on_max_reconnects => nil)
|
25
|
+
@mock_stream.stub!(:each_item).and_yield(MultiJson.encode(@tweet_values))
|
26
|
+
Twitter::JSONStream.stub!(:connect).and_return(@mock_stream)
|
27
|
+
@client_proxy = mock('NotificationPlugin', :publish_tweet => nil)
|
28
|
+
@consumer = Weeter::Twitter::TweetConsumer.new(Weeter::Configuration::TwitterConfig.instance, @client_proxy)
|
29
|
+
end
|
30
|
+
|
31
|
+
after(:each) do
|
32
|
+
@consumer.connect(@filter_params)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should instantiate a TweetItem" do
|
36
|
+
tweet_item = Weeter::TweetItem.new(@tweet_values)
|
37
|
+
Weeter::TweetItem.should_receive(:new).with({'text' => "Hey", 'id_str' => "123", 'user' => {'id_str' => "1"}}).and_return(tweet_item)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should connect to a Twitter JSON stream" do
|
41
|
+
Twitter::JSONStream.should_receive(:connect).
|
42
|
+
with(:ssl => true, :foo => :bar, :params => @filter_params, :method => 'POST')
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should publish new tweet if publishable" do
|
46
|
+
mock_tweet = mock('tweet', :deletion? => false, :publishable? => true)
|
47
|
+
tweet_item = Weeter::TweetItem.stub!(:new).and_return mock_tweet
|
48
|
+
@client_proxy.should_receive(:publish_tweet).with(mock_tweet)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should not publish unpublishable tweets" do
|
52
|
+
mock_tweet = mock('tweet', :deletion? => false, :publishable? => false, :[] => '')
|
53
|
+
tweet_item = Weeter::TweetItem.stub!(:new).and_return mock_tweet
|
54
|
+
@client_proxy.should_not_receive(:publish_tweet).with(mock_tweet)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should delete deletion tweets" do
|
58
|
+
mock_tweet = mock('tweet', :deletion? => true, :publishable? => false)
|
59
|
+
tweet_item = Weeter::TweetItem.stub!(:new).and_return mock_tweet
|
60
|
+
@client_proxy.should_receive(:delete_tweet).with(mock_tweet)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Weeter::TweetItem do
|
4
|
+
|
5
|
+
describe "deletion?" do
|
6
|
+
it "should be true if it is a deletion request" do
|
7
|
+
item = Weeter::TweetItem.new({"delete"=>{"status"=>{"id"=>234, "user_id"=>34555}}})
|
8
|
+
item.should be_deletion
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be false if it is not a deletion request" do
|
12
|
+
item = Weeter::TweetItem.new({'text' => "Hey", 'id_str' => "123", 'user' => {'id_str' => "1"}})
|
13
|
+
item.should_not be_deletion
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "publishable" do
|
18
|
+
|
19
|
+
before do
|
20
|
+
@tweet_json = {'text' => "Hey", 'id_str' => "123", 'user' => {'id_str' => '1'}}
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be publishable if not a reply or a retweet" do
|
24
|
+
item = Weeter::TweetItem.new(@tweet_json)
|
25
|
+
item.should be_publishable
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not be publishable if implicitly retweeted" do
|
29
|
+
item = Weeter::TweetItem.new(@tweet_json.merge({'text' => 'RT @joe Hey'}))
|
30
|
+
item.should_not be_publishable
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should not be publishable if explicitly retweeted" do
|
34
|
+
item = Weeter::TweetItem.new(@tweet_json.merge('retweeted_status' => {'id_str' => '111', 'text' => 'Hey', 'user' => {'id_str' => "1"}}))
|
35
|
+
item.should_not be_publishable
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should not be publishable if implicit reply" do
|
39
|
+
item = Weeter::TweetItem.new(@tweet_json.merge('text' => '@joe Hey'))
|
40
|
+
item.should_not be_publishable
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should not be publishable if explicit reply" do
|
44
|
+
item = Weeter::TweetItem.new(@tweet_json.merge('text' => '@joe Hey', 'in_reply_to_user_id_str' => '1'))
|
45
|
+
item.should_not be_publishable
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "json attributes" do
|
51
|
+
|
52
|
+
it "should delegate hash calls to its json" do
|
53
|
+
item = Weeter::TweetItem.new({'text' => "Hey"})
|
54
|
+
item['text'].should == "Hey"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should retrieve nested attributes" do
|
58
|
+
item = Weeter::TweetItem.new({'text' => "Hey", 'id_str' => "123", 'user' => {'id_str' => '1'}})
|
59
|
+
item['user']['id_str'].should == "1"
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
end
|
data/weeter.conf.example
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#
|
2
|
+
# Customize this configuration file according to your environment.
|
3
|
+
#
|
4
|
+
Weeter.configure do |conf|
|
5
|
+
|
6
|
+
# To log to STDOUT, don't specify anything.
|
7
|
+
# To log to a specific path:
|
8
|
+
# conf.log_path = '/tmp/weeter.log'
|
9
|
+
# To disable logging:
|
10
|
+
# conf.log_path = false
|
11
|
+
|
12
|
+
conf.twitter do |twitter|
|
13
|
+
# For basic auth
|
14
|
+
# twitter.basic_auth = {:username => 'johnny', :password => 'secret'}
|
15
|
+
|
16
|
+
# Or, for oauth
|
17
|
+
twitter.oauth = {:consumer_key => ENV['WEETER_TWITTER_CONSUMER_KEY'],
|
18
|
+
:consumer_secret => ENV['WEETER_TWITTER_CONSUMER_SECRET'],
|
19
|
+
:access_key => ENV['WEETER_TWITTER_ACCESS_KEY'],
|
20
|
+
:access_secret => ENV['WEETER_TWITTER_ACCESS_SECRET']
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
conf.client_app do |client_app|
|
25
|
+
client_app.notification_plugin = :http
|
26
|
+
client_app.oauth = {
|
27
|
+
:consumer_key => ENV['WEETER_CLIENT_CONSUMER_KEY'],
|
28
|
+
:consumer_secret => ENV['WEETER_CLIENT_CONSUMER_SECRET'],
|
29
|
+
:access_key => ENV['WEETER_CLIENT_ACCESS_KEY'],
|
30
|
+
:access_secret => ENV['WEETER_CLIENT_ACCESS_SECRET']
|
31
|
+
}
|
32
|
+
client_app.publish_url = ENV['WEETER_CLIENT_PUBLISH_URL']
|
33
|
+
client_app.delete_url = ENV['WEETER_CLIENT_DELETE_URL']
|
34
|
+
|
35
|
+
client_app.subscription_plugin = :http
|
36
|
+
client_app.subscriptions_url = ENV['WEETER_CLIENT_SUBSCRIPTIONS_URL']
|
37
|
+
client_app.subscription_updates_port = 7337 # only effective if running as a daemon
|
38
|
+
end
|
39
|
+
|
40
|
+
# Alternately...
|
41
|
+
|
42
|
+
# conf.client_app do |client_app|
|
43
|
+
# client_app.notification_plugin = :resque
|
44
|
+
# client_app.queue = 'weeter'
|
45
|
+
# client_app.redis_uri = 'redis://redistogo:abcdef0123456789abcdef0123456789@somehost.redistogo.com:9052/'
|
46
|
+
#
|
47
|
+
# client_app.subscription_plugin = :redis
|
48
|
+
# client_app.subscriptions_key = 'weeter:subscriptions'
|
49
|
+
# client_app.subscriptions_changed_channel = 'weeter:subscriptions_changed'
|
50
|
+
# end
|
51
|
+
end
|
data/weeter.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "weeter/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "weeter"
|
7
|
+
s.version = Weeter::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Luke Melia", "Noah Davis", "Joey Aghion"]
|
10
|
+
s.email = ["luke@lukemelia.com"]
|
11
|
+
s.homepage = "http://github.com/lukemelia/weeter"
|
12
|
+
s.summary = %q{Consume the Twitter stream and notify your app}
|
13
|
+
s.description = %q{Weeter subscribes to a set of twitter users or search terms using Twitter's streaming API, and notifies your app with each new tweet.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "weeter"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency('eventmachine')
|
23
|
+
s.add_dependency('eventmachine_httpserver', '>= 0.2.1')
|
24
|
+
s.add_dependency('em-hiredis', '>= 0.1.0')
|
25
|
+
s.add_dependency('multi_json', '>= 1.0.2')
|
26
|
+
s.add_dependency('hashie', '>= 1.1.0')
|
27
|
+
s.add_dependency('em-http-request', '>= 1.0.0')
|
28
|
+
s.add_dependency('i18n', "~> 0.6.0")
|
29
|
+
s.add_dependency('activesupport', ">= 3.1.1")
|
30
|
+
s.add_dependency("simple_oauth", '~> 0.1.5')
|
31
|
+
s.add_dependency('twitter-stream', '~> 0.1.14')
|
32
|
+
|
33
|
+
s.add_development_dependency 'rspec', '~> 2.6.0'
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,228 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: weeter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.9.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Luke Melia
|
9
|
+
- Noah Davis
|
10
|
+
- Joey Aghion
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
|
15
|
+
date: 2011-11-02 00:00:00 Z
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
18
|
+
name: eventmachine
|
19
|
+
prerelease: false
|
20
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
21
|
+
none: false
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: "0"
|
26
|
+
type: :runtime
|
27
|
+
version_requirements: *id001
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: eventmachine_httpserver
|
30
|
+
prerelease: false
|
31
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
32
|
+
none: false
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 0.2.1
|
37
|
+
type: :runtime
|
38
|
+
version_requirements: *id002
|
39
|
+
- !ruby/object:Gem::Dependency
|
40
|
+
name: em-hiredis
|
41
|
+
prerelease: false
|
42
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.1.0
|
48
|
+
type: :runtime
|
49
|
+
version_requirements: *id003
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: multi_json
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: 1.0.2
|
59
|
+
type: :runtime
|
60
|
+
version_requirements: *id004
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: hashie
|
63
|
+
prerelease: false
|
64
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.1.0
|
70
|
+
type: :runtime
|
71
|
+
version_requirements: *id005
|
72
|
+
- !ruby/object:Gem::Dependency
|
73
|
+
name: em-http-request
|
74
|
+
prerelease: false
|
75
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 1.0.0
|
81
|
+
type: :runtime
|
82
|
+
version_requirements: *id006
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: i18n
|
85
|
+
prerelease: false
|
86
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ~>
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: 0.6.0
|
92
|
+
type: :runtime
|
93
|
+
version_requirements: *id007
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: activesupport
|
96
|
+
prerelease: false
|
97
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 3.1.1
|
103
|
+
type: :runtime
|
104
|
+
version_requirements: *id008
|
105
|
+
- !ruby/object:Gem::Dependency
|
106
|
+
name: simple_oauth
|
107
|
+
prerelease: false
|
108
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ~>
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: 0.1.5
|
114
|
+
type: :runtime
|
115
|
+
version_requirements: *id009
|
116
|
+
- !ruby/object:Gem::Dependency
|
117
|
+
name: twitter-stream
|
118
|
+
prerelease: false
|
119
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ~>
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.1.14
|
125
|
+
type: :runtime
|
126
|
+
version_requirements: *id010
|
127
|
+
- !ruby/object:Gem::Dependency
|
128
|
+
name: rspec
|
129
|
+
prerelease: false
|
130
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ~>
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: 2.6.0
|
136
|
+
type: :development
|
137
|
+
version_requirements: *id011
|
138
|
+
description: Weeter subscribes to a set of twitter users or search terms using Twitter's streaming API, and notifies your app with each new tweet.
|
139
|
+
email:
|
140
|
+
- luke@lukemelia.com
|
141
|
+
executables:
|
142
|
+
- weeter
|
143
|
+
- weeter_control
|
144
|
+
extensions: []
|
145
|
+
|
146
|
+
extra_rdoc_files: []
|
147
|
+
|
148
|
+
files:
|
149
|
+
- .gitignore
|
150
|
+
- Gemfile
|
151
|
+
- LICENSE
|
152
|
+
- README.md
|
153
|
+
- Rakefile
|
154
|
+
- bin/weeter
|
155
|
+
- bin/weeter_control
|
156
|
+
- lib/weeter.rb
|
157
|
+
- lib/weeter/.DS_Store
|
158
|
+
- lib/weeter/cli.rb
|
159
|
+
- lib/weeter/configuration.rb
|
160
|
+
- lib/weeter/configuration/client_app_config.rb
|
161
|
+
- lib/weeter/configuration/twitter_config.rb
|
162
|
+
- lib/weeter/plugins.rb
|
163
|
+
- lib/weeter/plugins/lib/oauth_http.rb
|
164
|
+
- lib/weeter/plugins/lib/redis.rb
|
165
|
+
- lib/weeter/plugins/notification/http.rb
|
166
|
+
- lib/weeter/plugins/notification/resque.rb
|
167
|
+
- lib/weeter/plugins/notification_plugin.rb
|
168
|
+
- lib/weeter/plugins/subscription/http.rb
|
169
|
+
- lib/weeter/plugins/subscription/redis.rb
|
170
|
+
- lib/weeter/plugins/subscription_plugin.rb
|
171
|
+
- lib/weeter/runner.rb
|
172
|
+
- lib/weeter/tasks.rb
|
173
|
+
- lib/weeter/twitter.rb
|
174
|
+
- lib/weeter/twitter/tweet_consumer.rb
|
175
|
+
- lib/weeter/twitter/tweet_item.rb
|
176
|
+
- lib/weeter/version.rb
|
177
|
+
- log/.gitignore
|
178
|
+
- spec/.DS_Store
|
179
|
+
- spec/spec_helper.rb
|
180
|
+
- spec/weeter/configuration/client_app_config_spec.rb
|
181
|
+
- spec/weeter/configuration/twitter_config_spec.rb
|
182
|
+
- spec/weeter/configuration_spec.rb
|
183
|
+
- spec/weeter/plugins/notification_plugin_spec.rb
|
184
|
+
- spec/weeter/plugins/subscription/update_server_spec.rb
|
185
|
+
- spec/weeter/plugins/subscription_plugin_spec.rb
|
186
|
+
- spec/weeter/runner_spec.rb
|
187
|
+
- spec/weeter/twitter/tweet_consumer_spec.rb
|
188
|
+
- spec/weeter/twitter/tweet_item_spec.rb
|
189
|
+
- weeter.conf.example
|
190
|
+
- weeter.gemspec
|
191
|
+
homepage: http://github.com/lukemelia/weeter
|
192
|
+
licenses: []
|
193
|
+
|
194
|
+
post_install_message:
|
195
|
+
rdoc_options: []
|
196
|
+
|
197
|
+
require_paths:
|
198
|
+
- lib
|
199
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
200
|
+
none: false
|
201
|
+
requirements:
|
202
|
+
- - ">="
|
203
|
+
- !ruby/object:Gem::Version
|
204
|
+
version: "0"
|
205
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
206
|
+
none: false
|
207
|
+
requirements:
|
208
|
+
- - ">="
|
209
|
+
- !ruby/object:Gem::Version
|
210
|
+
version: "0"
|
211
|
+
requirements: []
|
212
|
+
|
213
|
+
rubyforge_project: weeter
|
214
|
+
rubygems_version: 1.8.10
|
215
|
+
signing_key:
|
216
|
+
specification_version: 3
|
217
|
+
summary: Consume the Twitter stream and notify your app
|
218
|
+
test_files:
|
219
|
+
- spec/spec_helper.rb
|
220
|
+
- spec/weeter/configuration/client_app_config_spec.rb
|
221
|
+
- spec/weeter/configuration/twitter_config_spec.rb
|
222
|
+
- spec/weeter/configuration_spec.rb
|
223
|
+
- spec/weeter/plugins/notification_plugin_spec.rb
|
224
|
+
- spec/weeter/plugins/subscription/update_server_spec.rb
|
225
|
+
- spec/weeter/plugins/subscription_plugin_spec.rb
|
226
|
+
- spec/weeter/runner_spec.rb
|
227
|
+
- spec/weeter/twitter/tweet_consumer_spec.rb
|
228
|
+
- spec/weeter/twitter/tweet_item_spec.rb
|