mashery_rails 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/.gitignore +6 -0
  2. data/.travis.yml +12 -0
  3. data/.yardoc/checksums +17 -0
  4. data/.yardoc/object_types +0 -0
  5. data/.yardoc/objects/root.dat +0 -0
  6. data/.yardoc/proxy_types +0 -0
  7. data/Gemfile +21 -0
  8. data/Gemfile.devtools +55 -0
  9. data/Gemfile.lock +215 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +63 -0
  12. data/Rakefile +9 -0
  13. data/VERSION +1 -0
  14. data/config/devtools.yml +2 -0
  15. data/config/flay.yml +3 -0
  16. data/config/flog.yml +2 -0
  17. data/config/mutant.yml +3 -0
  18. data/config/reek.yml +103 -0
  19. data/config/rubocop.yml +58 -0
  20. data/config/yardstick.yml +2 -0
  21. data/lib/mashery.rb +55 -0
  22. data/lib/mashery/config.rb +71 -0
  23. data/lib/mashery/exceptions.rb +46 -0
  24. data/lib/mashery/key.rb +7 -0
  25. data/lib/mashery/local.rb +3 -0
  26. data/lib/mashery/member.rb +8 -0
  27. data/lib/mashery/query_builder.rb +173 -0
  28. data/lib/mashery/rails.rb +19 -0
  29. data/lib/mashery/rest_client.rb +31 -0
  30. data/lib/mashery/rest_client/query.rb +77 -0
  31. data/lib/mashery/rpc_client.rb +58 -0
  32. data/lib/mashery/rpc_client/base.rb +51 -0
  33. data/lib/mashery/rpc_client/response.rb +79 -0
  34. data/lib/mashery/service.rb +9 -0
  35. data/masheri.gemspec +26 -0
  36. data/mashery_rails.gemspec +25 -0
  37. data/spec/fixtures/config.no_host.yml +4 -0
  38. data/spec/fixtures/config.no_key.yml +4 -0
  39. data/spec/fixtures/config.no_secret.yml +4 -0
  40. data/spec/fixtures/config.no_site_id.yml +4 -0
  41. data/spec/fixtures/config.yml +5 -0
  42. data/spec/fixtures/services.json +3 -0
  43. data/spec/mashery/config_spec.rb +38 -0
  44. data/spec/mashery/member_spec.rb +47 -0
  45. data/spec/mashery/query_builder_spec.rb +13 -0
  46. data/spec/mashery/rest_client_spec.rb +47 -0
  47. data/spec/mashery/rpc_client_spec.rb +28 -0
  48. data/spec/mashery/service_spec.rb +101 -0
  49. data/spec/mashery_spec.rb +5 -0
  50. data/spec/spec_helper.rb +50 -0
  51. data/tasks/mashery.thor +200 -0
  52. metadata +147 -0
data/config/flay.yml ADDED
@@ -0,0 +1,3 @@
1
+ ---
2
+ threshold: 0
3
+ total_score: 0
data/config/flog.yml ADDED
@@ -0,0 +1,2 @@
1
+ ---
2
+ threshold: 0
data/config/mutant.yml ADDED
@@ -0,0 +1,3 @@
1
+ ---
2
+ name: your_lib
3
+ namespace: YourLib
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
@@ -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
@@ -0,0 +1,2 @@
1
+ ---
2
+ threshold: 100
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
@@ -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,3 @@
1
+
2
+
3
+
@@ -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