masheri 0.3.1 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
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