ruby-dmm 0.0.2
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 +2 -0
- data/Guardfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +58 -0
- data/Rakefile +9 -0
- data/lib/faraday/response/raise_dmm_error.rb +24 -0
- data/lib/faraday_middleware/response/dmm_rashify.rb +33 -0
- data/lib/multi_xml_tweaks.rb +29 -0
- data/lib/ruby-dmm.rb +24 -0
- data/lib/ruby-dmm/client.rb +71 -0
- data/lib/ruby-dmm/client/item_list.rb +34 -0
- data/lib/ruby-dmm/configuration.rb +42 -0
- data/lib/ruby-dmm/error.rb +14 -0
- data/lib/ruby-dmm/response.rb +28 -0
- data/lib/ruby-dmm/response/item.rb +64 -0
- data/lib/ruby-dmm/response/item_info.rb +42 -0
- data/lib/ruby-dmm/version.rb +4 -0
- data/ruby-dmm.gemspec +30 -0
- data/spec/client_spec.rb +17 -0
- data/spec/fixtures/com.xml +5987 -0
- data/spec/fixtures/com_digital.xml +1115 -0
- data/spec/fixtures/com_digital_book.xml +3407 -0
- data/spec/fixtures/com_iroiro.xml +1711 -0
- data/spec/fixtures/com_lod.xml +125 -0
- data/spec/fixtures/com_mono.xml +3723 -0
- data/spec/fixtures/com_monthly.xml +2075 -0
- data/spec/fixtures/com_pcsoft.xml +729 -0
- data/spec/fixtures/com_rental.xml +2691 -0
- data/spec/fixtures/r18.xml +4203 -0
- data/spec/fixtures/r18_book.xml +4965 -0
- data/spec/fixtures/r18_digital.xml +26987 -0
- data/spec/fixtures/r18_doujin.xml +2741 -0
- data/spec/fixtures/r18_mono.xml +3723 -0
- data/spec/fixtures/r18_monthly.xml +3515 -0
- data/spec/fixtures/r18_pcgame.xml +3373 -0
- data/spec/fixtures/r18_ppm.xml +2883 -0
- data/spec/fixtures/r18_rental.xml +12371 -0
- data/spec/response/item_spec.rb +16 -0
- data/spec/response_spec.rb +42 -0
- data/spec/spec_helper.rb +45 -0
- metadata +275 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 meganemura
|
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,58 @@
|
|
1
|
+
# ruby-dmm [![Build Status](https://travis-ci.org/meganemura/ruby-dmm.png?branch=master)](https://travis-ci.org/meganemura/ruby-dmm)
|
2
|
+
|
3
|
+
Client for the DMM Web Service API 2.0.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'ruby-dmm'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install ruby-dmm
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
client = DMM.new(:api_id => "your_api_id", :affiliate_id => "your_affiliate_id", :result_only => true)
|
23
|
+
response = client.order("date").limit(5).item_list("妄想")
|
24
|
+
response.items.map {|item| item.title }
|
25
|
+
# => ["ココロ@ファンクション!",
|
26
|
+
# "やらせてっ!てぃーちゃー学園旅行〜やらてぃーが学園を飛び出したァ!?〜(DVDPG)",
|
27
|
+
# "彫刻ボディ 瀧川花音",
|
28
|
+
# "目が奪われる瞬間 vol.02",
|
29
|
+
# "彫刻ボディ 瀧川花音"]
|
30
|
+
```
|
31
|
+
|
32
|
+
### Choose your favorite XML Parser
|
33
|
+
|
34
|
+
You can use `ox`, `libxml`, `nokogiri` through `multi_xml`.
|
35
|
+
|
36
|
+
Add 'ox' and 'nokogiri' to your Gemfile, then it works below.
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
> require 'ruby-dmm'
|
40
|
+
> MultiXml.parser # => MultiXml::Parsers::Ox
|
41
|
+
> MultiXml.parser = :nokogiri
|
42
|
+
> MultiXml.parser # => MultiXml::Parsers::Nokogiri
|
43
|
+
```
|
44
|
+
|
45
|
+
See [multi_xml documents](http://rdoc.info/gems/multi_xml).
|
46
|
+
|
47
|
+
## Contributing
|
48
|
+
|
49
|
+
1. Fork it
|
50
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
51
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
52
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
53
|
+
5. Create new Pull Request
|
54
|
+
|
55
|
+
## See also
|
56
|
+
|
57
|
+
[API Reference](https://affiliate.dmm.com/api/)
|
58
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'faraday'
|
3
|
+
|
4
|
+
module Faraday
|
5
|
+
class Response::RaiseDMMError < Response::Middleware
|
6
|
+
ERROR_MAP = {
|
7
|
+
400 => DMM::BadRequest,
|
8
|
+
401 => DMM::Unauthorized,
|
9
|
+
403 => DMM::Forbidden,
|
10
|
+
404 => DMM::NotFound,
|
11
|
+
406 => DMM::NotAcceptable,
|
12
|
+
422 => DMM::UnprocessableEntity,
|
13
|
+
500 => DMM::InternalServerError,
|
14
|
+
501 => DMM::NotImplemented,
|
15
|
+
502 => DMM::BadGateway,
|
16
|
+
503 => DMM::ServiceUnavailable
|
17
|
+
}
|
18
|
+
|
19
|
+
def on_complete(response)
|
20
|
+
key = response[:status].to_i
|
21
|
+
raise ERROR_MAP[key].new(response) if ERROR_MAP.has_key? key
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'faraday_middleware/response/mashify'
|
3
|
+
require 'rash'
|
4
|
+
|
5
|
+
module DMM
|
6
|
+
class Rash < ::Hashie::Rash
|
7
|
+
protected
|
8
|
+
def underscore_string(str)
|
9
|
+
str.to_s.strip.
|
10
|
+
gsub(' ', '_').
|
11
|
+
gsub(/::/, '/').
|
12
|
+
gsub(/(URL)([a-z])/, '\1_\2').
|
13
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
14
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
15
|
+
tr("-", "_").
|
16
|
+
squeeze("_").
|
17
|
+
downcase
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module FaradayMiddleware
|
23
|
+
# Public: Converts parsed response bodies to a Hashie::Rash if they were of
|
24
|
+
# Hash or Array type.
|
25
|
+
class DMMRashify < Mashify
|
26
|
+
dependency do
|
27
|
+
self.mash_class = DMM::Rash
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# deprecated alias
|
33
|
+
Faraday::Response::DMMRashify = FaradayMiddleware::DMMRashify
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'multi_xml'
|
3
|
+
|
4
|
+
module MultiXml
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def encoding_values(params, encoding=Encoding::UTF_8)
|
8
|
+
case params
|
9
|
+
when Hash
|
10
|
+
params.inject({}) do |result, (key, value)|
|
11
|
+
result.merge(key => encoding_values(value))
|
12
|
+
end
|
13
|
+
when String
|
14
|
+
params.encode(encoding)
|
15
|
+
when Array
|
16
|
+
params.map {|v| encoding_values(v) }
|
17
|
+
else
|
18
|
+
params
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
alias :original_parse :parse
|
23
|
+
def parse(xml, options={})
|
24
|
+
hash = original_parse(xml, options)
|
25
|
+
return encoding_values(hash)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
data/lib/ruby-dmm.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "ruby-dmm/configuration"
|
3
|
+
require 'ruby-dmm/error'
|
4
|
+
require "ruby-dmm/client"
|
5
|
+
|
6
|
+
module DMM
|
7
|
+
extend Configuration
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def new(options={})
|
11
|
+
DMM::Client.new(options)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Delegate to DMM::Client.new
|
15
|
+
def method_missing(method, *args, &block)
|
16
|
+
return super unless new.respond_to?(method)
|
17
|
+
new.send(method, *args, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def respond_to?(method, include_private=false)
|
21
|
+
new.respond_to?(method, include_private) || super(method, include_private)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'faraday'
|
3
|
+
require 'faraday/response/raise_dmm_error'
|
4
|
+
require 'faraday_middleware'
|
5
|
+
require 'faraday_middleware/response/dmm_rashify'
|
6
|
+
require 'multi_xml_tweaks'
|
7
|
+
require 'ruby-dmm/response'
|
8
|
+
require 'ruby-dmm/client/item_list'
|
9
|
+
|
10
|
+
module DMM
|
11
|
+
DEFAULT_API_VERSION = '2.00'.freeze
|
12
|
+
SITE_DMM_CO_JP = 'DMM.co.jp'.freeze
|
13
|
+
SITE_DMM_COM = 'DMM.com'.freeze
|
14
|
+
DEFAULT_SITE = SITE_DMM_CO_JP
|
15
|
+
|
16
|
+
class Client
|
17
|
+
attr_accessor(*Configuration::VALID_OPTIONS_KEYS)
|
18
|
+
attr_accessor :params
|
19
|
+
|
20
|
+
def initialize(params={})
|
21
|
+
params = params.inject({}) {|hash, (key, value)| hash.merge({key.to_sym => value})}
|
22
|
+
@params = {
|
23
|
+
:api_id => params[:api_id], # your own api_id
|
24
|
+
:affiliate_id => params[:affiliate_id], # your own api_id
|
25
|
+
:operation => nil, # "ItemList" is only available now.
|
26
|
+
:version => DEFAULT_API_VERSION,
|
27
|
+
:timestamp => Time.now.strftime("%F %T"),
|
28
|
+
:site => DEFAULT_SITE,
|
29
|
+
:result_only => false, # Set true to get only response.result.
|
30
|
+
}.merge(params)
|
31
|
+
|
32
|
+
DMM.options.each {|key, value| send("#{key}=", value) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def operation(value)
|
36
|
+
self.tap {|o| o.params.update(:operation => value) }
|
37
|
+
end
|
38
|
+
|
39
|
+
def all
|
40
|
+
@params[:operation] ? get('/', @params) : nil
|
41
|
+
end
|
42
|
+
|
43
|
+
include DMM::Client::ItemList
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def get(path, options={})
|
48
|
+
encode_params!
|
49
|
+
response = connection.get('/', options)
|
50
|
+
response.body
|
51
|
+
end
|
52
|
+
|
53
|
+
def connection(options={})
|
54
|
+
# TODO: not to create on every request.
|
55
|
+
Faraday.new(api_endpoint, options) do |faraday|
|
56
|
+
faraday.adapter(adapter)
|
57
|
+
faraday.request(:url_encoded)
|
58
|
+
faraday.response(:xml, :content_type => "text/xml; charset=euc-jp")
|
59
|
+
faraday.use(FaradayMiddleware::DMMRashify)
|
60
|
+
faraday.use(FaradayMiddleware::ParseXml)
|
61
|
+
faraday.use(Faraday::Response::RaiseDMMError)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def encode_params!
|
66
|
+
@params.each do |key, value|
|
67
|
+
value.encode!(Encoding::EUC_JP) if value.is_a?(String) && !value.frozen?
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module DMM
|
3
|
+
OPERATION_ITEM_LIST = 'ItemList'
|
4
|
+
|
5
|
+
class Client
|
6
|
+
module ItemList
|
7
|
+
|
8
|
+
def item_list(keyword="", options={})
|
9
|
+
@params = @params.merge(:keyword => keyword).merge(options)
|
10
|
+
@params[:operation] = OPERATION_ITEM_LIST
|
11
|
+
response = get('/', @params)
|
12
|
+
item_list = DMM::Response.new(response[:response])
|
13
|
+
@params[:result_only] ? item_list.result : item_list
|
14
|
+
end
|
15
|
+
alias :items :item_list
|
16
|
+
|
17
|
+
[:service,
|
18
|
+
:floor,
|
19
|
+
:hits,
|
20
|
+
:offset,
|
21
|
+
:sort,
|
22
|
+
:keyword,
|
23
|
+
:mono_stock].each do |key|
|
24
|
+
next if method_defined?(key)
|
25
|
+
define_method(key) do |value|
|
26
|
+
self.tap {|o| o.params.update(key => value) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
alias :limit :hits
|
30
|
+
alias :order :sort
|
31
|
+
alias :stock :mono_stock
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'faraday'
|
3
|
+
require "ruby-dmm/version"
|
4
|
+
|
5
|
+
module DMM
|
6
|
+
|
7
|
+
module Configuration
|
8
|
+
VALID_OPTIONS_KEYS = [
|
9
|
+
:adapter,
|
10
|
+
:user_agent,
|
11
|
+
:api_endpoint,
|
12
|
+
].freeze
|
13
|
+
|
14
|
+
DEFAULT_ADAPTER = Faraday.default_adapter
|
15
|
+
DEFAULT_USER_AGENT = "ruby-dmm gem #{DMM::VERSION}".freeze
|
16
|
+
DEFAULT_API_ENDPOINT = ENV['DMM_API_ENDPOINT'] || 'http://affiliate-api.dmm.com'
|
17
|
+
|
18
|
+
attr_accessor(*VALID_OPTIONS_KEYS)
|
19
|
+
|
20
|
+
def self.extended(base)
|
21
|
+
base.reset
|
22
|
+
end
|
23
|
+
|
24
|
+
def configure
|
25
|
+
yield self
|
26
|
+
end
|
27
|
+
|
28
|
+
def options
|
29
|
+
VALID_OPTIONS_KEYS.inject({}) {|h, k| h.merge!(k => send(k)) };
|
30
|
+
end
|
31
|
+
|
32
|
+
def api_endpoint=(value)
|
33
|
+
@api_endpoint = File.join(value, "")
|
34
|
+
end
|
35
|
+
|
36
|
+
def reset
|
37
|
+
self.adapter = DEFAULT_ADAPTER
|
38
|
+
self.user_agent = DEFAULT_USER_AGENT
|
39
|
+
self.api_endpoint = DEFAULT_API_ENDPOINT
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module DMM
|
3
|
+
class Error < StandardError; end
|
4
|
+
class BadRequest < Error; end
|
5
|
+
class Unauthorized < Error; end
|
6
|
+
class Forbidden < Error; end
|
7
|
+
class NotFound < Error; end
|
8
|
+
class NotAcceptable < Error; end
|
9
|
+
class UnprocessableEntity < Error; end
|
10
|
+
class InternalServerError < Error; end
|
11
|
+
class NotImplemented < Error; end
|
12
|
+
class BadGateway < Error; end
|
13
|
+
class ServiceUnavailable < Error; end
|
14
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'ruby-dmm/response/item'
|
3
|
+
|
4
|
+
module DMM
|
5
|
+
class Response
|
6
|
+
attr_reader :request, :result
|
7
|
+
|
8
|
+
def initialize(response)
|
9
|
+
@request = response[:request][:parameters][:parameter].inject({}) {|hash, params| hash.merge(params[:name].to_sym => params[:value]) }
|
10
|
+
@result = DMM::Response::Result.new(response[:result])
|
11
|
+
end
|
12
|
+
|
13
|
+
class Result
|
14
|
+
RESULT_KEYS = [:result_count, :total_count, :first_position, :items]
|
15
|
+
attr_reader *RESULT_KEYS
|
16
|
+
|
17
|
+
def initialize(result)
|
18
|
+
(RESULT_KEYS - [:items]).each do |key|
|
19
|
+
instance_variable_set("@#{key}", result[key].to_i)
|
20
|
+
end
|
21
|
+
|
22
|
+
@items = [result[:items][:item]].flatten.map do |item|
|
23
|
+
DMM::Response::Item.new(item)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|