markpercival-twitter_getter 1.0.6

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 ADDED
@@ -0,0 +1 @@
1
+ /spec/test_account.yaml
data/README.markdown ADDED
@@ -0,0 +1,24 @@
1
+ # TwitterGetter - A simple Twitter API gem
2
+
3
+ ## Installation
4
+
5
+ sudo gem install markpercival-twittergetter --sources http://gems.github.com
6
+
7
+ ## Usage
8
+
9
+ @tg = TwitterGetter::Base.new('ev', 'password')
10
+ tweets = @tg.search('failwhale')
11
+ tweets.each do |t|
12
+ p "#{t.from_user}: #{t.text}"
13
+ end
14
+
15
+ @tg.follow('aplusk')
16
+
17
+ ## License
18
+
19
+ This code is free to use under the terms of the MIT license.
20
+
21
+ ## Contact
22
+
23
+ Mark Percival <mark@mpercival.com>
24
+
@@ -0,0 +1,123 @@
1
+ require 'rubygems'
2
+ require 'cgi'
3
+ require 'rest_client'
4
+ require 'json/pure'
5
+ require 'twitter_getter/promiscuous_struct'
6
+
7
+ module TwitterGetter
8
+
9
+ class Tweet
10
+ include PromiscuousStruct
11
+ end
12
+
13
+ class User
14
+ include PromiscuousStruct
15
+ end
16
+
17
+ class Base
18
+
19
+ attr_accessor :user, :password
20
+
21
+ def initialize(user=nil, password=nil)
22
+ @user = user
23
+ @password = password
24
+ end
25
+
26
+ def update_status(message, in_reply_to_status_id = nil)
27
+ raise AuthenicationNeeded if @password.nil?
28
+ t = JSON.parse(RestClient.post("http://#{@user}:#{@password}@twitter.com/statuses/update.json",
29
+ :status => message,
30
+ :in_reply_to_status_id => in_reply_to_status_id))
31
+ Tweet.new(t)
32
+ end
33
+
34
+ def destroy_status(id)
35
+ raise AuthenicationNeeded if @password.nil?
36
+ t = JSON.parse(RestClient.post("http://#{@user}:#{@password}@twitter.com/statuses/destroy/#{id}.json", :id => id))
37
+ Tweet.new(t)
38
+ end
39
+
40
+ def status(id)
41
+ t = JSON.parse(RestClient.get("http://twitter.com/statuses/show/#{id}.json"))
42
+ Tweet.new(t)
43
+ end
44
+
45
+ def friend_ids
46
+ JSON.parse(RestClient.get("http://twitter.com/friends/ids/#{self.user}.json"))
47
+ end
48
+
49
+ def follower_ids
50
+ JSON.parse(RestClient.get("http://twitter.com/followers/ids/#{self.user}.json"))
51
+ end
52
+
53
+ def unfriendly_ids
54
+ self.friend_ids - self.follower_ids
55
+ end
56
+
57
+ def unfollow(id)
58
+ raise AuthenicationNeeded if @password.nil?
59
+ begin
60
+ u = JSON.parse(RestClient.post("http://#{@user}:#{@password}@twitter.com/friendships/destroy/#{id}.json", :id => id))
61
+ u['status'] ? User.new(u) : nil
62
+ rescue RestClient::ResourceNotFound => e
63
+ p "Error - #{e}"
64
+ nil
65
+ end
66
+ end
67
+
68
+ def follow(id)
69
+ raise AuthenicationNeeded if @password.nil?
70
+ begin
71
+ u = JSON.parse(RestClient.post("http://#{@user}:#{@password}@twitter.com/friendships/create/#{id}.json", :id => id))
72
+ u['status'] ? User.new(u) : nil
73
+ rescue RestClient::ResourceNotFound => e
74
+ p "Error - #{e}"
75
+ nil
76
+ end
77
+ end
78
+
79
+ def rate_limit_status
80
+ results = JSON.parse(RestClient.get("http://#{@user}:#{@password}@twitter.com/account/rate_limit_status.json"))
81
+ end
82
+
83
+ def search(term, opts = {})
84
+ if opts[:max_pages]
85
+ max_pages = opts[:max_pages]
86
+ opts.delete(:max_pages)
87
+ end
88
+ term = CGI.escape(term)
89
+ opts = {
90
+ :since_id => 10,
91
+ :rpp => 50
92
+ }.merge(opts)
93
+ params = hash2params(opts)
94
+ tweets = []
95
+ JSON.parse(RestClient.get("http://search.twitter.com/search.json?q=#{term}#{params}"))['results'].each do |t|
96
+ tweets << Tweet.new(t)
97
+ end
98
+ results = tweets.size
99
+ page = 2
100
+ while results == 50 && page <= max_pages.to_i
101
+ next_tweets = JSON.parse(RestClient.get("http://search.twitter.com/search.json?q=#{term}#{params}&page=#{page}"))['results']
102
+ results = next_tweets.size
103
+ next_tweets.each do |t|
104
+ tweets << Tweet.new(t)
105
+ end
106
+ page += 1
107
+ end
108
+ tweets.reverse
109
+ end
110
+
111
+ private
112
+
113
+ def hash2params(hash)
114
+ params = ''
115
+ hash.each_pair do |k,v|
116
+ params += "&#{k}=#{CGI.escape(v.to_s)}"
117
+ end
118
+ params
119
+ end
120
+
121
+
122
+ end
123
+ end
@@ -0,0 +1,35 @@
1
+ module PromiscuousStruct
2
+ attr_reader :attributes
3
+
4
+ def initialize(h)
5
+ @attributes = h
6
+ end
7
+
8
+ def get_val(a)
9
+ val = @attributes[a] || @attributes[a.to_s] || @attributes[a.to_sym]
10
+ if val.is_a?(Hash)
11
+ self.class.new(val)
12
+ else
13
+ val
14
+ end
15
+ end
16
+
17
+ def [](a)
18
+ get_val(a)
19
+ end
20
+
21
+ # an existing but depricated method we need to overide
22
+ def id
23
+ get_val(:id)
24
+ end
25
+
26
+ def method_missing(m)
27
+ if val = get_val(m)
28
+ return val
29
+ elsif @attributes.respond_to?(m)
30
+ return @attributes.send(m)
31
+ else
32
+ nil
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe TwitterGetter, "behaviour" do
4
+
5
+ it "should destroy an existing status" do
6
+ auth = YAML.load(File.open(File.dirname(__FILE__) + '/test_account.yaml'))
7
+ tg = TwitterGetter::Base.new(auth['user'], auth['password'])
8
+ p tg.destroy_status(1650005187)
9
+ end
10
+
11
+ end
@@ -0,0 +1,14 @@
1
+ dir = File.dirname(__FILE__)
2
+
3
+ $:.unshift(File.join(dir, '/../lib/'))
4
+ require dir + '/../lib/twitter_getter'
5
+
6
+
7
+ def unauthenticate_twitter
8
+ TwitterGetter::Base.new
9
+ end
10
+
11
+ def authenticated_twitter
12
+ auth = YAML.load(File.open(File.dirname(__FILE__) + '/test_account.yaml'))
13
+ TwitterGetter::Base.new(auth['user'], auth['password'])
14
+ end
@@ -0,0 +1,4 @@
1
+ ---
2
+ # Just rename this to test_account.yaml to run the specs
3
+ user: testaccount
4
+ password: secret
@@ -0,0 +1,48 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe TwitterGetter::Tweet, "behaviour" do
4
+
5
+
6
+ before :all do
7
+ @t = TwitterGetter::Tweet.new(:itsa => "hash", :andalso => {:complex=>true}, 'andevenallows' => 'string keys')
8
+ end
9
+
10
+ it "should instantiate with a hash and be accessible" do
11
+ @t.andalso.complex.should == true
12
+ @t.andalso[:complex].should == true
13
+ @t[:itsa].should == 'hash'
14
+ @t['itsa'].should == 'hash'
15
+ @t.itsa.should == 'hash'
16
+ @t.size.should == 3
17
+ end
18
+
19
+ it "should force instantiation with a hash" do
20
+ lambda {TwitterGetter::Tweet.new()}.should raise_error(ArgumentError)
21
+ end
22
+
23
+ it "should raise nil on an unknown method call" do
24
+ @t.wtf.should == nil
25
+ end
26
+
27
+
28
+ end
29
+
30
+
31
+ describe TwitterGetter, "example of what to expect in the return from twitter" do
32
+
33
+ before :all do
34
+ @tg = authenticated_twitter
35
+ @status_update = @tg.search('twitter').first
36
+ end
37
+
38
+ it "from a status update" do
39
+ @status_update.from_user.should be_an_instance_of(String)
40
+ end
41
+
42
+ it "from a user follow" do
43
+ user = @tg.follow(@status_update.from_user)
44
+ user.screen_name.should == @status_update.from_user
45
+ user.friends_count.should >= 0
46
+ end
47
+
48
+ end
@@ -0,0 +1,49 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+ require 'yaml'
3
+
4
+ describe TwitterGetter, "GeoIP search" do
5
+
6
+
7
+ before :all do
8
+ @tg = unauthenticate_twitter
9
+ end
10
+
11
+ it "should find all location based tweets" do
12
+ t = @tg.search('twitter', :geocode => '33.75916942652898,-84.38941955566406,100mi')
13
+ t.size.should eql(50)
14
+ t[0].from_user.size.should >= 1
15
+ end
16
+
17
+ it "should allow search multiple pages" do
18
+ t = @tg.search('twitter', :geocode => '33.75916942652898,-84.38941955566406,100mi', :max_pages => 2)
19
+ t.size.should eql(100)
20
+ end
21
+
22
+
23
+ end
24
+
25
+ describe TwitterGetter, "sends a tweet, find it, and destroy it" do
26
+
27
+ before :all do
28
+ @tg = authenticated_twitter
29
+ tweets = @tg.search('twitter')
30
+ t = tweets.first
31
+ @test_message = "RT @#{t.from_user} #{t.text[0, t.from_user.size + 5]}"
32
+ @test_update = @tg.update_status(@test_message)
33
+ end
34
+
35
+ it "should be able to send and then find a status update for the authenticated user" do
36
+ @test_update.text.should eql(@test_message)
37
+ end
38
+
39
+ it "should be able to find the test tweet" do
40
+ @tg.status(@test_update.id).text.should eql(@test_message)
41
+ end
42
+
43
+ it "should also be able to destroy it" do
44
+ @tg.destroy_status(@test_update.id).text.should eql(@test_message)
45
+ # Verify it's destroyed
46
+ lambda {@tg.status(@test_update.id)}.should raise_error(RestClient::Exception)
47
+ end
48
+
49
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: markpercival-twitter_getter
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.6
5
+ platform: ruby
6
+ authors:
7
+ - Mark Percival
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-09 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: mark@mpercival.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.markdown
24
+ files:
25
+ - .gitignore
26
+ - README.markdown
27
+ - lib/twitter_getter.rb
28
+ - lib/twitter_getter/promiscuous_struct.rb
29
+ - spec/destroy_spec.rb
30
+ - spec/spec_helper.rb
31
+ - spec/test_account.sample.yaml
32
+ - spec/tweet_spec.rb
33
+ - spec/twitter_getter_spec.rb
34
+ has_rdoc: true
35
+ homepage: http://github.com/markpercival/twitter_getter
36
+ post_install_message:
37
+ rdoc_options:
38
+ - --charset=UTF-8
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ requirements: []
54
+
55
+ rubyforge_project:
56
+ rubygems_version: 1.2.0
57
+ signing_key:
58
+ specification_version: 2
59
+ summary: TwitterGetter - The Twitter API Wrapper
60
+ test_files:
61
+ - spec/destroy_spec.rb
62
+ - spec/spec_helper.rb
63
+ - spec/tweet_spec.rb
64
+ - spec/twitter_getter_spec.rb