twitter 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +673 -0
- data/LICENSE.md +20 -0
- data/README.md +415 -0
- data/Rakefile +11 -0
- data/lib/twitter.rb +29 -0
- data/lib/twitter/action/favorite.rb +19 -0
- data/lib/twitter/action/follow.rb +31 -0
- data/lib/twitter/action/list_member_added.rb +41 -0
- data/lib/twitter/action/mention.rb +48 -0
- data/lib/twitter/action/reply.rb +27 -0
- data/lib/twitter/action/retweet.rb +27 -0
- data/lib/twitter/action/tweet.rb +22 -0
- data/lib/twitter/action_factory.rb +22 -0
- data/lib/twitter/api.rb +2442 -0
- data/lib/twitter/base.rb +119 -0
- data/lib/twitter/basic_user.rb +8 -0
- data/lib/twitter/client.rb +96 -0
- data/lib/twitter/configurable.rb +67 -0
- data/lib/twitter/configuration.rb +20 -0
- data/lib/twitter/core_ext/array.rb +7 -0
- data/lib/twitter/core_ext/enumerable.rb +11 -0
- data/lib/twitter/core_ext/hash.rb +100 -0
- data/lib/twitter/core_ext/kernel.rb +15 -0
- data/lib/twitter/core_ext/string.rb +10 -0
- data/lib/twitter/creatable.rb +20 -0
- data/lib/twitter/cursor.rb +87 -0
- data/lib/twitter/default.rb +101 -0
- data/lib/twitter/direct_message.rb +21 -0
- data/lib/twitter/entity.rb +7 -0
- data/lib/twitter/entity/hashtag.rb +9 -0
- data/lib/twitter/entity/url.rb +9 -0
- data/lib/twitter/entity/user_mention.rb +9 -0
- data/lib/twitter/error.rb +34 -0
- data/lib/twitter/error/bad_gateway.rb +11 -0
- data/lib/twitter/error/bad_request.rb +10 -0
- data/lib/twitter/error/client_error.rb +35 -0
- data/lib/twitter/error/decode_error.rb +9 -0
- data/lib/twitter/error/forbidden.rb +10 -0
- data/lib/twitter/error/gateway_timeout.rb +11 -0
- data/lib/twitter/error/identity_map_key_error.rb +9 -0
- data/lib/twitter/error/internal_server_error.rb +11 -0
- data/lib/twitter/error/not_acceptable.rb +10 -0
- data/lib/twitter/error/not_found.rb +10 -0
- data/lib/twitter/error/rate_limited.rb +11 -0
- data/lib/twitter/error/server_error.rb +28 -0
- data/lib/twitter/error/service_unavailable.rb +11 -0
- data/lib/twitter/error/unauthorized.rb +10 -0
- data/lib/twitter/factory.rb +21 -0
- data/lib/twitter/geo.rb +15 -0
- data/lib/twitter/geo/point.rb +22 -0
- data/lib/twitter/geo/polygon.rb +8 -0
- data/lib/twitter/geo_factory.rb +18 -0
- data/lib/twitter/identity.rb +50 -0
- data/lib/twitter/identity_map.rb +22 -0
- data/lib/twitter/language.rb +7 -0
- data/lib/twitter/list.rb +18 -0
- data/lib/twitter/media/photo.rb +22 -0
- data/lib/twitter/media_factory.rb +17 -0
- data/lib/twitter/metadata.rb +7 -0
- data/lib/twitter/oembed.rb +8 -0
- data/lib/twitter/place.rb +34 -0
- data/lib/twitter/rate_limit.rb +45 -0
- data/lib/twitter/relationship.rb +36 -0
- data/lib/twitter/request/multipart_with_file.rb +41 -0
- data/lib/twitter/response/parse_json.rb +25 -0
- data/lib/twitter/response/raise_error.rb +30 -0
- data/lib/twitter/saved_search.rb +9 -0
- data/lib/twitter/search_results.rb +48 -0
- data/lib/twitter/settings.rb +17 -0
- data/lib/twitter/size.rb +24 -0
- data/lib/twitter/source_user.rb +15 -0
- data/lib/twitter/suggestion.rb +22 -0
- data/lib/twitter/target_user.rb +8 -0
- data/lib/twitter/trend.rb +14 -0
- data/lib/twitter/tweet.rb +145 -0
- data/lib/twitter/user.rb +97 -0
- data/lib/twitter/version.rb +18 -0
- data/spec/fixtures/about_me.json +1 -0
- data/spec/fixtures/activity_summary.json +1 -0
- data/spec/fixtures/all.json +1 -0
- data/spec/fixtures/bad_gateway.json +1 -0
- data/spec/fixtures/bad_request.json +1 -0
- data/spec/fixtures/by_friends.json +1 -0
- data/spec/fixtures/category.json +1 -0
- data/spec/fixtures/configuration.json +1 -0
- data/spec/fixtures/contributees.json +1 -0
- data/spec/fixtures/contributors.json +1 -0
- data/spec/fixtures/direct_message.json +1 -0
- data/spec/fixtures/direct_messages.json +1 -0
- data/spec/fixtures/end_session.json +1 -0
- data/spec/fixtures/enhance_your_calm.text +11 -0
- data/spec/fixtures/favorites.json +1 -0
- data/spec/fixtures/following.json +1 -0
- data/spec/fixtures/forbidden.json +1 -0
- data/spec/fixtures/friendships.json +1 -0
- data/spec/fixtures/ids.json +1 -0
- data/spec/fixtures/ids_list.json +1 -0
- data/spec/fixtures/ids_list2.json +1 -0
- data/spec/fixtures/image_facets.json +1 -0
- data/spec/fixtures/internal_server_error.json +1 -0
- data/spec/fixtures/languages.json +1 -0
- data/spec/fixtures/list.json +1 -0
- data/spec/fixtures/lists.json +1 -0
- data/spec/fixtures/locations.json +1 -0
- data/spec/fixtures/matching_trends.json +1 -0
- data/spec/fixtures/me.jpeg +0 -0
- data/spec/fixtures/media_timeline.json +1 -0
- data/spec/fixtures/members.json +1 -0
- data/spec/fixtures/no_user_matches.json +1 -0
- data/spec/fixtures/not_acceptable.json +1 -0
- data/spec/fixtures/not_following.json +1 -0
- data/spec/fixtures/not_found.json +1 -0
- data/spec/fixtures/oembed.json +1 -0
- data/spec/fixtures/pbjt.gif +0 -0
- data/spec/fixtures/pengwynn.json +1 -0
- data/spec/fixtures/phoenix_search.phoenix +1 -0
- data/spec/fixtures/place.json +1 -0
- data/spec/fixtures/places.json +1 -0
- data/spec/fixtures/privacy.json +1 -0
- data/spec/fixtures/profile_image.text +24 -0
- data/spec/fixtures/rate_limit_status.json +1 -0
- data/spec/fixtures/recommendations.json +1 -0
- data/spec/fixtures/related_results.json +1 -0
- data/spec/fixtures/resolve.json +1 -0
- data/spec/fixtures/retweet.json +1 -0
- data/spec/fixtures/retweeted_status.json +1 -0
- data/spec/fixtures/retweeters_of.json +1 -0
- data/spec/fixtures/retweets.json +1 -0
- data/spec/fixtures/saved_search.json +1 -0
- data/spec/fixtures/saved_searches.json +1 -0
- data/spec/fixtures/search.json +1 -0
- data/spec/fixtures/search_malformed.json +1 -0
- data/spec/fixtures/service_unavailable.json +1 -0
- data/spec/fixtures/settings.json +1 -0
- data/spec/fixtures/sferik.json +1 -0
- data/spec/fixtures/status.json +1 -0
- data/spec/fixtures/status_with_media.json +104 -0
- data/spec/fixtures/statuses.json +1 -0
- data/spec/fixtures/suggestions.json +1 -0
- data/spec/fixtures/tos.json +1 -0
- data/spec/fixtures/totals.json +1 -0
- data/spec/fixtures/trends.json +1 -0
- data/spec/fixtures/trends_current.json +1 -0
- data/spec/fixtures/trends_daily.json +1 -0
- data/spec/fixtures/trends_weekly.json +1 -0
- data/spec/fixtures/unauthorized.json +1 -0
- data/spec/fixtures/user_search.json +1 -0
- data/spec/fixtures/user_timeline.json +1 -0
- data/spec/fixtures/users.json +1 -0
- data/spec/fixtures/users_list.json +1 -0
- data/spec/fixtures/video_facets.json +1 -0
- data/spec/fixtures/we_concept_bg2.png +0 -0
- data/spec/fixtures/wildcomet2.jpe +0 -0
- data/spec/helper.rb +53 -0
- data/spec/twitter/action/favorite_spec.rb +29 -0
- data/spec/twitter/action/follow_spec.rb +29 -0
- data/spec/twitter/action/list_member_added_spec.rb +41 -0
- data/spec/twitter/action/mention_spec.rb +52 -0
- data/spec/twitter/action/reply_spec.rb +41 -0
- data/spec/twitter/action/retweet_spec.rb +41 -0
- data/spec/twitter/action_factory_spec.rb +37 -0
- data/spec/twitter/action_spec.rb +16 -0
- data/spec/twitter/api/account_spec.rb +148 -0
- data/spec/twitter/api/activity_spec.rb +41 -0
- data/spec/twitter/api/blocks_spec.rb +167 -0
- data/spec/twitter/api/direct_messages_spec.rb +142 -0
- data/spec/twitter/api/friendships_spec.rb +567 -0
- data/spec/twitter/api/geo_spec.rb +100 -0
- data/spec/twitter/api/help_spec.rb +76 -0
- data/spec/twitter/api/lists_spec.rb +900 -0
- data/spec/twitter/api/report_spam_spec.rb +29 -0
- data/spec/twitter/api/saved_searches_spec.rb +100 -0
- data/spec/twitter/api/search_spec.rb +68 -0
- data/spec/twitter/api/statuses_spec.rb +559 -0
- data/spec/twitter/api/trends_spec.rb +80 -0
- data/spec/twitter/api/users_spec.rb +419 -0
- data/spec/twitter/base_spec.rb +113 -0
- data/spec/twitter/basic_user_spec.rb +23 -0
- data/spec/twitter/client_spec.rb +175 -0
- data/spec/twitter/configuration_spec.rb +17 -0
- data/spec/twitter/cursor_spec.rb +102 -0
- data/spec/twitter/direct_message_spec.rb +56 -0
- data/spec/twitter/error/client_error_spec.rb +40 -0
- data/spec/twitter/error/server_error_spec.rb +24 -0
- data/spec/twitter/error_spec.rb +20 -0
- data/spec/twitter/geo/point_spec.rb +41 -0
- data/spec/twitter/geo/polygon_spec.rb +29 -0
- data/spec/twitter/geo_factory_spec.rb +21 -0
- data/spec/twitter/geo_spec.rb +29 -0
- data/spec/twitter/identifiable_spec.rb +54 -0
- data/spec/twitter/list_spec.rb +45 -0
- data/spec/twitter/media/photo_spec.rb +35 -0
- data/spec/twitter/media_factory_spec.rb +17 -0
- data/spec/twitter/oembed_spec.rb +146 -0
- data/spec/twitter/place_spec.rb +75 -0
- data/spec/twitter/rate_limit_spec.rb +76 -0
- data/spec/twitter/relationship_spec.rb +35 -0
- data/spec/twitter/saved_search_spec.rb +34 -0
- data/spec/twitter/search_results_spec.rb +89 -0
- data/spec/twitter/settings_spec.rb +16 -0
- data/spec/twitter/size_spec.rb +38 -0
- data/spec/twitter/source_user_spec.rb +23 -0
- data/spec/twitter/suggestion_spec.rb +50 -0
- data/spec/twitter/target_user_spec.rb +23 -0
- data/spec/twitter/trend_spec.rb +38 -0
- data/spec/twitter/tweet_spec.rb +307 -0
- data/spec/twitter/user_spec.rb +127 -0
- data/spec/twitter_spec.rb +93 -0
- data/twitter.gemspec +30 -0
- metadata +584 -0
data/lib/twitter/base.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'twitter/core_ext/kernel'
|
2
|
+
require 'twitter/error/identity_map_key_error'
|
3
|
+
|
4
|
+
module Twitter
|
5
|
+
class Base
|
6
|
+
attr_reader :attrs
|
7
|
+
alias to_hash attrs
|
8
|
+
|
9
|
+
# Define methods that retrieve the value from an initialized instance variable Hash, using the attribute as a key
|
10
|
+
#
|
11
|
+
# @overload self.attr_reader(attr)
|
12
|
+
# @param attr [Symbol]
|
13
|
+
# @overload self.attr_reader(attrs)
|
14
|
+
# @param attrs [Array<Symbol>]
|
15
|
+
def self.attr_reader(*attrs)
|
16
|
+
attrs.each do |attribute|
|
17
|
+
class_eval do
|
18
|
+
define_method attribute do
|
19
|
+
@attrs[attribute.to_sym]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# return [Twitter::IdentityMap]
|
26
|
+
def self.identity_map
|
27
|
+
return unless Twitter.identity_map
|
28
|
+
@identity_map = Twitter.identity_map.new unless defined?(@identity_map) && @identity_map.class == Twitter.identity_map
|
29
|
+
@identity_map
|
30
|
+
end
|
31
|
+
|
32
|
+
# Retrieves an object from the identity map.
|
33
|
+
#
|
34
|
+
# @param attrs [Hash]
|
35
|
+
# @return [Twitter::Base]
|
36
|
+
def self.fetch(attrs)
|
37
|
+
return unless identity_map
|
38
|
+
if object = identity_map.fetch(Marshal.dump(attrs))
|
39
|
+
return object
|
40
|
+
end
|
41
|
+
return yield if block_given?
|
42
|
+
raise Twitter::Error::IdentityMapKeyError, "key not found"
|
43
|
+
end
|
44
|
+
|
45
|
+
# Stores an object in the identity map.
|
46
|
+
#
|
47
|
+
# @param object [Object]
|
48
|
+
# @return [Twitter::Base]
|
49
|
+
def self.store(object)
|
50
|
+
return object unless identity_map
|
51
|
+
identity_map.store(Marshal.dump(object.attrs), object)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns a new object based on the response hash
|
55
|
+
#
|
56
|
+
# @param response [Hash]
|
57
|
+
# @return [Twitter::Base]
|
58
|
+
def self.from_response(response={})
|
59
|
+
fetch_or_new(response[:body])
|
60
|
+
end
|
61
|
+
|
62
|
+
# Retrieves an object from the identity map, or stores it in the
|
63
|
+
# identity map if it doesn't already exist.
|
64
|
+
#
|
65
|
+
# @param attrs [Hash]
|
66
|
+
# @return [Twitter::Base]
|
67
|
+
def self.fetch_or_new(attrs={})
|
68
|
+
return unless attrs
|
69
|
+
return new(attrs) unless identity_map
|
70
|
+
|
71
|
+
fetch(attrs) do
|
72
|
+
object = new(attrs)
|
73
|
+
store(object)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Initializes a new object
|
78
|
+
#
|
79
|
+
# @param attrs [Hash]
|
80
|
+
# @return [Twitter::Base]
|
81
|
+
def initialize(attrs={})
|
82
|
+
@attrs = attrs
|
83
|
+
end
|
84
|
+
|
85
|
+
# Fetches an attribute of an object using hash notation
|
86
|
+
#
|
87
|
+
# @param method [String, Symbol] Message to send to the object
|
88
|
+
def [](method)
|
89
|
+
send(method.to_sym)
|
90
|
+
rescue NoMethodError
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
|
94
|
+
# Update the attributes of an object
|
95
|
+
#
|
96
|
+
# @param attrs [Hash]
|
97
|
+
# @return [Twitter::Base]
|
98
|
+
def update(attrs)
|
99
|
+
@attrs.update(attrs)
|
100
|
+
self
|
101
|
+
end
|
102
|
+
|
103
|
+
protected
|
104
|
+
|
105
|
+
# @param attr [Symbol]
|
106
|
+
# @param other [Twitter::Base]
|
107
|
+
# @return [Boolean]
|
108
|
+
def attr_equal(attr, other)
|
109
|
+
self.class == other.class && !other.send(attr).nil? && send(attr) == other.send(attr)
|
110
|
+
end
|
111
|
+
|
112
|
+
# @param other [Twitter::Base]
|
113
|
+
# @return [Boolean]
|
114
|
+
def attrs_equal(other)
|
115
|
+
self.class == other.class && !other.attrs.empty? && attrs == other.attrs
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'multi_json'
|
3
|
+
require 'twitter/api'
|
4
|
+
require 'twitter/configurable'
|
5
|
+
require 'twitter/error/client_error'
|
6
|
+
require 'twitter/error/decode_error'
|
7
|
+
require 'simple_oauth'
|
8
|
+
require 'uri'
|
9
|
+
|
10
|
+
module Twitter
|
11
|
+
# Wrapper for the Twitter REST API
|
12
|
+
#
|
13
|
+
# @note All methods have been separated into modules and follow the same grouping used in {http://dev.twitter.com/doc the Twitter API Documentation}.
|
14
|
+
# @see http://dev.twitter.com/pages/every_developer
|
15
|
+
class Client
|
16
|
+
include Twitter::API
|
17
|
+
include Twitter::Configurable
|
18
|
+
|
19
|
+
# Initializes a new Client object
|
20
|
+
#
|
21
|
+
# @param options [Hash]
|
22
|
+
# @return [Twitter::Client]
|
23
|
+
def initialize(options={})
|
24
|
+
Twitter::Configurable.keys.each do |key|
|
25
|
+
instance_variable_set(:"@#{key}", options[key] || Twitter.instance_variable_get(:"@#{key}"))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Perform an HTTP DELETE request
|
30
|
+
def delete(path, params={}, options={})
|
31
|
+
request(:delete, path, params, options)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Perform an HTTP GET request
|
35
|
+
def get(path, params={}, options={})
|
36
|
+
request(:get, path, params, options)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Perform an HTTP POST request
|
40
|
+
def post(path, params={}, options={})
|
41
|
+
request(:post, path, params, options)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Perform an HTTP UPDATE request
|
45
|
+
def put(path, params={}, options={})
|
46
|
+
request(:put, path, params, options)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# Returns a Faraday::Connection object
|
52
|
+
#
|
53
|
+
# @return [Faraday::Connection]
|
54
|
+
def connection
|
55
|
+
@connection ||= Faraday.new(@endpoint, @connection_options.merge(:builder => @middleware))
|
56
|
+
end
|
57
|
+
|
58
|
+
# Perform an HTTP request
|
59
|
+
#
|
60
|
+
# @raise [Twitter::Error::ClientError, Twitter::Error::DecodeError]
|
61
|
+
def request(method, path, params={}, options={})
|
62
|
+
uri = options[:endpoint] || @endpoint
|
63
|
+
uri = URI(uri) unless uri.respond_to?(:host)
|
64
|
+
uri += path
|
65
|
+
request_headers = {}
|
66
|
+
if credentials?
|
67
|
+
authorization = auth_header(method, uri, params)
|
68
|
+
request_headers[:authorization] = authorization.to_s
|
69
|
+
end
|
70
|
+
connection.url_prefix = options[:endpoint] || @endpoint
|
71
|
+
response = connection.run_request(method.to_sym, path, nil, request_headers) do |request|
|
72
|
+
unless params.empty?
|
73
|
+
case request.method
|
74
|
+
when :post, :put
|
75
|
+
request.body = params
|
76
|
+
else
|
77
|
+
request.params.update(params)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
yield request if block_given?
|
81
|
+
end.env
|
82
|
+
response
|
83
|
+
rescue Faraday::Error::ClientError
|
84
|
+
raise Twitter::Error::ClientError
|
85
|
+
rescue MultiJson::DecodeError
|
86
|
+
raise Twitter::Error::DecodeError
|
87
|
+
end
|
88
|
+
|
89
|
+
def auth_header(method, uri, params={})
|
90
|
+
# When posting a file, don't sign any params
|
91
|
+
signature_params = [:post, :put].include?(method.to_sym) && params.values.any?{|value| value.respond_to?(:to_io)} ? {} : params
|
92
|
+
SimpleOAuth::Header.new(method, uri, signature_params, credentials)
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'twitter/default'
|
2
|
+
|
3
|
+
module Twitter
|
4
|
+
module Configurable
|
5
|
+
attr_writer :consumer_key, :consumer_secret, :oauth_token, :oauth_token_secret
|
6
|
+
attr_accessor :endpoint, :connection_options, :identity_map, :middleware
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def keys
|
11
|
+
@keys ||= [
|
12
|
+
:consumer_key,
|
13
|
+
:consumer_secret,
|
14
|
+
:oauth_token,
|
15
|
+
:oauth_token_secret,
|
16
|
+
:endpoint,
|
17
|
+
:connection_options,
|
18
|
+
:identity_map,
|
19
|
+
:middleware,
|
20
|
+
]
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
# Convenience method to allow configuration options to be set in a block
|
26
|
+
def configure
|
27
|
+
yield self
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Boolean]
|
32
|
+
def credentials?
|
33
|
+
credentials.values.all?
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Fixnum]
|
37
|
+
def cache_key
|
38
|
+
options.hash
|
39
|
+
end
|
40
|
+
|
41
|
+
def reset!
|
42
|
+
Twitter::Configurable.keys.each do |key|
|
43
|
+
instance_variable_set(:"@#{key}", Twitter::Default.options[key])
|
44
|
+
end
|
45
|
+
self
|
46
|
+
end
|
47
|
+
alias setup reset!
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# @return [Hash]
|
52
|
+
def credentials
|
53
|
+
{
|
54
|
+
:consumer_key => @consumer_key,
|
55
|
+
:consumer_secret => @consumer_secret,
|
56
|
+
:token => @oauth_token,
|
57
|
+
:token_secret => @oauth_token_secret,
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [Hash]
|
62
|
+
def options
|
63
|
+
Hash[Twitter::Configurable.keys.map{|key| [key, instance_variable_get(:"@#{key}")]}]
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'twitter/base'
|
2
|
+
require 'twitter/size'
|
3
|
+
|
4
|
+
module Twitter
|
5
|
+
class Configuration < Twitter::Base
|
6
|
+
attr_reader :characters_reserved_per_media, :max_media_per_upload,
|
7
|
+
:non_username_paths, :photo_size_limit, :short_url_length, :short_url_length_https
|
8
|
+
|
9
|
+
# Returns an array of photo sizes
|
10
|
+
#
|
11
|
+
# @return [Array<Twitter::Size>]
|
12
|
+
def photo_sizes
|
13
|
+
@photo_sizes ||= Array(@attrs[:photo_sizes]).inject({}) do |object, (key, value)|
|
14
|
+
object[key] = Twitter::Size.fetch_or_new(value)
|
15
|
+
object
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
# Return a hash that includes everything but the given keys.
|
4
|
+
#
|
5
|
+
# @param keys [Array, Set]
|
6
|
+
# @return [Hash]
|
7
|
+
def except(*keys)
|
8
|
+
self.dup.except!(*keys)
|
9
|
+
end unless method_defined?(:except)
|
10
|
+
|
11
|
+
# Replaces the hash without the given keys.
|
12
|
+
#
|
13
|
+
# @param keys [Array, Set]
|
14
|
+
# @return [Hash]
|
15
|
+
def except!(*keys)
|
16
|
+
keys.each{|key| delete(key)}
|
17
|
+
self
|
18
|
+
end unless method_defined?(:except!)
|
19
|
+
|
20
|
+
# Take a list and merge it into the hash with the correct key
|
21
|
+
#
|
22
|
+
# @param list [Integer, String, Twitter::List] A Twitter list ID, slug, or object.
|
23
|
+
# @return [Hash]
|
24
|
+
def merge_list!(list)
|
25
|
+
case list
|
26
|
+
when Integer
|
27
|
+
self[:list_id] = list
|
28
|
+
when String
|
29
|
+
self[:slug] = list
|
30
|
+
when Twitter::List
|
31
|
+
self[:list_id] = list.id
|
32
|
+
self.merge_owner!(list.user)
|
33
|
+
end
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
# Take an owner and merge it into the hash with the correct key
|
38
|
+
#
|
39
|
+
# @param user[Integer, String, Twitter::User] A Twitter user ID, screen_name, or object.
|
40
|
+
# @return [Hash]
|
41
|
+
def merge_owner!(user)
|
42
|
+
self.merge_user!(user, "owner")
|
43
|
+
self[:owner_id] = self.delete(:owner_user_id) unless self[:owner_user_id].nil?
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
# Take a user and merge it into the hash with the correct key
|
48
|
+
#
|
49
|
+
# @param user[Integer, String, Twitter::User] A Twitter user ID, screen_name, or object.
|
50
|
+
# @return [Hash]
|
51
|
+
def merge_user(user, prefix=nil)
|
52
|
+
self.dup.merge_user!(user, prefix)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Take a user and merge it into the hash with the correct key
|
56
|
+
#
|
57
|
+
# @param user[Integer, String, Twitter::User] A Twitter user ID, screen_name, or object.
|
58
|
+
# @return [Hash]
|
59
|
+
def merge_user!(user, prefix=nil)
|
60
|
+
case user
|
61
|
+
when Integer
|
62
|
+
self[[prefix, "user_id"].compact.join("_").to_sym] = user
|
63
|
+
when String
|
64
|
+
self[[prefix, "screen_name"].compact.join("_").to_sym] = user
|
65
|
+
when Twitter::User
|
66
|
+
self[[prefix, "user_id"].compact.join("_").to_sym] = user.id
|
67
|
+
end
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
# Take a multiple users and merge them into the hash with the correct keys
|
72
|
+
#
|
73
|
+
# @param users [Array<Integer, String, Twitter::User>, Set<Integer, String, Twitter::User>] An array of Twitter user IDs, screen_names, or objects.
|
74
|
+
# @return [Hash]
|
75
|
+
def merge_users(*users)
|
76
|
+
self.dup.merge_users!(*users)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Take a multiple users and merge them into the hash with the correct keys
|
80
|
+
#
|
81
|
+
# @param users [Array<Integer, String, Twitter::User>, Set<Integer, String, Twitter::User>] An array of Twitter user IDs, screen_names, or objects.
|
82
|
+
# @return [Hash]
|
83
|
+
def merge_users!(*users)
|
84
|
+
user_ids, screen_names = [], []
|
85
|
+
users.flatten.each do |user|
|
86
|
+
case user
|
87
|
+
when Integer
|
88
|
+
user_ids << user
|
89
|
+
when String
|
90
|
+
screen_names << user
|
91
|
+
when Twitter::User
|
92
|
+
user_ids << user.id
|
93
|
+
end
|
94
|
+
end
|
95
|
+
self[:user_id] = user_ids.join(',') unless user_ids.empty?
|
96
|
+
self[:screen_name] = screen_names.join(',') unless screen_names.empty?
|
97
|
+
self
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Kernel
|
2
|
+
|
3
|
+
def calling_method
|
4
|
+
caller[1][/`([^']*)'/, 1].to_sym
|
5
|
+
end
|
6
|
+
|
7
|
+
# Returns the object's singleton class (exists in Ruby 1.9.2)
|
8
|
+
def singleton_class; class << self; self; end; end unless method_defined?(:singleton_class)
|
9
|
+
|
10
|
+
# class_eval on an object acts like singleton_class.class_eval.
|
11
|
+
def class_eval(*args, &block)
|
12
|
+
singleton_class.class_eval(*args, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|