masheri 0.3.5 → 0.3.6

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.
@@ -7,20 +7,16 @@ require 'restclient'
7
7
 
8
8
  require 'masheri/exceptions'
9
9
  require 'masheri/config'
10
- require 'masheri/query_builder'
11
- require 'masheri/query_methods'
12
10
 
13
11
  require 'masheri/rpc_client'
12
+
14
13
  require 'masheri/rest_client'
14
+ require 'masheri/query_builder'
15
15
  require 'masheri/rest_client/query'
16
-
17
- require 'masheri/api_object_base'
16
+ require 'masheri/rest_client/base'
18
17
 
19
18
  require 'masheri/member'
20
19
  require 'masheri/service'
21
- require 'masheri/key'
22
- require 'masheri/role'
23
- require 'masheri/query'
24
20
 
25
21
  module Masheri
26
22
  @@config = nil
@@ -38,10 +34,6 @@ module Masheri
38
34
  Masheri.config = Masheri::Config.new(yaml_file)
39
35
  end
40
36
 
41
- def self.local_config
42
- File.expand_path("~/.masheri.yml")
43
- end
44
-
45
37
  def self.rpc
46
38
  Masheri::RpcClient.new
47
39
  end
@@ -57,12 +49,7 @@ end
57
49
 
58
50
  # TODO: Let config be accepted as command line argument
59
51
  # (masheri -C config.yml)
52
+ #
60
53
  if defined?(Rails)
61
54
  require 'masheri/rails'
62
- elsif File.exists?(Masheri.local_config)
63
- Masheri.load_config! Masheri.local_config
64
- elsif defined?(RSpec)
65
- # Skip testing environment..
66
- else
67
- raise Masheri::MissingConfig.new
68
55
  end
@@ -1,4 +1,10 @@
1
1
  module Masheri
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
+
2
8
  class InvalidDateRange < Exception
3
9
  def initialize(start_date, end_date)
4
10
  days = ((end_date - start_date) / 1.day).ceil
@@ -9,13 +15,13 @@ module Masheri
9
15
 
10
16
  class QueryParamMissing < Exception
11
17
  def initialize(param)
12
- super "Couldn't complete request. The query param #{param} is missing."
18
+ super "Couldn't complete request. The query param #{param.inspect} is missing."
13
19
  end
14
20
  end
15
21
 
16
22
  class ParamMissing < Exception
17
23
  def initialize(param)
18
- super "Couldn't determine Mashery #{param}! Please check your config/masheri.yml"
24
+ super "Couldn't determine Mashery #{param.inspect}! Please check your config/masheri.yml"
19
25
  end
20
26
  end
21
27
 
@@ -27,19 +33,14 @@ module Masheri
27
33
 
28
34
  class MissingConfig < Exception
29
35
  def initialize
30
- if defined?(Rails)
31
- super("Couldn't find config/masheri.yml! \n" +
32
- "Please run `rails g masheri:install` to create one and populate it with the necessary API credentials.")
33
- else
34
- super("Couldn't find ~/.masheri.yml! \n" +
35
- "Please run `masheri --init` to create one and populate it with the necessary API credentials.")
36
- end
36
+ super("Couldn't find config/masheri.yml! \n" +
37
+ "Please run `rails g masheri:install` to create one and populate it with the necessary API credentials.")
37
38
  end
38
39
  end
39
40
 
40
41
  class UnknownFormat < Exception
41
42
  def initialize(format)
42
- super "Unknown format #{format} for REST API call. Standard formats are CSV and JSON."
43
+ super "Unknown format #{format.inspect} for REST API call. Standard formats are CSV and JSON."
43
44
  end
44
45
  end
45
46
  end
@@ -1,27 +1,7 @@
1
1
  module Masheri
2
- class Member < ApiObjectBase
3
- def self.create(username, display_name, email, fields = {})
4
- fields ||= {}
5
- our_fields = fields.merge('username' => username, 'display_name' => display_name, 'email' => email)
6
- super(our_fields)
7
- end
8
-
9
- def self.fetch_all
10
- Masheri::RpcClient.new.call_remote("object.query", params: "SELECT * FROM members")
11
- end
12
-
13
- def self.fetch_by_username(username)
14
- Masheri::RpcClient.new.call_remote("member.fetch", params: username)
15
- end
16
-
17
- def add_role(role_or_id)
18
- role_id = role_or_id.is_a?(Role) ? role_or_id.id : role_or_id
19
- Masheri.client.call_remote('member.addRole', {'username' => username}, {'id' => role_id})
20
- end
21
-
22
- def remove_role(role_or_id)
23
- role_id = role_or_id.is_a?(Role) ? role_or_id.id : role_or_id
24
- Masheri.client.call_remote('member.removeRole', {'username' => username}, {'id' => role_id})
2
+ class Member < RestClient::Base
3
+ def self.object_type
4
+ "members"
25
5
  end
26
6
  end
27
7
  end
@@ -1,8 +1,6 @@
1
1
  module Masheri
2
2
  class QueryBuilder
3
- attr_accessor :klass
4
-
5
- def initialize(klass, options = {})
3
+ def initialize(klass = nil, options = {})
6
4
  @klass = klass
7
5
  @options = options
8
6
  @conditions = Where.new
@@ -45,6 +43,11 @@ module Masheri
45
43
  }.compact.join(" ").strip
46
44
  end
47
45
 
46
+ def reify(*args)
47
+ raise NoClassGiven.new if @klass.blank?
48
+ @klass.new(*args)
49
+ end
50
+
48
51
  alias :to_s :query
49
52
 
50
53
  def to_json
@@ -1,17 +1,12 @@
1
1
  module Masheri
2
2
  class RestClient
3
- def config
4
- Masheri.config
3
+ def build_url(query_params)
4
+ Query.new(query_params).url
5
5
  end
6
6
 
7
7
  def developer_activity_query(service_id, options)
8
8
  query_options = {service_id: service_id, resource: "developer_activity"}.merge(options)
9
- Masheri::RestClient::Query.new(query_options)
10
- end
11
-
12
- def developer_activity_url(service_id, options)
13
- query = developer_activity_query(service_id, options)
14
- query.url
9
+ Query.new(query_options)
15
10
  end
16
11
 
17
12
  def developer_activity(service_id, options)
@@ -0,0 +1,44 @@
1
+ module Masheri
2
+ class RestClient
3
+ class Base
4
+ def initialize(attributes)
5
+ attributes.each do |key, value|
6
+ send("#{key}=", value)
7
+ end
8
+ end
9
+
10
+ def self.all
11
+ default_query.all
12
+ end
13
+
14
+ def self.items(argument)
15
+ default_query.items(argument)
16
+ end
17
+
18
+ def self.where(argument)
19
+ default_query.where(argument)
20
+ end
21
+
22
+ def self.page(argument)
23
+ default_query.page(argument)
24
+ end
25
+
26
+ def self.find_each(&block)
27
+ default_query.find_each(&block)
28
+ end
29
+
30
+ def self.standard_query
31
+ Masheri.rpc.query_builder(self).from(object_type).items(100)
32
+ end
33
+
34
+ def self.default_query
35
+ standard_query
36
+ end
37
+
38
+ def self.first
39
+ new(standard_query.items(1).all.items[0])
40
+ end
41
+ end
42
+ end
43
+ end
44
+
@@ -5,6 +5,14 @@ module Masheri
5
5
  @options = options
6
6
  end
7
7
 
8
+ def service_id
9
+ @options[:service_id]
10
+ end
11
+
12
+ def resource
13
+ @options[:resource]
14
+ end
15
+
8
16
  def format
9
17
  @options[:format] || "csv"
10
18
  end
@@ -22,6 +30,7 @@ module Masheri
22
30
  end
23
31
 
24
32
  def check_params!
33
+ raise QueryParamMissing.new("resource") if @options[:resource].blank?
25
34
  raise QueryParamMissing.new("end_date") if @options[:end_date].blank?
26
35
  raise QueryParamMissing.new("start_date") if @options[:start_date].blank?
27
36
  end
@@ -54,20 +63,14 @@ module Masheri
54
63
  URI.encode_www_form(params).gsub("%3A", ":")
55
64
  end
56
65
 
57
- def service_id
58
- @options[:service_id]
59
- end
60
-
61
- def resource
62
- @options[:resource]
63
- end
64
-
65
- def path
66
+ def rest_path
66
67
  "/v2/rest/#{config.site_id}/reports/calls/#{resource}/service/#{service_id}"
67
68
  end
68
69
 
69
70
  def url
70
- URI::HTTP.build(host: config.host, path: path, query: query_params).to_s
71
+ uri = URI::HTTP.build(host: config.host, path: rest_path, query: query_params)
72
+ uri.scheme = "https"
73
+ uri.to_s
71
74
  end
72
75
  end
73
76
  end
@@ -19,12 +19,12 @@ module Masheri
19
19
 
20
20
  def to_objects
21
21
  items.map do |item|
22
- @query_builder.klass.new(item)
22
+ @query_builder.reify(item)
23
23
  end
24
24
  end
25
25
 
26
26
  def find_each(&block)
27
- items.each(&block)
27
+ to_objects.each(&block)
28
28
 
29
29
  if next_page?
30
30
  response = next_page!
@@ -104,6 +104,12 @@ module Masheri
104
104
  perform('method' => method, 'params' => Array(opts[:params]), 'id' => 1)
105
105
  end
106
106
 
107
+ def full_url
108
+ build_url(config.site_id, config.key, config.signature)
109
+ end
110
+
111
+ alias :url :full_url
112
+
107
113
  protected
108
114
 
109
115
  def perform(params)
@@ -112,19 +118,17 @@ module Masheri
112
118
 
113
119
  def post!(full_url, params)
114
120
  ::RestClient.post(full_url, params.to_json, {
115
- "Content-Type" => "application/json",
116
- "Accept" => "text/plain",
117
- "Content-Length" => params.size
118
- })
119
- end
120
-
121
- def full_url
122
- build_url(config.site_id, config.key, config.signature)
121
+ "Content-Type" => "application/json",
122
+ "Accept" => "text/plain",
123
+ "Content-Length" => params.size
124
+ })
123
125
  end
124
126
 
125
127
  def build_url(site_id, apikey, signature)
126
- query = URI.encode_www_form(apikey: apikey, sig: signature)
127
- URI::HTTP.build(host: config.host, path: "/v2/json-rpc/#{site_id}", query: query.to_s).to_s
128
+ query = URI.encode_www_form(apikey: apikey, sig: signature)
129
+ uri = URI::HTTP.build(host: config.host, path: "/v2/json-rpc/#{site_id}", query: query.to_s)
130
+ uri.scheme = "https"
131
+ uri.to_s
128
132
  end
129
133
  end
130
134
  end
@@ -1,8 +1,5 @@
1
1
  module Masheri
2
- class Service
3
- include QueryInstanceMethods
4
- extend QueryClassMethods
5
-
2
+ class Service < RestClient::Base
6
3
  attr_accessor :service_key, :name, :limits, :created, :updated, :object_type
7
4
 
8
5
  def self.object_type
@@ -13,10 +10,6 @@ module Masheri
13
10
  Masheri.rest.developer_activity(service_key, start_date: 1.day.ago, end_date: 0.days.ago)
14
11
  end
15
12
 
16
- def self.show_list
17
- find_each do |entry|
18
- printf "Service Name: %-50s Service Key: %s\n", entry.name.inspect, entry.service_key
19
- end
20
- end
13
+ alias :activity :developer_activity
21
14
  end
22
15
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: masheri
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.3.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-09-12 00:00:00.000000000 Z
12
+ date: 2013-09-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -59,6 +59,102 @@ dependencies:
59
59
  - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: jeweler
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: redcarpet
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: devtools
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rake
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 10.1.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 10.1.0
126
+ - !ruby/object:Gem::Dependency
127
+ name: rspec
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: 2.14.1
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: 2.14.1
142
+ - !ruby/object:Gem::Dependency
143
+ name: yard
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: 0.8.7
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: 0.8.7
62
158
  description:
63
159
  email: farleyknight@gmail.com
64
160
  executables: []
@@ -69,20 +165,16 @@ extra_rdoc_files:
69
165
  - README.textile
70
166
  files:
71
167
  - lib/masheri.rb
72
- - lib/masheri/api_object_base.rb
73
168
  - lib/masheri/config.rb
74
169
  - lib/masheri/exceptions.rb
75
170
  - lib/masheri/init.rb
76
- - lib/masheri/key.rb
77
171
  - lib/masheri/local.rb
78
172
  - lib/masheri/member.rb
79
- - lib/masheri/query.rb
80
173
  - lib/masheri/query_builder.rb
81
- - lib/masheri/query_methods.rb
82
174
  - lib/masheri/rails.rb
83
175
  - lib/masheri/rest_client.rb
176
+ - lib/masheri/rest_client/base.rb
84
177
  - lib/masheri/rest_client/query.rb
85
- - lib/masheri/role.rb
86
178
  - lib/masheri/rpc_client.rb
87
179
  - lib/masheri/service.rb
88
180
  - LICENSE.txt
@@ -103,7 +195,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
103
195
  version: '0'
104
196
  segments:
105
197
  - 0
106
- hash: 1386576050914279145
198
+ hash: 2313416616875261274
107
199
  required_rubygems_version: !ruby/object:Gem::Requirement
108
200
  none: false
109
201
  requirements:
@@ -1,28 +0,0 @@
1
- module Masheri
2
- class ApiObjectBase
3
- mattr_accessor :type_name
4
-
5
- def self.create(fields = {})
6
- # XXX: only send fields that aren't read-only
7
- new(Masheri.client.call_remote(method('create'), fields))
8
- end
9
-
10
- def self.fetch(id)
11
- data = Masheri.rpc.call_remote(method('fetch'), id)
12
- data.nil?? nil : new(data)
13
- end
14
-
15
- def self.delete(id)
16
- Masheri.client.call_remote(method('delete'), id)
17
- end
18
-
19
- def self.method(basename)
20
- "#{name.split(/\:\:/).last.downcase}.#{basename}"
21
- end
22
-
23
- def initialize(data)
24
- # XXX: use setter methods
25
- data.each_pair {|k, v| instance_variable_set("@#{k}".to_sym, v)}
26
- end
27
- end
28
- end
@@ -1,22 +0,0 @@
1
- module Masheri
2
- class Key < ApiObjectBase
3
- attr_reader :id, :created, :updated, :service_key, :username, :limits
4
- attr_accessor(:apikey, :status, :rate_limit_ceiling, :qps_limit_ceiling, :rate_limit_exempt, :qps_limit_exempt,
5
- :required_referer, :secret)
6
-
7
- def self.create(service_key, username, fields = {})
8
- fields ||= {}
9
- our_fields = fields.merge('service' => {'service_key' => service_key}, 'member' => {'username' => username})
10
- super(our_fields)
11
- end
12
-
13
- def initialize(data)
14
- limits = data.delete('limits')
15
- @limits = limits.map {|l| Limit.new(l['period'], l['source'], l['ceiling'])} if limits
16
- super
17
- end
18
- end
19
-
20
- class Limit < Struct.new(:period, :source, :ceiling)
21
- end
22
- end
@@ -1,68 +0,0 @@
1
- #
2
- # This class handles this aspect of the API:
3
- #
4
- # http://support.mashery.com/docs/read/mashery_api/20/Query_Language
5
- #
6
- module Masheri
7
- class Query
8
- OBJECT_TYPES = ['members', 'keys', 'services', 'roles', 'applications']
9
- DEFAULT_QUERIES_PER_SECOND = 2
10
-
11
- attr_reader :object_type, :fields
12
- attr_accessor :page
13
-
14
- def initialize(object_type, options={})
15
- if !OBJECT_TYPES.include?(object_type)
16
- raise "Invalid object type. '#{object_type}' must be in #{OBJECT_TYPES.inspect}"
17
- end
18
-
19
- @object_type = object_type
20
-
21
- if options[:fields]
22
- @fields = options[:fields]
23
- else
24
- @fields = "*"
25
- end
26
-
27
- @where = options[:where]
28
- @page = options[:page]
29
- end
30
-
31
- def page_clause
32
- "PAGE #{@page}" if @page
33
- end
34
-
35
- def where_clause
36
- "WHERE #{@where}" if @where
37
- end
38
-
39
- def query_string
40
- "SELECT #{fields} FROM #{object_type} #{where_clause} #{page_clause}"
41
- end
42
-
43
- def execute
44
- Masheri.client.call_remote('object.query', query_string)
45
- end
46
-
47
- def items
48
- execute['items']
49
- end
50
-
51
- # Page through the results. Due heavy use of the API, this method
52
- # takes a qps parameter to control how often the API is called.
53
- def fetch_all(qps = DEFAULT_QUERIES_PER_SECOND)
54
- response = execute
55
- items = response['items']
56
-
57
- while response['current_page'] < response['total_pages']
58
- self.page = response['current_page'] + 1
59
- response = execute
60
- items = items + response['items']
61
-
62
- sleep(1.0/DEFAULT_QUERIES_PER_SECOND)
63
- end
64
-
65
- return items
66
- end
67
- end
68
- end
@@ -1,39 +0,0 @@
1
- module Masheri
2
- module QueryInstanceMethods
3
- def initialize(attributes)
4
- attributes.each do |key, value|
5
- send("#{key}=", value)
6
- end
7
- end
8
- end
9
-
10
- module QueryClassMethods
11
- def items(argument)
12
- default_query.items(argument)
13
- end
14
-
15
- def where(argument)
16
- default_query.where(argument)
17
- end
18
-
19
- def page(argument)
20
- default_query.page(argument)
21
- end
22
-
23
- def find_each(&block)
24
- default_query.find_each(&block)
25
- end
26
-
27
- def standard_query
28
- Masheri.rpc.query_builder(self).from(object_type).items(100)
29
- end
30
-
31
- def default_query
32
- standard_query
33
- end
34
-
35
- def first
36
- Masheri::Service.new standard_query.items(1).all.items[0]
37
- end
38
- end
39
- end
@@ -1,20 +0,0 @@
1
- module Masheri
2
- class Role < ApiObjectBase
3
- attr_reader :id, :created, :updated, :is_assignable, :is_predefined
4
- attr_accessor :name, :description
5
-
6
- def assignable?
7
- is_assignable == true
8
- end
9
-
10
- def predefined?
11
- is_predefined == true
12
- end
13
-
14
- def self.create(name, fields = {})
15
- fields ||= {}
16
- our_fields = fields.merge('name' => name)
17
- super(our_fields)
18
- end
19
- end
20
- end