mashery_rails 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/.travis.yml +12 -0
- data/.yardoc/checksums +17 -0
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/.yardoc/proxy_types +0 -0
- data/Gemfile +21 -0
- data/Gemfile.devtools +55 -0
- data/Gemfile.lock +215 -0
- data/LICENSE.txt +21 -0
- data/README.md +63 -0
- data/Rakefile +9 -0
- data/VERSION +1 -0
- data/config/devtools.yml +2 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/mutant.yml +3 -0
- data/config/reek.yml +103 -0
- data/config/rubocop.yml +58 -0
- data/config/yardstick.yml +2 -0
- data/lib/mashery.rb +55 -0
- data/lib/mashery/config.rb +71 -0
- data/lib/mashery/exceptions.rb +46 -0
- data/lib/mashery/key.rb +7 -0
- data/lib/mashery/local.rb +3 -0
- data/lib/mashery/member.rb +8 -0
- data/lib/mashery/query_builder.rb +173 -0
- data/lib/mashery/rails.rb +19 -0
- data/lib/mashery/rest_client.rb +31 -0
- data/lib/mashery/rest_client/query.rb +77 -0
- data/lib/mashery/rpc_client.rb +58 -0
- data/lib/mashery/rpc_client/base.rb +51 -0
- data/lib/mashery/rpc_client/response.rb +79 -0
- data/lib/mashery/service.rb +9 -0
- data/masheri.gemspec +26 -0
- data/mashery_rails.gemspec +25 -0
- data/spec/fixtures/config.no_host.yml +4 -0
- data/spec/fixtures/config.no_key.yml +4 -0
- data/spec/fixtures/config.no_secret.yml +4 -0
- data/spec/fixtures/config.no_site_id.yml +4 -0
- data/spec/fixtures/config.yml +5 -0
- data/spec/fixtures/services.json +3 -0
- data/spec/mashery/config_spec.rb +38 -0
- data/spec/mashery/member_spec.rb +47 -0
- data/spec/mashery/query_builder_spec.rb +13 -0
- data/spec/mashery/rest_client_spec.rb +47 -0
- data/spec/mashery/rpc_client_spec.rb +28 -0
- data/spec/mashery/service_spec.rb +101 -0
- data/spec/mashery_spec.rb +5 -0
- data/spec/spec_helper.rb +50 -0
- data/tasks/mashery.thor +200 -0
- metadata +147 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
module Mashery
|
2
|
+
def self.load_rails_config!
|
3
|
+
if File.exists? rails_config
|
4
|
+
load_config! rails_config
|
5
|
+
else
|
6
|
+
raise MissingConfig.new
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.rails_config
|
11
|
+
Rails.root.join("config", "mashery.yml")
|
12
|
+
end
|
13
|
+
|
14
|
+
class Engine < ::Rails::Engine
|
15
|
+
initializer "load_masheri_config" do
|
16
|
+
Mashery.load_rails_config!
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Mashery
|
2
|
+
class RestClient
|
3
|
+
def build_url(query_params)
|
4
|
+
Query.new(query_params).url
|
5
|
+
end
|
6
|
+
|
7
|
+
def activity(activity_type, service_id, options)
|
8
|
+
if activity_type == "developer_activity"
|
9
|
+
developer_activity(service_id, options)
|
10
|
+
else
|
11
|
+
raise "No such activity type!"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def developer_activity_query(service_id, options)
|
16
|
+
query_options = {service_id: service_id, resource: "developer_activity"}.merge(options)
|
17
|
+
Query.new(query_options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def developer_activity(service_id, options)
|
21
|
+
query = developer_activity_query(service_id, options)
|
22
|
+
response = ::RestClient.get(query.url)
|
23
|
+
|
24
|
+
if query.format == "json" or query.format == "csv"
|
25
|
+
response
|
26
|
+
else
|
27
|
+
raise UnknownFormat.new(query.format)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Mashery
|
2
|
+
class RestClient
|
3
|
+
class Query
|
4
|
+
def initialize(options)
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def service_id
|
9
|
+
@options[:service_id]
|
10
|
+
end
|
11
|
+
|
12
|
+
def resource
|
13
|
+
@options[:resource]
|
14
|
+
end
|
15
|
+
|
16
|
+
def format
|
17
|
+
@options[:format] || "csv"
|
18
|
+
end
|
19
|
+
|
20
|
+
def limit
|
21
|
+
@options[:limit] || 1000
|
22
|
+
end
|
23
|
+
|
24
|
+
def start_date
|
25
|
+
@options[:start_date].strftime("%Y-%m-%dT00:00:00Z")
|
26
|
+
end
|
27
|
+
|
28
|
+
def end_date
|
29
|
+
@options[:end_date].strftime("%Y-%m-%dT00:00:00Z")
|
30
|
+
end
|
31
|
+
|
32
|
+
def check_params!
|
33
|
+
raise QueryParamMissing.new("resource") if @options[:resource].blank?
|
34
|
+
raise QueryParamMissing.new("end_date") if @options[:end_date].blank?
|
35
|
+
raise QueryParamMissing.new("start_date") if @options[:start_date].blank?
|
36
|
+
end
|
37
|
+
|
38
|
+
def check_dates!
|
39
|
+
if @options[:end_date] - @options[:start_date] > 7.days
|
40
|
+
raise InvalidDateRange.new(@options[:start_date], @options[:end_date])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def params
|
45
|
+
check_params!
|
46
|
+
check_dates!
|
47
|
+
|
48
|
+
params = {
|
49
|
+
start_date: start_date,
|
50
|
+
end_date: end_date,
|
51
|
+
format: format,
|
52
|
+
limit: limit,
|
53
|
+
apikey: config.key,
|
54
|
+
sig: config.signature
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def config
|
59
|
+
Mashery.config
|
60
|
+
end
|
61
|
+
|
62
|
+
def query_params
|
63
|
+
URI.encode_www_form(params).gsub("%3A", ":")
|
64
|
+
end
|
65
|
+
|
66
|
+
def rest_path
|
67
|
+
"/v2/rest/#{config.site_id}/reports/calls/#{resource}/service/#{service_id}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def url
|
71
|
+
uri = URI::HTTP.build(host: config.host, path: rest_path, query: query_params)
|
72
|
+
uri.scheme = "https"
|
73
|
+
uri.to_s
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Mashery
|
2
|
+
class RpcClient
|
3
|
+
def config
|
4
|
+
Mashery.config
|
5
|
+
end
|
6
|
+
|
7
|
+
# Test Mashery API with echo service
|
8
|
+
def echo(value)
|
9
|
+
call_remote('test.echo', value)
|
10
|
+
end
|
11
|
+
|
12
|
+
def query_builder(klass)
|
13
|
+
Mashery::QueryBuilder.new(klass)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Use the Mashery query language to grab data
|
17
|
+
def query(string)
|
18
|
+
call_remote("object.query", params: string)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Create an object
|
22
|
+
def create(type, params)
|
23
|
+
# TODO: Handle params!
|
24
|
+
call_remote [type_name, "create"].join('.')
|
25
|
+
end
|
26
|
+
|
27
|
+
def call_remote(method, opts = {})
|
28
|
+
perform('method' => method, 'params' => Array(opts[:params]), 'id' => 1)
|
29
|
+
end
|
30
|
+
|
31
|
+
def full_url
|
32
|
+
build_url(config.site_id, config.key, config.signature)
|
33
|
+
end
|
34
|
+
|
35
|
+
alias :url :full_url
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
def perform(params)
|
40
|
+
JSON.parse(post!(full_url, params))
|
41
|
+
end
|
42
|
+
|
43
|
+
def post!(full_url, params)
|
44
|
+
::RestClient.post(full_url, params.to_json, {
|
45
|
+
"Content-Type" => "application/json",
|
46
|
+
"Accept" => "text/plain",
|
47
|
+
"Content-Length" => params.size
|
48
|
+
})
|
49
|
+
end
|
50
|
+
|
51
|
+
def build_url(site_id, apikey, signature)
|
52
|
+
query = URI.encode_www_form(apikey: apikey, sig: signature)
|
53
|
+
uri = URI::HTTP.build(host: config.host, path: "/v2/json-rpc/#{site_id}", query: query.to_s)
|
54
|
+
uri.scheme = "https"
|
55
|
+
uri.to_s
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Mashery
|
2
|
+
class RpcClient
|
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.count
|
11
|
+
default_query.items(1).to_json["result"]["total_items"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.all
|
15
|
+
default_query.all
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.items(argument)
|
19
|
+
default_query.items(argument)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.where(argument)
|
23
|
+
default_query.where(argument)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.page(argument)
|
27
|
+
default_query.page(argument)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.find_each(&block)
|
31
|
+
default_query.find_each(&block)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.standard_query
|
35
|
+
Mashery.rpc.query_builder(self).from(object_type).items(100)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.default_query
|
39
|
+
standard_query
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.first
|
43
|
+
new(standard_query.items(1).all.items[0])
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.object_type
|
47
|
+
self.name.underscore.split('/').last.pluralize
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Mashery
|
2
|
+
class RpcClient
|
3
|
+
class Response
|
4
|
+
def initialize(query_builder)
|
5
|
+
@query_builder = query_builder
|
6
|
+
@json = query_builder.to_json
|
7
|
+
end
|
8
|
+
|
9
|
+
def result
|
10
|
+
@json["result"]
|
11
|
+
end
|
12
|
+
|
13
|
+
def error
|
14
|
+
@json["error"]
|
15
|
+
end
|
16
|
+
|
17
|
+
def items
|
18
|
+
result["items"]
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_objects
|
22
|
+
items.map do |item|
|
23
|
+
@query_builder.reify(item)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def find_each(&block)
|
28
|
+
to_objects.each(&block)
|
29
|
+
|
30
|
+
if next_page?
|
31
|
+
response = next_page!
|
32
|
+
response.find_each(&block)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def error?
|
37
|
+
error.present?
|
38
|
+
end
|
39
|
+
|
40
|
+
def length
|
41
|
+
items.length
|
42
|
+
end
|
43
|
+
|
44
|
+
def more_pages?
|
45
|
+
current_page < total_pages
|
46
|
+
end
|
47
|
+
|
48
|
+
alias :next_page? :more_pages?
|
49
|
+
|
50
|
+
def next_page_number
|
51
|
+
current_page + 1
|
52
|
+
end
|
53
|
+
|
54
|
+
# Can't call Mashery too many times, or they get mad
|
55
|
+
MASHERY_WAIT_TIME = 0.1
|
56
|
+
|
57
|
+
def next_page!
|
58
|
+
sleep(MASHERY_WAIT_TIME)
|
59
|
+
Response.new(@query_builder.page(next_page_number))
|
60
|
+
end
|
61
|
+
|
62
|
+
def total_items
|
63
|
+
result["total_items"]
|
64
|
+
end
|
65
|
+
|
66
|
+
def total_pages
|
67
|
+
result["total_pages"]
|
68
|
+
end
|
69
|
+
|
70
|
+
def current_page
|
71
|
+
result["current_page"]
|
72
|
+
end
|
73
|
+
|
74
|
+
def items_per_page
|
75
|
+
result["items_per_page"]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Mashery
|
2
|
+
class Service < RpcClient::Base
|
3
|
+
attr_accessor :service_key, :name, :limits, :created, :updated, :object_type
|
4
|
+
|
5
|
+
def activity(options = {})
|
6
|
+
Mashery.rest.activity("developer_activity", service_key, start_date: 1.day.ago, end_date: 0.days.ago)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
data/masheri.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "masheri"
|
3
|
+
s.version = File.read("VERSION")
|
4
|
+
|
5
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
6
|
+
s.authors = ["Farley Knight"]
|
7
|
+
s.date = "2013-09-23"
|
8
|
+
s.email = "farleyknight@gmail.com"
|
9
|
+
s.extra_rdoc_files = [
|
10
|
+
"LICENSE.txt",
|
11
|
+
"README.md",
|
12
|
+
"README.textile"
|
13
|
+
]
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
|
17
|
+
s.homepage = "http://github.com/farleyknight/masheri"
|
18
|
+
s.licenses = ["MIT"]
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
s.rubygems_version = "1.8.25"
|
21
|
+
s.summary = "Rails gem for Mashery. Clean config and includes tests with decent test coverage"
|
22
|
+
|
23
|
+
s.add_dependency(%q<activesupport>, [">= 3.1.0"])
|
24
|
+
s.add_dependency(%q<rest-client>, [">= 0"])
|
25
|
+
s.add_dependency(%q<json>, [">= 0"])
|
26
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "mashery_rails"
|
3
|
+
s.version = File.read("VERSION")
|
4
|
+
|
5
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
6
|
+
s.authors = ["Farley Knight"]
|
7
|
+
s.date = "2013-09-23"
|
8
|
+
s.email = "farleyknight@gmail.com"
|
9
|
+
s.extra_rdoc_files = [
|
10
|
+
"LICENSE.txt",
|
11
|
+
"README.md",
|
12
|
+
]
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
|
16
|
+
s.homepage = "http://github.com/farleyknight/mashery_rails"
|
17
|
+
s.licenses = ["MIT"]
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
s.rubygems_version = "1.8.25"
|
20
|
+
s.summary = "Rails gem for Mashery. Clean config and includes tests with decent test coverage"
|
21
|
+
|
22
|
+
s.add_dependency(%q<activesupport>, [">= 3.1.0"])
|
23
|
+
s.add_dependency(%q<rest-client>, [">= 0"])
|
24
|
+
s.add_dependency(%q<json>, [">= 0"])
|
25
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mashery::Config do
|
4
|
+
it "should raise an error on lack of key" do
|
5
|
+
expect {
|
6
|
+
Mashery::Config.new("spec/fixtures/config.no_key.yml")
|
7
|
+
}.to raise_error(Mashery::ParamMissing, /key/)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should raise an error on lack of site_id" do
|
11
|
+
expect {
|
12
|
+
Mashery::Config.new("spec/fixtures/config.no_site_id.yml")
|
13
|
+
}.to raise_error(Mashery::ParamMissing, /site_id/)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should raise an error on lack of secret" do
|
17
|
+
expect {
|
18
|
+
Mashery::Config.new("spec/fixtures/config.no_secret.yml")
|
19
|
+
}.to raise_error(Mashery::ParamMissing, /secret/)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should raise an error on lack of host" do
|
23
|
+
expect {
|
24
|
+
Mashery::Config.new("spec/fixtures/config.no_host.yml")
|
25
|
+
}.to raise_error(Mashery::ParamMissing, /host/)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should have site_id, key, secret, host and signature as attributes" do
|
29
|
+
config = Mashery::Config.new("spec/fixtures/config.yml")
|
30
|
+
expect do
|
31
|
+
config.key
|
32
|
+
config.secret
|
33
|
+
config.signature
|
34
|
+
config.host
|
35
|
+
config.site_id
|
36
|
+
end.to_not raise_error
|
37
|
+
end
|
38
|
+
end
|