opendmm 0.1.4 → 0.1.5

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.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -0
  3. data/Rakefile +35 -27
  4. data/bin/opendmm +7 -7
  5. data/lib/opendmm.rb +35 -26
  6. data/lib/opendmm/maker.rb +18 -59
  7. data/lib/opendmm/makers/aknr.rb +18 -34
  8. data/lib/opendmm/makers/ako3.rb +18 -34
  9. data/lib/opendmm/makers/anna_and_hanako.rb +20 -36
  10. data/lib/opendmm/makers/apa.rb +19 -35
  11. data/lib/opendmm/makers/aroma.rb +40 -54
  12. data/lib/opendmm/makers/attackers.rb +30 -48
  13. data/lib/opendmm/makers/aurora.rb +24 -40
  14. data/lib/opendmm/makers/baltan.rb +20 -36
  15. data/lib/opendmm/makers/befree.rb +22 -38
  16. data/lib/opendmm/makers/bi.rb +24 -40
  17. data/lib/opendmm/makers/bijin_majo.rb +19 -35
  18. data/lib/opendmm/makers/candy.rb +27 -43
  19. data/lib/opendmm/makers/caribbean.rb +21 -36
  20. data/lib/opendmm/makers/cross.rb +22 -39
  21. data/lib/opendmm/makers/dip.rb +22 -38
  22. data/lib/opendmm/makers/dmm_collection.rb +19 -35
  23. data/lib/opendmm/makers/ebody.rb +22 -38
  24. data/lib/opendmm/makers/ideapocket.rb +42 -60
  25. data/lib/opendmm/makers/kawaii.rb +21 -37
  26. data/lib/opendmm/makers/kira_kira.rb +21 -37
  27. data/lib/opendmm/makers/madonna.rb +21 -37
  28. data/lib/opendmm/makers/moodyz.rb +41 -44
  29. data/lib/opendmm/makers/munekyunkissa.rb +21 -37
  30. data/lib/opendmm/makers/opera.rb +27 -43
  31. data/lib/opendmm/makers/oppai.rb +33 -51
  32. data/lib/opendmm/makers/premium.rb +23 -39
  33. data/lib/opendmm/makers/prestige.rb +40 -58
  34. data/lib/opendmm/makers/ran_maru.rb +29 -46
  35. data/lib/opendmm/makers/s1.rb +21 -37
  36. data/lib/opendmm/makers/s_cute.rb +41 -55
  37. data/lib/opendmm/makers/sod.rb +23 -39
  38. data/lib/opendmm/makers/tameikegoro.rb +22 -38
  39. data/lib/opendmm/makers/to_satsu.rb +20 -36
  40. data/lib/opendmm/makers/waap.rb +24 -41
  41. data/lib/opendmm/search_engine.rb +20 -0
  42. data/lib/opendmm/search_engines/dmm.rb +38 -58
  43. data/lib/opendmm/search_engines/jav_library.rb +32 -63
  44. data/lib/opendmm/site.rb +73 -0
  45. data/lib/opendmm/utils.rb +22 -2
  46. data/lib/opendmm/version.rb +1 -1
  47. data/test/{fixtures → dmm_fixtures}/DMYJ-001.json +1 -1
  48. data/test/fixture_test.rb +17 -13
  49. data/test/{fixtures → jav_library_fixtures}/XV-100.json +0 -0
  50. data/test/{fixtures → jav_library_fixtures}/XV-1000.json +0 -0
  51. data/test/{fixtures → maker_fixtures}/ABP-013.json +0 -0
  52. data/test/{fixtures → maker_fixtures}/ABS-014.json +0 -0
  53. data/test/{fixtures → maker_fixtures}/ABY-003.json +0 -0
  54. data/test/{fixtures → maker_fixtures}/ADN-019.json +0 -0
  55. data/test/{fixtures → maker_fixtures}/AIR-017.json +1 -1
  56. data/test/{fixtures → maker_fixtures}/AKO-011.json +1 -1
  57. data/test/{fixtures → maker_fixtures}/ALB-182.json +0 -0
  58. data/test/{fixtures → maker_fixtures}/ANND-066.json +0 -0
  59. data/test/{fixtures → maker_fixtures}/AP-001.json +0 -0
  60. data/test/{fixtures → maker_fixtures}/APAA-182.json +0 -0
  61. data/test/{fixtures → maker_fixtures}/APAK-051.json +0 -0
  62. data/test/{fixtures → maker_fixtures}/ARM-191.json +0 -0
  63. data/test/{fixtures → maker_fixtures}/ARMG-223.json +0 -0
  64. data/test/{fixtures → maker_fixtures}/ATID-183.json +0 -0
  65. data/test/{fixtures → maker_fixtures}/BBI-104.json +0 -0
  66. data/test/{fixtures → maker_fixtures}/BEB-001.json +0 -0
  67. data/test/{fixtures → maker_fixtures}/BF-175.json +0 -0
  68. data/test/{fixtures → maker_fixtures}/BID-017.json +0 -0
  69. data/test/{fixtures → maker_fixtures}/BIJN-006.json +0 -0
  70. data/test/{fixtures → maker_fixtures}/BLK-049.json +0 -0
  71. data/test/{fixtures → maker_fixtures}/BRA-002.json +0 -0
  72. data/test/{fixtures → maker_fixtures}/BWB-005.json +0 -0
  73. data/test/{fixtures → maker_fixtures}/CHN-008.json +0 -0
  74. data/test/{fixtures → maker_fixtures}/CHS-015.json +0 -0
  75. data/test/{fixtures → maker_fixtures}/CLUB-003.json +0 -0
  76. data/test/{fixtures → maker_fixtures}/CND-012.json +0 -0
  77. data/test/{fixtures → maker_fixtures}/CND-062.json +0 -0
  78. data/test/{fixtures → maker_fixtures}/CRAD-099.json +0 -0
  79. data/test/{fixtures → maker_fixtures}/CRPD-451.json +0 -0
  80. data/test/{fixtures → maker_fixtures}/CRSS-013.json +0 -0
  81. data/test/{fixtures → maker_fixtures}/CWM-156.json +1 -1
  82. data/test/fixtures/Carib 021511-620.json b/data/test/maker_fixtures/Carib → 021511-620.json +0 -0
  83. data/test/{fixtures → maker_fixtures}/DCOL-017.json +1 -1
  84. data/test/{fixtures → maker_fixtures}/DGL-007.json +1 -1
  85. data/test/{fixtures → maker_fixtures}/DOM-045.json +0 -0
  86. data/test/{fixtures → maker_fixtures}/EBOD-109.json +0 -0
  87. data/test/{fixtures → maker_fixtures}/ECB-078.json +1 -1
  88. data/test/{fixtures → maker_fixtures}/EDD-189.json +0 -0
  89. data/test/{fixtures → maker_fixtures}/ESK-232.json +0 -0
  90. data/test/{fixtures → maker_fixtures}/EZD-369.json +0 -0
  91. data/test/{fixtures → maker_fixtures}/FSET-399.json +0 -0
  92. data/test/{fixtures → maker_fixtures}/HAZ-009.json +0 -0
  93. data/test/{fixtures → maker_fixtures}/HON-001.json +0 -0
  94. data/test/{fixtures → maker_fixtures}/IDBD-447.json +0 -0
  95. data/test/{fixtures → maker_fixtures}/INU-013.json +0 -0
  96. data/test/{fixtures → maker_fixtures}/IPSD-041.json +0 -0
  97. data/test/{fixtures → maker_fixtures}/IPTD-464.json +0 -0
  98. data/test/{fixtures → maker_fixtures}/IPTD-629.json +0 -0
  99. data/test/{fixtures → maker_fixtures}/IPZ-005.json +0 -0
  100. data/test/{fixtures → maker_fixtures}/JBD-153.json +0 -0
  101. data/test/{fixtures → maker_fixtures}/JBS-004.json +0 -0
  102. data/test/{fixtures → maker_fixtures}/JOB-010.json +0 -0
  103. data/test/{fixtures → maker_fixtures}/JUC-285.json +0 -0
  104. data/test/{fixtures → maker_fixtures}/JUFD-137.json +0 -0
  105. data/test/{fixtures → maker_fixtures}/JUX-007.json +0 -0
  106. data/test/{fixtures → maker_fixtures}/JUX-119.json +0 -0
  107. data/test/{fixtures → maker_fixtures}/KAWD-249.json +1 -1
  108. data/test/{fixtures → maker_fixtures}/KIRD-147.json +0 -0
  109. data/test/{fixtures → maker_fixtures}/KISD-042.json +0 -0
  110. data/test/{fixtures → maker_fixtures}/LLR-005.json +0 -0
  111. data/test/{fixtures → maker_fixtures}/MAS-042.json +0 -0
  112. data/test/{fixtures → maker_fixtures}/MBD-148.json +0 -0
  113. data/test/{fixtures → maker_fixtures}/MDC-002.json +0 -0
  114. data/test/{fixtures → maker_fixtures}/MDYD-544.json +0 -0
  115. data/test/{fixtures → maker_fixtures}/MEK-008.json +0 -0
  116. data/test/{fixtures → maker_fixtures}/MIAD-490.json +0 -0
  117. data/test/{fixtures → maker_fixtures}/MIDD-599.json +0 -0
  118. data/test/{fixtures → maker_fixtures}/MIDD-643.json +0 -0
  119. data/test/{fixtures → maker_fixtures}/MIDD-644.json +0 -0
  120. data/test/{fixtures → maker_fixtures}/MIDE-004.json +0 -0
  121. data/test/{fixtures → maker_fixtures}/MIGD-284.json +0 -0
  122. data/test/{fixtures → maker_fixtures}/MIGD-336.json +0 -0
  123. data/test/{fixtures → maker_fixtures}/MIGD-337.json +0 -0
  124. data/test/{fixtures → maker_fixtures}/MIMK-005.json +0 -0
  125. data/test/{fixtures → maker_fixtures}/MINT-004.json +0 -0
  126. data/test/{fixtures → maker_fixtures}/MIQD-010.json +0 -0
  127. data/test/{fixtures → maker_fixtures}/MIRD-071.json +0 -0
  128. data/test/{fixtures → maker_fixtures}/MIRD-072.json +0 -0
  129. data/test/{fixtures → maker_fixtures}/MIRD-073.json +0 -0
  130. data/test/{fixtures → maker_fixtures}/MIXS-005.json +0 -0
  131. data/test/{fixtures → maker_fixtures}/MMY-010.json +0 -0
  132. data/test/{fixtures → maker_fixtures}/NAGE-001.json +0 -0
  133. data/test/{fixtures → maker_fixtures}/NDR-001.json +0 -0
  134. data/test/{fixtures → maker_fixtures}/NOF-003.json +0 -0
  135. data/test/{fixtures → maker_fixtures}/NPS-130.json +0 -0
  136. data/test/{fixtures → maker_fixtures}/OBA-045.json +1 -1
  137. data/test/{fixtures → maker_fixtures}/ONSD-570.json +0 -0
  138. data/test/{fixtures → maker_fixtures}/OPUD-125.json +1 -1
  139. data/test/{fixtures → maker_fixtures}/OSR-003.json +0 -0
  140. data/test/{fixtures → maker_fixtures}/PARM-028.json +0 -0
  141. data/test/{fixtures → maker_fixtures}/PBD-134.json +0 -0
  142. data/test/{fixtures → maker_fixtures}/PGD-306.json +0 -0
  143. data/test/{fixtures → maker_fixtures}/PJD-085.json +0 -0
  144. data/test/{fixtures → maker_fixtures}/PPB-008.json +0 -0
  145. data/test/{fixtures → maker_fixtures}/PPP-001.json +0 -0
  146. data/test/{fixtures → maker_fixtures}/PPPD-102.json +1 -1
  147. data/test/{fixtures → maker_fixtures}/PPSD-028.json +1 -1
  148. data/test/{fixtures → maker_fixtures}/PPT-004.json +0 -0
  149. data/test/{fixtures → maker_fixtures}/PTS-230.json +0 -0
  150. data/test/{fixtures → maker_fixtures}/PTV-001.json +0 -0
  151. data/test/{fixtures → maker_fixtures}/PXD-027.json +0 -0
  152. data/test/{fixtures → maker_fixtures}/RAW-005.json +0 -0
  153. data/test/{fixtures → maker_fixtures}/RBD-183.json +0 -0
  154. data/test/fixtures/S-Cute 248_hibiki_07.json b/data/test/maker_fixtures/S-Cute → 248_hibiki_07.json +0 -0
  155. data/test/fixtures/S-Cute 353_rena_01.json b/data/test/maker_fixtures/S-Cute → 353_rena_01.json +0 -0
  156. data/test/fixtures/S-Cute ps5_07_rimu.json b/data/test/maker_fixtures/S-Cute → ps5_07_rimu.json +0 -0
  157. data/test/fixtures/S-Cute ps6_99_reona.json b/data/test/maker_fixtures/S-Cute → ps6_99_reona.json +0 -0
  158. data/test/fixtures/S-Cute ps7_83_akari2.json b/data/test/maker_fixtures/S-Cute → ps7_83_akari2.json +0 -0
  159. data/test/fixtures/S-Cute swm_05_risa2.json b/data/test/maker_fixtures/S-Cute → swm_05_risa2.json +0 -0
  160. data/test/{fixtures → maker_fixtures}/SAD-031.json +0 -0
  161. data/test/{fixtures → maker_fixtures}/SDDE-312.json +0 -0
  162. data/test/{fixtures → maker_fixtures}/SDMT-802.json +0 -0
  163. data/test/{fixtures → maker_fixtures}/SDMU-008.json +0 -0
  164. data/test/{fixtures → maker_fixtures}/SDNM-011.json +0 -0
  165. data/test/{fixtures → maker_fixtures}/SET-007.json +0 -0
  166. data/test/{fixtures → maker_fixtures}/SGA-001.json +1 -0
  167. data/test/{fixtures → maker_fixtures}/SHKD-415.json +3 -3
  168. data/test/{fixtures → maker_fixtures}/SNIS-041.json +0 -0
  169. data/test/{fixtures → maker_fixtures}/SOE-259.json +0 -0
  170. data/test/{fixtures → maker_fixtures}/SPC-001.json +0 -0
  171. data/test/{fixtures → maker_fixtures}/SPS-008.json +0 -0
  172. data/test/{fixtures → maker_fixtures}/SRS-015.json +0 -0
  173. data/test/{fixtures → maker_fixtures}/SSPD-077.json +0 -0
  174. data/test/{fixtures → maker_fixtures}/STAR-359.json +0 -0
  175. data/test/{fixtures → maker_fixtures}/SUPD-065.json +0 -0
  176. data/test/{fixtures → maker_fixtures}/TDT-018.json +0 -0
  177. data/test/{fixtures → maker_fixtures}/TMAM-034.json +0 -0
  178. data/test/{fixtures → maker_fixtures}/TMCY-039.json +0 -0
  179. data/test/{fixtures → maker_fixtures}/TMDI-040.json +0 -0
  180. data/test/{fixtures → maker_fixtures}/TMEM-044.json +0 -0
  181. data/test/{fixtures → maker_fixtures}/TMVI-042.json +0 -0
  182. data/test/{fixtures → maker_fixtures}/TRD-062.json +0 -0
  183. data/test/{fixtures → maker_fixtures}/TYOD-232.json +1 -1
  184. data/test/{fixtures → maker_fixtures}/URE-011.json +0 -0
  185. data/test/{fixtures → maker_fixtures}/WA-201.json +0 -0
  186. data/test/{fixtures → maker_fixtures}/WAT-003.json +0 -0
  187. data/test/{fixtures → maker_fixtures}/WPC-002.json +0 -0
  188. data/test/{fixtures → maker_fixtures}/WSS-231.json +1 -1
  189. data/test/{fixtures → maker_fixtures}/XND-023.json +0 -0
  190. data/test/{fixtures → maker_fixtures}/YRH-008.json +0 -0
  191. data/test/{fixtures → maker_fixtures}/YRZ-009.json +0 -0
  192. data/test/{fixtures → maker_fixtures}/ZEX-068.json +0 -0
  193. metadata +294 -292
@@ -1,66 +1,35 @@
1
- require 'opendmm/utils'
1
+ base_uri 'www.javlibrary.com'
2
2
 
3
- module OpenDMM
4
- module SearchEngine
5
- module JavLibrary
6
- module Site
7
- include HTTParty
8
- base_uri 'www.javlibrary.com'
9
- follow_redirects false
3
+ def self.search_url(name)
4
+ "/ja/vl_searchbyid.php?keyword=#{CGI::escape(name)}"
5
+ end
10
6
 
11
- def self.search(name)
12
- get("/ja/vl_searchbyid.php?keyword=#{CGI::escape(name)}")
13
- end
14
-
15
- def self.item(id)
16
- get("/ja/?v=#{id}")
17
- end
18
-
19
- def self.get(uri)
20
- super(uri)
21
- rescue Errno::ETIMEDOUT => e
22
- tries ||= 0
23
- tries++
24
- tries <= 5 ? retry : raise
25
- end
26
- end
27
-
28
- module Parser
29
- def self.parse_search_result(content)
30
- html = Nokogiri::HTML(content)
31
- first_result = html.css('#rightcolumn > div.videothumblist > div.videos > div.video > a').first
32
- first_result['href'].remove('./?v=') if first_result
33
- end
34
-
35
- def self.parse_item(content)
36
- page_uri = content.request.last_uri
37
- html = Nokogiri::HTML(content)
38
- return {
39
- actresses: html.css('#video_cast .text span.cast').map(&:text),
40
- code: html.css('#video_id .text').text,
41
- cover_image: html.at_css('#video_jacket > a')['href'],
42
- directors: html.css('#video_director .text span.director').map(&:text),
43
- genres: html.css('#video_genres .text span.genre').map(&:text),
44
- label: html.css('#video_label .text').text,
45
- maker: html.css('#video_maker .text').text,
46
- movie_length: html.css('#video_length .text').text + ' minutes',
47
- page: page_uri.to_s,
48
- release_date: html.css('#video_date .text').text,
49
- thumbnail_image: html.at_css('#video_jacket_img')['src'],
50
- title: html.css('#video_title > h3').text.remove(html.css('#video_id .text').text),
51
- }
52
- end
53
- end
54
-
55
- def self.search(name)
56
- search_result = Site.search(name)
57
- if search_result.code == 302
58
- jav_id = search_result.headers['location'].remove('./?v=')
59
- else
60
- jav_id = Parser.parse_search_result(search_result)
61
- end
62
- Parser.parse_item(Site.item(jav_id)) if jav_id
63
- end
64
- end
7
+ def self.product_url(name)
8
+ search_page = get_with_retry search_url(name)
9
+ return nil unless search_page
10
+ if search_page.code == 302
11
+ url = search_page.headers['location']
12
+ else
13
+ search_html = Utils.html_in_utf8 search_page
14
+ first_result = search_html.at_css('#rightcolumn > div.videothumblist > div.videos > div.video > a')
15
+ return nil unless first_result
16
+ url = first_result['href']
65
17
  end
66
- end
18
+ URI.join(search_page.request.last_uri, url).to_s
19
+ end
20
+
21
+ def self.parse_product_html(html)
22
+ {
23
+ actresses: html.css('#video_cast .text span.cast').map(&:text),
24
+ code: html.css('#video_id .text').text,
25
+ cover_image: html.at_css('#video_jacket > a')['href'],
26
+ directors: html.css('#video_director .text span.director').map(&:text),
27
+ genres: html.css('#video_genres .text span.genre').map(&:text),
28
+ label: html.css('#video_label .text').text,
29
+ maker: html.css('#video_maker .text').text,
30
+ movie_length: html.css('#video_length .text').text + ' minutes',
31
+ release_date: html.css('#video_date .text').text,
32
+ thumbnail_image: html.at_css('#video_jacket_img')['src'],
33
+ title: html.css('#video_title > h3').text.remove(html.css('#video_id .text').text),
34
+ }
35
+ end
@@ -0,0 +1,73 @@
1
+ require 'active_support/core_ext/module/attribute_accessors'
2
+ require 'httparty'
3
+ require 'opendmm/utils'
4
+
5
+ module OpenDMM
6
+ module Site
7
+
8
+ def self.included(klass)
9
+ klass.mattr_accessor :url_generators
10
+ klass.mattr_accessor :code_generators
11
+ klass.url_generators = Hash.new
12
+ klass.code_generators = Hash.new
13
+
14
+ klass.include HTTParty
15
+ klass.follow_redirects false
16
+
17
+ klass.extend ClassMethods
18
+ end
19
+
20
+ module ClassMethods
21
+ def get_with_retry(url, limit = 5)
22
+ return nil unless url
23
+ get url
24
+ rescue Errno::ETIMEDOUT => e
25
+ tries ||= 0
26
+ tries++
27
+ tries <= 5 ? retry : raise
28
+ end
29
+
30
+ def register_product(matcher, url_generator, code_generator = '#{$1.upcase}-#{$2}')
31
+ url_generators[matcher] = '"' + url_generator + '"'
32
+ code_generators[matcher] = '"' + code_generator + '"'
33
+ end
34
+
35
+ def product_url(name)
36
+ url_generators.each do |matcher, url_generator|
37
+ if name =~ matcher
38
+ return eval url_generator
39
+ end
40
+ end
41
+ nil
42
+ end
43
+
44
+ def product_code(name)
45
+ code_generators.each do |matcher, code_generator|
46
+ if name =~ matcher
47
+ return eval code_generator
48
+ end
49
+ end
50
+ nil
51
+ end
52
+
53
+ def product_extra_info(name, url, page, html)
54
+ Hash.new
55
+ end
56
+
57
+ def product(name)
58
+ url = product_url name
59
+ page = get_with_retry url
60
+ return nil unless page
61
+ html = Utils.html_in_utf8 page
62
+ details = parse_product_html html
63
+ details[:code] ||= product_code name
64
+ details[:page] ||= page.request.last_uri.to_s
65
+ extra_info = product_extra_info(name, url, page, html)
66
+ extra_info.each do |k, v|
67
+ details[k] ||= v
68
+ end
69
+ Utils.finalize_details_hash details
70
+ end
71
+ end
72
+ end
73
+ end
@@ -2,8 +2,10 @@ require 'active_support/core_ext/array/access'
2
2
  require 'active_support/core_ext/array/grouping'
3
3
  require 'active_support/core_ext/module/aliasing'
4
4
  require 'active_support/core_ext/numeric/time'
5
+ require 'active_support/core_ext/string/filters'
5
6
  require 'active_support/core_ext/string/starts_ends_with'
6
7
  require 'chronic_duration'
8
+ require 'nokogiri'
7
9
 
8
10
  class << Date
9
11
  def parse_with_chinese_support(str)
@@ -61,13 +63,31 @@ module OpenDMM
61
63
  end.to_h
62
64
  end
63
65
 
64
- def self.force_utf8(content)
66
+ def self.html_in_utf8(content)
65
67
  # This is to get rid of the annoying error message:
66
68
  # 'encoding error : input conversion failed due to input error'
67
69
  $stderr.reopen('/dev/null', 'w')
68
- encoding = Nokogiri::HTML(content).encoding
70
+ encoding = Nokogiri.HTML(content).encoding
69
71
  $stderr = STDERR
70
72
  content = content.encode('UTF-8', encoding, invalid: :replace, undef: :replace, replace: '')
73
+ Nokogiri.HTML content
74
+ end
75
+
76
+ def self.finalize_details_hash(details)
77
+ details = details.squish_hard
78
+ details[:cover_image] = join_url_if_relative(details[:page], details[:cover_image])
79
+ details[:thumbnail_image] = join_url_if_relative(details[:page], details[:thumbnail_image])
80
+ details[:sample_images] = details[:sample_images].map do |uri|
81
+ join_url_if_relative(details[:page], uri)
82
+ end if details[:sample_images]
83
+ details[:movie_length] = ChronicDuration.parse(details[:movie_length]) if details[:movie_length]
84
+ details[:release_date] = Date.parse(details[:release_date]) if details[:release_date]
85
+ details.sort.to_h
86
+ end
87
+
88
+ def self.join_url_if_relative(page_url, image_url)
89
+ return nil unless image_url
90
+ image_url.start_with?('http') ? image_url : URI.join(page_url, image_url).to_s
71
91
  end
72
92
  end
73
93
  end
@@ -1,3 +1,3 @@
1
1
  module OpenDMM
2
- VERSION = '0.1.4'
2
+ VERSION = '0.1.5'
3
3
  end
@@ -1,5 +1,5 @@
1
1
  {
2
- "code": "dmyj00001",
2
+ "code": "DMYJ-001",
3
3
  "cover_image": "http://pics.dmm.co.jp/digital/video/dmyj00001/dmyj00001pl.jpg",
4
4
  "directors": [
5
5
  "三谷任三郎"
@@ -56,19 +56,23 @@ class FixtureTest < Minitest::Test
56
56
  end
57
57
  end
58
58
 
59
- Dir[File.dirname(__FILE__) + '/fixtures/*.json'].each do |path|
60
- name = File.basename(path, '.json')
61
- eval <<-TESTCASE
59
+ { 'dmm' => 'OpenDMM::SearchEngine::Dmm',
60
+ 'jav_library' => 'OpenDMM::SearchEngine::JavLibrary',
61
+ 'maker' => 'OpenDMM::Maker' }.each do |category, klass|
62
+ Dir[File.dirname(__FILE__) + "/#{category}_fixtures/*.json"].each do |file|
63
+ name = File.basename(file, '.json')
64
+ eval <<-TESTCASE
62
65
 
63
- class FixtureTest
64
- def test_#{name.parameterize.underscore}
65
- expected = load_product('#{path}')
66
- actual = OpenDMM.search!('#{name}')
67
- assert_has_basic_keys(actual)
68
- assert_no_unknown_keys(actual)
69
- assert_equal expected, actual, HashDiff.diff(expected, actual)
66
+ class FixtureTest
67
+ def test_#{category}_#{name.parameterize.underscore}
68
+ expected = load_product('#{file}')
69
+ actual = #{klass}.search('#{name}')
70
+ assert_has_basic_keys(actual)
71
+ assert_no_unknown_keys(actual)
72
+ assert_equal expected, actual, HashDiff.diff(expected, actual)
73
+ end
70
74
  end
71
- end
72
75
 
73
- TESTCASE
74
- end
76
+ TESTCASE
77
+ end
78
+ end
@@ -3,7 +3,7 @@
3
3
  "大槻ひびき"
4
4
  ],
5
5
  "brand": "AIR*WAAP",
6
- "code": "AIR017",
6
+ "code": "AIR-017",
7
7
  "cover_image": "http://www.waap.co.jp/hskhsk/itsub/AIR017.jpg",
8
8
  "description": "肉厚で長いベロを持つガーリーなひびき嬢が、目隠しされて悦んでるドMのオッサンを、全身リップでゾクゾクさせちゃう。特にチクビを重点的に責め尽くし、チ●コをギン勃ちさせると、敏感な裏スジを丹念に舐めあげ吸引し、アナル舐めまでヤリタイ放題した後、ちくび責めと手コキで「ダメダメ」と罵られ、何度も寸止めされてヘロヘロのM男の顔面に、アソコを押しつけ強制クンニさせてアクメる。インサートは騎乗位からで、この腰使いはエロスネーク。半狂乱でイキまくって汗まみれで、フィニッシュ!",
9
9
  "genres": [
@@ -2,7 +2,7 @@
2
2
  "actresses": [
3
3
  "MARI[まり]"
4
4
  ],
5
- "code": "AKO011",
5
+ "code": "AKO-011",
6
6
  "cover_image": "http://www.ako-3.com/img/jacket/AKO011.jpg",
7
7
  "description": "コスプレしてみたりソフトSMをしてみたいというMARIちゃんは、爽やかイケメンがタイプで男に関しては色々うるさそう。そんな彼女のお餅みたく白くて柔らかい上物パイオツをぺろぺろナメナメしたり、アソコをぐっちょぐっちょ掻き回すと、カワイイ声で喘ぐスケベちゃんに豹変。で、ズッポリ挿入、フィニッシュは舌上、で、ごっくんしてくれたよ。で、おまけに、セックス後のシャワー室に侵入し、俺の乳首をイジらせ、フェラに持ち込み「ぐえっ」っと咽る彼女を尻目に精子を舐めさせちゃったぜ!",
8
8
  "maker": "A子さん",
@@ -3,7 +3,7 @@
3
3
  "愛沢有紗"
4
4
  ],
5
5
  "brand": "CLUB WAAP",
6
- "code": "CWM156",
6
+ "code": "CWM-156",
7
7
  "cover_image": "http://www.waap.co.jp/hskhsk/itsub/CWM156.jpg",
8
8
  "description": "日焼け跡を、ワシヅカミ☆ 真っ黒にこんがり灼けたボディに残るセクシーな水着の日焼け跡が、褐色の肢体にくっきりと卑猥に浮かぶことで自らを常に欲情的に燃え上がらせ、自然とオトコを挑発する情熱的なフェロモンを撒き散らす。金麦色の肌にくっきりと浮かぶ乳房に性交というカタチで吐き出される、全編・巨乳&日焼け跡フェチ要素100%の灼熱セックス130分!! 全5編。",
9
9
  "directors": [
@@ -2,7 +2,7 @@
2
2
  "actresses": [
3
3
  "鈴木心春"
4
4
  ],
5
- "code": "dcol017",
5
+ "code": "DCOL-017",
6
6
  "cover_image": "http://dmm-collection.com/images/works/dcol017/dcol017pl.jpg",
7
7
  "description": "鈴木心春がレイプ作品解禁!白く美しい肌と完璧な巨乳を持つ人妻は知らず知らずのうちに周囲の男性達を誘惑してしまい、夫の留守中に水道局員が訪れた時、悲劇は始まった。夫に言えない秘密を背負ってしまった心春を襲うレイプの連鎖。抵抗できない人妻に男達が容赦なく肉棒を突き刺します!",
8
8
  "maker": "D★Collection",
@@ -2,7 +2,7 @@
2
2
  "actresses": [
3
3
  "宮崎ちひろ"
4
4
  ],
5
- "code": "dgl007",
5
+ "code": "DGL-007",
6
6
  "cover_image": "http://dmm-collection.com/images/works/dgl007/dgl007pl.jpg",
7
7
  "description": "衝撃のデビュー作から1年、たった1作のみの出演でAV界から姿を消した伝説の美女優が復活!男を誘惑する視線とパーフェクトなカラダは更に妖艶さを増し、激しいイキっぷりももちろん健在!芸能人美●うらんDコレ専属復活作です!",
8
8
  "maker": "D★Collection",
@@ -3,7 +3,7 @@
3
3
  "向井恋"
4
4
  ],
5
5
  "brand": "est WAAP",
6
- "code": "ECB078",
6
+ "code": "ECB-078",
7
7
  "cover_image": "http://www.waap.co.jp/hskhsk/itsub/ECB078.jpg",
8
8
  "description": "このオンナ、下品なクセしてキレイ好き。 ドスケベフェロモン出っ放しのお姉さん・向井恋が、卑猥な口唇からヨダレをダラダラ垂らしながら、M男チ●ポにむしゃぶりついて精子を頂戴する。汁まみれになった射精後の敏感チ●ポにも、容赦ないお掃除フェラで徹底バキュームして、汁という汁が干からびるまでエンドレスに求め続ける、超肉食系淫女のアドリブごっくん&お掃除痴女ライブ!! 全4編。",
9
9
  "directors": [
@@ -2,7 +2,7 @@
2
2
  "actresses": [
3
3
  "横山美雪"
4
4
  ],
5
- "code": "KAWD249",
5
+ "code": "KAWD-249",
6
6
  "cover_image": "http://kawaiikawaii.jp/images/works/kawd249/kawd249pl.jpg",
7
7
  "description": "オナニー快感に憑りつかれてしまった看護師・美雪☆夜勤がある日も無い日も毎日オナニー。少しずつ寝る時間が短くなりオナニーする時間のほうが長くなっちゃった!チンポも精子もズリネタ同然♪盗撮させてエッチ!クリ激擦り3P!見せ付けオナセックchu!全6コーナー収録!",
8
8
  "genres": [