mbbx6spp-twitter4r 0.3.1 → 0.4.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/CHANGES CHANGED
@@ -3,6 +3,11 @@
3
3
  Catalog(ue) of changes for Twitter4R 0.1.x releases including Retrospectiva ticket cross-reference numbers. Refer to http://retro.tautology.net/projects/twitter4r/tickets for more information.
4
4
 
5
5
  == 0.3.1 Changes
6
+ *
7
+ * Added specs for Twitter::Client#profile (:info, :colors and :device cases)
8
+ * Added Twitter4R shell
9
+ * Improved code coverage for twitter/ext/stdlib code and removed hard coded extension in GET request path for retrieving account information
10
+ * Changed Twitter::RESTError super class to be RuntimeError instead of Exception
6
11
  * Added URI.encode => CGI.escape fix
7
12
  * Added block methods
8
13
  * Added Twitter::Client#inspect method to XXXX out passwords
data/README CHANGED
@@ -7,10 +7,15 @@
7
7
  * {Susan Potter}[http://SusanPotter.NET] <me at susanpotter dot net>
8
8
 
9
9
  == Contributors
10
+ Code:
10
11
  * Kaiichi Matsunaga <ma2 at lifemedia dot co dot jp> - proxy code suggestion
11
12
  * Sergio Santos <> - message paging code suggestion
12
13
  * Adam Stiles <adam at stilesoft dot com> - URI.encode => CGI.escape fix
13
14
  * Carl Crawley <cwcrawley at gmail dot com> - Friendship get => post fix
15
+ * Christian Johansen <christian at cjohansen dot no> - in_reply_to attributes in Twitter::Status
16
+
17
+ Design Suggestions:
18
+ * Bosco So <rubymeetup at boscoso dot com> - making Twitter::Error a RuntimeError instead of an Exception to prevent irb from crashing out.
14
19
 
15
20
  == Description
16
21
  Twitter4R provides an object based API to query or update your Twitter account via pure Ruby. It hides the ugly HTTP/REST code from your code.
data/TODO CHANGED
@@ -1,9 +1,7 @@
1
1
 
2
2
  0.3.1 TODO:
3
3
  * Add specs for :page, :lite and :since options support in Twitter::Client#my(...), Twitter::Client#user(....) and Twitter::User#followers calls
4
- * Add specs for Kernel#gem_present? extension
5
- * Add spec to test that warning is given to Rails 2.0+ users requiring 'twitter/rails'
6
4
  * Add specs for :replies support in Twitter::Client#status(...) and Twitter::Client#timeline_for(...)
7
5
  * Add RDoc for :replies support
8
6
  * Add better RDoc for Twitter::Client.account_info(:rate_limit_status)
9
- * Add specs for Twitter::Client.account_info(:rate_limit_status)
7
+ * Add specs for Twitter::Client.account_info(:rate_limit_status)
data/bin/t4rsh ADDED
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require("irb")
4
+ require("irb/completion")
5
+ require("rubygems")
6
+
7
+ begin
8
+ gem('twitter4r', '>0.3.0')
9
+ require("twitter")
10
+ require("twitter/console")
11
+ rescue Gem::LoadError
12
+ begin
13
+ gem("mbbx6spp-twitter4r", '>=0.3.1')
14
+ require("twitter")
15
+ require("twitter/console")
16
+ rescue Gem::LoadError
17
+ abort("Error: You must install either twitter4r gem from Rubyforge with version 0.3.1 or greater or the mbbx6spp-twitter4r gem from GitHub's servers with version 0.3.1 or greater (and make sure it is a recent version of the gem).")
18
+ end
19
+ end
20
+
21
+ module Twitter
22
+ class Console
23
+ class << self
24
+ @@OPTIONS = { :debugger => false, :config => "~/.twitter4r/accounts.yml" }
25
+ def parse_options
26
+ OptionParser.new do |opt|
27
+ opt.banner = "Usage: t4rsh [environment] [options]"
28
+ opt.on("--config=[~/.twitter4r/accounts.yml]", 'Use a specific config file.') { |v| @@OPTIONS[:config] = v }
29
+ opt.parse!(ARGV)
30
+ end
31
+ end
32
+
33
+ def config_file
34
+ result = ENV["T4R_CONFIG"]
35
+ file_name = File.expand_path('twitter.yml')
36
+ result ||= file_name if File.exists?(file_name)
37
+ file_name = File.expand_path('twitter.yml', 'config')
38
+ result ||= file_name if File.exists?(file_name)
39
+ file_name = File.expand_path('~/.twitter.yml')
40
+ result ||= file_name if File.exists?(file_name)
41
+ result
42
+ end
43
+
44
+ def account
45
+ ENV["T4R_ENV"] || ENV["MERB_ENV"] || ENV["RAILS_ENV"]
46
+ end
47
+
48
+ def run(file)
49
+ IRB.init_config(nil)
50
+ # configuration...
51
+ IRB.conf[:IRB_NAME] = "t4rsh"
52
+ IRB.conf[:VERSION] = Twitter::Version.to_version
53
+ IRB.conf[:USE_READLINE] = true
54
+ IRB.conf[:PROMPT_MODE] = :T4RSH
55
+ IRB.conf[:PROMPT][:T4RSH] = {
56
+ :PROMPT_I => "%N[%3n:%i]> ", # top level prompt
57
+ :PROMPT_C => "%N[%3n:%i]* ", # after conditional like "if"
58
+ :PROMPT_S => "%N[%3n:%i]* ", # during continuing string
59
+ :RETURN => "=> %s\n", # return value
60
+ }
61
+ IRB.start(file)
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ #if __FILE__ == $0
68
+ @twitter = nil
69
+ config_file = Twitter::Console.config_file
70
+ account = Twitter::Console.account
71
+
72
+ if config_file && account
73
+ @twitter = Twitter::Client.from_config(config_file, account)
74
+ puts "Used #{config_file} to create client for #{account} account."
75
+ puts "Access @twitter for instantiated client."
76
+ Twitter::Console.run(__FILE__)
77
+ else
78
+ abort("Please make sure #{config_file} exists and contains your Twitter credentials (separated by account/environment) and that you specify the account/environment to use, e.g. if you have a 'test' section in your configuration file that you want to use set/export T4R_ENV=test as an environment variable or RAILS_ENV=test or MERB_ENV=test")
79
+ end
80
+ #end
data/lib/twitter.rb CHANGED
@@ -1,4 +1,5 @@
1
- #
1
+ #
2
+ require('rubygems')
2
3
 
3
4
  module Twitter; end
4
5
 
@@ -6,9 +7,11 @@ def require_local(suffix)
6
7
  require(File.expand_path(File.join(File.dirname(__FILE__), suffix)))
7
8
  end
8
9
 
9
- # For better unicode support
10
- $KCODE = 'u'
11
- require 'jcode'
10
+ # For better unicode support in 1.8
11
+ if RUBY_VERSION < '1.9'
12
+ $KCODE = 'u'
13
+ require 'jcode'
14
+ end
12
15
 
13
16
  # External requires
14
17
  require('yaml')
@@ -9,13 +9,16 @@ class Twitter::Client
9
9
  include Twitter::ClassUtilMixin
10
10
  end
11
11
 
12
- require('twitter/client/base.rb')
13
- require('twitter/client/timeline.rb')
14
- require('twitter/client/status.rb')
15
- require('twitter/client/friendship.rb')
16
- require('twitter/client/messaging.rb')
17
- require('twitter/client/user.rb')
18
- require('twitter/client/auth.rb')
19
- require('twitter/client/favorites.rb')
20
- require('twitter/client/blocks.rb')
21
- require('twitter/client/account.rb')
12
+ require('twitter/client/base')
13
+ require('twitter/client/timeline')
14
+ require('twitter/client/status')
15
+ require('twitter/client/friendship')
16
+ require('twitter/client/messaging')
17
+ require('twitter/client/user')
18
+ require('twitter/client/auth')
19
+ require('twitter/client/favorites')
20
+ require('twitter/client/blocks')
21
+ require('twitter/client/account')
22
+ require('twitter/client/graph')
23
+ require('twitter/client/profile')
24
+ require('twitter/client/search')
@@ -3,22 +3,22 @@ class Twitter::Client
3
3
  :rate_limit_status => '/account/rate_limit_status',
4
4
  }
5
5
 
6
- # Provides access to the Twitter rate limit status API.
7
- #
8
- # You can find out information about your account status. Currently the only
9
- # supported type of account status is the <tt>:rate_limit_status</tt> which
10
- # returns a <tt>Twitter::RateLimitStatus</tt> object.
6
+ # Provides access to the Twitter rate limit status API.
11
7
  #
12
- # Example:
13
- # account_status = client.account_info
14
- # puts account_status.remaining_hits
15
- def account_info(type = :rate_limit_status)
16
- connection = create_http_connection
17
- connection.start do |connection|
18
- response = http_connect do |conn|
19
- create_http_get_request("#{@@ACCOUNT_URIS[type]}.json")
20
- end
21
- bless_models(Twitter::RateLimitStatus.unmarshal(response.body))
8
+ # You can find out information about your account status. Currently the only
9
+ # supported type of account status is the <tt>:rate_limit_status</tt> which
10
+ # returns a <tt>Twitter::RateLimitStatus</tt> object.
11
+ #
12
+ # Example:
13
+ # account_status = client.account_info
14
+ # puts account_status.remaining_hits
15
+ def account_info(type = :rate_limit_status)
16
+ connection = create_http_connection
17
+ connection.start do |connection|
18
+ response = http_connect do |conn|
19
+ create_http_get_request(@@ACCOUNT_URIS[type])
20
+ end
21
+ bless_models(Twitter::RateLimitStatus.unmarshal(response.body))
22
22
  end
23
- end
23
+ end
24
24
  end
@@ -1,16 +1,18 @@
1
1
  class Twitter::Client
2
2
  alias :old_inspect :inspect
3
+
3
4
  def inspect
4
5
  s = old_inspect
5
6
  s.gsub!(/@password=".*?"/, '@password="XXXX"')
6
7
  end
8
+
7
9
  protected
8
10
  attr_accessor :login, :password
9
11
 
10
12
  # Returns the response of the HTTP connection.
11
- def http_connect(body = nil, require_auth = true, &block)
13
+ def http_connect(body = nil, require_auth = true, service = :rest, &block)
12
14
  require_block(block_given?)
13
- connection = create_http_connection
15
+ connection = create_http_connection(service)
14
16
  connection.start do |connection|
15
17
  request = yield connection if block_given?
16
18
  request.basic_auth(@login, @password) if require_auth
@@ -34,8 +36,10 @@ class Twitter::Client
34
36
  @@http_header = nil
35
37
 
36
38
  def raise_rest_error(response, uri = nil)
39
+ map = JSON.parse(response.body)
37
40
  raise Twitter::RESTError.new(:code => response.code,
38
41
  :message => response.message,
42
+ :error => map["error"],
39
43
  :uri => uri)
40
44
  end
41
45
 
@@ -45,11 +49,17 @@ class Twitter::Client
45
49
  end
46
50
  end
47
51
 
48
- def create_http_connection
49
- conn = Net::HTTP.new(@@config.host, @@config.port,
52
+ def create_http_connection(service = :rest)
53
+ case service
54
+ when :rest
55
+ protocol, host, port = @@config.protocol, @@config.host, @@config.port
56
+ when :search
57
+ protocol, host, port = @@config.search_protocol, @@config.search_host, @@config.search_port
58
+ end
59
+ conn = Net::HTTP.new(host, port,
50
60
  @@config.proxy_host, @@config.proxy_port,
51
61
  @@config.proxy_user, @@config.proxy_pass)
52
- if @@config.protocol == :ssl
62
+ if protocol == :ssl
53
63
  conn.use_ssl = true
54
64
  conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
55
65
  end
@@ -84,4 +94,3 @@ class Twitter::Client
84
94
  Net::HTTP::Delete.new(path, http_header)
85
95
  end
86
96
  end
87
-
@@ -1,9 +1,9 @@
1
1
  class Twitter::Client
2
2
  # Why Twitter.com developers can't correctly document their API, I do not know!
3
- @@FAVORITES_URIS = {
4
- :add => '/favourings/create',
5
- :remove => '/favourings/destroy',
6
- }
3
+ @@FAVORITES_URIS = {
4
+ :add => '/favourings/create',
5
+ :remove => '/favourings/destroy',
6
+ }
7
7
 
8
8
  # Provides access to the Twitter list favorites API.
9
9
  #
@@ -13,41 +13,41 @@ class Twitter::Client
13
13
  # To get a previous page you can provide options to this method. For example,
14
14
  # statuses = client.favorites(:page => 2)
15
15
  # The above one-liner will get the second page of favorites for the authenticated user.
16
- def favorites(options = nil)
17
- def uri_suffix(opts); opts && opts[:page] ? "?page=#{opts[:page]}" : ""; end
16
+ def favorites(options = nil)
17
+ def uri_suffix(opts); opts && opts[:page] ? "?page=#{opts[:page]}" : ""; end
18
18
  uri = '/favorites.json' + uri_suffix(options)
19
19
  response = http_connect {|conn| create_http_get_request(uri) }
20
20
  bless_models(Twitter::Status.unmarshal(response.body))
21
- end
21
+ end
22
22
 
23
- # Provides access to the Twitter add/remove favorite API.
24
- #
25
- # You can add and remove favorite status using this method.
26
- #
27
- # <tt>action</tt> can be any of the following values:
28
- # * <tt>:add</tt> - to add a status to your favorites, you would use this <tt>action</tt> value
29
- # * <tt>:remove</tt> - to remove an status from your existing favorites list use this.
30
- #
31
- # The <tt>value</tt> must be either the status object to add or remove or
32
- # the integer unique status ID.
33
- #
34
- # Examples:
35
- # id = 126006103423
36
- # client.favorite(:add, id)
37
- # client.favorite(:remove, id)
38
- # status = Twitter::Status.find(id, client)
39
- # client.favorite(:add, status)
40
- # client.favorite(:remove, status)
41
- def favorite(action, value)
42
- raise ArgumentError, "Invalid favorite action provided: #{action}" unless @@FAVORITES_URIS.keys.member?(action)
43
- value = value.to_i.to_s unless value.is_a?(String)
44
- uri = "#{@@FAVORITES_URIS[action]}/#{value}.json"
45
- case action
46
- when :add
47
- response = http_connect {|conn| create_http_post_request(uri) }
48
- when :remove
49
- response = http_connect {|conn| create_http_delete_request(uri) }
50
- end
51
- bless_model(Twitter::Status.unmarshal(response.body))
52
- end
23
+ # Provides access to the Twitter add/remove favorite API.
24
+ #
25
+ # You can add and remove favorite status using this method.
26
+ #
27
+ # <tt>action</tt> can be any of the following values:
28
+ # * <tt>:add</tt> - to add a status to your favorites, you would use this <tt>action</tt> value
29
+ # * <tt>:remove</tt> - to remove an status from your existing favorites list use this.
30
+ #
31
+ # The <tt>value</tt> must be either the status object to add or remove or
32
+ # the integer unique status ID.
33
+ #
34
+ # Examples:
35
+ # id = 126006103423
36
+ # client.favorite(:add, id)
37
+ # client.favorite(:remove, id)
38
+ # status = Twitter::Status.find(id, client)
39
+ # client.favorite(:add, status)
40
+ # client.favorite(:remove, status)
41
+ def favorite(action, value)
42
+ raise ArgumentError, "Invalid favorite action provided: #{action}" unless @@FAVORITES_URIS.keys.member?(action)
43
+ value = value.to_i.to_s unless value.is_a?(String)
44
+ uri = "#{@@FAVORITES_URIS[action]}/#{value}.json"
45
+ case action
46
+ when :add
47
+ response = http_connect {|conn| create_http_post_request(uri) }
48
+ when :remove
49
+ response = http_connect {|conn| create_http_delete_request(uri) }
50
+ end
51
+ bless_model(Twitter::Status.unmarshal(response.body))
52
+ end
53
53
  end
@@ -0,0 +1,37 @@
1
+ class Twitter::Client
2
+ @@GRAPH_URIS = {
3
+ :friends => '/friends/ids',
4
+ :followers => '/followers/ids',
5
+ }
6
+
7
+ # Provides access to the Twitter Social Graphing API.
8
+ #
9
+ # You can retrieve the full graph of a user's friends or followers in one method call.
10
+ #
11
+ # <tt>action</tt> can be any of the following values:
12
+ # * <tt>:friends</tt> - retrieves ids of all friends of a given user.
13
+ # * <tt>:followers</tt> - retrieves ids of all followers of a given user.
14
+ #
15
+ # The <tt>value</tt> must be either the user screen name, integer unique user ID or Twitter::User
16
+ # object representation.
17
+ #
18
+ # Examples:
19
+ # screen_name = 'dictionary'
20
+ # client.graph(:friends, 'dictionary')
21
+ # client.graph(:followers, 'dictionary')
22
+ # id = 1260061
23
+ # client.graph(:friends, id)
24
+ # client.graph(:followers, id)
25
+ # user = Twitter::User.find(id, client)
26
+ # client.graph(:friends, user)
27
+ # client.graph(:followers, user)
28
+ def graph(action, value = nil)
29
+ raise ArgumentError, "Invalid friend action provided: #{action}" unless @@GRAPH_URIS.keys.member?(action)
30
+ id = value.to_i unless value.nil? || value.is_a?(String)
31
+ id ||= value
32
+ id ||= @login
33
+ uri = "#{@@GRAPH_URIS[action]}.json"
34
+ response = http_connect {|conn| create_http_get_request(uri, :id => id) }
35
+ JSON.parse(response.body)
36
+ end
37
+ end
@@ -0,0 +1,29 @@
1
+ class Twitter::Client
2
+ @@PROFILE_URIS = {
3
+ :info => '/account/update_profile',
4
+ :colors => '/account/update_profile_colors',
5
+ :device => '/account/update_delivery_device',
6
+ }
7
+
8
+ # Provides access to the Twitter Profile API.
9
+ #
10
+ # You can update profile information. You can update the types of profile
11
+ # information:
12
+ # * :info (name, email, url, location, description)
13
+ # * :colors (background_color, text_color, link_color, sidebar_fill_color,
14
+ # sidebar_border_color)
15
+ # * :device (set device to either "sms", "im" or "none")
16
+ #
17
+ # Example:
18
+ # user = client.profile(:info, :location => "University Library")
19
+ # puts user.inspect
20
+ def profile(action, attributes)
21
+ connection = create_http_connection
22
+ connection.start do |connection|
23
+ response = http_connect(attributes.to_http_str) do |conn|
24
+ create_http_post_request(@@PROFILE_URIS[action])
25
+ end
26
+ bless_models(Twitter::User.unmarshal(response.body))
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ class Twitter::Client
2
+
3
+ @@SEARCH_URIS = {
4
+ :basic => "/search.json",
5
+ }
6
+
7
+ # Provides access to Twitter's Search API.
8
+ #
9
+ # Example:
10
+ # # For keyword search
11
+ # iterator = @twitter.search(:q => "coworking")
12
+ # while (tweet = iterator.next)
13
+ # puts tweet.text
14
+ # end
15
+ #
16
+ # An <tt>ArgumentError</tt> will be raised if an invalid <tt>action</tt>
17
+ # is given. Valid actions are:
18
+ # * +:received+
19
+ # * +:sent+
20
+ def search(options = {})
21
+ # raise ArgumentError, "Invalid messaging action: #{action}"
22
+ uri = @@SEARCH_URIS[:basic]
23
+ response = http_connect(nil, false, :search) {|conn| create_http_get_request(uri, options) }
24
+ json = JSON.parse(response.body)
25
+ bless_models(Twitter::Status.unmarshal(JSON.dump(json["results"])))
26
+ end
27
+ end