dmm 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +6 -0
- data/dmm.gemspec +23 -0
- data/lib/dmm/base.rb +25 -0
- data/lib/dmm/client.rb +77 -0
- data/lib/dmm/core_ext/hash.rb +22 -0
- data/lib/dmm/core_ext/string.rb +5 -0
- data/lib/dmm/error.rb +8 -0
- data/lib/dmm/item.rb +48 -0
- data/lib/dmm/iteminfo.rb +29 -0
- data/lib/dmm/price.rb +37 -0
- data/lib/dmm/response.rb +24 -0
- data/lib/dmm/result.rb +29 -0
- data/lib/dmm/version.rb +3 -0
- data/lib/dmm.rb +19 -0
- data/lib/faraday/response/raise_dmm_error.rb +34 -0
- data/spec/dmm/client_spec.rb +84 -0
- data/spec/dmm/item_spec.rb +87 -0
- data/spec/dmm/iteminfo_spec.rb +57 -0
- data/spec/dmm/response_spec.rb +36 -0
- data/spec/dmm/result_spec.rb +48 -0
- data/spec/dmm_spec.rb +25 -0
- data/spec/spec_helper.rb +6 -0
- metadata +127 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Shun Sugai
|
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,29 @@
|
|
1
|
+
# Dmm
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'dmm'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install dmm
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/dmm.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dmm/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "dmm"
|
8
|
+
gem.version = Dmm::VERSION
|
9
|
+
gem.authors = ["Shun Sugai"]
|
10
|
+
gem.email = ["sugaishun@gmail.com"]
|
11
|
+
gem.description = "Ruby wrapper for DMM Web Service API ver2"
|
12
|
+
gem.summary = "Ruby wrapper for DMM Web Service API ver2"
|
13
|
+
gem.homepage = "https://github.com/shunsugai/dmm"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency 'faraday', '~> 0.8'
|
21
|
+
gem.add_dependency 'faraday_middleware', '~> 0.8'
|
22
|
+
gem.add_development_dependency 'rspec'
|
23
|
+
end
|
data/lib/dmm/base.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Dmm
|
2
|
+
class Base
|
3
|
+
def self.attr_reader(*attrs)
|
4
|
+
mod = Module.new do
|
5
|
+
attrs.each do |attribute|
|
6
|
+
define_method attribute do
|
7
|
+
@attrs[attribute.to_sym]
|
8
|
+
end
|
9
|
+
define_method "#{attribute}?" do
|
10
|
+
!!@attribute[attribute.to_sym]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
const_set(:Attributes, mod)
|
15
|
+
include mod
|
16
|
+
end
|
17
|
+
|
18
|
+
# Initializes a new object
|
19
|
+
#
|
20
|
+
# @param attrs [Hash]
|
21
|
+
def initialize(attrs={})
|
22
|
+
@attrs = attrs
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/dmm/client.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'dmm'
|
2
|
+
require 'dmm/response'
|
3
|
+
require 'dmm/item'
|
4
|
+
require 'dmm/error'
|
5
|
+
require 'dmm/core_ext/hash'
|
6
|
+
require 'dmm/core_ext/string'
|
7
|
+
require 'faraday'
|
8
|
+
require 'faraday_middleware'
|
9
|
+
require 'faraday/response/raise_dmm_error'
|
10
|
+
|
11
|
+
module Dmm
|
12
|
+
class Client
|
13
|
+
ROOT_URL = 'http://affiliate-api.dmm.com'
|
14
|
+
API_VERSION = '2.00'
|
15
|
+
COM = 'DMM.com'
|
16
|
+
R18 = 'DMM.co.jp'
|
17
|
+
OPTIONS = [:api_id, :affiliate_id]
|
18
|
+
|
19
|
+
attr_accessor *OPTIONS
|
20
|
+
|
21
|
+
def initialize(args)
|
22
|
+
OPTIONS.each do |id|
|
23
|
+
send("#{id}=", args[id])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Dmm::Response]
|
28
|
+
def item_list(options={})
|
29
|
+
res = get('/', params(options))
|
30
|
+
raise Dmm::Error, error_message(res) if res[:response][:result][:errors]
|
31
|
+
Dmm::Response.new(res)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [Hash]
|
35
|
+
def get(path, params={})
|
36
|
+
request(:get, path, params)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def request(method, path, params={})
|
42
|
+
response = connection.send(method.to_sym, path, params) do |request|
|
43
|
+
request.url(path, params)
|
44
|
+
end
|
45
|
+
Hash.from_xml(response.body)
|
46
|
+
end
|
47
|
+
|
48
|
+
def connection
|
49
|
+
@connection ||= Faraday.new(:url => ROOT_URL) do |builder|
|
50
|
+
builder.request :url_encoded
|
51
|
+
builder.adapter :net_http
|
52
|
+
builder.use Faraday::Response::RaiseDmmError
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def params(options={})
|
57
|
+
params = {
|
58
|
+
:api_id => @api_id,
|
59
|
+
:affiliate_id => @affiliate_id,
|
60
|
+
:operation => 'ItemList',
|
61
|
+
:version => API_VERSION,
|
62
|
+
:timestamp => Time.now.to_s,
|
63
|
+
:site => 'DMM.co.jp',
|
64
|
+
}
|
65
|
+
options[:keyword].encode!("euc-jp") if options[:keyword]
|
66
|
+
params.merge!(options)
|
67
|
+
end
|
68
|
+
|
69
|
+
def error_message(response)
|
70
|
+
result = response[:response][:result]
|
71
|
+
message = result[:message] || "Error"
|
72
|
+
error_name = "\s(#{result[:errors][:error][:name]})"
|
73
|
+
error_val = result[:errors][:error][:value] || ""
|
74
|
+
"#{message.camelize}: #{error_val.capitalize}#{error_name}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
class Hash
|
4
|
+
class << self
|
5
|
+
def from_xml(xml)
|
6
|
+
xml_to_hash REXML::Document.new(xml).root
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def xml_to_hash(node)
|
12
|
+
return { node.name.to_sym => node.text } unless node.has_elements?
|
13
|
+
child = {}
|
14
|
+
node.each_element do |e|
|
15
|
+
child.merge!(xml_to_hash(e)) do |key, old_val, new_val|
|
16
|
+
old_val.kind_of?(Array) ? old_val << new_val : [old_val, new_val]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
{ node.name.to_sym => child }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/dmm/error.rb
ADDED
data/lib/dmm/item.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'dmm/base'
|
2
|
+
require 'dmm/price'
|
3
|
+
require 'dmm/iteminfo'
|
4
|
+
|
5
|
+
module Dmm
|
6
|
+
class Item < Dmm::Base
|
7
|
+
attr_reader :service_name, :floor_name, :category_name,
|
8
|
+
:content_id, :product_id, :title, :URL, :affiliateURL,
|
9
|
+
:URLsp, :affiliateURLsp, :imageURL, :date,
|
10
|
+
:jancode, :maker_product, :isbn, :stock
|
11
|
+
|
12
|
+
alias :url :URL
|
13
|
+
alias :affiliate_url :affiliateURL
|
14
|
+
alias :image_url :imageURL
|
15
|
+
alias :url_sp :URLsp
|
16
|
+
alias :affiliate_url_sp :affiliateURLsp
|
17
|
+
|
18
|
+
def sampleImageURL
|
19
|
+
@attrs[:sampleImageURL][:sample_s][:image]
|
20
|
+
end
|
21
|
+
alias :sample_image_url :sampleImageURL
|
22
|
+
|
23
|
+
# @return [Dmm::Price]
|
24
|
+
def prices
|
25
|
+
@price ||= Dmm::Price.new(@attrs[:prices])
|
26
|
+
@price
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [Dmm::Iteminfo]
|
30
|
+
def iteminfo
|
31
|
+
@iteminfo ||= Dmm::Iteminfo.new(@attrs[:iteminfo])
|
32
|
+
@iteminfo
|
33
|
+
end
|
34
|
+
|
35
|
+
def method_missing(method)
|
36
|
+
if iteminfo.respond_to? method.to_sym
|
37
|
+
iteminfo.send(method.to_sym)
|
38
|
+
elsif prices.respond_to? method.to_sym
|
39
|
+
prices.send(method.to_sym)
|
40
|
+
else
|
41
|
+
super
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def respond_to_missing?(method, include_private = false); iteminfo.respond_to?(method.to_sym) || price.respond_to?(method.to_sym) || super; end if RUBY_VERSION >= '1.9'
|
46
|
+
def respond_to?(method, include_private = false); iteminfo.respond_to?(method.to_sym) || price.respond_to?(method.to_sym) || super; end if RUBY_VERSION < '1.9'
|
47
|
+
end
|
48
|
+
end
|
data/lib/dmm/iteminfo.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'dmm/base'
|
2
|
+
|
3
|
+
module Dmm
|
4
|
+
class Iteminfo < Dmm::Base
|
5
|
+
def method_missing(method)
|
6
|
+
if method.to_s =~ /^(series|maker|label)$/
|
7
|
+
return nil unless @attrs[method.to_sym]
|
8
|
+
@attrs[method.to_sym][:name]
|
9
|
+
elsif method.to_s =~ /^(keyword|actress|director|author)$/
|
10
|
+
return nil unless @attrs[method.to_sym]
|
11
|
+
to_array(method)
|
12
|
+
else
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def respond_to_missing?(method, include_private = false); return true if method.to_s =~ /^(series|maker|label|keyword|actress|director|author)$/; end if RUBY_VERSION >= '1.9'
|
18
|
+
def respond_to? (method, include_private = false); return true if method.to_s =~ /^(series|maker|label|keyword|actress|director|author)$/; super; end if RUBY_VERSION < '1.9'
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def to_array(method)
|
23
|
+
ret_val = @attrs[method.to_sym]
|
24
|
+
return [ret_val[:name]] if ret_val.kind_of? Hash
|
25
|
+
selected = ret_val.select {|hash| hash[:id] =~ /^\d+$/}
|
26
|
+
selected.map {|hash| hash[:name]}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/dmm/price.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'dmm/base'
|
2
|
+
|
3
|
+
module Dmm
|
4
|
+
class Price < Dmm::Base
|
5
|
+
attr_reader :price
|
6
|
+
|
7
|
+
# @return [Integer]
|
8
|
+
def min_price
|
9
|
+
@attrs[:price].to_i
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [Array]
|
13
|
+
def deliveries
|
14
|
+
return [] unless @attrs[:deliveries]
|
15
|
+
@attrs[:deliveries][:delivery]
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [Array]
|
19
|
+
def delivery_types
|
20
|
+
@delivery_types ||= deliveries.map { |price| price[:type] }
|
21
|
+
@delivery_types
|
22
|
+
end
|
23
|
+
|
24
|
+
# ex) item.price_stream #=> 1980
|
25
|
+
def method_missing(method)
|
26
|
+
if method.to_s =~ /^price_(\w+)$/
|
27
|
+
array = deliveries.select{ |hash| hash[:type] == $1 }
|
28
|
+
array.first[:price].to_i unless array.empty?
|
29
|
+
else
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def respond_to_missing?(method, include_private = false); method.to_s =~ /^price_(\w+)$/ || super; end if RUBY_VERSION >= '1.9'
|
35
|
+
def respond_to?(method, include_private = false); method.to_s =~ /^price_(\w+)$/ || super; end if RUBY_VERSION < '1.9'
|
36
|
+
end
|
37
|
+
end
|
data/lib/dmm/response.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'dmm/base'
|
2
|
+
require 'dmm/result'
|
3
|
+
|
4
|
+
module Dmm
|
5
|
+
class Response < Dmm::Base
|
6
|
+
attr_reader :response
|
7
|
+
|
8
|
+
# Delegate to a Dmm::Result
|
9
|
+
#
|
10
|
+
# @return [Dmm::Result]
|
11
|
+
def result
|
12
|
+
@result ||= Dmm::Result.new @attrs[:response][:result]
|
13
|
+
@result
|
14
|
+
end
|
15
|
+
|
16
|
+
def method_missing(method, *args)
|
17
|
+
return super unless result.respond_to? method.to_sym
|
18
|
+
result.send(method.to_sym)
|
19
|
+
end
|
20
|
+
|
21
|
+
def respond_to_missing?(method, include_private = false); result.respond_to?(method.to_sym, include_private) || super; end if RUBY_VERSION >= '1.9'
|
22
|
+
def respond_to?(method, include_private = false); result.respond_to?(method.to_sym, include_private) || super; end if RUBY_VERSION < '1.9'
|
23
|
+
end
|
24
|
+
end
|
data/lib/dmm/result.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'dmm/base'
|
2
|
+
require 'dmm/item'
|
3
|
+
|
4
|
+
module Dmm
|
5
|
+
class Result < Dmm::Base
|
6
|
+
# @return [Integer]
|
7
|
+
def result_count
|
8
|
+
@attrs[:result_count].to_i
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [Integer]
|
12
|
+
def total_count
|
13
|
+
@attrs[:total_count].to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Integer]
|
17
|
+
def first_position
|
18
|
+
@attrs[:first_position].to_i
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Array]
|
22
|
+
def items
|
23
|
+
return [] unless @attrs[:items]
|
24
|
+
item_list = @attrs[:items][:item]
|
25
|
+
item_list = [item_list] if item_list.kind_of? Hash
|
26
|
+
item_list.map! { |item| Dmm::Item.new(item) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/dmm/version.rb
ADDED
data/lib/dmm.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "dmm/client"
|
2
|
+
require "dmm/version"
|
3
|
+
|
4
|
+
module Dmm
|
5
|
+
class << self
|
6
|
+
def new(options={})
|
7
|
+
Dmm::Client.new(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def const_missing(name)
|
11
|
+
return super unless Dmm::Client.const_defined?(name.to_sym)
|
12
|
+
Dmm::Client.const_get(name.to_sym)
|
13
|
+
end
|
14
|
+
|
15
|
+
def const_defined?(name)
|
16
|
+
Dmm::Client.const_defined?(name.to_sym) || super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
class Response::RaiseDmmError < Response::Middleware
|
5
|
+
def on_complete(response)
|
6
|
+
case response[:status]
|
7
|
+
when 400
|
8
|
+
raise Dmm::BadRequest, error_message(response)
|
9
|
+
when 401
|
10
|
+
raise Dmm::Unauthorized, error_message(response)
|
11
|
+
when 403
|
12
|
+
raise Dmm::Forbidden, error_message(response)
|
13
|
+
when 404
|
14
|
+
raise Dmm::NotFound, error_message(response)
|
15
|
+
when 406
|
16
|
+
raise Dmm::NotAcceptable, error_message(response)
|
17
|
+
when 422
|
18
|
+
raise Dmm::UnprocessableEntity, error_message(response)
|
19
|
+
when 500
|
20
|
+
raise Dmm::InternalServerError, error_message(response)
|
21
|
+
when 503
|
22
|
+
raise Dmm::ServiceUnavailable, error_message(response)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def error_message(response)
|
29
|
+
message = response[:body]['error']
|
30
|
+
return message unless message.empty?
|
31
|
+
"#{response[:method].to_s.upcase} #{response[:url].to_s}: #{response[:status]}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dmm::Client do
|
4
|
+
|
5
|
+
context 'initialize with correct configuration value' do
|
6
|
+
|
7
|
+
subject do
|
8
|
+
Dmm::Client.new(:api_id => ENV['API_ID'], :affiliate_id => ENV['AFFILIATE_ID'])
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'initialization' do
|
12
|
+
its(:api_id) { should eq ENV['API_ID'] }
|
13
|
+
its(:affiliate_id) { should eq ENV['AFFILIATE_ID'] }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#params' do
|
17
|
+
it 'should return collect params' do
|
18
|
+
params = {
|
19
|
+
:api_id => ENV['API_ID'],
|
20
|
+
:affiliate_id => ENV['AFFILIATE_ID'],
|
21
|
+
:operation => 'ItemList',
|
22
|
+
:version => Dmm::API_VERSION,
|
23
|
+
:timestamp => Time.now.to_s,
|
24
|
+
:site => Dmm::R18,
|
25
|
+
:keyword => 'hogehoge'
|
26
|
+
}
|
27
|
+
subject.send(:params, {:keyword => 'hogehoge'}).should eq params
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'initialize with wrong configuration value' do
|
33
|
+
|
34
|
+
share_examples_for '#item_list with wrong arguments' do
|
35
|
+
it { proc{subject.item_list}.should raise_error Dmm::Error }
|
36
|
+
end
|
37
|
+
|
38
|
+
share_examples_for '#error_message with wrong api_id' do
|
39
|
+
it 'should equal "LoginError: No existing account (login)"' do
|
40
|
+
res = subject.get('/', subject.send(:params))
|
41
|
+
subject.send(:error_message, res).should eq 'LoginError: No existing account (login)'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'call API with wrong api_id' do
|
46
|
+
subject { Dmm.new(:api_id => 'foo', :affiliate_id => ENV['AFFILIATE_ID']) }
|
47
|
+
|
48
|
+
describe '#item_list' do
|
49
|
+
it_should_behave_like '#item_list with wrong arguments'
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#error_message' do
|
53
|
+
it_should_behave_like '#error_message with wrong api_id'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'call API with wrong affiliate_id' do
|
58
|
+
subject { Dmm.new(:api_id => ENV['API_ID'], :affiliate_id => 'foo') }
|
59
|
+
|
60
|
+
describe '#item_list' do
|
61
|
+
it_should_behave_like '#item_list with wrong arguments'
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#error_message' do
|
65
|
+
it 'should equal "RequestError: Parameter not found (affiliate_id)"' do
|
66
|
+
res = subject.get('/', subject.send(:params))
|
67
|
+
subject.send(:error_message, res).should eq 'RequestError: Parameter not found (affiliate_id)'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'call API with wrong api_id and affiliate_id' do
|
73
|
+
subject { Dmm.new(:api_id => 'foo', :affiliate_id => 'bar') }
|
74
|
+
|
75
|
+
describe '#item_list' do
|
76
|
+
it_should_behave_like '#item_list with wrong arguments'
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '#error_message' do
|
80
|
+
it_should_behave_like '#error_message with wrong api_id'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Dmm::Item do
|
5
|
+
|
6
|
+
subject do
|
7
|
+
Dmm::Item.new({:service_name=>"動画",
|
8
|
+
:floor_name=>"ビデオ",
|
9
|
+
:category_name=>"ビデオ (動画)",
|
10
|
+
:content_id=>"118mas00093",
|
11
|
+
:product_id=>"118mas00093",
|
12
|
+
:title=>"絶対的美少女、お貸しします。 ACT.25",
|
13
|
+
:URL=>
|
14
|
+
"http://www.dmm.co.jp/digital/videoa/-/detail/=/cid=118mas00093/",
|
15
|
+
:affiliateURL=>
|
16
|
+
"http://www.dmm.co.jp/digital/videoa/-/detail/=/cid=118mas00093/#{ENV['AFFILIATE_ID']}",
|
17
|
+
:imageURL=>
|
18
|
+
{:list=>
|
19
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093pt.jpg",
|
20
|
+
:small=>
|
21
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093ps.jpg",
|
22
|
+
:large=>
|
23
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093pl.jpg"},
|
24
|
+
:sampleImageURL=>
|
25
|
+
{:sample_s=>
|
26
|
+
{:image=>
|
27
|
+
["http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-1.jpg",
|
28
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-2.jpg",
|
29
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-3.jpg",
|
30
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-4.jpg",
|
31
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-5.jpg",
|
32
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-6.jpg",
|
33
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-7.jpg",
|
34
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-8.jpg",
|
35
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-9.jpg",
|
36
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-10.jpg"]}},
|
37
|
+
:prices=>
|
38
|
+
{:price=>"1980~",
|
39
|
+
:deliveries=>
|
40
|
+
{:delivery=>
|
41
|
+
[{:type=>"stream", :price=>"1980"},
|
42
|
+
{:type=>"download", :price=>"1980"}]}},
|
43
|
+
:date=>"2013-01-12 10:01:00",
|
44
|
+
:iteminfo=>
|
45
|
+
{:keyword=>
|
46
|
+
[{:name=>"顔射", :id=>"5023"},
|
47
|
+
{:name=>"単体作品", :id=>"4025"},
|
48
|
+
{:name=>"美少女", :id=>"1027"}],
|
49
|
+
:series=>{:name=>"絶対的美少女、お貸しします。", :id=>"79983"},
|
50
|
+
:maker=>{:name=>"プレステージ", :id=>"40136"},
|
51
|
+
:actress=>
|
52
|
+
[{:name=>"あやみ旬果", :id=>"1016835"},
|
53
|
+
{:name=>"あやみしゅんか", :id=>"1016835_ruby"},
|
54
|
+
{:name=>"av", :id=>"1016835_classify"}],
|
55
|
+
:label=>{:name=>"ます。", :id=>"20940"}}})
|
56
|
+
end
|
57
|
+
|
58
|
+
its(:service_name) { should eq '動画' }
|
59
|
+
its(:floor_name) { should eq 'ビデオ' }
|
60
|
+
its(:category_name) { should eq 'ビデオ (動画)' }
|
61
|
+
its(:content_id) { should eq '118mas00093' }
|
62
|
+
its(:product_id) { should eq '118mas00093' }
|
63
|
+
its(:title) { should eq '絶対的美少女、お貸しします。 ACT.25' }
|
64
|
+
its(:url) { should eq 'http://www.dmm.co.jp/digital/videoa/-/detail/=/cid=118mas00093/' }
|
65
|
+
its(:affiliateURL) { should eq "http://www.dmm.co.jp/digital/videoa/-/detail/=/cid=118mas00093/#{ENV['AFFILIATE_ID']}" }
|
66
|
+
its(:sample_image_url) { should eq ["http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-1.jpg",
|
67
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-2.jpg",
|
68
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-3.jpg",
|
69
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-4.jpg",
|
70
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-5.jpg",
|
71
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-6.jpg",
|
72
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-7.jpg",
|
73
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-8.jpg",
|
74
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-9.jpg",
|
75
|
+
"http://pics.dmm.co.jp/digital/video/118mas00093/118mas00093-10.jpg"] }
|
76
|
+
its(:prices) { should be_a_kind_of Dmm::Price }
|
77
|
+
its(:iteminfo) { should be_a_kind_of Dmm::Iteminfo }
|
78
|
+
|
79
|
+
its(:keyword) { should eq ['顔射', '単体作品', '美少女'] }
|
80
|
+
its(:price) { should eq '1980~' }
|
81
|
+
its(:min_price) { should eq 1980 }
|
82
|
+
its(:price_stream) { should eq 1980 }
|
83
|
+
its(:price_download) { should eq 1980 }
|
84
|
+
its(:price_androiddl) { should be_nil }
|
85
|
+
its(:deliveries) { should eq [{:type=>"stream", :price=>"1980"},{:type=>"download", :price=>"1980"}] }
|
86
|
+
its(:delivery_types) { should eq ['stream', 'download'] }
|
87
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Dmm::Iteminfo do
|
6
|
+
|
7
|
+
describe '#method_missing' do
|
8
|
+
subject { Dmm::Iteminfo.new({:keyword =>[{:name => "顔射", :id => "5023"},{:name =>"単体作品", :id =>"4025"},{:name =>"美少女", :id =>"1027"}],:series => {:name => "絶対的美少女、お貸しします。", :id => "79983"},:maker => {:name => "プレステージ", :id => "40136"},:actress =>[{:name => "あやみ旬果", :id => "1016835"},{:name => "あやみしゅんか", :id => "1016835_ruby"},{:name => "av", :id => "1016835_classify"}],:label => {:name => "ます。", :id => "20940"}})}
|
9
|
+
|
10
|
+
context 'with argument :keyword' do
|
11
|
+
its(:keyword) { should eq ['顔射', '単体作品', '美少女']}
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'with argument :series' do
|
15
|
+
its(:series) { should eq '絶対的美少女、お貸しします。' }
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'with argument :maker' do
|
19
|
+
its(:maker) { should eq 'プレステージ' }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with argument :actress' do
|
23
|
+
its(:actress) { should eq ['あやみ旬果'] }
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with argument :director' do
|
27
|
+
its(:director) { should be_nil }
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with argument :label' do
|
31
|
+
its(:label) { should eq 'ます。' }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with argument :undefined_method' do
|
35
|
+
it { proc{ subject.undefined_method }.should raise_error NoMethodError }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#keyword' do
|
40
|
+
context 'has one keyword' do
|
41
|
+
subject { Dmm::Iteminfo.new(:keyword => {:name => "顔射"}) }
|
42
|
+
|
43
|
+
its(:keyword) { should eq ['顔射'] }
|
44
|
+
end
|
45
|
+
context 'has no keyword' do
|
46
|
+
subject { Dmm::Iteminfo.new }
|
47
|
+
its(:keyword) { should be_nil }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#respond_to?' do
|
52
|
+
subject { Dmm::Iteminfo.new }
|
53
|
+
it 'return true with argument :keyword' do
|
54
|
+
subject.respond_to?(:keyword).should be_true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dmm::Response do
|
4
|
+
subject { Dmm.new(:api_id => ENV['API_ID'], :affiliate_id => ENV['AFFILIATE_ID']).item_list }
|
5
|
+
|
6
|
+
describe '#respond_to?' do
|
7
|
+
it 'should be true with argument :items' do
|
8
|
+
subject.respond_to?(:items).should be_true
|
9
|
+
end
|
10
|
+
it 'should be true with argument :result_count' do
|
11
|
+
subject.respond_to?(:result_count).should be_true
|
12
|
+
end
|
13
|
+
it 'should be true with argument :total_count' do
|
14
|
+
subject.respond_to?(:total_count).should be_true
|
15
|
+
end
|
16
|
+
it 'should be true with argument :first_position' do
|
17
|
+
subject.respond_to?(:first_position).should be_true
|
18
|
+
end
|
19
|
+
it 'should be true with argument :result' do
|
20
|
+
subject.respond_to?(:result).should be_true
|
21
|
+
end
|
22
|
+
it 'should not be true with argument :hogehoge' do
|
23
|
+
subject.respond_to?(:hogehoge).should_not be_true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'Object#method' do
|
28
|
+
it 'should be return instance of Method' do
|
29
|
+
subject.method(:items).should be_kind_of Method
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should raise NameError argument with undefined method in Dmm::Result' do
|
33
|
+
lambda{subject.method(:fooooo)}.should raise_error NameError
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Dmm::Result do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@dmm = Dmm.new(:api_id => ENV['API_ID'], :affiliate_id => ENV['AFFILIATE_ID'])
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'has no item' do
|
11
|
+
|
12
|
+
subject { @dmm.item_list(:keyword => 'ほげほげほげ').result }
|
13
|
+
|
14
|
+
its(:result_count) { should eq 0 }
|
15
|
+
its(:total_count) { should eq 0 }
|
16
|
+
its(:first_position) { should eq 0 }
|
17
|
+
|
18
|
+
describe '#items' do
|
19
|
+
it { subject.items.should be_empty }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'has a item' do
|
24
|
+
|
25
|
+
subject { @dmm.item_list(:hits => 1).result }
|
26
|
+
|
27
|
+
its(:result_count) { should eq 1 }
|
28
|
+
|
29
|
+
describe '#items' do
|
30
|
+
its(:items) { should have_exactly(1).items }
|
31
|
+
it 'should include an instance of Dmm::Item' do
|
32
|
+
subject.items.first.should be_an_instance_of Dmm::Item
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'has some items' do
|
38
|
+
|
39
|
+
subject { @dmm.item_list(:keyword => '吉川あいみ').result }
|
40
|
+
|
41
|
+
describe '#items' do
|
42
|
+
its(:items) { should have_at_least(1).items }
|
43
|
+
it 'should include an instance of Dmm::Item' do
|
44
|
+
subject.items.sample.should be_an_instance_of Dmm::Item
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/spec/dmm_spec.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dmm do
|
4
|
+
it { should respond_to(:new) }
|
5
|
+
|
6
|
+
describe 'new' do
|
7
|
+
it 'returns Dmm::Client instance' do
|
8
|
+
subject.new.should be_a_kind_of Dmm::Client
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'const_missing' do
|
13
|
+
it 'should be "DMM.co.jp" when call DMM::R18' do
|
14
|
+
Dmm::R18.should == 'DMM.co.jp'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should be "DMM.com" when call DMM::COM' do
|
18
|
+
Dmm::COM.should == 'DMM.com'
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should raise NameError when call undefined constant "Foo"' do
|
22
|
+
lambda{Dmm::Foo}.should raise_error NameError
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dmm
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Shun Sugai
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: faraday
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.8'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.8'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: faraday_middleware
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0.8'
|
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.8'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: Ruby wrapper for DMM Web Service API ver2
|
63
|
+
email:
|
64
|
+
- sugaishun@gmail.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- .gitignore
|
70
|
+
- .rspec
|
71
|
+
- Gemfile
|
72
|
+
- LICENSE.txt
|
73
|
+
- README.md
|
74
|
+
- Rakefile
|
75
|
+
- dmm.gemspec
|
76
|
+
- lib/dmm.rb
|
77
|
+
- lib/dmm/base.rb
|
78
|
+
- lib/dmm/client.rb
|
79
|
+
- lib/dmm/core_ext/hash.rb
|
80
|
+
- lib/dmm/core_ext/string.rb
|
81
|
+
- lib/dmm/error.rb
|
82
|
+
- lib/dmm/item.rb
|
83
|
+
- lib/dmm/iteminfo.rb
|
84
|
+
- lib/dmm/price.rb
|
85
|
+
- lib/dmm/response.rb
|
86
|
+
- lib/dmm/result.rb
|
87
|
+
- lib/dmm/version.rb
|
88
|
+
- lib/faraday/response/raise_dmm_error.rb
|
89
|
+
- spec/dmm/client_spec.rb
|
90
|
+
- spec/dmm/item_spec.rb
|
91
|
+
- spec/dmm/iteminfo_spec.rb
|
92
|
+
- spec/dmm/response_spec.rb
|
93
|
+
- spec/dmm/result_spec.rb
|
94
|
+
- spec/dmm_spec.rb
|
95
|
+
- spec/spec_helper.rb
|
96
|
+
homepage: https://github.com/shunsugai/dmm
|
97
|
+
licenses: []
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
104
|
+
requirements:
|
105
|
+
- - ! '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ! '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
requirements: []
|
115
|
+
rubyforge_project:
|
116
|
+
rubygems_version: 1.8.23
|
117
|
+
signing_key:
|
118
|
+
specification_version: 3
|
119
|
+
summary: Ruby wrapper for DMM Web Service API ver2
|
120
|
+
test_files:
|
121
|
+
- spec/dmm/client_spec.rb
|
122
|
+
- spec/dmm/item_spec.rb
|
123
|
+
- spec/dmm/iteminfo_spec.rb
|
124
|
+
- spec/dmm/response_spec.rb
|
125
|
+
- spec/dmm/result_spec.rb
|
126
|
+
- spec/dmm_spec.rb
|
127
|
+
- spec/spec_helper.rb
|