rubeetup 0.0.1
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/.gitignore +11 -0
- data/.travis.yml +9 -0
- data/Gemfile +4 -0
- data/README.md +173 -0
- data/Rakefile +7 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/rubeetup/errors.rb +32 -0
- data/lib/rubeetup/request.rb +133 -0
- data/lib/rubeetup/request_builder.rb +68 -0
- data/lib/rubeetup/request_response.rb +88 -0
- data/lib/rubeetup/request_sender.rb +93 -0
- data/lib/rubeetup/requester.rb +74 -0
- data/lib/rubeetup/requests_catalog.rb +79 -0
- data/lib/rubeetup/requests_lib/meetup_catalog.json +634 -0
- data/lib/rubeetup/requests_lib/meetup_catalog.rb +33 -0
- data/lib/rubeetup/response_wrapper.rb +29 -0
- data/lib/rubeetup/utilities.rb +51 -0
- data/lib/rubeetup/version.rb +6 -0
- data/lib/rubeetup.rb +140 -0
- data/rubeetup.gemspec +33 -0
- metadata +179 -0
@@ -0,0 +1,74 @@
|
|
1
|
+
module Rubeetup
|
2
|
+
##
|
3
|
+
# @author Mike Vascelli <michele.vascelli@gmail.com>
|
4
|
+
#
|
5
|
+
# Requester instances perform requests for the user
|
6
|
+
#
|
7
|
+
class Requester
|
8
|
+
include Rubeetup::Utilities
|
9
|
+
|
10
|
+
##
|
11
|
+
# @return [Hash{Symbol=>String}] this Requester's auth data
|
12
|
+
#
|
13
|
+
attr_reader :auth
|
14
|
+
|
15
|
+
##
|
16
|
+
# @return [Symbol] the chosen request builder
|
17
|
+
#
|
18
|
+
attr_reader :request_builder
|
19
|
+
|
20
|
+
##
|
21
|
+
# @param [Hash{Symbol=>String}] args holds auth data to send with each request
|
22
|
+
# @option args [String] :key the api key
|
23
|
+
#
|
24
|
+
def initialize(args)
|
25
|
+
self.auth = args
|
26
|
+
@request_builder = Rubeetup::RequestBuilder
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Sets auth data, and validates it.
|
31
|
+
# @param [Hash{Symbol=>String}] args holds auth data to send with each request
|
32
|
+
# @option args [String] :key the api key
|
33
|
+
# @raise [Rubeetup::InvalidAuthenticationError] if the passed auth data is not a Hash,
|
34
|
+
# or if it does not include key: 'val'
|
35
|
+
#
|
36
|
+
def auth=(args)
|
37
|
+
@auth = args
|
38
|
+
validate_auth
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
##
|
43
|
+
# Performs the actual request, by dynamically creating a Request instance,
|
44
|
+
# and by then executing it.
|
45
|
+
# @param [Symbol] name request name
|
46
|
+
# @param [Array<Hash{Symbol=>String}, ...>] args holds the request options
|
47
|
+
# @return [Array<Rubeetup::ResponseWrapper>] the request response
|
48
|
+
#
|
49
|
+
def method_missing(name, *args)
|
50
|
+
merge_auth(args)
|
51
|
+
request = request_builder.compose_request(name, args)
|
52
|
+
request.execute
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def validate_auth
|
58
|
+
fail Rubeetup::InvalidAuthenticationError, 'Must respond to #merge' unless
|
59
|
+
auth.respond_to? :merge
|
60
|
+
fail Rubeetup::InvalidAuthenticationError, "Requires ---> {key: /[^\s]+/}" unless
|
61
|
+
(val = auth[:key]) && present?(val)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Operates on the memory referenced by args
|
65
|
+
# @note should both auth, and args have the same keys, then the keys in auth
|
66
|
+
# will overwrite those in options. This guarantees that if the user
|
67
|
+
# includes api keys while sending a request, those will be ignored.
|
68
|
+
#
|
69
|
+
def merge_auth(args)
|
70
|
+
options = args[0]
|
71
|
+
args[0] = options.respond_to?(:merge) ? options.merge(auth) : auth
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'rubeetup/requests_lib/meetup_catalog'
|
2
|
+
|
3
|
+
module Rubeetup
|
4
|
+
##
|
5
|
+
# Provides an interface to an abstract catalog of all the supported requests.
|
6
|
+
# The concrete catalogs are provided in the +rubeetup/requests_lib+ folder,
|
7
|
+
# and they are fetched by #build_catalog
|
8
|
+
# @note This module expects to be mixed in to a class which implements
|
9
|
+
# the instance method +#name+.
|
10
|
+
#
|
11
|
+
module RequestsCatalog
|
12
|
+
##
|
13
|
+
# @return [Boolean] whether a +name+ entry exists in the catalog
|
14
|
+
#
|
15
|
+
def is_in_catalog?
|
16
|
+
catalog[name]
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Reads the +name+ entry in the catalog and then gets its required parameters
|
21
|
+
# @note this module expects a concrete catalog whose entries can respond to +[:options]+
|
22
|
+
# @return [Array<Symbol>] the list of all the required parameters
|
23
|
+
#
|
24
|
+
def required_options
|
25
|
+
catalog[name][:options]
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Reads the +name+ entry in the catalog and then gets its lambda to compute the request's path
|
30
|
+
# @note this module expects a concrete catalog whose entries can respond to +[:path]+
|
31
|
+
# @return [Lambda] the lambda expression to compute the path for the request
|
32
|
+
#
|
33
|
+
def request_path
|
34
|
+
path = catalog[name][:path]
|
35
|
+
eval path if path
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Reads the +name+ entry in the catalog and then gets its POST logic if defined
|
40
|
+
# @note the entry in the concrete catalog may not respond to +:[:multipart]+
|
41
|
+
# @return [Lambda] If defined, it provides the logic to encode for multipart POST
|
42
|
+
#
|
43
|
+
def request_multipart
|
44
|
+
multi = catalog[name][:multipart]
|
45
|
+
eval multi if multi
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
##
|
51
|
+
# @todo Could be fitted to take an arg, or even an attribute, to decide which
|
52
|
+
# catalog should be built dynamically...
|
53
|
+
#
|
54
|
+
def catalog
|
55
|
+
Rubeetup::RequestsCatalog.send(:build_catalog)
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Gives you the list of all the supported requests
|
60
|
+
# @return [Array<Symbol>] the complete list of supported operations
|
61
|
+
#
|
62
|
+
def self.supported_requests
|
63
|
+
build_catalog.keys
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Here we choose the catalog we want to build.
|
68
|
+
# Then we load the catalog into a class instance variable. This should speed up
|
69
|
+
# processing, but may be costly in terms of space.
|
70
|
+
# @todo analyze the situation and decide whether to load the catalog at each
|
71
|
+
# request
|
72
|
+
#
|
73
|
+
def self.build_catalog
|
74
|
+
@data ||= Rubeetup::MeetupCatalog.requests
|
75
|
+
end
|
76
|
+
|
77
|
+
private_class_method :build_catalog
|
78
|
+
end
|
79
|
+
end
|