mashery_rails 0.6.2
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/.gitignore +6 -0
- data/.travis.yml +12 -0
- data/.yardoc/checksums +17 -0
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/.yardoc/proxy_types +0 -0
- data/Gemfile +21 -0
- data/Gemfile.devtools +55 -0
- data/Gemfile.lock +215 -0
- data/LICENSE.txt +21 -0
- data/README.md +63 -0
- data/Rakefile +9 -0
- data/VERSION +1 -0
- data/config/devtools.yml +2 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/mutant.yml +3 -0
- data/config/reek.yml +103 -0
- data/config/rubocop.yml +58 -0
- data/config/yardstick.yml +2 -0
- data/lib/mashery.rb +55 -0
- data/lib/mashery/config.rb +71 -0
- data/lib/mashery/exceptions.rb +46 -0
- data/lib/mashery/key.rb +7 -0
- data/lib/mashery/local.rb +3 -0
- data/lib/mashery/member.rb +8 -0
- data/lib/mashery/query_builder.rb +173 -0
- data/lib/mashery/rails.rb +19 -0
- data/lib/mashery/rest_client.rb +31 -0
- data/lib/mashery/rest_client/query.rb +77 -0
- data/lib/mashery/rpc_client.rb +58 -0
- data/lib/mashery/rpc_client/base.rb +51 -0
- data/lib/mashery/rpc_client/response.rb +79 -0
- data/lib/mashery/service.rb +9 -0
- data/masheri.gemspec +26 -0
- data/mashery_rails.gemspec +25 -0
- data/spec/fixtures/config.no_host.yml +4 -0
- data/spec/fixtures/config.no_key.yml +4 -0
- data/spec/fixtures/config.no_secret.yml +4 -0
- data/spec/fixtures/config.no_site_id.yml +4 -0
- data/spec/fixtures/config.yml +5 -0
- data/spec/fixtures/services.json +3 -0
- data/spec/mashery/config_spec.rb +38 -0
- data/spec/mashery/member_spec.rb +47 -0
- data/spec/mashery/query_builder_spec.rb +13 -0
- data/spec/mashery/rest_client_spec.rb +47 -0
- data/spec/mashery/rpc_client_spec.rb +28 -0
- data/spec/mashery/service_spec.rb +101 -0
- data/spec/mashery_spec.rb +5 -0
- data/spec/spec_helper.rb +50 -0
- data/tasks/mashery.thor +200 -0
- metadata +147 -0
data/config/flay.yml
ADDED
data/config/flog.yml
ADDED
data/config/mutant.yml
ADDED
data/config/reek.yml
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
---
|
2
|
+
Attribute:
|
3
|
+
enabled: true
|
4
|
+
exclude: []
|
5
|
+
BooleanParameter:
|
6
|
+
enabled: true
|
7
|
+
exclude: []
|
8
|
+
ClassVariable:
|
9
|
+
enabled: true
|
10
|
+
exclude: []
|
11
|
+
ControlParameter:
|
12
|
+
enabled: true
|
13
|
+
exclude: []
|
14
|
+
DataClump:
|
15
|
+
enabled: true
|
16
|
+
exclude: []
|
17
|
+
max_copies: 2
|
18
|
+
min_clump_size: 2
|
19
|
+
DuplicateMethodCall:
|
20
|
+
enabled: true
|
21
|
+
exclude: []
|
22
|
+
max_calls: 1
|
23
|
+
allow_calls: []
|
24
|
+
FeatureEnvy:
|
25
|
+
enabled: true
|
26
|
+
exclude: []
|
27
|
+
IrresponsibleModule:
|
28
|
+
enabled: true
|
29
|
+
exclude: []
|
30
|
+
LongParameterList:
|
31
|
+
enabled: true
|
32
|
+
exclude: []
|
33
|
+
max_params: 2
|
34
|
+
overrides:
|
35
|
+
initialize:
|
36
|
+
max_params: 3
|
37
|
+
LongYieldList:
|
38
|
+
enabled: true
|
39
|
+
exclude: []
|
40
|
+
max_params: 2
|
41
|
+
NestedIterators:
|
42
|
+
enabled: true
|
43
|
+
exclude: []
|
44
|
+
max_allowed_nesting: 1
|
45
|
+
ignore_iterators: []
|
46
|
+
NilCheck:
|
47
|
+
enabled: true
|
48
|
+
exclude: []
|
49
|
+
RepeatedConditional:
|
50
|
+
enabled: true
|
51
|
+
exclude: []
|
52
|
+
max_ifs: 1
|
53
|
+
TooManyInstanceVariables:
|
54
|
+
enabled: true
|
55
|
+
exclude: []
|
56
|
+
max_instance_variables: 3
|
57
|
+
TooManyMethods:
|
58
|
+
enabled: true
|
59
|
+
exclude: []
|
60
|
+
max_methods: 10
|
61
|
+
TooManyStatements:
|
62
|
+
enabled: true
|
63
|
+
exclude:
|
64
|
+
- each
|
65
|
+
max_statements: 2
|
66
|
+
UncommunicativeMethodName:
|
67
|
+
enabled: true
|
68
|
+
exclude: []
|
69
|
+
reject:
|
70
|
+
- !ruby/regexp /^[a-z]$/
|
71
|
+
- !ruby/regexp /[0-9]$/
|
72
|
+
- !ruby/regexp /[A-Z]/
|
73
|
+
accept: []
|
74
|
+
UncommunicativeModuleName:
|
75
|
+
enabled: true
|
76
|
+
exclude: []
|
77
|
+
reject:
|
78
|
+
- !ruby/regexp /^.$/
|
79
|
+
- !ruby/regexp /[0-9]$/
|
80
|
+
accept: []
|
81
|
+
UncommunicativeParameterName:
|
82
|
+
enabled: true
|
83
|
+
exclude: []
|
84
|
+
reject:
|
85
|
+
- !ruby/regexp /^.$/
|
86
|
+
- !ruby/regexp /[0-9]$/
|
87
|
+
- !ruby/regexp /[A-Z]/
|
88
|
+
accept: []
|
89
|
+
UncommunicativeVariableName:
|
90
|
+
enabled: true
|
91
|
+
exclude: []
|
92
|
+
reject:
|
93
|
+
- !ruby/regexp /^.$/
|
94
|
+
- !ruby/regexp /[0-9]$/
|
95
|
+
- !ruby/regexp /[A-Z]/
|
96
|
+
accept: []
|
97
|
+
UnusedParameters:
|
98
|
+
enabled: true
|
99
|
+
exclude: []
|
100
|
+
UtilityFunction:
|
101
|
+
enabled: true
|
102
|
+
exclude: []
|
103
|
+
max_helper_calls: 0
|
data/config/rubocop.yml
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
AllCops:
|
2
|
+
Includes:
|
3
|
+
- '**/*.rake'
|
4
|
+
- 'Gemfile'
|
5
|
+
- 'Gemfile.devtools'
|
6
|
+
Excludes:
|
7
|
+
- '**/vendor/**'
|
8
|
+
- '**/benchmarks/**'
|
9
|
+
|
10
|
+
# Avoid parameter lists longer than five parameters.
|
11
|
+
ParameterLists:
|
12
|
+
Max: 3
|
13
|
+
CountKeywordArgs: true
|
14
|
+
|
15
|
+
# Avoid more than `Max` levels of nesting.
|
16
|
+
BlockNesting:
|
17
|
+
Max: 3
|
18
|
+
|
19
|
+
# Align with the style guide.
|
20
|
+
CollectionMethods:
|
21
|
+
PreferredMethods:
|
22
|
+
collect: 'map'
|
23
|
+
inject: 'reduce'
|
24
|
+
find: 'detect'
|
25
|
+
find_all: 'select'
|
26
|
+
|
27
|
+
# Do not force public/protected/private keyword to be indented at the same
|
28
|
+
# level as the def keyword. My personal preference is to outdent these keywords
|
29
|
+
# because I think when scanning code it makes it easier to identify the
|
30
|
+
# sections of code and visually separate them. When the keyword is at the same
|
31
|
+
# level I think it sort of blends in with the def keywords and makes it harder
|
32
|
+
# to scan the code and see where the sections are.
|
33
|
+
AccessControl:
|
34
|
+
Enabled: false
|
35
|
+
|
36
|
+
# Limit line length
|
37
|
+
LineLength:
|
38
|
+
Max: 79
|
39
|
+
|
40
|
+
# Disable documentation checking until a class needs to be documented once
|
41
|
+
Documentation:
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
# Do not favor modifier if/unless usage when you have a single-line body
|
45
|
+
IfUnlessModifier:
|
46
|
+
Enabled: false
|
47
|
+
|
48
|
+
# Allow case equality operator (in limited use within the specs)
|
49
|
+
CaseEquality:
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
# Constants do not always have to use SCREAMING_SNAKE_CASE
|
53
|
+
ConstantName:
|
54
|
+
Enabled: false
|
55
|
+
|
56
|
+
# Not all trivial readers/writers can be defined with attr_* methods
|
57
|
+
TrivialAccessors:
|
58
|
+
Enabled: false
|
data/lib/mashery.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path("./lib")
|
2
|
+
|
3
|
+
require 'active_support/core_ext'
|
4
|
+
require 'logger'
|
5
|
+
require 'digest/md5'
|
6
|
+
require 'restclient'
|
7
|
+
|
8
|
+
require 'mashery/exceptions'
|
9
|
+
require 'mashery/config'
|
10
|
+
|
11
|
+
require 'mashery/rpc_client'
|
12
|
+
require 'mashery/rpc_client/base'
|
13
|
+
require 'mashery/rpc_client/response'
|
14
|
+
|
15
|
+
require 'mashery/rest_client'
|
16
|
+
require 'mashery/query_builder'
|
17
|
+
require 'mashery/rest_client/query'
|
18
|
+
|
19
|
+
|
20
|
+
require 'mashery/member'
|
21
|
+
require 'mashery/key'
|
22
|
+
require 'mashery/service'
|
23
|
+
|
24
|
+
module Mashery
|
25
|
+
@@config = nil
|
26
|
+
|
27
|
+
def self.config
|
28
|
+
raise Mashery::ConfigMissing.new unless @@config.present?
|
29
|
+
@@config
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.config=(other)
|
33
|
+
@@config = other
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.load_config!(yaml_file)
|
37
|
+
Mashery.config = Mashery::Config.new(yaml_file)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.rpc
|
41
|
+
Mashery::RpcClient.new
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.rest
|
45
|
+
Mashery::RestClient.new
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.activity(activity_type, service_id, options)
|
49
|
+
Mashery.rest.activity(activity_type, service_id, options)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
if defined?(Rails)
|
54
|
+
require 'mashery/rails'
|
55
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Mashery
|
2
|
+
class Config
|
3
|
+
DEFAULT_HOSTS = {
|
4
|
+
test: 'api.sandbox.mashery.com',
|
5
|
+
production: 'api.mashery.com'
|
6
|
+
}
|
7
|
+
|
8
|
+
attr_accessor :config
|
9
|
+
|
10
|
+
def initialize(yaml_file)
|
11
|
+
@config ||= YAML.load_file(yaml_file)
|
12
|
+
check_config!
|
13
|
+
end
|
14
|
+
|
15
|
+
def check_config!
|
16
|
+
if config["site_id"].blank?
|
17
|
+
raise ParamMissing.new("site_id")
|
18
|
+
end
|
19
|
+
|
20
|
+
if config["key"].blank?
|
21
|
+
raise ParamMissing.new("key")
|
22
|
+
end
|
23
|
+
|
24
|
+
if config["secret"].blank?
|
25
|
+
raise ParamMissing.new("secret")
|
26
|
+
end
|
27
|
+
|
28
|
+
find_host!
|
29
|
+
end
|
30
|
+
|
31
|
+
def site_id
|
32
|
+
@site_id ||= config["site_id"]
|
33
|
+
end
|
34
|
+
|
35
|
+
def key
|
36
|
+
@key ||= config["key"]
|
37
|
+
end
|
38
|
+
|
39
|
+
alias :api_key :key
|
40
|
+
|
41
|
+
def secret
|
42
|
+
@secret ||= config["secret"]
|
43
|
+
end
|
44
|
+
|
45
|
+
def host
|
46
|
+
@host ||= find_host!
|
47
|
+
end
|
48
|
+
|
49
|
+
def signature
|
50
|
+
Digest::MD5.hexdigest(key + secret + Time.now.to_f.to_i.to_s)
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def find_host!
|
56
|
+
if config["host"].present?
|
57
|
+
config["host"]
|
58
|
+
else
|
59
|
+
if defined?(Rails)
|
60
|
+
if Rails.env.test? || Rails.env.development?
|
61
|
+
DEFAULT_HOSTS[:test]
|
62
|
+
elsif Rails.env.production?
|
63
|
+
DEFAULT_HOSTS[:production]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
raise ParamMissing.new("host")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Mashery
|
2
|
+
class NoClassGiven < Exception
|
3
|
+
def initialize
|
4
|
+
super("Cannot create new instance for query builder because class was not given!")
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class InvalidDateRange < Exception
|
9
|
+
def initialize(start_date, end_date)
|
10
|
+
days = ((end_date - start_date) / 1.day).ceil
|
11
|
+
|
12
|
+
super("Your start_date and end_date are #{days} days apart. Mashery's API does not like date ranges that span longer than 7 days. Please use multiple queries to gather your data.")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class QueryParamMissing < Exception
|
17
|
+
def initialize(param)
|
18
|
+
super "Couldn't complete request. The query param #{param.inspect} is missing."
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class ParamMissing < Exception
|
23
|
+
def initialize(param)
|
24
|
+
super "Couldn't determine Mashery #{param.inspect}! Please check your config/masheri.yml"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class ConfigMissing < Exception
|
29
|
+
def initialize
|
30
|
+
super "No configuration has been loaded! Please call Mashery.load_config! with a valid Yaml file."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class MissingConfig < Exception
|
35
|
+
def initialize
|
36
|
+
super("Couldn't find config/mashery.yml! \n" +
|
37
|
+
"Please run `rails g mashery:install` to create one and populate it with the necessary API credentials.")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class UnknownFormat < Exception
|
42
|
+
def initialize(format)
|
43
|
+
super "Unknown format #{format.inspect} for REST API call. Standard formats are CSV and JSON."
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/mashery/key.rb
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
module Mashery
|
2
|
+
class Key < RpcClient::Base
|
3
|
+
attr_accessor(:id, :created, :updated, :service_key, :apikey, :username, :status,
|
4
|
+
:rate_limit_ceiling, :qps_limit_ceiling, :rate_limit_exempt, :qps_limit_exempt,
|
5
|
+
:required_referer, :secret, :limits, :object_type)
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module Mashery
|
2
|
+
class Member < RpcClient::Base
|
3
|
+
attr_accessor(:created, :updated, :username, :email, :display_name,
|
4
|
+
:uri, :blog, :im, :imsvc, :phone, :company, :address1, :address2,
|
5
|
+
:locality, :region, :postal_code, :country_code, :first_name, :last_name,
|
6
|
+
:registration_ipaddr, :area_status, :external_id, :passwd_new, :object_type)
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
module Mashery
|
2
|
+
class QueryBuilder
|
3
|
+
def initialize(klass = nil, options = {})
|
4
|
+
@klass = klass
|
5
|
+
@options = options
|
6
|
+
@conditions = Where.new
|
7
|
+
@select = Select.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def select(argument)
|
11
|
+
@select = Select.new(argument)
|
12
|
+
clone
|
13
|
+
end
|
14
|
+
|
15
|
+
def from(argument)
|
16
|
+
@from = From.new(argument)
|
17
|
+
clone
|
18
|
+
end
|
19
|
+
|
20
|
+
def where(argument)
|
21
|
+
@conditions.add argument
|
22
|
+
clone
|
23
|
+
end
|
24
|
+
|
25
|
+
def order(column, order)
|
26
|
+
@order = Order.new(column, order)
|
27
|
+
clone
|
28
|
+
end
|
29
|
+
|
30
|
+
def items(argument)
|
31
|
+
@items = Items.new(argument)
|
32
|
+
clone
|
33
|
+
end
|
34
|
+
|
35
|
+
def page(argument)
|
36
|
+
@page = Page.new(argument)
|
37
|
+
clone
|
38
|
+
end
|
39
|
+
|
40
|
+
def query
|
41
|
+
[@select, @from, @order, @conditions, @page, @items].map(&:to_s).reject {|s|
|
42
|
+
s.blank?
|
43
|
+
}.compact.join(" ").strip
|
44
|
+
end
|
45
|
+
|
46
|
+
def reify(*args)
|
47
|
+
raise NoClassGiven.new if @klass.blank?
|
48
|
+
@klass.new(*args)
|
49
|
+
end
|
50
|
+
|
51
|
+
alias :to_s :query
|
52
|
+
|
53
|
+
def to_json
|
54
|
+
Mashery.rpc.query(query)
|
55
|
+
end
|
56
|
+
|
57
|
+
def all
|
58
|
+
Mashery::RpcClient::Response.new(self)
|
59
|
+
end
|
60
|
+
|
61
|
+
def find_each(&block)
|
62
|
+
Mashery::RpcClient::Response.new(self).find_each(&block)
|
63
|
+
end
|
64
|
+
|
65
|
+
def first
|
66
|
+
Mashery::RpcClient::Response.new(items(1)).to_objects.first
|
67
|
+
end
|
68
|
+
|
69
|
+
protected
|
70
|
+
|
71
|
+
class Select
|
72
|
+
def initialize(argument = nil)
|
73
|
+
@argument = argument
|
74
|
+
end
|
75
|
+
|
76
|
+
def query
|
77
|
+
@argument || "*"
|
78
|
+
end
|
79
|
+
|
80
|
+
def to_s
|
81
|
+
"SELECT #{query}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class From
|
86
|
+
def initialize(argument)
|
87
|
+
@argument = argument
|
88
|
+
end
|
89
|
+
|
90
|
+
def to_s
|
91
|
+
raise MissingFrom.new if @argument.nil?
|
92
|
+
"FROM #{@argument}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
class Where
|
97
|
+
def initialize(hash = {})
|
98
|
+
@hash = hash
|
99
|
+
end
|
100
|
+
|
101
|
+
def add(hash)
|
102
|
+
@hash.merge!(hash)
|
103
|
+
end
|
104
|
+
|
105
|
+
def to_s
|
106
|
+
if @hash.blank?
|
107
|
+
""
|
108
|
+
else
|
109
|
+
"WHERE #{compute_relation}"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def compute_relation
|
114
|
+
@hash.map do |key, value|
|
115
|
+
if value.is_a? String
|
116
|
+
"#{key} = '#{value}'"
|
117
|
+
else
|
118
|
+
"#{key} = #{value}"
|
119
|
+
end
|
120
|
+
end.join(" AND ")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# An ASC or DESC modifier may appear after each field in the ORDER BY list. If no modifer appears, ASC is assumed.
|
125
|
+
# > SELECT * FROM members ORDER BY created DESC
|
126
|
+
class Order
|
127
|
+
def initialize(column, order)
|
128
|
+
@column = column
|
129
|
+
@order = order
|
130
|
+
end
|
131
|
+
|
132
|
+
def to_s
|
133
|
+
if @column.blank? || @order.blank?
|
134
|
+
""
|
135
|
+
else
|
136
|
+
"ORDER BY #{@column} #{@desc}"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# the ITEMS clause can specify an alternative number of records to return per page.
|
142
|
+
# > SELECT * FROM members ITEMS 25
|
143
|
+
class Items
|
144
|
+
def initialize(count)
|
145
|
+
@count = count
|
146
|
+
end
|
147
|
+
|
148
|
+
def to_s
|
149
|
+
if @count.blank?
|
150
|
+
""
|
151
|
+
else
|
152
|
+
"ITEMS #{@count}"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# By default the first page is returned. The PAGE clause allows additional pages to be returned.
|
158
|
+
# > SELECT * FROM members PAGE 5
|
159
|
+
class Page
|
160
|
+
def initialize(page)
|
161
|
+
@page = page
|
162
|
+
end
|
163
|
+
|
164
|
+
def to_s
|
165
|
+
if @page.blank?
|
166
|
+
""
|
167
|
+
else
|
168
|
+
"PAGE #{@page}"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|