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.
Files changed (92) hide show
  1. data/History +7 -0
  2. data/License +17 -16
  3. data/Notes +33 -0
  4. data/README.rdoc +9 -0
  5. data/Rakefile +84 -42
  6. data/VERSION.yml +4 -0
  7. data/examples/connect.rb +32 -0
  8. data/examples/helpers/config_store.rb +30 -0
  9. data/examples/search.rb +6 -14
  10. data/examples/timeline.rb +13 -28
  11. data/examples/update.rb +11 -0
  12. data/lib/twitter/base.rb +93 -216
  13. data/lib/twitter/oauth.rb +31 -0
  14. data/lib/twitter/request.rb +87 -0
  15. data/lib/twitter/search.rb +10 -12
  16. data/lib/twitter.rb +25 -27
  17. data/test/fixtures/firehose.json +1 -0
  18. data/test/fixtures/friends_timeline.json +1 -0
  19. data/test/fixtures/rate_limit_exceeded.json +1 -0
  20. data/test/fixtures/replies.json +1 -0
  21. data/test/fixtures/search.json +1 -0
  22. data/test/fixtures/search_from_jnunemaker.json +1 -0
  23. data/test/fixtures/status.json +1 -0
  24. data/test/fixtures/user_timeline.json +1 -0
  25. data/test/test_helper.rb +34 -0
  26. data/test/twitter/base_test.rb +74 -0
  27. data/test/twitter/oauth_test.rb +55 -0
  28. data/test/twitter/request_test.rb +203 -0
  29. data/test/twitter/search_test.rb +128 -0
  30. data/test/twitter_test.rb +12 -0
  31. metadata +43 -124
  32. data/Manifest +0 -68
  33. data/README +0 -84
  34. data/bin/twitter +0 -14
  35. data/examples/blocks.rb +0 -15
  36. data/examples/direct_messages.rb +0 -29
  37. data/examples/favorites.rb +0 -20
  38. data/examples/friends_followers.rb +0 -25
  39. data/examples/friendships.rb +0 -13
  40. data/examples/identica_timeline.rb +0 -7
  41. data/examples/location.rb +0 -8
  42. data/examples/posting.rb +0 -9
  43. data/examples/replies.rb +0 -27
  44. data/examples/sent_messages.rb +0 -27
  45. data/examples/twitter.rb +0 -27
  46. data/examples/verify_credentials.rb +0 -13
  47. data/lib/twitter/cli/config.rb +0 -9
  48. data/lib/twitter/cli/helpers.rb +0 -109
  49. data/lib/twitter/cli/migrations/20080722194500_create_accounts.rb +0 -13
  50. data/lib/twitter/cli/migrations/20080722194508_create_tweets.rb +0 -16
  51. data/lib/twitter/cli/migrations/20080722214605_add_account_id_to_tweets.rb +0 -9
  52. data/lib/twitter/cli/migrations/20080722214606_create_configurations.rb +0 -13
  53. data/lib/twitter/cli/models/account.rb +0 -33
  54. data/lib/twitter/cli/models/configuration.rb +0 -13
  55. data/lib/twitter/cli/models/tweet.rb +0 -20
  56. data/lib/twitter/cli.rb +0 -334
  57. data/lib/twitter/direct_message.rb +0 -22
  58. data/lib/twitter/easy_class_maker.rb +0 -43
  59. data/lib/twitter/rate_limit_status.rb +0 -19
  60. data/lib/twitter/search_result.rb +0 -83
  61. data/lib/twitter/search_result_info.rb +0 -82
  62. data/lib/twitter/status.rb +0 -22
  63. data/lib/twitter/user.rb +0 -38
  64. data/lib/twitter/version.rb +0 -3
  65. data/spec/base_spec.rb +0 -139
  66. data/spec/cli/helper_spec.rb +0 -49
  67. data/spec/direct_message_spec.rb +0 -35
  68. data/spec/fixtures/follower_ids.xml +0 -11
  69. data/spec/fixtures/followers.xml +0 -706
  70. data/spec/fixtures/friend_ids.xml +0 -12
  71. data/spec/fixtures/friends.xml +0 -609
  72. data/spec/fixtures/friends_for.xml +0 -584
  73. data/spec/fixtures/friends_lite.xml +0 -192
  74. data/spec/fixtures/friends_timeline.xml +0 -66
  75. data/spec/fixtures/friendship_already_exists.xml +0 -5
  76. data/spec/fixtures/friendship_created.xml +0 -12
  77. data/spec/fixtures/public_timeline.xml +0 -148
  78. data/spec/fixtures/rate_limit_status.xml +0 -7
  79. data/spec/fixtures/search_result_info.yml +0 -147
  80. data/spec/fixtures/search_results.json +0 -1
  81. data/spec/fixtures/status.xml +0 -25
  82. data/spec/fixtures/user.xml +0 -38
  83. data/spec/fixtures/user_timeline.xml +0 -465
  84. data/spec/search_spec.rb +0 -100
  85. data/spec/spec.opts +0 -1
  86. data/spec/spec_helper.rb +0 -23
  87. data/spec/status_spec.rb +0 -40
  88. data/spec/user_spec.rb +0 -42
  89. data/twitter.gemspec +0 -45
  90. data/website/css/common.css +0 -47
  91. data/website/images/terminal_output.png +0 -0
  92. 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) 2007 John Nunemaker
1
+ Copyright (c) 2009 John Nunemaker
2
2
 
3
- Permission is hereby granted, free of charge, to any person obtaining a copy
4
- of this software and associated documentation files (the "Software"), to deal
5
- in the Software without restriction, including without limitation the rights
6
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- copies of the Software, and to permit persons to whom the Software is
8
- furnished to do so, subject to the following conditions:
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 included in
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, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
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
- ProjectName = 'twitter'
2
- WebsitePath = "jnunemaker@rubyforge.org:/var/www/gforge-projects/#{ProjectName}"
3
-
4
- require 'rubygems'
5
- require 'rake'
6
- require 'echoe'
7
- require 'spec/rake/spectask'
8
- require "lib/#{ProjectName}/version"
9
-
10
- Echoe.new(ProjectName, Twitter::Version) do |p|
11
- p.description = "a command line interface for twitter, also a library which wraps the twitter api"
12
- p.url = "http://#{ProjectName}.rubyforge.org"
13
- p.author = "John Nunemaker"
14
- p.email = "nunemaker@gmail.com"
15
- p.extra_deps = [['hpricot', '>= 0.6'], ['activesupport', '>= 2.1'], ['httparty', '>= 0.2.4']]
16
- p.need_tar_gz = false
17
- p.docs_host = WebsitePath
18
- end
19
-
20
- desc 'Upload website files to rubyforge'
21
- task :website do
22
- sh %{rsync -av website/ #{WebsitePath}}
23
- Rake::Task['website_docs'].invoke
24
- end
25
-
26
- task :website_docs do
27
- Rake::Task['redocs'].invoke
28
- sh %{rsync -av doc/ #{WebsitePath}/docs}
29
- end
30
-
31
- desc 'Preps the gem for a new release'
32
- task :prepare do
33
- %w[manifest build_gemspec].each do |task|
34
- Rake::Task[task].invoke
35
- end
36
- end
37
-
38
- Rake::Task[:default].prerequisites.clear
39
- task :default => :spec
40
- Spec::Rake::SpecTask.new do |t|
41
- t.spec_files = FileList["spec/**/*_spec.rb"]
42
- end
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
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 5
4
+ :patch: 0
@@ -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('httparty').each { |r| puts r.inspect,'' }
5
- Twitter::Search.new('httparty').page(2).each { |r| puts r.inspect, '' }
4
+ search = Twitter::Search.new.from('jnunemaker')
6
5
 
7
- # search = Twitter::Search.new
8
- # search.from('jnunemaker').to('oaknd1').each { |r| puts r.inspect, '' }
9
- # pp search.result
10
- # search.clear
6
+ puts '*'*50, 'First Run', '*'*50
7
+ search.each { |result| pp result }
11
8
 
12
- # search.from('jnunemaker').to('oaknd1').since(814529437).containing('milk').each { |r| puts r.inspect, '' }
13
- # search.clear
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
- config = YAML::load(open(ENV['HOME'] + '/.twitter'))
2
+ require File.join(File.dirname(__FILE__), 'helpers', 'config_store')
3
+ require 'pp'
5
4
 
6
- twitter = Twitter::Base.new(config['email'], config['password'])
5
+ config = ConfigStore.new("#{ENV['HOME']}/.twitter")
7
6
 
8
- puts 'SINCE'
9
- twitter.timeline(:user, :since => Time.now - 1.day).each do |s|
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
- puts 'SINCE_ID'
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
- puts 'COUNT'
23
- twitter.timeline(:user, :count => 1).each do |s|
24
- puts "- #{s.text}"
25
- end
26
- puts
27
- puts
12
+ pp client.friends_timeline
13
+ puts '*'*50
28
14
 
29
- puts 'PAGE'
30
- twitter.timeline(:user, :page => 1).each do |s|
31
- puts "- #{s.text}"
32
- end
33
- puts
34
- puts
15
+ pp client.user_timeline
16
+ puts '*'*50
17
+
18
+ pp client.replies
19
+ puts '*'*50
@@ -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')