masheri 0.3.1 → 0.3.4

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/README.md CHANGED
@@ -1,3 +1,58 @@
1
+ # masheri
1
2
 
3
+ A Rails library for the [Mashery API](http://support.mashery.com/docs/mashery_api).
4
+
5
+ ## Installation
6
+
7
+ Add the following to your `Gemfile`
8
+
9
+ ```ruby
10
+ gem "masheri"
11
+ ```
12
+
13
+ Then run the installer to create `config/masheri.yml`
14
+
15
+ ```bash
16
+ $ rails g masheri:install
17
+ ```
18
+
19
+ ## Configuration
20
+
21
+ Edit `config/masheri.yml` with your `site_key`, `api_key` and `shared_secret` options.
22
+
23
+
24
+
25
+ ```yaml
26
+ development:
27
+ site_id: 123
28
+ api_key: abc
29
+ shared_secret: xyz
30
+
31
+ test:
32
+ site_id: 123
33
+ api_key: abc
34
+ shared_secret: xyz
35
+
36
+ production:
37
+ site_id: 123
38
+ api_key: abc
39
+ shared_secret: xyz
40
+ ```
41
+
42
+ ## Usage
43
+
44
+
45
+ ### Members
46
+
47
+ ```ruby
48
+ Masheri::Member.fetch_all #=>
49
+ ```
50
+
51
+ ### ???
52
+
53
+
54
+ ### ???
55
+
56
+
57
+ ### ???
2
58
 
3
- Fix this!
data/lib/masheri.rb CHANGED
@@ -1,32 +1,68 @@
1
- require 'active_support/core_ext/module/attribute_accessors'
1
+ $LOAD_PATH.unshift File.expand_path("./lib")
2
+
3
+ require 'active_support/core_ext'
2
4
  require 'logger'
5
+ require 'digest/md5'
6
+ require 'restclient'
3
7
 
4
8
  require 'masheri/exceptions'
5
- require 'masheri/client'
9
+ require 'masheri/config'
10
+ require 'masheri/query_builder'
11
+ require 'masheri/query_methods'
12
+
13
+ require 'masheri/rpc_client'
14
+ require 'masheri/rest_client'
15
+ require 'masheri/rest_client/query'
16
+
6
17
  require 'masheri/api_object_base'
18
+
7
19
  require 'masheri/member'
20
+ require 'masheri/service'
8
21
  require 'masheri/key'
9
22
  require 'masheri/role'
10
23
  require 'masheri/query'
11
24
 
12
- if defined?(Rails)
13
- require 'masheri/rails'
14
- end
15
-
16
25
  module Masheri
17
- mattr_accessor :client
18
- @@client = nil
26
+ @@config = nil
19
27
 
20
- mattr_accessor :logger, :instance_writer => false
21
- # TODO: Handle possible Rails logger.
22
- @@logger = Logger.new(STDOUT)
23
- @@logger.level = Logger::WARN
28
+ def self.config
29
+ raise Masheri::ConfigMissing.new unless @@config.present?
30
+ @@config
31
+ end
24
32
 
25
- mattr_accessor :test_mode, :instance_writer => false
26
- @@test_mode = false
33
+ def self.config=(other)
34
+ @@config = other
35
+ end
27
36
 
28
37
  def self.load_config!(yaml_file)
29
- Masheri.client = Masheri::Client.from_yaml(yaml_file)
38
+ Masheri.config = Masheri::Config.new(yaml_file)
39
+ end
40
+
41
+ def self.local_config
42
+ File.expand_path("~/.masheri.yml")
43
+ end
44
+
45
+ def self.rpc
46
+ Masheri::RpcClient.new
47
+ end
48
+
49
+ def self.rest
50
+ Masheri::RestClient.new
51
+ end
52
+
53
+ def self.developer_activity(service_id, options)
54
+ Masheri.rest.developer_activity(service_id, options)
30
55
  end
31
56
  end
32
57
 
58
+ # TODO: Let config be accepted as command line argument
59
+ # (masheri -C config.yml)
60
+ if defined?(Rails)
61
+ 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
+ end
@@ -1,12 +1,14 @@
1
1
  module Masheri
2
2
  class ApiObjectBase
3
+ mattr_accessor :type_name
4
+
3
5
  def self.create(fields = {})
4
6
  # XXX: only send fields that aren't read-only
5
7
  new(Masheri.client.call_remote(method('create'), fields))
6
8
  end
7
9
 
8
10
  def self.fetch(id)
9
- data = Masheri.client.call_remote(method('fetch'), id)
11
+ data = Masheri.rpc.call_remote(method('fetch'), id)
10
12
  data.nil?? nil : new(data)
11
13
  end
12
14
 
@@ -0,0 +1,71 @@
1
+ module Masheri
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
@@ -1,27 +1,45 @@
1
1
  module Masheri
2
- class Exception < ::Exception
3
- def self.create(options = {})
4
- case options['code']
5
- when 1000 then ValidationException.new(options['data'])
6
- when 1001 then DuplicateObjectException.new("#{options['message']} (JSON-RPC error #{options['code']})")
7
- else JsonRpcException.new("#{options['message']} (JSON-RPC error #{options['code']})")
8
- end
2
+ class InvalidDateRange < Exception
3
+ def initialize(start_date, end_date)
4
+ days = ((end_date - start_date) / 1.day).ceil
5
+
6
+ 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.")
9
7
  end
10
8
  end
11
9
 
12
- class HttpException < Exception
10
+ class QueryParamMissing < Exception
11
+ def initialize(param)
12
+ super "Couldn't complete request. The query param #{param} is missing."
13
+ end
13
14
  end
14
15
 
15
- class JsonRpcException < Exception
16
+ class ParamMissing < Exception
17
+ def initialize(param)
18
+ super "Couldn't determine Mashery #{param}! Please check your config/masheri.yml"
19
+ end
16
20
  end
17
21
 
18
- class DuplicateObjectException < Exception
22
+ class ConfigMissing < Exception
23
+ def initialize
24
+ super "No configuration has been loaded! Please call Masheri.load_config! with a valid Yaml file."
25
+ end
26
+ end
27
+
28
+ class MissingConfig < Exception
29
+ 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
37
+ end
19
38
  end
20
39
 
21
- class ValidationException < Exception
22
- attr_reader :errors
23
- def initialize(errs= {})
24
- @errors = errs
40
+ class UnknownFormat < Exception
41
+ def initialize(format)
42
+ super "Unknown format #{format} for REST API call. Standard formats are CSV and JSON."
25
43
  end
26
44
  end
27
45
  end
data/lib/masheri/init.rb CHANGED
@@ -1,2 +1,7 @@
1
1
 
2
- Masheri.load_rails_config!
2
+ class Masheri
3
+ # Used by the command line tool
4
+ class Init
5
+
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+
2
+
3
+
@@ -1,12 +1,5 @@
1
1
  module Masheri
2
2
  class Member < ApiObjectBase
3
- attr_reader :created, :updated
4
-
5
- attr_accessor(:username, :email, :display_name, :uri, :blog, :im, :imsvc, :phone,
6
- :company, :address1, :address2, :locality, :region, :postal_code,
7
- :country_code, :first_name, :last_name, :registration_ipaddr, :area_status,
8
- :external_id, :passwd_new)
9
-
10
3
  def self.create(username, display_name, email, fields = {})
11
4
  fields ||= {}
12
5
  our_fields = fields.merge('username' => username, 'display_name' => display_name, 'email' => email)
@@ -14,11 +7,11 @@ module Masheri
14
7
  end
15
8
 
16
9
  def self.fetch_all
17
- Masheri.client.call_remote("object.query", params: "SELECT * FROM members")
10
+ Masheri::RpcClient.new.call_remote("object.query", params: "SELECT * FROM members")
18
11
  end
19
12
 
20
13
  def self.fetch_by_username(username)
21
- Masheri.client.call_remote("object.query", params: "SELECT * FROM members WHERE username = '#{username}'")
14
+ Masheri::RpcClient.new.call_remote("member.fetch", params: username)
22
15
  end
23
16
 
24
17
  def add_role(role_or_id)
data/lib/masheri/query.rb CHANGED
@@ -1,3 +1,8 @@
1
+ #
2
+ # This class handles this aspect of the API:
3
+ #
4
+ # http://support.mashery.com/docs/read/mashery_api/20/Query_Language
5
+ #
1
6
  module Masheri
2
7
  class Query
3
8
  OBJECT_TYPES = ['members', 'keys', 'services', 'roles', 'applications']
@@ -0,0 +1,170 @@
1
+ module Masheri
2
+ class QueryBuilder
3
+ attr_accessor :klass
4
+
5
+ def initialize(klass, options = {})
6
+ @klass = klass
7
+ @options = options
8
+ @conditions = Where.new
9
+ @select = Select.new
10
+ end
11
+
12
+ def select(argument)
13
+ @select = Select.new(argument)
14
+ clone
15
+ end
16
+
17
+ def from(argument)
18
+ @from = From.new(argument)
19
+ clone
20
+ end
21
+
22
+ def where(argument)
23
+ @conditions.add argument
24
+ clone
25
+ end
26
+
27
+ def order(column, order)
28
+ @order = Order.new(column, order)
29
+ clone
30
+ end
31
+
32
+ def items(argument)
33
+ @items = Items.new(argument)
34
+ clone
35
+ end
36
+
37
+ def page(argument)
38
+ @page = Page.new(argument)
39
+ clone
40
+ end
41
+
42
+ def query
43
+ [@select, @from, @order, @conditions, @page, @items].map(&:to_s).reject {|s|
44
+ s.blank?
45
+ }.compact.join(" ").strip
46
+ end
47
+
48
+ alias :to_s :query
49
+
50
+ def to_json
51
+ Masheri.rpc.query(query)
52
+ end
53
+
54
+ def all
55
+ Masheri::RpcResponse.new(self)
56
+ end
57
+
58
+ def find_each(&block)
59
+ Masheri::RpcResponse.new(self).find_each(&block)
60
+ end
61
+
62
+ def first
63
+ Masheri::RpcResponse.new(items(1)).to_objects.first
64
+ end
65
+
66
+ protected
67
+
68
+ class Select
69
+ def initialize(argument = nil)
70
+ @argument = argument
71
+ end
72
+
73
+ def query
74
+ @argument || "*"
75
+ end
76
+
77
+ def to_s
78
+ "SELECT #{query}"
79
+ end
80
+ end
81
+
82
+ class From
83
+ def initialize(argument)
84
+ @argument = argument
85
+ end
86
+
87
+ def to_s
88
+ raise MissingFrom.new if @argument.nil?
89
+ "FROM #{@argument}"
90
+ end
91
+ end
92
+
93
+ class Where
94
+ def initialize(hash = {})
95
+ @hash = hash
96
+ end
97
+
98
+ def add(hash)
99
+ @hash.merge!(hash)
100
+ end
101
+
102
+ def to_s
103
+ if @hash.blank?
104
+ ""
105
+ else
106
+ "WHERE #{compute_relation}"
107
+ end
108
+ end
109
+
110
+ def compute_relation
111
+ @hash.map do |key, value|
112
+ if value.is_a? String
113
+ "#{key} = '#{value}'"
114
+ else
115
+ "#{key} = #{value}"
116
+ end
117
+ end.join(" AND ")
118
+ end
119
+ end
120
+
121
+ # An ASC or DESC modifier may appear after each field in the ORDER BY list. If no modifer appears, ASC is assumed.
122
+ # > SELECT * FROM members ORDER BY created DESC
123
+ class Order
124
+ def initialize(column, order)
125
+ @column = column
126
+ @order = order
127
+ end
128
+
129
+ def to_s
130
+ if @column.blank? || @order.blank?
131
+ ""
132
+ else
133
+ "ORDER BY #{@column} #{@desc}"
134
+ end
135
+ end
136
+ end
137
+
138
+ # the ITEMS clause can specify an alternative number of records to return per page.
139
+ # > SELECT * FROM members ITEMS 25
140
+ class Items
141
+ def initialize(count)
142
+ @count = count
143
+ end
144
+
145
+ def to_s
146
+ if @count.blank?
147
+ ""
148
+ else
149
+ "ITEMS #{@count}"
150
+ end
151
+ end
152
+ end
153
+
154
+ # By default the first page is returned. The PAGE clause allows additional pages to be returned.
155
+ # > SELECT * FROM members PAGE 5
156
+ class Page
157
+ def initialize(page)
158
+ @page = page
159
+ end
160
+
161
+ def to_s
162
+ if @page.blank?
163
+ ""
164
+ else
165
+ "PAGE #{@page}"
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,39 @@
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
data/lib/masheri/rails.rb CHANGED
@@ -1,11 +1,10 @@
1
1
  module Masheri
2
- class MissingConfig < Exception; end
3
2
 
4
3
  def self.load_rails_config!
5
4
  if File.exists? rails_config
6
5
  load_config! rails_config
7
6
  else
8
- raise MissingConfig.new("Couldn't find config/masheri.yml! Please run rails g masheri:install to create one and populate it with the necessary API credentials.")
7
+ raise MissingConfig.new
9
8
  end
10
9
  end
11
10
 
@@ -0,0 +1,30 @@
1
+ module Masheri
2
+ class RestClient
3
+ def config
4
+ Masheri.config
5
+ end
6
+
7
+ def developer_activity_query(service_id, options)
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
15
+ end
16
+
17
+ def developer_activity(service_id, options)
18
+ query = developer_activity_query(service_id, options)
19
+ response = ::RestClient.get(query.url)
20
+
21
+ if query.format == "json"
22
+ JSON.parse(response)
23
+ elsif query.format == "csv"
24
+ response
25
+ else
26
+ raise UnknownFormat.new(query.format)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,74 @@
1
+ module Masheri
2
+ class RestClient
3
+ class Query
4
+ def initialize(options)
5
+ @options = options
6
+ end
7
+
8
+ def format
9
+ @options[:format] || "csv"
10
+ end
11
+
12
+ def limit
13
+ @options[:limit] || 1000
14
+ end
15
+
16
+ def start_date
17
+ @options[:start_date].strftime("%Y-%m-%dT00:00:00Z")
18
+ end
19
+
20
+ def end_date
21
+ @options[:end_date].strftime("%Y-%m-%dT00:00:00Z")
22
+ end
23
+
24
+ def check_params!
25
+ raise QueryParamMissing.new("end_date") if @options[:end_date].blank?
26
+ raise QueryParamMissing.new("start_date") if @options[:start_date].blank?
27
+ end
28
+
29
+ def check_dates!
30
+ if @options[:end_date] - @options[:start_date] > 7.days
31
+ raise InvalidDateRange.new(@options[:start_date], @options[:end_date])
32
+ end
33
+ end
34
+
35
+ def params
36
+ check_params!
37
+ check_dates!
38
+
39
+ params = {
40
+ start_date: start_date,
41
+ end_date: end_date,
42
+ format: format,
43
+ limit: limit,
44
+ apikey: config.key,
45
+ sig: config.signature
46
+ }
47
+ end
48
+
49
+ def config
50
+ Masheri.config
51
+ end
52
+
53
+ def query_params
54
+ URI.encode_www_form(params).gsub("%3A", ":")
55
+ end
56
+
57
+ def service_id
58
+ @options[:service_id]
59
+ end
60
+
61
+ def resource
62
+ @options[:resource]
63
+ end
64
+
65
+ def path
66
+ "/v2/rest/#{config.site_id}/reports/calls/#{resource}/service/#{service_id}"
67
+ end
68
+
69
+ def url
70
+ URI::HTTP.build(host: config.host, path: path, query: query_params).to_s
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,130 @@
1
+ module Masheri
2
+ class RpcResponse
3
+ def initialize(query_builder)
4
+ @query_builder = query_builder
5
+ @json = query_builder.to_json
6
+ end
7
+
8
+ def result
9
+ @json["result"]
10
+ end
11
+
12
+ def error
13
+ @json["error"]
14
+ end
15
+
16
+ def items
17
+ result["items"]
18
+ end
19
+
20
+ def to_objects
21
+ items.map do |item|
22
+ @query_builder.klass.new(item)
23
+ end
24
+ end
25
+
26
+ def find_each(&block)
27
+ items.each(&block)
28
+
29
+ if next_page?
30
+ response = next_page!
31
+ response.find_each(&block)
32
+ end
33
+ end
34
+
35
+ def error?
36
+ error.present?
37
+ end
38
+
39
+ def length
40
+ items.length
41
+ end
42
+
43
+ def more_pages?
44
+ current_page < total_pages
45
+ end
46
+
47
+ alias :next_page? :more_pages?
48
+
49
+ def next_page_number
50
+ current_page + 1
51
+ end
52
+
53
+ # Can't call Mashery too many times, or they get mad
54
+ MASHERY_WAIT_TIME = 0.1
55
+
56
+ def next_page!
57
+ sleep(MASHERY_WAIT_TIME)
58
+ RpcResponse.new(@query_builder.page(next_page_number))
59
+ end
60
+
61
+ def total_items
62
+ result["total_items"]
63
+ end
64
+
65
+ def total_pages
66
+ result["total_pages"]
67
+ end
68
+
69
+ def current_page
70
+ result["current_page"]
71
+ end
72
+
73
+ def items_per_page
74
+ result["items_per_page"]
75
+ end
76
+ end
77
+
78
+ class RpcClient
79
+ def config
80
+ Masheri.config
81
+ end
82
+
83
+ # Test Mashery API with echo service
84
+ def echo(value)
85
+ call_remote('test.echo', value)
86
+ end
87
+
88
+ def query_builder(klass)
89
+ Masheri::QueryBuilder.new(klass)
90
+ end
91
+
92
+ # Use the Mashery query language to grab data
93
+ def query(string)
94
+ call_remote("object.query", params: string)
95
+ end
96
+
97
+ # Create an object
98
+ def create(type, params)
99
+ # TODO: Handle params!
100
+ call_remote [type_name, "create"].join('.')
101
+ end
102
+
103
+ def call_remote(method, opts = {})
104
+ perform('method' => method, 'params' => Array(opts[:params]), 'id' => 1)
105
+ end
106
+
107
+ protected
108
+
109
+ def perform(params)
110
+ JSON.parse(post!(full_url, params))
111
+ end
112
+
113
+ def post!(full_url, params)
114
+ ::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)
123
+ end
124
+
125
+ 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
+ end
129
+ end
130
+ end
@@ -0,0 +1,22 @@
1
+ module Masheri
2
+ class Service
3
+ include QueryInstanceMethods
4
+ extend QueryClassMethods
5
+
6
+ attr_accessor :service_key, :name, :limits, :created, :updated, :object_type
7
+
8
+ def self.object_type
9
+ "services"
10
+ end
11
+
12
+ def developer_activity(options = {})
13
+ Masheri.rest.developer_activity(service_key, start_date: 1.day.ago, end_date: 0.days.ago)
14
+ end
15
+
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
21
+ end
22
+ 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.1
4
+ version: 0.3.4
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-05 00:00:00.000000000 Z
12
+ date: 2013-09-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -28,23 +28,7 @@ dependencies:
28
28
  - !ruby/object:Gem::Version
29
29
  version: 3.1.0
30
30
  - !ruby/object:Gem::Dependency
31
- name: thor
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ! '>='
36
- - !ruby/object:Gem::Version
37
- version: '0'
38
- type: :runtime
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ! '>='
44
- - !ruby/object:Gem::Version
45
- version: '0'
46
- - !ruby/object:Gem::Dependency
47
- name: httparty
31
+ name: rest-client
48
32
  requirement: !ruby/object:Gem::Requirement
49
33
  none: false
50
34
  requirements:
@@ -84,25 +68,26 @@ extra_rdoc_files:
84
68
  - README.md
85
69
  - README.textile
86
70
  files:
87
- - Gemfile
88
- - Gemfile.lock
89
- - LICENSE.txt
90
- - README.md
91
- - README.textile
92
- - Rakefile
93
- - VERSION
94
71
  - lib/masheri.rb
95
72
  - lib/masheri/api_object_base.rb
96
- - lib/masheri/client.rb
73
+ - lib/masheri/config.rb
97
74
  - lib/masheri/exceptions.rb
98
75
  - lib/masheri/init.rb
99
76
  - lib/masheri/key.rb
77
+ - lib/masheri/local.rb
100
78
  - lib/masheri/member.rb
101
79
  - lib/masheri/query.rb
80
+ - lib/masheri/query_builder.rb
81
+ - lib/masheri/query_methods.rb
102
82
  - lib/masheri/rails.rb
83
+ - lib/masheri/rest_client.rb
84
+ - lib/masheri/rest_client/query.rb
103
85
  - lib/masheri/role.rb
104
- - masheri.gemspec
105
- - tasks/mashery.thor
86
+ - lib/masheri/rpc_client.rb
87
+ - lib/masheri/service.rb
88
+ - LICENSE.txt
89
+ - README.md
90
+ - README.textile
106
91
  homepage: http://github.com/farleyknight/masheri
107
92
  licenses:
108
93
  - MIT
@@ -118,7 +103,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
118
103
  version: '0'
119
104
  segments:
120
105
  - 0
121
- hash: 4568995836595795516
106
+ hash: 2969431552703139300
122
107
  required_rubygems_version: !ruby/object:Gem::Requirement
123
108
  none: false
124
109
  requirements:
data/Gemfile DELETED
@@ -1,6 +0,0 @@
1
- source 'http://rubygems.org'
2
-
3
- gem 'activesupport', ">= 3.1.0"
4
- gem 'thor'
5
- gem 'httparty'
6
- gem 'json'
data/Gemfile.lock DELETED
@@ -1,31 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- activesupport (4.0.0)
5
- i18n (~> 0.6, >= 0.6.4)
6
- minitest (~> 4.2)
7
- multi_json (~> 1.3)
8
- thread_safe (~> 0.1)
9
- tzinfo (~> 0.3.37)
10
- atomic (1.1.13)
11
- httparty (0.11.0)
12
- multi_json (~> 1.0)
13
- multi_xml (>= 0.5.2)
14
- i18n (0.6.5)
15
- json (1.8.0)
16
- minitest (4.7.5)
17
- multi_json (1.7.9)
18
- multi_xml (0.5.5)
19
- thor (0.18.1)
20
- thread_safe (0.1.2)
21
- atomic
22
- tzinfo (0.3.37)
23
-
24
- PLATFORMS
25
- ruby
26
-
27
- DEPENDENCIES
28
- activesupport (>= 3.1.0)
29
- httparty
30
- json
31
- thor
data/Rakefile DELETED
@@ -1,15 +0,0 @@
1
- begin
2
- require 'jeweler'
3
- Jeweler::RubygemsDotOrgTasks.new
4
-
5
- Jeweler::Tasks.new do |gemspec|
6
- gemspec.name = "masheri"
7
- gemspec.summary = "Rails gem for Mashery. Clean config and includes tests."
8
- gemspec.email = "farleyknight@gmail.com"
9
- gemspec.homepage = "http://github.com/farleyknight/masheri"
10
- gemspec.authors = ["Farley Knight"]
11
- gemspec.license = "MIT"
12
- end
13
- rescue LoadError => error
14
- puts error
15
- end
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.3.1
@@ -1,61 +0,0 @@
1
- require 'active_support'
2
- require 'json'
3
- require 'httparty'
4
- require 'digest/md5'
5
-
6
- module Masheri
7
- class Client
8
- TEST_HOST = 'api.sandbox.mashery.com'
9
- PRODUCTION_HOST = 'api.mashery.com'
10
-
11
- def self.from_yaml(yaml_file)
12
- config = YAML.load_file(yaml_file)
13
- new(config["site_id"], config["key"], config["secret"])
14
- end
15
-
16
- attr_accessor :uri, :key, :secret
17
-
18
- def initialize(site_id, key, secret)
19
- host = Masheri.test_mode ? TEST_HOST : PRODUCTION_HOST
20
- @uri = "http://#{host}/v2/json-rpc/#{site_id}"
21
- @key = key
22
- @secret = secret
23
- end
24
-
25
- def echo(value)
26
- call_remote('test.echo', value)
27
- end
28
-
29
- def perform(params)
30
- # all calls are synchronous, so id in request and response will always be 1
31
- if Masheri.logger
32
- Masheri.logger.debug("Calling query with params #{params.inspect} on URI #{full_url}")
33
- end
34
-
35
- response = RestClient.post(full_url, params.to_json, {
36
- "Content-Type" => "application/json",
37
- "Accept" => "text/plain",
38
- "Content-Length" => params.size
39
- })
40
-
41
- JSON.parse response
42
- end
43
-
44
- def query(string)
45
- call_remote("object.query", params: string)
46
- end
47
-
48
- def call_remote(method, opts = {})
49
- perform({'method' => method, 'params'=> [opts[:params]], 'id' => 1})
50
- end
51
-
52
- def create(type, params)
53
- call_remote("#{type}.create")
54
- end
55
-
56
- protected
57
- def full_url
58
- "#{@uri}?apikey=#{@key}&sig=#{Digest::MD5.hexdigest(@key + @secret + Time.now.to_f.to_i.to_s)}"
59
- end
60
- end
61
- end
data/masheri.gemspec DELETED
@@ -1,67 +0,0 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = "masheri"
8
- s.version = "0.3.1"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Farley Knight"]
12
- s.date = "2013-09-05"
13
- s.email = "farleyknight@gmail.com"
14
- s.extra_rdoc_files = [
15
- "LICENSE.txt",
16
- "README.md",
17
- "README.textile"
18
- ]
19
- s.files = [
20
- "Gemfile",
21
- "Gemfile.lock",
22
- "LICENSE.txt",
23
- "README.md",
24
- "README.textile",
25
- "Rakefile",
26
- "VERSION",
27
- "lib/masheri.rb",
28
- "lib/masheri/api_object_base.rb",
29
- "lib/masheri/client.rb",
30
- "lib/masheri/exceptions.rb",
31
- "lib/masheri/init.rb",
32
- "lib/masheri/key.rb",
33
- "lib/masheri/member.rb",
34
- "lib/masheri/query.rb",
35
- "lib/masheri/rails.rb",
36
- "lib/masheri/role.rb",
37
- "masheri.gemspec",
38
- "tasks/mashery.thor"
39
- ]
40
- s.homepage = "http://github.com/farleyknight/masheri"
41
- s.licenses = ["MIT"]
42
- s.require_paths = ["lib"]
43
- s.rubygems_version = "1.8.25"
44
- s.summary = "Rails gem for Mashery. Clean config and includes tests."
45
-
46
- if s.respond_to? :specification_version then
47
- s.specification_version = 3
48
-
49
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
- s.add_runtime_dependency(%q<activesupport>, [">= 3.1.0"])
51
- s.add_runtime_dependency(%q<thor>, [">= 0"])
52
- s.add_runtime_dependency(%q<httparty>, [">= 0"])
53
- s.add_runtime_dependency(%q<json>, [">= 0"])
54
- else
55
- s.add_dependency(%q<activesupport>, [">= 3.1.0"])
56
- s.add_dependency(%q<thor>, [">= 0"])
57
- s.add_dependency(%q<httparty>, [">= 0"])
58
- s.add_dependency(%q<json>, [">= 0"])
59
- end
60
- else
61
- s.add_dependency(%q<activesupport>, [">= 3.1.0"])
62
- s.add_dependency(%q<thor>, [">= 0"])
63
- s.add_dependency(%q<httparty>, [">= 0"])
64
- s.add_dependency(%q<json>, [">= 0"])
65
- end
66
- end
67
-
data/tasks/mashery.thor DELETED
@@ -1,200 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- Bundler.setup
4
-
5
- # XXX: only do this when the task has not been installed
6
- $: << 'lib'
7
-
8
- require 'mashery'
9
-
10
- module Mashery
11
- class CLI < Thor
12
- namespace :mashery
13
-
14
- desc "echo VALUE", "Echo the provided value (tests connectivity and authentication)"
15
- def echo(value)
16
- run { ok(::Mashery.client.echo(value)) }
17
- end
18
-
19
- protected
20
- def run(&block)
21
- site_id = ENV['MASHERY_SITE_ID'] or
22
- raise Exception, "Please set the MASHERY_SITE_ID environment variable."
23
- key = ENV['MASHERY_API_KEY'] or
24
- raise Exception, "Please set the MASHERY_API_KEY environment variable."
25
- secret = ENV['MASHERY_SHARED_SECRET'] or
26
- raise Exception, "Please set the MASHERY_SHARED_SECRET environment variable."
27
- ::Mashery.test_mode = ENV['MASHERY_PRODUCTION_MODE'].blank?
28
- ::Mashery.logger.level = Logger::DEBUG
29
- ::Mashery.client = ::Mashery::Client.new(site_id, key, secret)
30
- begin
31
- yield
32
- rescue ::Mashery::HttpException => e
33
- error("HTTP error: #{e.message}")
34
- rescue ::Mashery::JsonRpcException => e
35
- error(e.message)
36
- rescue ::Mashery::ValidationException => e
37
- e.errors.each {|err| warn("#{err['field']}: #{err['message']}")}
38
- error("Unable to execute method due to validation errors")
39
- end
40
- end
41
-
42
- def warn(msg)
43
- say_status :WARN, msg, :yellow
44
- end
45
-
46
- def ok(msg)
47
- say_status :OK, msg
48
- end
49
-
50
- def error(msg)
51
- say_status :ERROR, msg, :red
52
- end
53
-
54
- def debug(msg)
55
- say_status :DEBUG, msg, :cyan
56
- end
57
- end
58
-
59
- class MemberCLI < CLI
60
- namespace 'mashery:member'
61
-
62
- desc "create USERNAME DISPLAY_NAME EMAIL [--fields ...]", "Create a member"
63
- method_option :fields, :type => :hash
64
- def create(username, display_name, email)
65
- run do
66
- begin
67
- member = ::Mashery::Member.create(username, display_name, email, options[:fields])
68
- ok("Member #{member.username} created")
69
- rescue ::Mashery::DuplicateObjectException
70
- error("The username #{username} has already been claimed")
71
- end
72
- end
73
- end
74
-
75
- desc "fetch USERNAME", "Fetch a member"
76
- def fetch(username)
77
- run do
78
- member = ::Mashery::Member.fetch(username)
79
- if member
80
- ok("Member #{username} found")
81
- say(member.to_yaml)
82
- else
83
- warn("Member #{username} not found")
84
- end
85
- end
86
- end
87
-
88
- desc "addrole USERNAME ROLE_ID", "Assign a role to a member"
89
- def addrole(username, role_id)
90
- run do
91
- member = ::Mashery::Member.fetch(username)
92
- if member
93
- role = ::Mashery::Role.fetch(role_id.to_i)
94
- if role
95
- member.add_role(role)
96
- ok("Role #{role.name} assigned to member #{username}")
97
- else
98
- warn("Role #{role_id} not found")
99
- end
100
- else
101
- warn("Member #{username} not found")
102
- end
103
- end
104
- end
105
-
106
- desc "rmrole USERNAME ROLE_ID", "Revoke a role from a member"
107
- def rmrole(username, role_id)
108
- run do
109
- member = ::Mashery::Member.fetch(username)
110
- if member
111
- role = ::Mashery::Role.fetch(role_id.to_i)
112
- if role
113
- member.remove_role(role)
114
- ok("Role #{role.name} revoked from member #{username}")
115
- else
116
- warn("Role #{role_id} not found")
117
- end
118
- else
119
- warn("Member #{username} not found")
120
- end
121
- end
122
- end
123
-
124
- desc "delete USERNAME", "Delete a member"
125
- def delete(username)
126
- run do
127
- ::Mashery::Member.delete(username)
128
- ok("Member #{username} deleted")
129
- end
130
- end
131
- end
132
-
133
- class KeyCLI < CLI
134
- namespace 'mashery:key'
135
-
136
- desc "create SERVICE_KEY USERNAME [--fields ...]", "Create a key"
137
- method_option :fields, :type => :hash
138
- def create(service_key, username)
139
- run do
140
- key = ::Mashery::Key.create(service_key, username, options[:fields])
141
- ok("Key #{key.id} created for member #{username} and service #{service_key}")
142
- end
143
- end
144
-
145
- desc "fetch ID", "Fetch a key"
146
- def fetch(id)
147
- run do
148
- key = ::Mashery::Key.fetch(id.to_i)
149
- if key
150
- ok("Key #{id} found")
151
- say(key.to_yaml)
152
- else
153
- warn("Key #{id} not found")
154
- end
155
- end
156
- end
157
-
158
- desc "delete ID", "Delete a key"
159
- def delete(id)
160
- run do
161
- ::Mashery::Key.delete(id.to_i)
162
- ok("Key #{id} deleted")
163
- end
164
- end
165
- end
166
-
167
- class RoleCLI < CLI
168
- namespace 'mashery:role'
169
-
170
- desc "create NAME [--fields ...]", "Create a role"
171
- method_option :fields, :type => :hash
172
- def create(name)
173
- run do
174
- role = ::Mashery::Role.create(name, options[:fields])
175
- ok("Role #{role.id} created with name #{name}")
176
- end
177
- end
178
-
179
- desc "fetch ID", "Fetch a role"
180
- def fetch(id)
181
- run do
182
- role = ::Mashery::Role.fetch(id.to_i)
183
- if role
184
- ok("Role #{id} found")
185
- say(role.to_yaml)
186
- else
187
- warn("Role #{id} not found")
188
- end
189
- end
190
- end
191
-
192
- desc "delete ID", "Delete a role"
193
- def delete(id)
194
- run do
195
- ::Mashery::Role.delete(id.to_i)
196
- ok("Role #{id} deleted")
197
- end
198
- end
199
- end
200
- end