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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +11 -0
  3. data/hackeroo.gemspec +26 -0
  4. data/lib/hackeroo.rb +40 -0
  5. data/lib/hackeroo/action/favorite.rb +19 -0
  6. data/lib/hackeroo/action/follow.rb +30 -0
  7. data/lib/hackeroo/action/list_member_added.rb +39 -0
  8. data/lib/hackeroo/action/mention.rb +46 -0
  9. data/lib/hackeroo/action/reply.rb +27 -0
  10. data/lib/hackeroo/action/retweet.rb +27 -0
  11. data/lib/hackeroo/action/tweet.rb +20 -0
  12. data/lib/hackeroo/api/arguments.rb +13 -0
  13. data/lib/hackeroo/api/artists.rb +22 -0
  14. data/lib/hackeroo/api/performances.rb +22 -0
  15. data/lib/hackeroo/api/search.rb +37 -0
  16. data/lib/hackeroo/api/stages.rb +22 -0
  17. data/lib/hackeroo/api/users.rb +27 -0
  18. data/lib/hackeroo/api/utils.rb +187 -0
  19. data/lib/hackeroo/artist.rb +7 -0
  20. data/lib/hackeroo/base.rb +125 -0
  21. data/lib/hackeroo/client.rb +73 -0
  22. data/lib/hackeroo/configurable.rb +87 -0
  23. data/lib/hackeroo/core_ext/enumerable.rb +10 -0
  24. data/lib/hackeroo/core_ext/kernel.rb +6 -0
  25. data/lib/hackeroo/cursor.rb +87 -0
  26. data/lib/hackeroo/default.rb +77 -0
  27. data/lib/hackeroo/error.rb +32 -0
  28. data/lib/hackeroo/error/bad_gateway.rb +11 -0
  29. data/lib/hackeroo/error/bad_request.rb +10 -0
  30. data/lib/hackeroo/error/client_error.rb +35 -0
  31. data/lib/hackeroo/error/configuration_error.rb +8 -0
  32. data/lib/hackeroo/error/decode_error.rb +9 -0
  33. data/lib/hackeroo/error/forbidden.rb +10 -0
  34. data/lib/hackeroo/error/gateway_timeout.rb +11 -0
  35. data/lib/hackeroo/error/identity_map_key_error.rb +9 -0
  36. data/lib/hackeroo/error/internal_server_error.rb +11 -0
  37. data/lib/hackeroo/error/not_acceptable.rb +10 -0
  38. data/lib/hackeroo/error/not_found.rb +10 -0
  39. data/lib/hackeroo/error/server_error.rb +28 -0
  40. data/lib/hackeroo/error/service_unavailable.rb +11 -0
  41. data/lib/hackeroo/error/too_many_requests.rb +12 -0
  42. data/lib/hackeroo/error/unauthorized.rb +10 -0
  43. data/lib/hackeroo/error/unprocessable_entity.rb +10 -0
  44. data/lib/hackeroo/media/photo.rb +21 -0
  45. data/lib/hackeroo/performance.rb +7 -0
  46. data/lib/hackeroo/rate_limit.rb +45 -0
  47. data/lib/hackeroo/response/parse_json.rb +25 -0
  48. data/lib/hackeroo/response/raise_error.rb +31 -0
  49. data/lib/hackeroo/stage.rb +7 -0
  50. data/lib/hackeroo/user.rb +7 -0
  51. data/lib/hackeroo/version.rb +18 -0
  52. 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,7 @@
1
+ require 'hackeroo/base'
2
+ require 'hackeroo/error/identity_map_key_error'
3
+
4
+ module Hackeroo
5
+ class Artist < Hackeroo::Base
6
+ end
7
+ 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