ruby-dmm 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +2 -0
  4. data/Guardfile +8 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +58 -0
  7. data/Rakefile +9 -0
  8. data/lib/faraday/response/raise_dmm_error.rb +24 -0
  9. data/lib/faraday_middleware/response/dmm_rashify.rb +33 -0
  10. data/lib/multi_xml_tweaks.rb +29 -0
  11. data/lib/ruby-dmm.rb +24 -0
  12. data/lib/ruby-dmm/client.rb +71 -0
  13. data/lib/ruby-dmm/client/item_list.rb +34 -0
  14. data/lib/ruby-dmm/configuration.rb +42 -0
  15. data/lib/ruby-dmm/error.rb +14 -0
  16. data/lib/ruby-dmm/response.rb +28 -0
  17. data/lib/ruby-dmm/response/item.rb +64 -0
  18. data/lib/ruby-dmm/response/item_info.rb +42 -0
  19. data/lib/ruby-dmm/version.rb +4 -0
  20. data/ruby-dmm.gemspec +30 -0
  21. data/spec/client_spec.rb +17 -0
  22. data/spec/fixtures/com.xml +5987 -0
  23. data/spec/fixtures/com_digital.xml +1115 -0
  24. data/spec/fixtures/com_digital_book.xml +3407 -0
  25. data/spec/fixtures/com_iroiro.xml +1711 -0
  26. data/spec/fixtures/com_lod.xml +125 -0
  27. data/spec/fixtures/com_mono.xml +3723 -0
  28. data/spec/fixtures/com_monthly.xml +2075 -0
  29. data/spec/fixtures/com_pcsoft.xml +729 -0
  30. data/spec/fixtures/com_rental.xml +2691 -0
  31. data/spec/fixtures/r18.xml +4203 -0
  32. data/spec/fixtures/r18_book.xml +4965 -0
  33. data/spec/fixtures/r18_digital.xml +26987 -0
  34. data/spec/fixtures/r18_doujin.xml +2741 -0
  35. data/spec/fixtures/r18_mono.xml +3723 -0
  36. data/spec/fixtures/r18_monthly.xml +3515 -0
  37. data/spec/fixtures/r18_pcgame.xml +3373 -0
  38. data/spec/fixtures/r18_ppm.xml +2883 -0
  39. data/spec/fixtures/r18_rental.xml +12371 -0
  40. data/spec/response/item_spec.rb +16 -0
  41. data/spec/response_spec.rb +42 -0
  42. data/spec/spec_helper.rb +45 -0
  43. metadata +275 -0
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ gems
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,8 @@
1
+ # vim: ts=2 sts=2 et sw=2 ft=ruby
2
+
3
+ guard 'rspec', :all_after_pass => false, :all_on_start => false do
4
+ watch(%r{spec/.+_spec\.rb$})
5
+ watch(%r{lib/(.+)\.rb$}) {|m| "spec/#{m[1]}_spec.rb"}
6
+ watch(%r{lib/(.+)/.+\.rb$}) {|m| "spec/#{m[1]}_spec.rb"}
7
+ end
8
+
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,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:rspec) do |spec|
5
+ spec.pattern = 'spec/**/*_spec.rb'
6
+ spec.rspec_opts = ['-cfd --backtrace']
7
+ end
8
+
9
+ task :default => :rspec
@@ -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