twitter 4.8.1 → 5.0.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/CHANGELOG.md +36 -0
- data/CONTRIBUTING.md +13 -15
- data/LICENSE.md +1 -1
- data/README.md +401 -261
- data/Rakefile +6 -0
- data/lib/twitter/arguments.rb +14 -0
- data/lib/twitter/base.rb +109 -89
- data/lib/twitter/client.rb +38 -115
- data/lib/twitter/configuration.rb +5 -2
- data/lib/twitter/core_ext/kernel.rb +5 -1
- data/lib/twitter/creatable.rb +7 -4
- data/lib/twitter/cursor.rb +57 -45
- data/lib/twitter/direct_message.rb +2 -11
- data/lib/twitter/entity/uri.rb +14 -0
- data/lib/twitter/enumerable.rb +15 -0
- data/lib/twitter/error/already_favorited.rb +1 -1
- data/lib/twitter/error/already_posted.rb +10 -0
- data/lib/twitter/error/already_retweeted.rb +1 -1
- data/lib/twitter/error/bad_gateway.rb +2 -3
- data/lib/twitter/error/bad_request.rb +2 -2
- data/lib/twitter/error/forbidden.rb +2 -2
- data/lib/twitter/error/gateway_timeout.rb +2 -3
- data/lib/twitter/error/internal_server_error.rb +2 -3
- data/lib/twitter/error/not_acceptable.rb +2 -2
- data/lib/twitter/error/not_found.rb +2 -2
- data/lib/twitter/error/service_unavailable.rb +2 -3
- data/lib/twitter/error/too_many_requests.rb +2 -2
- data/lib/twitter/error/unauthorized.rb +2 -2
- data/lib/twitter/error/unprocessable_entity.rb +2 -2
- data/lib/twitter/error.rb +65 -14
- data/lib/twitter/factory.rb +13 -12
- data/lib/twitter/geo.rb +2 -7
- data/lib/twitter/geo_factory.rb +11 -7
- data/lib/twitter/geo_results.rb +40 -0
- data/lib/twitter/identity.rb +4 -34
- data/lib/twitter/list.rb +21 -4
- data/lib/twitter/media/photo.rb +6 -4
- data/lib/twitter/media_factory.rb +11 -7
- data/lib/twitter/null_object.rb +25 -0
- data/lib/twitter/oembed.rb +3 -2
- data/lib/twitter/place.rb +15 -15
- data/lib/twitter/profile_banner.rb +3 -2
- data/lib/twitter/rate_limit.rb +4 -17
- data/lib/twitter/relationship.rb +2 -19
- data/lib/twitter/rest/api/direct_messages.rb +138 -0
- data/lib/twitter/rest/api/favorites.rb +115 -0
- data/lib/twitter/rest/api/friends_and_followers.rb +287 -0
- data/lib/twitter/rest/api/help.rb +58 -0
- data/lib/twitter/rest/api/lists.rb +498 -0
- data/lib/twitter/rest/api/oauth.rb +62 -0
- data/lib/twitter/rest/api/places_and_geo.rb +86 -0
- data/lib/twitter/rest/api/saved_searches.rb +93 -0
- data/lib/twitter/rest/api/search.rb +37 -0
- data/lib/twitter/rest/api/spam_reporting.rb +29 -0
- data/lib/twitter/rest/api/suggested_users.rb +51 -0
- data/lib/twitter/rest/api/timelines.rb +202 -0
- data/lib/twitter/rest/api/trends.rb +58 -0
- data/lib/twitter/rest/api/tweets.rb +291 -0
- data/lib/twitter/rest/api/undocumented.rb +52 -0
- data/lib/twitter/rest/api/users.rb +383 -0
- data/lib/twitter/rest/api/utils.rb +246 -0
- data/lib/twitter/rest/client.rb +175 -0
- data/lib/twitter/rest/request/multipart_with_file.rb +36 -0
- data/lib/twitter/rest/response/parse_error_json.rb +15 -0
- data/lib/twitter/rest/response/parse_json.rb +31 -0
- data/lib/twitter/{response → rest/response}/raise_error.rb +8 -11
- data/lib/twitter/search_results.rb +37 -21
- data/lib/twitter/settings.rb +1 -6
- data/lib/twitter/size.rb +2 -15
- data/lib/twitter/streaming/client.rb +89 -0
- data/lib/twitter/streaming/connection.rb +22 -0
- data/lib/twitter/streaming/event.rb +35 -0
- data/lib/twitter/streaming/friend_list.rb +13 -0
- data/lib/twitter/streaming/message_parser.rb +18 -0
- data/lib/twitter/streaming/response.rb +34 -0
- data/lib/twitter/suggestion.rb +5 -8
- data/lib/twitter/token.rb +11 -1
- data/lib/twitter/trend.rb +4 -8
- data/lib/twitter/trend_results.rb +65 -0
- data/lib/twitter/tweet.rb +43 -92
- data/lib/twitter/user.rb +72 -47
- data/lib/twitter/version.rb +4 -4
- data/lib/twitter.rb +4 -39
- data/spec/fixtures/already_posted.json +1 -0
- data/spec/fixtures/ids_list.json +1 -1
- data/spec/fixtures/ids_list2.json +1 -1
- data/spec/fixtures/request_token.txt +6 -0
- data/spec/fixtures/search.json +1 -1
- data/spec/fixtures/search_malformed.json +1 -1
- data/spec/fixtures/track_streaming.json +3 -0
- data/spec/fixtures/track_streaming_user.json +5 -0
- data/spec/helper.rb +8 -13
- data/spec/twitter/base_spec.rb +13 -103
- data/spec/twitter/basic_user_spec.rb +3 -3
- data/spec/twitter/configuration_spec.rb +1 -1
- data/spec/twitter/cursor_spec.rb +17 -35
- data/spec/twitter/direct_message_spec.rb +44 -11
- data/spec/twitter/entity/uri_spec.rb +75 -0
- data/spec/twitter/error_spec.rb +59 -11
- data/spec/twitter/geo/point_spec.rb +6 -6
- data/spec/twitter/geo/polygon_spec.rb +5 -5
- data/spec/twitter/geo_factory_spec.rb +4 -4
- data/spec/twitter/geo_results_spec.rb +35 -0
- data/spec/twitter/geo_spec.rb +6 -6
- data/spec/twitter/identifiable_spec.rb +5 -26
- data/spec/twitter/list_spec.rb +54 -11
- data/spec/twitter/media/photo_spec.rb +122 -6
- data/spec/twitter/media_factory_spec.rb +3 -3
- data/spec/twitter/null_object_spec.rb +27 -0
- data/spec/twitter/oembed_spec.rb +69 -45
- data/spec/twitter/place_spec.rb +84 -28
- data/spec/twitter/profile_banner_spec.rb +1 -1
- data/spec/twitter/rate_limit_spec.rb +8 -25
- data/spec/twitter/relationship_spec.rb +26 -12
- data/spec/twitter/{api → rest/api}/direct_messages_spec.rb +28 -15
- data/spec/twitter/{api → rest/api}/favorites_spec.rb +80 -7
- data/spec/twitter/{api → rest/api}/friends_and_followers_spec.rb +121 -152
- data/spec/twitter/{api → rest/api}/geo_spec.rb +9 -23
- data/spec/twitter/{api → rest/api}/help_spec.rb +6 -6
- data/spec/twitter/{api → rest/api}/lists_spec.rb +116 -95
- data/spec/twitter/{api → rest/api}/oauth_spec.rb +21 -10
- data/spec/twitter/{api → rest/api}/saved_searches_spec.rb +13 -13
- data/spec/twitter/{api → rest/api}/search_spec.rb +8 -9
- data/spec/twitter/{api → rest/api}/spam_reporting_spec.rb +3 -3
- data/spec/twitter/{api → rest/api}/suggested_users_spec.rb +5 -5
- data/spec/twitter/{api → rest/api}/timelines_spec.rb +9 -9
- data/spec/twitter/{api → rest/api}/trends_spec.rb +6 -6
- data/spec/twitter/rest/api/tweets_spec.rb +503 -0
- data/spec/twitter/{api → rest/api}/undocumented_spec.rb +19 -45
- data/spec/twitter/{api → rest/api}/users_spec.rb +64 -39
- data/spec/twitter/rest/client_spec.rb +193 -0
- data/spec/twitter/saved_search_spec.rb +14 -3
- data/spec/twitter/search_results_spec.rb +32 -45
- data/spec/twitter/settings_spec.rb +17 -6
- data/spec/twitter/size_spec.rb +5 -15
- data/spec/twitter/source_user_spec.rb +3 -3
- data/spec/twitter/streaming/client_spec.rb +92 -0
- data/spec/twitter/streaming/event_spec.rb +45 -0
- data/spec/twitter/suggestion_spec.rb +5 -15
- data/spec/twitter/target_user_spec.rb +3 -3
- data/spec/twitter/token_spec.rb +16 -0
- data/spec/twitter/trend_results_spec.rb +89 -0
- data/spec/twitter/trend_spec.rb +26 -13
- data/spec/twitter/tweet_spec.rb +137 -124
- data/spec/twitter/user_spec.rb +139 -80
- data/spec/twitter_spec.rb +0 -119
- data/twitter.gemspec +12 -6
- data.tar.gz.sig +0 -0
- metadata +197 -138
- metadata.gz.sig +0 -0
- data/lib/twitter/action/favorite.rb +0 -19
- data/lib/twitter/action/follow.rb +0 -30
- data/lib/twitter/action/list_member_added.rb +0 -39
- data/lib/twitter/action/mention.rb +0 -46
- data/lib/twitter/action/reply.rb +0 -27
- data/lib/twitter/action/retweet.rb +0 -27
- data/lib/twitter/action/tweet.rb +0 -20
- data/lib/twitter/action_factory.rb +0 -22
- data/lib/twitter/api/arguments.rb +0 -13
- data/lib/twitter/api/direct_messages.rb +0 -148
- data/lib/twitter/api/favorites.rb +0 -126
- data/lib/twitter/api/friends_and_followers.rb +0 -334
- data/lib/twitter/api/help.rb +0 -64
- data/lib/twitter/api/lists.rb +0 -618
- data/lib/twitter/api/oauth.rb +0 -44
- data/lib/twitter/api/places_and_geo.rb +0 -121
- data/lib/twitter/api/saved_searches.rb +0 -99
- data/lib/twitter/api/search.rb +0 -37
- data/lib/twitter/api/spam_reporting.rb +0 -30
- data/lib/twitter/api/suggested_users.rb +0 -55
- data/lib/twitter/api/timelines.rb +0 -214
- data/lib/twitter/api/trends.rb +0 -63
- data/lib/twitter/api/tweets.rb +0 -304
- data/lib/twitter/api/undocumented.rb +0 -97
- data/lib/twitter/api/users.rb +0 -439
- data/lib/twitter/api/utils.rb +0 -187
- data/lib/twitter/configurable.rb +0 -96
- data/lib/twitter/default.rb +0 -102
- data/lib/twitter/entity/url.rb +0 -9
- data/lib/twitter/error/client_error.rb +0 -35
- data/lib/twitter/error/decode_error.rb +0 -9
- data/lib/twitter/error/identity_map_key_error.rb +0 -9
- data/lib/twitter/error/server_error.rb +0 -28
- data/lib/twitter/exceptable.rb +0 -36
- data/lib/twitter/identity_map.rb +0 -22
- data/lib/twitter/request/multipart_with_file.rb +0 -34
- data/lib/twitter/response/parse_json.rb +0 -25
- data/spec/fixtures/about_me.json +0 -1
- data/spec/fixtures/activity_summary.json +0 -1
- data/spec/fixtures/bad_gateway.json +0 -1
- data/spec/fixtures/bad_request.json +0 -1
- data/spec/fixtures/by_friends.json +0 -1
- data/spec/fixtures/end_session.json +0 -1
- data/spec/fixtures/forbidden.json +0 -1
- data/spec/fixtures/internal_server_error.json +0 -1
- data/spec/fixtures/not_acceptable.json +0 -1
- data/spec/fixtures/phoenix_search.phoenix +0 -1
- data/spec/fixtures/resolve.json +0 -1
- data/spec/fixtures/service_unavailable.json +0 -1
- data/spec/fixtures/totals.json +0 -1
- data/spec/fixtures/trends.json +0 -1
- data/spec/fixtures/unauthorized.json +0 -1
- data/spec/fixtures/video_facets.json +0 -1
- data/spec/twitter/action/favorite_spec.rb +0 -29
- data/spec/twitter/action/follow_spec.rb +0 -29
- data/spec/twitter/action/list_member_added_spec.rb +0 -41
- data/spec/twitter/action/mention_spec.rb +0 -52
- data/spec/twitter/action/reply_spec.rb +0 -41
- data/spec/twitter/action/retweet_spec.rb +0 -41
- data/spec/twitter/action_factory_spec.rb +0 -35
- data/spec/twitter/action_spec.rb +0 -16
- data/spec/twitter/api/tweets_spec.rb +0 -285
- data/spec/twitter/client_spec.rb +0 -223
- data/spec/twitter/error/client_error_spec.rb +0 -23
- data/spec/twitter/error/server_error_spec.rb +0 -20
data/Rakefile
CHANGED
|
@@ -7,5 +7,11 @@ RSpec::Core::RakeTask.new(:spec)
|
|
|
7
7
|
task :test => :spec
|
|
8
8
|
task :default => :spec
|
|
9
9
|
|
|
10
|
+
task :erd do
|
|
11
|
+
`bundle exec ruby ./etc/erd.rb > ./etc/erd.dot`
|
|
12
|
+
`dot -Tpng ./etc/erd.dot -o ./etc/erd.png`
|
|
13
|
+
`open ./etc/erd.png`
|
|
14
|
+
end
|
|
15
|
+
|
|
10
16
|
require 'yard'
|
|
11
17
|
YARD::Rake::YardocTask.new
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Twitter
|
|
2
|
+
class Arguments < Array
|
|
3
|
+
attr_reader :options
|
|
4
|
+
|
|
5
|
+
# Initializes a new Arguments object
|
|
6
|
+
#
|
|
7
|
+
# @return [Twitter::Arguments]
|
|
8
|
+
def initialize(args)
|
|
9
|
+
@options = args.last.is_a?(::Hash) ? args.pop : {}
|
|
10
|
+
super(args)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/twitter/base.rb
CHANGED
|
@@ -1,75 +1,116 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'forwardable'
|
|
2
|
+
require 'memoizable'
|
|
3
|
+
require 'twitter/null_object'
|
|
4
|
+
require 'uri'
|
|
2
5
|
|
|
3
6
|
module Twitter
|
|
4
7
|
class Base
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
extend Forwardable
|
|
9
|
+
include Memoizable
|
|
10
|
+
attr_reader :attrs
|
|
11
|
+
alias to_h attrs
|
|
12
|
+
alias to_hash attrs
|
|
13
|
+
alias to_hsh attrs
|
|
14
|
+
|
|
15
|
+
class << self
|
|
16
|
+
|
|
17
|
+
# Construct an object from a response hash
|
|
18
|
+
#
|
|
19
|
+
# @param response [Hash]
|
|
20
|
+
# @return [Twitter::Base]
|
|
21
|
+
def from_response(response={})
|
|
22
|
+
new(response[:body])
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Define methods that retrieve the value from attributes
|
|
26
|
+
#
|
|
27
|
+
# @param attrs [Array, Symbol]
|
|
28
|
+
def attr_reader(*attrs)
|
|
29
|
+
attrs.each do |attr|
|
|
30
|
+
define_attribute_method(attr)
|
|
31
|
+
define_predicate_method(attr)
|
|
17
32
|
end
|
|
18
33
|
end
|
|
19
|
-
const_set(:Attributes, mod)
|
|
20
|
-
include mod
|
|
21
|
-
end
|
|
22
34
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@
|
|
28
|
-
|
|
35
|
+
# Define object methods from attributes
|
|
36
|
+
#
|
|
37
|
+
# @param klass [Symbol]
|
|
38
|
+
# @param key1 [Symbol]
|
|
39
|
+
# @param key2 [Symbol]
|
|
40
|
+
def object_attr_reader(klass, key1, key2=nil)
|
|
41
|
+
define_attribute_method(key1, klass, key2)
|
|
42
|
+
define_predicate_method(key1)
|
|
43
|
+
end
|
|
29
44
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
45
|
+
# Define URI methods from attributes
|
|
46
|
+
#
|
|
47
|
+
# @param attrs [Array, Symbol]
|
|
48
|
+
def uri_attr_reader(*attrs)
|
|
49
|
+
attrs.each do |uri_key|
|
|
50
|
+
array = uri_key.to_s.split("_")
|
|
51
|
+
index = array.index("uri")
|
|
52
|
+
array[index] = "url"
|
|
53
|
+
url_key = array.join("_").to_sym
|
|
54
|
+
define_uri_method(uri_key, url_key)
|
|
55
|
+
alias_method(url_key, uri_key)
|
|
56
|
+
define_predicate_method(uri_key, url_key)
|
|
57
|
+
alias_method(:"#{url_key}?", :"#{uri_key}?")
|
|
58
|
+
end
|
|
38
59
|
end
|
|
39
|
-
return yield if block_given?
|
|
40
|
-
raise Twitter::Error::IdentityMapKeyError, "key not found"
|
|
41
|
-
end
|
|
42
60
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
end
|
|
61
|
+
# Define display_uri attribute methods
|
|
62
|
+
def display_uri_attr_reader
|
|
63
|
+
define_attribute_method(:display_url)
|
|
64
|
+
alias_method(:display_uri, :display_url)
|
|
65
|
+
define_predicate_method(:display_uri, :display_url)
|
|
66
|
+
alias_method(:display_url?, :display_uri?)
|
|
67
|
+
end
|
|
51
68
|
|
|
52
|
-
|
|
53
|
-
#
|
|
54
|
-
# @param response [Hash]
|
|
55
|
-
# @return [Twitter::Base]
|
|
56
|
-
def self.from_response(response={})
|
|
57
|
-
fetch_or_new(response[:body])
|
|
58
|
-
end
|
|
69
|
+
private
|
|
59
70
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
71
|
+
# Dynamically define a method for a URI
|
|
72
|
+
#
|
|
73
|
+
# @param key1 [Symbol]
|
|
74
|
+
# @param key2 [Symbol]
|
|
75
|
+
def define_uri_method(key1, key2)
|
|
76
|
+
define_method(key1) do ||
|
|
77
|
+
URI.parse(@attrs[key2]) if @attrs[key2]
|
|
78
|
+
end
|
|
79
|
+
memoize(key1)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Dynamically define a method for an attribute
|
|
83
|
+
#
|
|
84
|
+
# @param key1 [Symbol]
|
|
85
|
+
# @param klass [Symbol]
|
|
86
|
+
# @param key2 [Symbol]
|
|
87
|
+
def define_attribute_method(key1, klass=nil, key2=nil)
|
|
88
|
+
define_method(key1) do ||
|
|
89
|
+
if klass.nil?
|
|
90
|
+
@attrs[key1]
|
|
91
|
+
else
|
|
92
|
+
if @attrs[key1]
|
|
93
|
+
attrs = attrs_for_object(key1, key2)
|
|
94
|
+
Twitter.const_get(klass).new(attrs)
|
|
95
|
+
else
|
|
96
|
+
NullObject.new
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
memoize(key1)
|
|
101
|
+
end
|
|
68
102
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
103
|
+
# Dynamically define a predicate method for an attribute
|
|
104
|
+
#
|
|
105
|
+
# @param key1 [Symbol]
|
|
106
|
+
# @param key2 [Symbol]
|
|
107
|
+
def define_predicate_method(key1, key2=key1)
|
|
108
|
+
define_method(:"#{key1}?") do ||
|
|
109
|
+
!!@attrs[key2]
|
|
110
|
+
end
|
|
111
|
+
memoize(:"#{key1}?")
|
|
72
112
|
end
|
|
113
|
+
|
|
73
114
|
end
|
|
74
115
|
|
|
75
116
|
# Initializes a new object
|
|
@@ -77,7 +118,7 @@ module Twitter
|
|
|
77
118
|
# @param attrs [Hash]
|
|
78
119
|
# @return [Twitter::Base]
|
|
79
120
|
def initialize(attrs={})
|
|
80
|
-
@attrs = attrs
|
|
121
|
+
@attrs = attrs || {}
|
|
81
122
|
end
|
|
82
123
|
|
|
83
124
|
# Fetches an attribute of an object using hash notation
|
|
@@ -89,36 +130,15 @@ module Twitter
|
|
|
89
130
|
nil
|
|
90
131
|
end
|
|
91
132
|
|
|
92
|
-
|
|
93
|
-
#
|
|
94
|
-
# @return [Hash]
|
|
95
|
-
def attrs
|
|
96
|
-
@attrs
|
|
97
|
-
end
|
|
98
|
-
alias to_hash attrs
|
|
133
|
+
private
|
|
99
134
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
protected
|
|
110
|
-
|
|
111
|
-
# @param attr [Symbol]
|
|
112
|
-
# @param other [Twitter::Base]
|
|
113
|
-
# @return [Boolean]
|
|
114
|
-
def attr_equal(attr, other)
|
|
115
|
-
self.class == other.class && !other.send(attr).nil? && send(attr) == other.send(attr)
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# @param other [Twitter::Base]
|
|
119
|
-
# @return [Boolean]
|
|
120
|
-
def attrs_equal(other)
|
|
121
|
-
self.class == other.class && !other.attrs.empty? && attrs == other.attrs
|
|
135
|
+
def attrs_for_object(key1, key2=nil)
|
|
136
|
+
if key2.nil?
|
|
137
|
+
@attrs[key1]
|
|
138
|
+
else
|
|
139
|
+
attrs = @attrs.dup
|
|
140
|
+
attrs.delete(key1).merge(key2 => attrs)
|
|
141
|
+
end
|
|
122
142
|
end
|
|
123
143
|
|
|
124
144
|
end
|
data/lib/twitter/client.rb
CHANGED
|
@@ -1,147 +1,70 @@
|
|
|
1
|
-
require 'faraday'
|
|
2
|
-
require 'multi_json'
|
|
3
|
-
require 'twitter/api/direct_messages'
|
|
4
|
-
require 'twitter/api/favorites'
|
|
5
|
-
require 'twitter/api/friends_and_followers'
|
|
6
|
-
require 'twitter/api/help'
|
|
7
|
-
require 'twitter/api/lists'
|
|
8
|
-
require 'twitter/api/oauth'
|
|
9
|
-
require 'twitter/api/places_and_geo'
|
|
10
|
-
require 'twitter/api/saved_searches'
|
|
11
|
-
require 'twitter/api/search'
|
|
12
|
-
require 'twitter/api/spam_reporting'
|
|
13
|
-
require 'twitter/api/suggested_users'
|
|
14
|
-
require 'twitter/api/timelines'
|
|
15
|
-
require 'twitter/api/trends'
|
|
16
|
-
require 'twitter/api/tweets'
|
|
17
|
-
require 'twitter/api/undocumented'
|
|
18
|
-
require 'twitter/api/users'
|
|
19
|
-
require 'twitter/configurable'
|
|
20
|
-
require 'twitter/error/client_error'
|
|
21
|
-
require 'twitter/error/decode_error'
|
|
22
1
|
require 'simple_oauth'
|
|
2
|
+
require 'twitter/version'
|
|
23
3
|
require 'uri'
|
|
24
4
|
|
|
25
5
|
module Twitter
|
|
26
|
-
# Wrapper for the Twitter REST API
|
|
27
|
-
#
|
|
28
|
-
# @note All methods have been separated into modules and follow the same grouping used in {http://dev.twitter.com/doc the Twitter API Documentation}.
|
|
29
|
-
# @see http://dev.twitter.com/pages/every_developer
|
|
30
6
|
class Client
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
include Twitter::API::OAuth
|
|
37
|
-
include Twitter::API::PlacesAndGeo
|
|
38
|
-
include Twitter::API::SavedSearches
|
|
39
|
-
include Twitter::API::Search
|
|
40
|
-
include Twitter::API::SpamReporting
|
|
41
|
-
include Twitter::API::SuggestedUsers
|
|
42
|
-
include Twitter::API::Timelines
|
|
43
|
-
include Twitter::API::Trends
|
|
44
|
-
include Twitter::API::Tweets
|
|
45
|
-
include Twitter::API::Undocumented
|
|
46
|
-
include Twitter::API::Users
|
|
47
|
-
include Twitter::Configurable
|
|
7
|
+
attr_accessor :access_token, :access_token_secret, :consumer_key, :consumer_secret
|
|
8
|
+
alias oauth_token access_token
|
|
9
|
+
alias oauth_token= access_token=
|
|
10
|
+
alias oauth_token_secret access_token_secret
|
|
11
|
+
alias oauth_token_secret= access_token_secret=
|
|
48
12
|
|
|
49
13
|
# Initializes a new Client object
|
|
50
14
|
#
|
|
51
15
|
# @param options [Hash]
|
|
52
16
|
# @return [Twitter::Client]
|
|
53
17
|
def initialize(options={})
|
|
54
|
-
|
|
55
|
-
|
|
18
|
+
options.each do |key, value|
|
|
19
|
+
send(:"#{key}=", value)
|
|
56
20
|
end
|
|
21
|
+
yield self if block_given?
|
|
22
|
+
validate_credential_type!
|
|
57
23
|
end
|
|
58
24
|
|
|
59
|
-
#
|
|
60
|
-
def
|
|
61
|
-
|
|
25
|
+
# @return [Boolean]
|
|
26
|
+
def user_token?
|
|
27
|
+
!!(access_token && access_token_secret)
|
|
62
28
|
end
|
|
63
29
|
|
|
64
|
-
#
|
|
65
|
-
def
|
|
66
|
-
|
|
30
|
+
# @return [String]
|
|
31
|
+
def user_agent
|
|
32
|
+
@user_agent ||= "Twitter Ruby Gem #{Twitter::Version}"
|
|
67
33
|
end
|
|
68
34
|
|
|
69
|
-
#
|
|
70
|
-
def
|
|
71
|
-
|
|
72
|
-
|
|
35
|
+
# @return [Hash]
|
|
36
|
+
def credentials
|
|
37
|
+
{
|
|
38
|
+
:consumer_key => consumer_key,
|
|
39
|
+
:consumer_secret => consumer_secret,
|
|
40
|
+
:token => access_token,
|
|
41
|
+
:token_secret => access_token_secret,
|
|
42
|
+
}
|
|
73
43
|
end
|
|
74
44
|
|
|
75
|
-
#
|
|
76
|
-
def
|
|
77
|
-
|
|
45
|
+
# @return [Boolean]
|
|
46
|
+
def credentials?
|
|
47
|
+
credentials.values.all?
|
|
78
48
|
end
|
|
79
49
|
|
|
80
50
|
private
|
|
81
51
|
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
# @param method [Symbol]
|
|
85
|
-
# @param path [String]
|
|
86
|
-
# @param params [Hash]
|
|
87
|
-
# @return [Proc]
|
|
88
|
-
def request_setup(method, path, params, signature_params)
|
|
89
|
-
Proc.new do |request|
|
|
90
|
-
if params.delete(:bearer_token_request)
|
|
91
|
-
request.headers[:authorization] = bearer_token_credentials_auth_header
|
|
92
|
-
request.headers[:content_type] = 'application/x-www-form-urlencoded; charset=UTF-8'
|
|
93
|
-
request.headers[:accept] = '*/*' # It is important we set this, otherwise we get an error.
|
|
94
|
-
elsif params.delete(:app_auth) || !user_token?
|
|
95
|
-
unless bearer_token?
|
|
96
|
-
@bearer_token = token
|
|
97
|
-
Twitter.client.bearer_token = @bearer_token if Twitter.client?
|
|
98
|
-
end
|
|
99
|
-
request.headers[:authorization] = bearer_auth_header
|
|
100
|
-
else
|
|
101
|
-
request.headers[:authorization] = oauth_auth_header(method, path, signature_params).to_s
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def request(method, path, params={}, signature_params=params)
|
|
107
|
-
request_setup = request_setup(method, path, params, signature_params)
|
|
108
|
-
connection.send(method.to_sym, path, params, &request_setup).env
|
|
109
|
-
rescue Faraday::Error::ClientError
|
|
110
|
-
raise Twitter::Error::ClientError
|
|
111
|
-
rescue MultiJson::DecodeError
|
|
112
|
-
raise Twitter::Error::DecodeError
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
# Returns a Faraday::Connection object
|
|
116
|
-
#
|
|
117
|
-
# @return [Faraday::Connection]
|
|
118
|
-
def connection
|
|
119
|
-
@connection ||= Faraday.new(@endpoint, @connection_options.merge(:builder => @middleware))
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
# Generates authentication header for a bearer token request
|
|
52
|
+
# Ensures that all credentials set during configuration are of a
|
|
53
|
+
# valid type. Valid types are String and Symbol.
|
|
123
54
|
#
|
|
124
|
-
# @
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
def encode_value(value)
|
|
131
|
-
[value].pack("m0").gsub("\n", '')
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
def bearer_auth_header
|
|
135
|
-
if @bearer_token.is_a?(Twitter::Token) && @bearer_token.token_type == "bearer"
|
|
136
|
-
"Bearer #{@bearer_token.access_token}"
|
|
137
|
-
else
|
|
138
|
-
"Bearer #{@bearer_token}"
|
|
55
|
+
# @raise [Twitter::Error::ConfigurationError] Error is raised when
|
|
56
|
+
# supplied twitter credentials are not a String or Symbol.
|
|
57
|
+
def validate_credential_type!
|
|
58
|
+
credentials.each do |credential, value|
|
|
59
|
+
next if value.nil?
|
|
60
|
+
raise(Error::ConfigurationError, "Invalid #{credential} specified: #{value.inspect} must be a string or symbol.") unless value.is_a?(String) || value.is_a?(Symbol)
|
|
139
61
|
end
|
|
140
62
|
end
|
|
141
63
|
|
|
142
|
-
def oauth_auth_header(method,
|
|
143
|
-
uri = URI(
|
|
64
|
+
def oauth_auth_header(method, uri, params={})
|
|
65
|
+
uri = URI.parse(uri)
|
|
144
66
|
SimpleOAuth::Header.new(method, uri, params, credentials)
|
|
145
67
|
end
|
|
68
|
+
|
|
146
69
|
end
|
|
147
70
|
end
|
|
@@ -4,16 +4,19 @@ module Twitter
|
|
|
4
4
|
class Configuration < Twitter::Base
|
|
5
5
|
attr_reader :characters_reserved_per_media, :max_media_per_upload,
|
|
6
6
|
:non_username_paths, :photo_size_limit, :short_url_length, :short_url_length_https
|
|
7
|
+
alias short_uri_length short_url_length
|
|
8
|
+
alias short_uri_length_https short_url_length_https
|
|
7
9
|
|
|
8
10
|
# Returns an array of photo sizes
|
|
9
11
|
#
|
|
10
12
|
# @return [Array<Twitter::Size>]
|
|
11
13
|
def photo_sizes
|
|
12
|
-
|
|
13
|
-
object[key] =
|
|
14
|
+
Array(@attrs[:photo_sizes]).inject({}) do |object, (key, value)|
|
|
15
|
+
object[key] = Size.new(value)
|
|
14
16
|
object
|
|
15
17
|
end
|
|
16
18
|
end
|
|
19
|
+
memoize :photo_sizes
|
|
17
20
|
|
|
18
21
|
end
|
|
19
22
|
end
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
module Kernel
|
|
2
2
|
|
|
3
3
|
# Returns the object's singleton class (exists in Ruby 1.9.2)
|
|
4
|
-
def singleton_class
|
|
4
|
+
def singleton_class
|
|
5
|
+
class << self
|
|
6
|
+
self
|
|
7
|
+
end
|
|
8
|
+
end unless method_defined?(:singleton_class)
|
|
5
9
|
|
|
6
10
|
end
|
data/lib/twitter/creatable.rb
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
require 'time'
|
|
2
|
+
require 'memoizable'
|
|
2
3
|
|
|
3
4
|
module Twitter
|
|
4
5
|
module Creatable
|
|
6
|
+
include Memoizable
|
|
5
7
|
|
|
6
8
|
# Time when the object was created on Twitter
|
|
7
9
|
#
|
|
8
10
|
# @return [Time]
|
|
9
11
|
def created_at
|
|
10
|
-
|
|
12
|
+
Time.parse(@attrs[:created_at]) if @attrs[:created_at]
|
|
11
13
|
end
|
|
14
|
+
memoize :created_at
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
# @return [Boolean]
|
|
15
17
|
def created?
|
|
16
|
-
|
|
18
|
+
!!@attrs[:created_at]
|
|
17
19
|
end
|
|
20
|
+
memoize :created?
|
|
18
21
|
|
|
19
22
|
end
|
|
20
23
|
end
|
data/lib/twitter/cursor.rb
CHANGED
|
@@ -3,62 +3,62 @@ require 'twitter/core_ext/kernel'
|
|
|
3
3
|
module Twitter
|
|
4
4
|
class Cursor
|
|
5
5
|
include Enumerable
|
|
6
|
-
attr_reader :attrs
|
|
6
|
+
attr_reader :attrs
|
|
7
|
+
alias to_h attrs
|
|
7
8
|
alias to_hash attrs
|
|
9
|
+
alias to_hsh attrs
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
|
|
13
|
+
# Construct a new Cursor object from a response hash
|
|
14
|
+
#
|
|
15
|
+
# @param response [Hash]
|
|
16
|
+
# @param key [String, Symbol] The key to fetch the data from the response
|
|
17
|
+
# @param klass [Class] The class to instantiate objects in the response
|
|
18
|
+
# @param client [Twitter::REST::Client]
|
|
19
|
+
# @param request_method [String, Symbol]
|
|
20
|
+
# @param path [String]
|
|
21
|
+
# @param options [Hash]
|
|
22
|
+
# @return [Twitter::Cursor]
|
|
23
|
+
def from_response(response, key, klass, client, request_method, path, options)
|
|
24
|
+
new(response[:body], key, klass, client, request_method, path, options)
|
|
25
|
+
end
|
|
8
26
|
|
|
9
|
-
# Initializes a new Cursor object
|
|
10
|
-
#
|
|
11
|
-
# @param response [Hash]
|
|
12
|
-
# @param collection_name [String, Symbol] The name of the method to return the collection
|
|
13
|
-
# @param klass [Class] The class to instantiate object in the collection
|
|
14
|
-
# @param client [Twitter::Client]
|
|
15
|
-
# @param method_name [String, Symbol]
|
|
16
|
-
# @param method_options [Hash]
|
|
17
|
-
# @return [Twitter::Cursor]
|
|
18
|
-
def self.from_response(response, collection_name, klass, client, method_name, method_options)
|
|
19
|
-
new(response[:body], collection_name, klass, client, method_name, method_options)
|
|
20
27
|
end
|
|
21
28
|
|
|
22
29
|
# Initializes a new Cursor
|
|
23
30
|
#
|
|
24
31
|
# @param attrs [Hash]
|
|
25
|
-
# @param
|
|
26
|
-
# @param klass [Class] The class to instantiate
|
|
27
|
-
# @param client [Twitter::Client]
|
|
28
|
-
# @param
|
|
29
|
-
# @param
|
|
32
|
+
# @param key [String, Symbol] The key to fetch the data from the response
|
|
33
|
+
# @param klass [Class] The class to instantiate objects in the response
|
|
34
|
+
# @param client [Twitter::REST::Client]
|
|
35
|
+
# @param request_method [String, Symbol]
|
|
36
|
+
# @param path [String]
|
|
37
|
+
# @param options [Hash]
|
|
30
38
|
# @return [Twitter::Cursor]
|
|
31
|
-
def initialize(attrs,
|
|
32
|
-
@
|
|
39
|
+
def initialize(attrs, key, klass, client, request_method, path, options)
|
|
40
|
+
@key = key.to_sym
|
|
41
|
+
@klass = klass
|
|
33
42
|
@client = client
|
|
34
|
-
@
|
|
35
|
-
@
|
|
36
|
-
@
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
else
|
|
40
|
-
item
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
singleton_class.class_eval do
|
|
44
|
-
alias_method(collection_name.to_sym, :collection)
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# @param collection [Array]
|
|
49
|
-
# @param cursor [Integer]
|
|
50
|
-
# @return [Array]
|
|
51
|
-
def all(collection=collection, cursor=next_cursor)
|
|
52
|
-
cursor = @client.send(@method_name.to_sym, @method_options.merge(:cursor => cursor))
|
|
53
|
-
collection += cursor.collection
|
|
54
|
-
cursor.last? ? collection.flatten : all(collection, cursor.next_cursor)
|
|
43
|
+
@request_method = request_method.to_sym
|
|
44
|
+
@path = path
|
|
45
|
+
@options = options
|
|
46
|
+
@collection = []
|
|
47
|
+
set_attrs(attrs)
|
|
55
48
|
end
|
|
56
49
|
|
|
57
|
-
# @return [
|
|
58
|
-
def each
|
|
59
|
-
|
|
50
|
+
# @return [Enumerator]
|
|
51
|
+
def each(start = 0, &block)
|
|
52
|
+
return to_enum(:each) unless block_given?
|
|
53
|
+
Array(@collection[start..-1]).each do |element|
|
|
60
54
|
yield element
|
|
61
55
|
end
|
|
56
|
+
unless last?
|
|
57
|
+
start = [@collection.size, start].max
|
|
58
|
+
fetch_next_page
|
|
59
|
+
each(start, &block)
|
|
60
|
+
end
|
|
61
|
+
self
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def next_cursor
|
|
@@ -75,13 +75,25 @@ module Twitter
|
|
|
75
75
|
def first?
|
|
76
76
|
previous_cursor.zero?
|
|
77
77
|
end
|
|
78
|
-
alias first first?
|
|
79
78
|
|
|
80
79
|
# @return [Boolean]
|
|
81
80
|
def last?
|
|
82
81
|
next_cursor.zero?
|
|
83
82
|
end
|
|
84
|
-
|
|
83
|
+
|
|
84
|
+
private
|
|
85
|
+
|
|
86
|
+
def fetch_next_page
|
|
87
|
+
response = @client.send(@request_method, @path, @options.merge(:cursor => next_cursor))
|
|
88
|
+
set_attrs(response[:body])
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def set_attrs(attrs)
|
|
92
|
+
@attrs = attrs
|
|
93
|
+
Array(attrs[@key]).each do |element|
|
|
94
|
+
@collection << (@klass ? @klass.new(element) : element)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
85
97
|
|
|
86
98
|
end
|
|
87
99
|
end
|
|
@@ -6,16 +6,7 @@ module Twitter
|
|
|
6
6
|
include Twitter::Creatable
|
|
7
7
|
attr_reader :text
|
|
8
8
|
alias full_text text
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def recipient
|
|
12
|
-
@recipient ||= Twitter::User.fetch_or_new(@attrs[:recipient])
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# @return [Twitter::User]
|
|
16
|
-
def sender
|
|
17
|
-
@sender ||= Twitter::User.fetch_or_new(@attrs[:sender])
|
|
18
|
-
end
|
|
19
|
-
|
|
9
|
+
object_attr_reader :User, :recipient
|
|
10
|
+
object_attr_reader :User, :sender
|
|
20
11
|
end
|
|
21
12
|
end
|