jnunemaker-twitter 0.4.4 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History +7 -0
- data/License +17 -16
- data/Notes +33 -0
- data/README.rdoc +9 -0
- data/Rakefile +84 -42
- data/VERSION.yml +4 -0
- data/examples/connect.rb +32 -0
- data/examples/helpers/config_store.rb +30 -0
- data/examples/search.rb +6 -14
- data/examples/timeline.rb +13 -28
- data/examples/update.rb +11 -0
- data/lib/twitter/base.rb +93 -216
- data/lib/twitter/oauth.rb +31 -0
- data/lib/twitter/request.rb +87 -0
- data/lib/twitter/search.rb +10 -12
- data/lib/twitter.rb +25 -27
- data/test/fixtures/firehose.json +1 -0
- data/test/fixtures/friends_timeline.json +1 -0
- data/test/fixtures/rate_limit_exceeded.json +1 -0
- data/test/fixtures/replies.json +1 -0
- data/test/fixtures/search.json +1 -0
- data/test/fixtures/search_from_jnunemaker.json +1 -0
- data/test/fixtures/status.json +1 -0
- data/test/fixtures/user_timeline.json +1 -0
- data/test/test_helper.rb +34 -0
- data/test/twitter/base_test.rb +74 -0
- data/test/twitter/oauth_test.rb +55 -0
- data/test/twitter/request_test.rb +203 -0
- data/test/twitter/search_test.rb +128 -0
- data/test/twitter_test.rb +12 -0
- metadata +43 -124
- data/Manifest +0 -68
- data/README +0 -84
- data/bin/twitter +0 -14
- data/examples/blocks.rb +0 -15
- data/examples/direct_messages.rb +0 -29
- data/examples/favorites.rb +0 -20
- data/examples/friends_followers.rb +0 -25
- data/examples/friendships.rb +0 -13
- data/examples/identica_timeline.rb +0 -7
- data/examples/location.rb +0 -8
- data/examples/posting.rb +0 -9
- data/examples/replies.rb +0 -27
- data/examples/sent_messages.rb +0 -27
- data/examples/twitter.rb +0 -27
- data/examples/verify_credentials.rb +0 -13
- data/lib/twitter/cli/config.rb +0 -9
- data/lib/twitter/cli/helpers.rb +0 -109
- data/lib/twitter/cli/migrations/20080722194500_create_accounts.rb +0 -13
- data/lib/twitter/cli/migrations/20080722194508_create_tweets.rb +0 -16
- data/lib/twitter/cli/migrations/20080722214605_add_account_id_to_tweets.rb +0 -9
- data/lib/twitter/cli/migrations/20080722214606_create_configurations.rb +0 -13
- data/lib/twitter/cli/models/account.rb +0 -33
- data/lib/twitter/cli/models/configuration.rb +0 -13
- data/lib/twitter/cli/models/tweet.rb +0 -20
- data/lib/twitter/cli.rb +0 -334
- data/lib/twitter/direct_message.rb +0 -22
- data/lib/twitter/easy_class_maker.rb +0 -43
- data/lib/twitter/rate_limit_status.rb +0 -19
- data/lib/twitter/search_result.rb +0 -83
- data/lib/twitter/search_result_info.rb +0 -82
- data/lib/twitter/status.rb +0 -22
- data/lib/twitter/user.rb +0 -38
- data/lib/twitter/version.rb +0 -3
- data/spec/base_spec.rb +0 -139
- data/spec/cli/helper_spec.rb +0 -49
- data/spec/direct_message_spec.rb +0 -35
- data/spec/fixtures/follower_ids.xml +0 -11
- data/spec/fixtures/followers.xml +0 -706
- data/spec/fixtures/friend_ids.xml +0 -12
- data/spec/fixtures/friends.xml +0 -609
- data/spec/fixtures/friends_for.xml +0 -584
- data/spec/fixtures/friends_lite.xml +0 -192
- data/spec/fixtures/friends_timeline.xml +0 -66
- data/spec/fixtures/friendship_already_exists.xml +0 -5
- data/spec/fixtures/friendship_created.xml +0 -12
- data/spec/fixtures/public_timeline.xml +0 -148
- data/spec/fixtures/rate_limit_status.xml +0 -7
- data/spec/fixtures/search_result_info.yml +0 -147
- data/spec/fixtures/search_results.json +0 -1
- data/spec/fixtures/status.xml +0 -25
- data/spec/fixtures/user.xml +0 -38
- data/spec/fixtures/user_timeline.xml +0 -465
- data/spec/search_spec.rb +0 -100
- data/spec/spec.opts +0 -1
- data/spec/spec_helper.rb +0 -23
- data/spec/status_spec.rb +0 -40
- data/spec/user_spec.rb +0 -42
- data/twitter.gemspec +0 -45
- data/website/css/common.css +0 -47
- data/website/images/terminal_output.png +0 -0
- data/website/index.html +0 -147
data/History
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
0.5.0 - March 3, 2009
|
2
|
+
* 1 major rewrite for OAuth
|
3
|
+
* Backwards compatibility thrown to the wind
|
4
|
+
* Proxy no longer supported (someone please add it back in, I never use proxies)
|
5
|
+
* Identica support killed with an axe (nothing against them but I don't use it)
|
6
|
+
* CLI shot to death (will be reborn at a later date using oauth and its own gem)
|
7
|
+
|
1
8
|
0.4.3 - February 21, 2009
|
2
9
|
* 1 minor enhancement
|
3
10
|
* verify_credentials now returns a Twitter::User rather than an hpricot doc
|
data/License
CHANGED
@@ -1,19 +1,20 @@
|
|
1
|
-
Copyright (c)
|
1
|
+
Copyright (c) 2009 John Nunemaker
|
2
2
|
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
-
of this software and associated documentation files (the
|
5
|
-
in the Software without restriction, including
|
6
|
-
to use, copy, modify, merge, publish,
|
7
|
-
copies of the Software, and to
|
8
|
-
furnished to do so, subject to
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
9
10
|
|
10
|
-
The above copyright notice and this permission notice shall be
|
11
|
-
all copies or substantial portions of the Software.
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
12
13
|
|
13
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
14
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
15
|
-
FITNESS FOR A PARTICULAR PURPOSE AND
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
THE SOFTWARE.
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Notes
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
*****************************************************************
|
2
|
+
* From Twitter API Docs, so I don't have to keep going to them. *
|
3
|
+
*****************************************************************
|
4
|
+
|
5
|
+
http://apiwiki.twitter.com/REST+API+Documentation
|
6
|
+
|
7
|
+
200 OK: everything went awesome.
|
8
|
+
304 Not Modified: there was no new data to return.
|
9
|
+
400 Bad Request: your request is invalid, and we'll return an error message that tells you why. This is the status code returned if you've exceeded the rate limit (see below).
|
10
|
+
401 Not Authorized: either you need to provide authentication credentials, or the credentials provided aren't valid.
|
11
|
+
403 Forbidden: we understand your request, but are refusing to fulfill it. An accompanying error message should explain why.
|
12
|
+
404 Not Found: either you're requesting an invalid URI or the resource in question doesn't exist (ex: no such user).
|
13
|
+
500 Internal Server Error: we did something wrong. Please post to the group about it and the Twitter team will investigate.
|
14
|
+
502 Bad Gateway: returned if Twitter is down or being upgraded.
|
15
|
+
503 Service Unavailable: the Twitter servers are up, but are overloaded with requests. Try again later.
|
16
|
+
|
17
|
+
**********
|
18
|
+
* Errors *
|
19
|
+
**********
|
20
|
+
|
21
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
22
|
+
<hash>
|
23
|
+
<request>/direct_messages/destroy/456.xml</request>
|
24
|
+
<error>No direct message with that ID found.</error>
|
25
|
+
</hash>
|
26
|
+
|
27
|
+
**********************
|
28
|
+
* Rate Limit Headers *
|
29
|
+
**********************
|
30
|
+
|
31
|
+
X-RateLimit-Limit the current limit in effect
|
32
|
+
X-RateLimit-Remaining the number of hits remaining before you are rate limited
|
33
|
+
X-RateLimit-Reset the time the current rate limiting period ends (in epoch time, number of seconds since 1970-01-01 00:00:00)
|
data/README.rdoc
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
= twitter
|
2
|
+
|
3
|
+
The ruby twitter gem. The gem heard round the world and famous on the streets. Haha.
|
4
|
+
|
5
|
+
For now this is just an API wrapper. The command line interface is temporarily dead until I have time to make it work with oauth. At that point, I'll make it a new gem twitter-cli or something and it will depend on this gem to work. That will keep the separation of the api wrapper and cli and fix a lot of dependency issues.
|
6
|
+
|
7
|
+
== Copyright
|
8
|
+
|
9
|
+
Copyright (c) 2009 John Nunemaker. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -1,42 +1,84 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
require '
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "twitter"
|
8
|
+
gem.summary = %Q{wrapper for the twitter api (oauth only)}
|
9
|
+
gem.email = "nunemaker@gmail.com"
|
10
|
+
gem.homepage = "http://github.com/jnunemaker/twitter"
|
11
|
+
gem.authors = ["John Nunemaker"]
|
12
|
+
gem.rubyforge_project = "twitter"
|
13
|
+
gem.files = FileList["[A-Z]*", "{examples,lib,test}/**/*"]
|
14
|
+
|
15
|
+
gem.add_dependency('oauth')
|
16
|
+
gem.add_dependency('httparty', '>= 0.4.2')
|
17
|
+
end
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'rake/testtask'
|
23
|
+
Rake::TestTask.new(:test) do |test|
|
24
|
+
test.libs << 'lib' << 'test'
|
25
|
+
test.pattern = 'test/**/*_test.rb'
|
26
|
+
test.verbose = false
|
27
|
+
end
|
28
|
+
|
29
|
+
begin
|
30
|
+
require 'rcov/rcovtask'
|
31
|
+
Rcov::RcovTask.new do |test|
|
32
|
+
test.libs << 'test'
|
33
|
+
test.pattern = 'test/**/*_test.rb'
|
34
|
+
test.verbose = true
|
35
|
+
end
|
36
|
+
rescue LoadError
|
37
|
+
task :rcov do
|
38
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
if File.exist?('VERSION.yml')
|
48
|
+
config = YAML.load(File.read('VERSION.yml'))
|
49
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
50
|
+
else
|
51
|
+
version = ""
|
52
|
+
end
|
53
|
+
|
54
|
+
rdoc.rdoc_dir = 'rdoc'
|
55
|
+
rdoc.title = "twitter #{version}"
|
56
|
+
rdoc.rdoc_files.include('README*')
|
57
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
58
|
+
end
|
59
|
+
|
60
|
+
begin
|
61
|
+
require 'rake/contrib/sshpublisher'
|
62
|
+
namespace :rubyforge do
|
63
|
+
|
64
|
+
desc "Release gem and RDoc documentation to RubyForge"
|
65
|
+
task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
|
66
|
+
|
67
|
+
namespace :release do
|
68
|
+
desc "Publish RDoc to RubyForge."
|
69
|
+
task :docs => [:rdoc] do
|
70
|
+
config = YAML.load(
|
71
|
+
File.read(File.expand_path('~/.rubyforge/user-config.yml'))
|
72
|
+
)
|
73
|
+
|
74
|
+
host = "#{config['username']}@rubyforge.org"
|
75
|
+
remote_dir = "/var/www/gforge-projects/twitter/"
|
76
|
+
local_dir = 'rdoc'
|
77
|
+
|
78
|
+
Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
rescue LoadError
|
83
|
+
puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
|
84
|
+
end
|
data/VERSION.yml
ADDED
data/examples/connect.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
2
|
+
require File.join(File.dirname(__FILE__), 'helpers', 'config_store')
|
3
|
+
require 'pp'
|
4
|
+
|
5
|
+
config = ConfigStore.new("#{ENV['HOME']}/.twitter")
|
6
|
+
oauth = Twitter::OAuth.new(config['token'], config['secret'])
|
7
|
+
|
8
|
+
if config['atoken'] && config['asecret']
|
9
|
+
oauth.authorize_from_access(config['atoken'], config['asecret'])
|
10
|
+
# puts oauth.access_token.get("/statuses/friends_timeline.json")
|
11
|
+
twitter = Twitter::Base.new(oauth)
|
12
|
+
pp twitter.friends_timeline
|
13
|
+
|
14
|
+
elsif config['rtoken'] && config['rsecret']
|
15
|
+
oauth.authorize_from_request(config['rtoken'], config['rsecret'])
|
16
|
+
puts oauth.access_token.get("/statuses/friends_timeline.json")
|
17
|
+
|
18
|
+
config.update({
|
19
|
+
'atoken' => oauth.access_token.token,
|
20
|
+
'asecret' => oauth.access_token.secret,
|
21
|
+
'rtoken' => nil,
|
22
|
+
'rsecret' => nil,
|
23
|
+
})
|
24
|
+
else
|
25
|
+
config.update({
|
26
|
+
'rtoken' => oauth.request_token.token,
|
27
|
+
'rsecret' => oauth.request_token.secret,
|
28
|
+
})
|
29
|
+
|
30
|
+
# authorize in browser
|
31
|
+
%x(open #{oauth.request_token.authorize_url})
|
32
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class ConfigStore
|
2
|
+
attr_reader :file
|
3
|
+
|
4
|
+
def initialize(file)
|
5
|
+
@file = file
|
6
|
+
end
|
7
|
+
|
8
|
+
def load
|
9
|
+
@config ||= YAML::load(open(file))
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](key)
|
14
|
+
load
|
15
|
+
@config[key]
|
16
|
+
end
|
17
|
+
|
18
|
+
def []=(key, value)
|
19
|
+
@config[key] = value
|
20
|
+
end
|
21
|
+
|
22
|
+
def update(c={})
|
23
|
+
@config.merge!(c)
|
24
|
+
save
|
25
|
+
end
|
26
|
+
|
27
|
+
def save
|
28
|
+
File.open(file, 'w') { |f| f.write(YAML.dump(@config)) }
|
29
|
+
end
|
30
|
+
end
|
data/examples/search.rb
CHANGED
@@ -1,18 +1,10 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
2
|
+
require 'pp'
|
3
3
|
|
4
|
-
Twitter::Search.new('
|
5
|
-
Twitter::Search.new('httparty').page(2).each { |r| puts r.inspect, '' }
|
4
|
+
search = Twitter::Search.new.from('jnunemaker')
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
# pp search.result
|
10
|
-
# search.clear
|
6
|
+
puts '*'*50, 'First Run', '*'*50
|
7
|
+
search.each { |result| pp result }
|
11
8
|
|
12
|
-
|
13
|
-
|
14
|
-
#
|
15
|
-
# search.geocode('40.757929', '-73.985506', '50mi').containing('holland').each { |r| puts r.inspect, '' }
|
16
|
-
# search.clear
|
17
|
-
|
18
|
-
# pp search.from('jnunemaker').fetch()
|
9
|
+
puts '*'*50, 'Second Run', '*'*50
|
10
|
+
search.each { |result| pp result }
|
data/examples/timeline.rb
CHANGED
@@ -1,34 +1,19 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'activesupport'
|
3
1
|
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
4
|
-
|
2
|
+
require File.join(File.dirname(__FILE__), 'helpers', 'config_store')
|
3
|
+
require 'pp'
|
5
4
|
|
6
|
-
|
5
|
+
config = ConfigStore.new("#{ENV['HOME']}/.twitter")
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
puts "- #{s.text}"
|
11
|
-
end
|
12
|
-
puts
|
13
|
-
puts
|
7
|
+
oauth = Twitter::OAuth.new(config['token'], config['secret'])
|
8
|
+
oauth.authorize_from_access(config['atoken'], config['asecret'])
|
14
9
|
|
15
|
-
|
16
|
-
twitter.timeline(:user, :since_id => 865547074).each do |s|
|
17
|
-
puts "- #{s.text}"
|
18
|
-
end
|
19
|
-
puts
|
20
|
-
puts
|
10
|
+
client = Twitter::Base.new(oauth)
|
21
11
|
|
22
|
-
|
23
|
-
|
24
|
-
puts "- #{s.text}"
|
25
|
-
end
|
26
|
-
puts
|
27
|
-
puts
|
12
|
+
pp client.friends_timeline
|
13
|
+
puts '*'*50
|
28
14
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
puts
|
34
|
-
puts
|
15
|
+
pp client.user_timeline
|
16
|
+
puts '*'*50
|
17
|
+
|
18
|
+
pp client.replies
|
19
|
+
puts '*'*50
|
data/examples/update.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
2
|
+
require File.join(File.dirname(__FILE__), 'helpers', 'config_store')
|
3
|
+
require 'pp'
|
4
|
+
|
5
|
+
config = ConfigStore.new("#{ENV['HOME']}/.twitter")
|
6
|
+
|
7
|
+
oauth = Twitter::OAuth.new(config['token'], config['secret'])
|
8
|
+
oauth.authorize_from_access(config['atoken'], config['asecret'])
|
9
|
+
|
10
|
+
client = Twitter::Base.new(oauth)
|
11
|
+
pp client.update('This is an update from the twitter gem')
|