hackeroo 0.1.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.
- checksums.yaml +7 -0
- data/Rakefile +11 -0
- data/hackeroo.gemspec +26 -0
- data/lib/hackeroo.rb +40 -0
- data/lib/hackeroo/action/favorite.rb +19 -0
- data/lib/hackeroo/action/follow.rb +30 -0
- data/lib/hackeroo/action/list_member_added.rb +39 -0
- data/lib/hackeroo/action/mention.rb +46 -0
- data/lib/hackeroo/action/reply.rb +27 -0
- data/lib/hackeroo/action/retweet.rb +27 -0
- data/lib/hackeroo/action/tweet.rb +20 -0
- data/lib/hackeroo/api/arguments.rb +13 -0
- data/lib/hackeroo/api/artists.rb +22 -0
- data/lib/hackeroo/api/performances.rb +22 -0
- data/lib/hackeroo/api/search.rb +37 -0
- data/lib/hackeroo/api/stages.rb +22 -0
- data/lib/hackeroo/api/users.rb +27 -0
- data/lib/hackeroo/api/utils.rb +187 -0
- data/lib/hackeroo/artist.rb +7 -0
- data/lib/hackeroo/base.rb +125 -0
- data/lib/hackeroo/client.rb +73 -0
- data/lib/hackeroo/configurable.rb +87 -0
- data/lib/hackeroo/core_ext/enumerable.rb +10 -0
- data/lib/hackeroo/core_ext/kernel.rb +6 -0
- data/lib/hackeroo/cursor.rb +87 -0
- data/lib/hackeroo/default.rb +77 -0
- data/lib/hackeroo/error.rb +32 -0
- data/lib/hackeroo/error/bad_gateway.rb +11 -0
- data/lib/hackeroo/error/bad_request.rb +10 -0
- data/lib/hackeroo/error/client_error.rb +35 -0
- data/lib/hackeroo/error/configuration_error.rb +8 -0
- data/lib/hackeroo/error/decode_error.rb +9 -0
- data/lib/hackeroo/error/forbidden.rb +10 -0
- data/lib/hackeroo/error/gateway_timeout.rb +11 -0
- data/lib/hackeroo/error/identity_map_key_error.rb +9 -0
- data/lib/hackeroo/error/internal_server_error.rb +11 -0
- data/lib/hackeroo/error/not_acceptable.rb +10 -0
- data/lib/hackeroo/error/not_found.rb +10 -0
- data/lib/hackeroo/error/server_error.rb +28 -0
- data/lib/hackeroo/error/service_unavailable.rb +11 -0
- data/lib/hackeroo/error/too_many_requests.rb +12 -0
- data/lib/hackeroo/error/unauthorized.rb +10 -0
- data/lib/hackeroo/error/unprocessable_entity.rb +10 -0
- data/lib/hackeroo/media/photo.rb +21 -0
- data/lib/hackeroo/performance.rb +7 -0
- data/lib/hackeroo/rate_limit.rb +45 -0
- data/lib/hackeroo/response/parse_json.rb +25 -0
- data/lib/hackeroo/response/raise_error.rb +31 -0
- data/lib/hackeroo/stage.rb +7 -0
- data/lib/hackeroo/user.rb +7 -0
- data/lib/hackeroo/version.rb +18 -0
- metadata +157 -0
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'hackeroo/api/arguments'
|
2
|
+
require 'hackeroo/cursor'
|
3
|
+
require 'hackeroo/user'
|
4
|
+
|
5
|
+
module Hackeroo
|
6
|
+
module API
|
7
|
+
module Utils
|
8
|
+
|
9
|
+
DEFAULT_CURSOR = -1
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
# @param request_method [Symbol]
|
14
|
+
# @param path [String]
|
15
|
+
# @param args [Array]
|
16
|
+
# @return [Array<Hackeroo::User>]
|
17
|
+
def threaded_user_objects_from_response(request_method, path, args)
|
18
|
+
arguments = Hackeroo::API::Arguments.new(args)
|
19
|
+
arguments.flatten.threaded_map do |user|
|
20
|
+
object_from_response(Hackeroo::User, request_method, path, merge_user(arguments.options, user))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param request_method [Symbol]
|
25
|
+
# @param path [String]
|
26
|
+
# @param args [Array]
|
27
|
+
# @return [Array<Hackeroo::User>]
|
28
|
+
def user_objects_from_response(request_method, path, args)
|
29
|
+
arguments = Hackeroo::API::Arguments.new(args)
|
30
|
+
merge_user!(arguments.options, arguments.pop || screen_name) unless arguments.options[:user_id] || arguments.options[:screen_name]
|
31
|
+
objects_from_response(Hackeroo::User, request_method, path, arguments.options)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param klass [Class]
|
35
|
+
# @param request_method [Symbol]
|
36
|
+
# @param path [String]
|
37
|
+
# @param args [Array]
|
38
|
+
# @return [Array]
|
39
|
+
def objects_from_response_with_user(klass, request_method, path, args)
|
40
|
+
arguments = Hackeroo::API::Arguments.new(args)
|
41
|
+
merge_user!(arguments.options, arguments.pop)
|
42
|
+
objects_from_response(klass, request_method, path, arguments.options)
|
43
|
+
end
|
44
|
+
|
45
|
+
# @param klass [Class]
|
46
|
+
# @param request_method [Symbol]
|
47
|
+
# @param path [String]
|
48
|
+
# @param options [Hash]
|
49
|
+
# @return [Array]
|
50
|
+
def objects_from_response(klass, request_method, path, options={})
|
51
|
+
response = send(request_method.to_sym, path, options)[:body]
|
52
|
+
objects_from_array(klass, response)
|
53
|
+
end
|
54
|
+
|
55
|
+
# @param klass [Class]
|
56
|
+
# @param array [Array]
|
57
|
+
# @return [Array]
|
58
|
+
def objects_from_array(klass, array)
|
59
|
+
array.map do |element|
|
60
|
+
klass.fetch_or_new(element)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# @param klass [Class]
|
65
|
+
# @param request_method [Symbol]
|
66
|
+
# @param path [String]
|
67
|
+
# @param args [Array]
|
68
|
+
# @return [Array]
|
69
|
+
def threaded_object_from_response(klass, request_method, path, args)
|
70
|
+
arguments = Hackeroo::API::Arguments.new(args)
|
71
|
+
arguments.flatten.threaded_map do |id|
|
72
|
+
object_from_response(klass, request_method, path, arguments.options.merge(:id => id))
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# @param klass [Class]
|
77
|
+
# @param request_method [Symbol]
|
78
|
+
# @param path [String]
|
79
|
+
# @param options [Hash]
|
80
|
+
# @return [Object]
|
81
|
+
def object_from_response(klass, request_method, path, options={})
|
82
|
+
response = send(request_method.to_sym, path, options)
|
83
|
+
klass.from_response(response)
|
84
|
+
end
|
85
|
+
|
86
|
+
# @param collection_name [Symbol]
|
87
|
+
# @param klass [Class]
|
88
|
+
# @param request_method [Symbol]
|
89
|
+
# @param path [String]
|
90
|
+
# @param args [Array]
|
91
|
+
# @param method_name [Symbol]
|
92
|
+
# @return [Hackeroo::Cursor]
|
93
|
+
def cursor_from_response_with_user(collection_name, klass, request_method, path, args, method_name)
|
94
|
+
arguments = Hackeroo::API::Arguments.new(args)
|
95
|
+
merge_user!(arguments.options, arguments.pop || screen_name) unless arguments.options[:user_id] || arguments.options[:screen_name]
|
96
|
+
cursor_from_response(collection_name, klass, request_method, path, arguments.options, method_name)
|
97
|
+
end
|
98
|
+
|
99
|
+
# @param collection_name [Symbol]
|
100
|
+
# @param klass [Class]
|
101
|
+
# @param request_method [Symbol]
|
102
|
+
# @param path [String]
|
103
|
+
# @param options [Hash]
|
104
|
+
# @param method_name [Symbol]
|
105
|
+
# @return [Hackeroo::Cursor]
|
106
|
+
def cursor_from_response(collection_name, klass, request_method, path, options, method_name)
|
107
|
+
merge_default_cursor!(options)
|
108
|
+
response = send(request_method.to_sym, path, options)
|
109
|
+
Hackeroo::Cursor.from_response(response, collection_name.to_sym, klass, self, method_name, options)
|
110
|
+
end
|
111
|
+
|
112
|
+
def handle_forbidden_error(klass, error)
|
113
|
+
if error.message == klass::MESSAGE
|
114
|
+
raise klass.new
|
115
|
+
else
|
116
|
+
raise error
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def merge_default_cursor!(options)
|
121
|
+
options[:cursor] = DEFAULT_CURSOR unless options[:cursor]
|
122
|
+
end
|
123
|
+
|
124
|
+
def screen_name
|
125
|
+
@screen_name ||= verify_credentials.screen_name
|
126
|
+
end
|
127
|
+
|
128
|
+
# Take a user and merge it into the hash with the correct key
|
129
|
+
#
|
130
|
+
# @param hash [Hash]
|
131
|
+
# @param user [Integer, String, Hackeroo::User] A Hackeroo user ID, screen_name, or object.
|
132
|
+
# @return [Hash]
|
133
|
+
def merge_user(hash, user, prefix=nil)
|
134
|
+
merge_user!(hash.dup, user, prefix)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Take a user and merge it into the hash with the correct key
|
138
|
+
#
|
139
|
+
# @param hash [Hash]
|
140
|
+
# @param user [Integer, String, Hackeroo::User] A Hackeroo user ID, screen_name, or object.
|
141
|
+
# @return [Hash]
|
142
|
+
def merge_user!(hash, user, prefix=nil)
|
143
|
+
case user
|
144
|
+
when Integer
|
145
|
+
hash[[prefix, "user_id"].compact.join("_").to_sym] = user
|
146
|
+
when String
|
147
|
+
hash[[prefix, "screen_name"].compact.join("_").to_sym] = user
|
148
|
+
when Hackeroo::User
|
149
|
+
hash[[prefix, "user_id"].compact.join("_").to_sym] = user.id
|
150
|
+
end
|
151
|
+
hash
|
152
|
+
end
|
153
|
+
|
154
|
+
# Take a multiple users and merge them into the hash with the correct keys
|
155
|
+
#
|
156
|
+
# @param hash [Hash]
|
157
|
+
# @param users [Array<Integer, String, Hackeroo::User>, Set<Integer, String, Hackeroo::User>] An array of Hackeroo user IDs, screen_names, or objects.
|
158
|
+
# @return [Hash]
|
159
|
+
def merge_users(hash, users)
|
160
|
+
merge_users!(hash.dup, users)
|
161
|
+
end
|
162
|
+
|
163
|
+
# Take a multiple users and merge them into the hash with the correct keys
|
164
|
+
#
|
165
|
+
# @param hash [Hash]
|
166
|
+
# @param users [Array<Integer, String, Hackeroo::User>, Set<Integer, String, Hackeroo::User>] An array of Hackeroo user IDs, screen_names, or objects.
|
167
|
+
# @return [Hash]
|
168
|
+
def merge_users!(hash, users)
|
169
|
+
user_ids, screen_names = [], []
|
170
|
+
users.flatten.each do |user|
|
171
|
+
case user
|
172
|
+
when Integer
|
173
|
+
user_ids << user
|
174
|
+
when String
|
175
|
+
screen_names << user
|
176
|
+
when Hackeroo::User
|
177
|
+
user_ids << user.id
|
178
|
+
end
|
179
|
+
end
|
180
|
+
hash[:user_id] = user_ids.join(',') unless user_ids.empty?
|
181
|
+
hash[:screen_name] = screen_names.join(',') unless screen_names.empty?
|
182
|
+
hash
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'hackeroo/error/identity_map_key_error'
|
2
|
+
|
3
|
+
module Hackeroo
|
4
|
+
class Base
|
5
|
+
# Define methods that retrieve the value from an initialized instance variable Hash, using the attribute as a key
|
6
|
+
#
|
7
|
+
# @param attrs [Array, Set, Symbol]
|
8
|
+
def self.attr_reader(*attrs)
|
9
|
+
mod = Module.new do
|
10
|
+
attrs.each do |attribute|
|
11
|
+
define_method attribute do
|
12
|
+
@attrs[attribute.to_sym]
|
13
|
+
end
|
14
|
+
define_method "#{attribute}?" do
|
15
|
+
!!@attrs[attribute.to_sym]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
const_set(:Attributes, mod)
|
20
|
+
include mod
|
21
|
+
end
|
22
|
+
|
23
|
+
# return [Hackeroo::IdentityMap]
|
24
|
+
def self.identity_map
|
25
|
+
return unless Hackeroo.identity_map
|
26
|
+
@identity_map = Hackeroo.identity_map.new unless defined?(@identity_map) && @identity_map.class == Hackeroo.identity_map
|
27
|
+
@identity_map
|
28
|
+
end
|
29
|
+
|
30
|
+
# Retrieves an object from the identity map.
|
31
|
+
#
|
32
|
+
# @param attrs [Hash]
|
33
|
+
# @return [Hackeroo::Base]
|
34
|
+
def self.fetch(attrs)
|
35
|
+
return unless identity_map
|
36
|
+
if object = identity_map.fetch(Marshal.dump(attrs))
|
37
|
+
return object
|
38
|
+
end
|
39
|
+
return yield if block_given?
|
40
|
+
raise Hackeroo::Error::IdentityMapKeyError, "key not found"
|
41
|
+
end
|
42
|
+
|
43
|
+
# Stores an object in the identity map.
|
44
|
+
#
|
45
|
+
# @param object [Object]
|
46
|
+
# @return [Hackeroo::Base]
|
47
|
+
def self.store(object)
|
48
|
+
return object unless identity_map
|
49
|
+
identity_map.store(Marshal.dump(object.attrs), object)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns a new object based on the response hash
|
53
|
+
#
|
54
|
+
# @param response [Hash]
|
55
|
+
# @return [Hackeroo::Base]
|
56
|
+
def self.from_response(response={})
|
57
|
+
fetch_or_new(response[:body])
|
58
|
+
end
|
59
|
+
|
60
|
+
# Retrieves an object from the identity map, or stores it in the
|
61
|
+
# identity map if it doesn't already exist.
|
62
|
+
#
|
63
|
+
# @param attrs [Hash]
|
64
|
+
# @return [Hackeroo::Base]
|
65
|
+
def self.fetch_or_new(attrs={})
|
66
|
+
return unless attrs
|
67
|
+
return new(attrs) unless identity_map
|
68
|
+
|
69
|
+
fetch(attrs) do
|
70
|
+
object = new(attrs)
|
71
|
+
store(object)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Initializes a new object
|
76
|
+
#
|
77
|
+
# @param attrs [Hash]
|
78
|
+
# @return [Hackeroo::Base]
|
79
|
+
def initialize(attrs={})
|
80
|
+
@attrs = attrs
|
81
|
+
end
|
82
|
+
|
83
|
+
# Fetches an attribute of an object using hash notation
|
84
|
+
#
|
85
|
+
# @param method [String, Symbol] Message to send to the object
|
86
|
+
def [](method)
|
87
|
+
send(method.to_sym)
|
88
|
+
rescue NoMethodError
|
89
|
+
nil
|
90
|
+
end
|
91
|
+
|
92
|
+
# Retrieve the attributes of an object
|
93
|
+
#
|
94
|
+
# @return [Hash]
|
95
|
+
def attrs
|
96
|
+
@attrs
|
97
|
+
end
|
98
|
+
alias to_hash attrs
|
99
|
+
|
100
|
+
# Update the attributes of an object
|
101
|
+
#
|
102
|
+
# @param attrs [Hash]
|
103
|
+
# @return [Hackeroo::Base]
|
104
|
+
def update(attrs)
|
105
|
+
@attrs.update(attrs)
|
106
|
+
self
|
107
|
+
end
|
108
|
+
|
109
|
+
protected
|
110
|
+
|
111
|
+
# @param attr [Symbol]
|
112
|
+
# @param other [Hackeroo::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 [Hackeroo::Base]
|
119
|
+
# @return [Boolean]
|
120
|
+
def attrs_equal(other)
|
121
|
+
self.class == other.class && !other.attrs.empty? && attrs == other.attrs
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'multi_json'
|
3
|
+
require 'hackeroo/api/users'
|
4
|
+
require 'hackeroo/api/performances'
|
5
|
+
require 'hackeroo/api/stages'
|
6
|
+
require 'hackeroo/api/artists'
|
7
|
+
require 'hackeroo/configurable'
|
8
|
+
require 'hackeroo/error/client_error'
|
9
|
+
require 'hackeroo/error/decode_error'
|
10
|
+
require 'base64'
|
11
|
+
require 'uri'
|
12
|
+
|
13
|
+
module Hackeroo
|
14
|
+
# Wrapper for the Hackeroo REST API
|
15
|
+
#
|
16
|
+
# @note All methods have been separated into modules and follow the same grouping used in {http://dev.hackeroo.com/doc the Hackeroo API Documentation}.
|
17
|
+
# @see http://dev.hackeroo.com/pages/every_developer
|
18
|
+
class Client
|
19
|
+
include Hackeroo::API::Users
|
20
|
+
include Hackeroo::API::Performances
|
21
|
+
include Hackeroo::API::Stages
|
22
|
+
include Hackeroo::API::Artists
|
23
|
+
include Hackeroo::Configurable
|
24
|
+
|
25
|
+
# Initializes a new Client object
|
26
|
+
#
|
27
|
+
# @param options [Hash]
|
28
|
+
# @return [Hackeroo::Client]
|
29
|
+
def initialize(options={})
|
30
|
+
Hackeroo::Configurable.keys.each do |key|
|
31
|
+
instance_variable_set(:"@#{key}", options[key] || Hackeroo.instance_variable_get(:"@#{key}"))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Perform an HTTP GET request
|
36
|
+
def get(path, params={})
|
37
|
+
request(:get, path, params)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# Returns a proc that can be used to setup the Faraday::Request headers
|
43
|
+
#
|
44
|
+
# @param method [Symbol]
|
45
|
+
# @param path [String]
|
46
|
+
# @param params [Hash]
|
47
|
+
# @return [Proc]
|
48
|
+
def request_setup(method, path, params)
|
49
|
+
Proc.new do |request|
|
50
|
+
request.headers['x-app-id'] = @clientkey
|
51
|
+
request.headers[:content_type] = 'application/json'
|
52
|
+
request.headers[:accept] = 'application/json'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def request(method, path, params={}, signature_params=params)
|
57
|
+
request_setup = request_setup(method, path, params)
|
58
|
+
connection.send(method.to_sym, path, params, &request_setup).env
|
59
|
+
rescue Faraday::Error::ClientError
|
60
|
+
raise Hackeroo::Error::ClientError
|
61
|
+
rescue MultiJson::DecodeError
|
62
|
+
raise Hackeroo::Error::DecodeError
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns a Faraday::Connection object
|
66
|
+
#
|
67
|
+
# @return [Faraday::Connection]
|
68
|
+
def connection
|
69
|
+
@connection ||= Faraday.new(@endpoint, @connection_options.merge(:builder => @middleware))
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'hackeroo/error/configuration_error'
|
3
|
+
|
4
|
+
module Hackeroo
|
5
|
+
module Configurable
|
6
|
+
extend Forwardable
|
7
|
+
attr_accessor :clientkey, :endpoint, :connection_options, :identity_map, :middleware
|
8
|
+
def_delegator :options, :hash
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
def keys
|
13
|
+
@keys ||= [
|
14
|
+
:clientkey,
|
15
|
+
:endpoint,
|
16
|
+
:connection_options,
|
17
|
+
:identity_map,
|
18
|
+
:middleware,
|
19
|
+
]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
# Convenience method to allow configuration options to be set in a block
|
25
|
+
#
|
26
|
+
# @raise [Hackeroo::Error::ConfigurationError] Error is raised when supplied
|
27
|
+
# hackeroo credentials are not a String or Symbol.
|
28
|
+
def configure
|
29
|
+
yield self
|
30
|
+
validate_credential_type!
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def reset!
|
35
|
+
Hackeroo::Configurable.keys.each do |key|
|
36
|
+
instance_variable_set(:"@#{key}", Hackeroo::Default.options[key])
|
37
|
+
end
|
38
|
+
self
|
39
|
+
end
|
40
|
+
alias setup reset!
|
41
|
+
|
42
|
+
# @return [Boolean]
|
43
|
+
def user_token?
|
44
|
+
!!(@oauth_token && @oauth_token_secret)
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Boolean]
|
48
|
+
def bearer_token?
|
49
|
+
!!@bearer_token
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Boolean]
|
53
|
+
def credentials?
|
54
|
+
credentials.values.all? || bearer_token?
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
# @return [Hash]
|
60
|
+
def credentials
|
61
|
+
{
|
62
|
+
:clientkey => @clientkey,
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [Hash]
|
67
|
+
def options
|
68
|
+
Hash[Hackeroo::Configurable.keys.map{|key| [key, instance_variable_get(:"@#{key}")]}]
|
69
|
+
end
|
70
|
+
|
71
|
+
# Ensures that all credentials set during configuration are of a
|
72
|
+
# valid type. Valid types are String and Symbol.
|
73
|
+
#
|
74
|
+
# @raise [Hackeroo::Error::ConfigurationError] Error is raised when
|
75
|
+
# supplied hackeroo credentials are not a String or Symbol.
|
76
|
+
def validate_credential_type!
|
77
|
+
credentials.each do |credential, value|
|
78
|
+
next if value.nil?
|
79
|
+
|
80
|
+
unless value.is_a?(String) || value.is_a?(Symbol)
|
81
|
+
raise(Error::ConfigurationError, "Invalid #{credential} specified: #{value} must be a string or symbol.")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|