jnunemaker-twitter 0.4.4 → 0.5.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/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')
|