reg.api2 0.0.1
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/.gitignore +17 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/.yardopts +7 -0
- data/Gemfile +6 -0
- data/LICENSE +22 -0
- data/README.md +56 -0
- data/Rakefile +32 -0
- data/lib/reg_api2/builder.rb +29 -0
- data/lib/reg_api2/clients.rb +14 -0
- data/lib/reg_api2/common.rb +46 -0
- data/lib/reg_api2/domains.rb +13 -0
- data/lib/reg_api2/entity/entity_base.rb +57 -0
- data/lib/reg_api2/entity/user.rb +36 -0
- data/lib/reg_api2/impl.rb +175 -0
- data/lib/reg_api2/request_contract/default.rb +66 -0
- data/lib/reg_api2/result_contract/default.rb +25 -0
- data/lib/reg_api2/result_contract/single_field.rb +16 -0
- data/lib/reg_api2/service.rb +27 -0
- data/lib/reg_api2/user.rb +52 -0
- data/lib/reg_api2/util.rb +13 -0
- data/lib/reg_api2/version.rb +5 -0
- data/lib/reg_api2.rb +53 -0
- data/reg.api2.gemspec +31 -0
- data/spec/blueprints/user.rb +39 -0
- data/spec/lib/reg_api2/clients_spec.rb +10 -0
- data/spec/lib/reg_api2/common_spec.rb +39 -0
- data/spec/lib/reg_api2/domains_spec.rb +9 -0
- data/spec/lib/reg_api2/entity/entity_base_spec.rb +22 -0
- data/spec/lib/reg_api2/request_contract/default_spec.rb +22 -0
- data/spec/lib/reg_api2/result_contract/default_spec.rb +25 -0
- data/spec/lib/reg_api2/result_contract/single_field_spec.rb +22 -0
- data/spec/lib/reg_api2/service_spec.rb +23 -0
- data/spec/lib/reg_api2/user_spec.rb +65 -0
- data/spec/spec_helper.rb +40 -0
- metadata +259 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Akzhan Abdulin
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# REG.API 2 for Ruby
|
2
|
+
|
3
|
+
[](https://travis-ci.org/regru/reg_api2-ruby)
|
4
|
+
[](https://codeclimate.com/github/regru/reg_api2-ruby)
|
5
|
+
[](https://coveralls.io/r/regru/reg_api2-ruby)
|
6
|
+
|
7
|
+
REG.API v2 Implementation.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'reg.api2'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install reg.api2
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
### List of services by specified identifiers
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require "reg_api2"
|
29
|
+
|
30
|
+
RegApi2.service.nop(services: [
|
31
|
+
{ dname:"test.ru" },
|
32
|
+
{ dname: "test.su", servtype: "srv_hosting_ispmgr" },
|
33
|
+
{ service_id: 111111 },
|
34
|
+
{ service_id: "22bug22" },
|
35
|
+
{ surprise: "surprise.ru" }
|
36
|
+
])
|
37
|
+
```
|
38
|
+
|
39
|
+
## Documentation
|
40
|
+
|
41
|
+
Simply do
|
42
|
+
|
43
|
+
```bash
|
44
|
+
bundle exec rake yard
|
45
|
+
open doc/index.html
|
46
|
+
```
|
47
|
+
|
48
|
+
Also documentation available at https://www.reg.com/support/help/API-version2
|
49
|
+
|
50
|
+
## Contributing
|
51
|
+
|
52
|
+
1. Fork it
|
53
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
54
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
55
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
56
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
|
5
|
+
APP_ROOT = File.dirname(__FILE__).freeze
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'rspec/core/rake_task'
|
9
|
+
|
10
|
+
RSpec::Core::RakeTask.new
|
11
|
+
|
12
|
+
RSpec::Core::RakeTask.new(:rcov) do |t|
|
13
|
+
t.rcov = true
|
14
|
+
t.ruby_opts = '-w'
|
15
|
+
t.rcov_opts = %q[-Ilib --exclude "spec/*,gems/*"]
|
16
|
+
end
|
17
|
+
rescue LoadError
|
18
|
+
$stderr.puts "RSpec not available. Install it with: gem install rspec-core rspec-expectations"
|
19
|
+
end
|
20
|
+
|
21
|
+
task :default => :spec
|
22
|
+
|
23
|
+
begin
|
24
|
+
require 'yard'
|
25
|
+
|
26
|
+
YARD::Rake::YardocTask.new do |yard|
|
27
|
+
version = File.exists?('VERSION') ? IO.read('VERSION') : ""
|
28
|
+
yard.options << "--title='reg.api2 #{version}'"
|
29
|
+
end
|
30
|
+
rescue LoadError
|
31
|
+
$stderr.puts "Please install YARD with: gem install yard"
|
32
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module RegApi2
|
3
|
+
# Internal DSL Builder. Provides metamethods.
|
4
|
+
module Builder
|
5
|
+
|
6
|
+
# Extends module by metamethods `category` and `define`.
|
7
|
+
def self.included(mod)
|
8
|
+
mod.module_eval do
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# @!method Sets method category
|
12
|
+
# @param category [String or NilClass] Category of methods
|
13
|
+
# @see define
|
14
|
+
def category category
|
15
|
+
@cat = category
|
16
|
+
end
|
17
|
+
|
18
|
+
# @!method Defines API method.
|
19
|
+
# @param name Name of specified method.
|
20
|
+
def define name, defopts = {}
|
21
|
+
define_method name do |opts = {}|
|
22
|
+
RegApi2.make_action(@cat, name, defopts, opts)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require 'reg_api2/result_contract/single_field'
|
4
|
+
|
5
|
+
module RegApi2
|
6
|
+
|
7
|
+
# REG.API common category
|
8
|
+
module Common
|
9
|
+
|
10
|
+
include RegApi2::Builder
|
11
|
+
|
12
|
+
category nil
|
13
|
+
|
14
|
+
# @!method nop
|
15
|
+
# @param None
|
16
|
+
# For testing purposes (do nothing + get the login and identifier of the user logged into the system).
|
17
|
+
# @return [Hash("login", "user_id")]
|
18
|
+
define :nop
|
19
|
+
|
20
|
+
# @!method reseller_nop
|
21
|
+
# @param None
|
22
|
+
# Similar to the nop function, except for the following aspects.
|
23
|
+
# @note Accessibility: partners
|
24
|
+
# @note Access mode: Secure HTTPS only
|
25
|
+
# @note Support of service lists: no
|
26
|
+
# @return [Hash("login", "user_id")]
|
27
|
+
define :reseller_nop
|
28
|
+
|
29
|
+
|
30
|
+
# @!method get_user_id
|
31
|
+
# @param None
|
32
|
+
# For testing purposes (returns the identifier of the user logged into the system).
|
33
|
+
# @return [String] user_id
|
34
|
+
define :get_user_id, result: :single_field, field: 'user_id'
|
35
|
+
|
36
|
+
# @!method get_service_id(opts = {})
|
37
|
+
# @param [Hash] opts The options.
|
38
|
+
# @option opts [FixNum] :service_id Service identifier.
|
39
|
+
# Gets service/domain identifier
|
40
|
+
# @return [String] service_id
|
41
|
+
define :get_service_id, result: :single_field, field: 'service_id'
|
42
|
+
|
43
|
+
extend self
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'yajl'
|
2
|
+
|
3
|
+
module RegApi2
|
4
|
+
# Optional entities that can be used instead of clean hashes.
|
5
|
+
module Entity
|
6
|
+
# Base entity class.
|
7
|
+
class EntityBase
|
8
|
+
|
9
|
+
# Skipped property names.
|
10
|
+
SKIPPED_MEMBERS = [
|
11
|
+
"taguri" # from YAML mixin
|
12
|
+
].freeze
|
13
|
+
|
14
|
+
# Gets instance property names
|
15
|
+
# @return [Array(String)]
|
16
|
+
def property_names
|
17
|
+
methods = self.class.public_instance_methods(false).map(&:to_s)
|
18
|
+
methods.select do |n|
|
19
|
+
true &&
|
20
|
+
!SKIPPED_MEMBERS.detect { |n3| n3 == n } &&
|
21
|
+
n =~ /^[^=\?!]+$/ &&
|
22
|
+
methods.detect { |n2| "#{n}=" == n2 } &&
|
23
|
+
true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# All r/w properties interpreted as symbol hash.
|
28
|
+
# @return [Hash] properties as hash.
|
29
|
+
def to_hash
|
30
|
+
h = {}
|
31
|
+
property_names.each do |n|
|
32
|
+
v = self.send n.to_sym
|
33
|
+
h[n.to_sym] = v unless v.nil?
|
34
|
+
end
|
35
|
+
h
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns JSON
|
39
|
+
# @return [String] JSON
|
40
|
+
# @see #to_hash
|
41
|
+
def to_json
|
42
|
+
Yajl::Encoder.encode to_hash
|
43
|
+
end
|
44
|
+
|
45
|
+
# Initializes the instance.
|
46
|
+
# opts values are assigned to properties if exist.
|
47
|
+
# @param [Hash] opts
|
48
|
+
def initialize opts = {}
|
49
|
+
methods = self.class.public_instance_methods(false).map(&:to_s)
|
50
|
+
opts.keys.each do |key|
|
51
|
+
next unless methods.detect { |m| m == "#{key}=" }
|
52
|
+
send("#{key}=", opts[key])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'reg_api2/entity/entity_base'
|
2
|
+
|
3
|
+
module RegApi2
|
4
|
+
module Entity
|
5
|
+
# Represents REG.API user.
|
6
|
+
class User < EntityBase
|
7
|
+
# @note Required property.
|
8
|
+
attr_accessor :user_login
|
9
|
+
# @note Required property.
|
10
|
+
attr_accessor :user_password
|
11
|
+
# @note Required property.
|
12
|
+
attr_accessor :user_email
|
13
|
+
# @note Required property.
|
14
|
+
attr_accessor :user_country_code
|
15
|
+
|
16
|
+
attr_accessor :user_first_name
|
17
|
+
attr_accessor :user_last_name
|
18
|
+
attr_accessor :user_company
|
19
|
+
attr_accessor :user_jabber_id
|
20
|
+
attr_accessor :user_icq
|
21
|
+
attr_accessor :user_phone
|
22
|
+
attr_accessor :user_fax
|
23
|
+
attr_accessor :user_addr
|
24
|
+
attr_accessor :user_city
|
25
|
+
attr_accessor :user_state
|
26
|
+
attr_accessor :user_postcode
|
27
|
+
attr_accessor :user_wmid
|
28
|
+
attr_accessor :user_website
|
29
|
+
|
30
|
+
attr_accessor :user_subsribe
|
31
|
+
attr_accessor :user_mailnotify
|
32
|
+
attr_accessor :set_me_as_referrer
|
33
|
+
attr_accessor :check_only
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'net/http'
|
3
|
+
require 'net/https'
|
4
|
+
require 'yajl'
|
5
|
+
|
6
|
+
require 'reg_api2/util'
|
7
|
+
|
8
|
+
module RegApi2
|
9
|
+
# Networking Error
|
10
|
+
class NetError < Exception
|
11
|
+
end
|
12
|
+
# API Contract Error
|
13
|
+
class ContractError < Exception
|
14
|
+
end
|
15
|
+
# API Error
|
16
|
+
class ApiError < Exception
|
17
|
+
# @!attribute [r] description
|
18
|
+
# Localized error description.
|
19
|
+
attr_reader :description
|
20
|
+
# @!attribute [r] params
|
21
|
+
# Optional error params.
|
22
|
+
attr_reader :params
|
23
|
+
|
24
|
+
def initialize code, description, params
|
25
|
+
super code
|
26
|
+
@description = description
|
27
|
+
@params = params
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class << self
|
32
|
+
# @!attribute [rw] username
|
33
|
+
# @return [String] User name.
|
34
|
+
attr_accessor :username
|
35
|
+
# @!attribute [rw] password
|
36
|
+
# @return [String] Password.
|
37
|
+
attr_accessor :password
|
38
|
+
# @!attribute [rw] io_encoding
|
39
|
+
# @return [String] IO encoding ('utf-8' by default).
|
40
|
+
attr_accessor :io_encoding
|
41
|
+
# @!attribute [rw] lang
|
42
|
+
# @return [String] Language ('en' by default).
|
43
|
+
attr_accessor :lang
|
44
|
+
|
45
|
+
# Default IO encoding
|
46
|
+
DEFAULT_IO_ENCODING = 'utf-8'
|
47
|
+
# Default lang.
|
48
|
+
DEFAULT_LANG = 'en'
|
49
|
+
# Default API contract for requests
|
50
|
+
DEFAULT_REQUEST_CONTRACT = RegApi2::RequestContract::Default
|
51
|
+
# Default API contract for results
|
52
|
+
DEFAULT_RESULT_CONTRACT = RegApi2::ResultContract::Default
|
53
|
+
|
54
|
+
# REG.API base URI
|
55
|
+
API_URI = URI.parse("https://api.reg.ru/api/regru2")
|
56
|
+
|
57
|
+
# Creates or gets HTTPS handler.
|
58
|
+
# @return [Net::HTTP] HTTPS handler.
|
59
|
+
def http
|
60
|
+
@http ||= begin
|
61
|
+
http = Net::HTTP.new(
|
62
|
+
API_URI.host,
|
63
|
+
API_URI.port
|
64
|
+
)
|
65
|
+
http.use_ssl = true
|
66
|
+
http
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Placeholder to inspect sent form
|
71
|
+
# @param [String] path
|
72
|
+
# @param [Hash] form
|
73
|
+
# @return Doesn't matter
|
74
|
+
def form_to_be_sent(path, form)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Placeholder to inspect got response.
|
78
|
+
# @param [Net::HTTPResponse] response
|
79
|
+
# @return Doesn't matter
|
80
|
+
def got_response(response)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Gets {Class} by its name.
|
84
|
+
# @param [Class] ancestor
|
85
|
+
# @param [NilClass, Class, String] name
|
86
|
+
# @param [Class] default_value
|
87
|
+
# @return [Class] {RegApi2::RequestContract}
|
88
|
+
def get_contract ancestor, name, default_value
|
89
|
+
return default_value unless name
|
90
|
+
return name if name.kind_of?(Class)
|
91
|
+
ancestor.const_get(RegApi2::Util.constantize name)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Gets {RegApi2::RequestContract} by its name.
|
95
|
+
# @param [NilClass, Class, String] name
|
96
|
+
# @return [Class] {RegApi2::RequestContract}
|
97
|
+
def get_request_contract_by_name name
|
98
|
+
get_contract(RegApi2::RequestContract, name, DEFAULT_REQUEST_CONTRACT)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Gets {RegApi2::ResultContract} by its name.
|
102
|
+
# @param [NilClass, Class, String] name
|
103
|
+
# @return [Class] {RegApi2::ResultContract}
|
104
|
+
def get_result_contract_by_name name
|
105
|
+
get_contract(RegApi2::ResultContract, name, DEFAULT_RESULT_CONTRACT)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Gets form data for POST request
|
109
|
+
# @param [Hash] defopts
|
110
|
+
# @param [Hash] opts
|
111
|
+
# @return [Hash] Form data to be sent.
|
112
|
+
# @raise [ContractError]
|
113
|
+
def get_form_data(defopts, opts)
|
114
|
+
# HACK: REG.API doesn't know about utf-8.
|
115
|
+
io_encoding = 'utf8' if !io_encoding || io_encoding == DEFAULT_IO_ENCODING
|
116
|
+
opts = opts.to_hash if opts.respond_to?(:to_hash)
|
117
|
+
get_request_contract_by_name(defopts[:request]).new(defopts).validate(opts)
|
118
|
+
form = {
|
119
|
+
'username' => username,
|
120
|
+
'password' => password,
|
121
|
+
'io_encoding' => io_encoding,
|
122
|
+
'lang' => lang || DEFAULT_LANG,
|
123
|
+
'output_format' => 'json',
|
124
|
+
'input_format' => 'json',
|
125
|
+
'show_input_params' => 0,
|
126
|
+
'input_data' => Yajl::Encoder.encode(opts)
|
127
|
+
}
|
128
|
+
form
|
129
|
+
end
|
130
|
+
|
131
|
+
# Handles response
|
132
|
+
# @param [Hash] defopts
|
133
|
+
# @param [Net::HTTPResponse] res HTTP Response
|
134
|
+
# @return [Object] Contracted response.
|
135
|
+
# @raise [NetError]
|
136
|
+
# @raise [ApiError]
|
137
|
+
# @raise [ContractError]
|
138
|
+
def handle_response(defopts, res)
|
139
|
+
raise NetError.new(res.body) unless res.code == '200'
|
140
|
+
|
141
|
+
json = Yajl::Parser.parse(res.body)
|
142
|
+
raise ApiError.new(
|
143
|
+
json['error_code'],
|
144
|
+
json['error_text'],
|
145
|
+
json['error_params']
|
146
|
+
) if json['result'] == 'error'
|
147
|
+
|
148
|
+
get_result_contract_by_name(defopts[:result]).new(defopts).handle_result(json)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Do actual call to REG.API using POST/JSON convention.
|
152
|
+
# @param [Symbol] category
|
153
|
+
# @param [Symbol] name
|
154
|
+
# @param [Hash] defopts
|
155
|
+
# @param [Hash] opts
|
156
|
+
# @return [Hash] Result answer field.
|
157
|
+
# @raise [NetError]
|
158
|
+
# @raise [ApiError]
|
159
|
+
# @raise [ContractError]
|
160
|
+
def make_action category, name, defopts, opts = {}
|
161
|
+
req = Net::HTTP::Post.new(
|
162
|
+
category.nil? ? "#{API_URI.path}/#{name}" : "#{API_URI.path}/#{category}/#{name}"
|
163
|
+
)
|
164
|
+
form = get_form_data(defopts, opts)
|
165
|
+
form_to_be_sent(req.path, form)
|
166
|
+
|
167
|
+
req.set_form_data(form)
|
168
|
+
res = http.request(req)
|
169
|
+
got_response(res)
|
170
|
+
|
171
|
+
handle_response(defopts, res)
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module RegApi2
|
3
|
+
# Contracts for API requests.
|
4
|
+
# Take a look at {RegApi2::DEFAULT_REQUEST_CONTRACT} for defaults.
|
5
|
+
module RequestContract
|
6
|
+
# Checks for specified `required` fields.
|
7
|
+
# Also checks for `optional` fields.
|
8
|
+
# Take in care :re option.
|
9
|
+
class Default
|
10
|
+
attr_reader :opts
|
11
|
+
|
12
|
+
def initialize(opts = {})
|
13
|
+
@opts = opts
|
14
|
+
end
|
15
|
+
|
16
|
+
# Normalizes `required` and `optional` fields to the form of Hash with options.
|
17
|
+
# @param [NilClass,Hash,Array, etc.] arr Something to normalize.
|
18
|
+
def to_hash arr
|
19
|
+
return {} if arr.nil?
|
20
|
+
return arr if arr.kind_of?(Hash)
|
21
|
+
arr = [ arr.to_sym ] unless arr.kind_of?(Array)
|
22
|
+
ret = {}
|
23
|
+
arr.each { |key| ret[key.to_sym] = {} }
|
24
|
+
ret
|
25
|
+
end
|
26
|
+
|
27
|
+
# Gets fields to validate
|
28
|
+
# @return [Hash] Fields to validate.
|
29
|
+
def fields_to_validate
|
30
|
+
required_fields = to_hash opts[:required]
|
31
|
+
optional_fields = to_hash opts[:optional]
|
32
|
+
required_fields.keys.each { |key| required_fields[key][:required] = true }
|
33
|
+
optional_fields.merge(required_fields)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Validates specified `form` with `required` and `optional` fields.
|
37
|
+
# @param [Hash] form Form to validate.
|
38
|
+
# @raise ContractError
|
39
|
+
def validate(form)
|
40
|
+
fields = fields_to_validate
|
41
|
+
return if fields.empty?
|
42
|
+
absent_fields = []
|
43
|
+
fields.each_pair do |key, opts|
|
44
|
+
if !form.has_key?(key) || form[key].nil?
|
45
|
+
if opts[:required]
|
46
|
+
absent_fields << key
|
47
|
+
end
|
48
|
+
next
|
49
|
+
end
|
50
|
+
if opts[:re]
|
51
|
+
if form[key] !~ opts[:re]
|
52
|
+
raise RegApi2::ContractError.new(
|
53
|
+
"Field #{key} mismatch regular expression: #{form[key]}"
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
unless absent_fields.empty?
|
59
|
+
raise RegApi2::ContractError.new(
|
60
|
+
"Required fields missed: #{absent_fields.join(', ')}"
|
61
|
+
)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module RegApi2
|
3
|
+
# Contracts for API results.
|
4
|
+
# Take a look at {RegApi2::DEFAULT_RESULT_CONTRACT} for defaults.
|
5
|
+
module ResultContract
|
6
|
+
# Waits for answer field and returns it only.
|
7
|
+
class Default
|
8
|
+
attr_reader :opts
|
9
|
+
|
10
|
+
def initialize(opts = {})
|
11
|
+
@opts = opts
|
12
|
+
end
|
13
|
+
|
14
|
+
# Extracts answer field and returns it wrapped by {#handle_answer}.
|
15
|
+
def handle_result(result)
|
16
|
+
handle_answer(result['answer'])
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return passed argument by default.
|
20
|
+
def handle_answer(answer)
|
21
|
+
answer
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require 'reg_api2/result_contract/default'
|
4
|
+
|
5
|
+
# Waits for single field in answer field and returns it only.
|
6
|
+
class RegApi2::ResultContract::SingleField < RegApi2::ResultContract::Default
|
7
|
+
def handle_answer answer
|
8
|
+
field = opts[:field]
|
9
|
+
unless answer[field]
|
10
|
+
raise RegApi2::ContractError.new(
|
11
|
+
"#{field} field should be found in API result."
|
12
|
+
)
|
13
|
+
end
|
14
|
+
answer[field]
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module RegApi2
|
3
|
+
# REG.API service category
|
4
|
+
module Service
|
5
|
+
|
6
|
+
include RegApi2::Builder
|
7
|
+
|
8
|
+
category :service
|
9
|
+
|
10
|
+
# @!method nop(opts = {})
|
11
|
+
# @param opts
|
12
|
+
# @option opts [Array] services
|
13
|
+
# Return list of specified services with its stats if specified.
|
14
|
+
# @return [Hash("services" => [])]
|
15
|
+
# @example List of services by specified identifiers
|
16
|
+
# RegApi2.service.nop(services: [
|
17
|
+
# { dname:"test.ru" },
|
18
|
+
# { dname: "test.su", servtype: "srv_hosting_ispmgr" },
|
19
|
+
# { service_id: 111111 },
|
20
|
+
# { service_id: "22bug22" },
|
21
|
+
# { surprise: "surprise.ru" }
|
22
|
+
# ])
|
23
|
+
define :nop
|
24
|
+
|
25
|
+
extend self
|
26
|
+
end
|
27
|
+
end
|