whois-parser 0.0.1 → 1.0.0.pre.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (282) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -0
  3. data/CHANGELOG.md +20 -0
  4. data/CONTRIBUTING.md +40 -0
  5. data/LICENSE.txt +17 -18
  6. data/README.md +6 -24
  7. data/lib/whois/parser/contact.rb +56 -0
  8. data/lib/whois/parser/errors.rb +46 -0
  9. data/lib/whois/parser/nameserver.rb +39 -0
  10. data/lib/whois/parser/registrar.rb +25 -0
  11. data/lib/whois/parser/super_struct.rb +53 -0
  12. data/lib/whois/parser/version.rb +3 -2
  13. data/lib/whois/parser.rb +407 -3
  14. data/lib/whois/parser_extensions/whois.rb +78 -0
  15. data/lib/whois/parser_extensions/whois_record.rb +222 -0
  16. data/lib/whois/parser_extensions.rb +9 -0
  17. data/lib/whois/parsers/base.rb +412 -0
  18. data/lib/whois/parsers/base_afilias.rb +139 -0
  19. data/lib/whois/parsers/base_afilias2.rb +140 -0
  20. data/lib/whois/parsers/base_cocca.rb +97 -0
  21. data/lib/whois/parsers/base_cocca2.rb +91 -0
  22. data/lib/whois/parsers/base_icann_compliant.rb +150 -0
  23. data/lib/whois/parsers/base_icb.rb +92 -0
  24. data/lib/whois/parsers/base_iisse.rb +113 -0
  25. data/lib/whois/parsers/base_nic_fr.rb +169 -0
  26. data/lib/whois/parsers/base_shared1.rb +108 -0
  27. data/lib/whois/parsers/base_shared2.rb +127 -0
  28. data/lib/whois/parsers/base_shared3.rb +127 -0
  29. data/lib/whois/parsers/base_verisign.rb +106 -0
  30. data/lib/whois/parsers/base_whoisd.rb +145 -0
  31. data/lib/whois/parsers/blank.rb +35 -0
  32. data/lib/whois/parsers/capetown-whois.registry.net.za.rb +25 -0
  33. data/lib/whois/parsers/ccwhois.ksregistry.net.rb +25 -0
  34. data/lib/whois/parsers/ccwhois.verisign-grs.com.rb +25 -0
  35. data/lib/whois/parsers/durban-whois.registry.net.za.rb +25 -0
  36. data/lib/whois/parsers/example.rb +163 -0
  37. data/lib/whois/parsers/joburg-whois.registry.net.za.rb +25 -0
  38. data/lib/whois/parsers/kero.yachay.pe.rb +86 -0
  39. data/lib/whois/parsers/org-whois.registry.net.za.rb +25 -0
  40. data/lib/whois/parsers/tvwhois.verisign-grs.com.rb +25 -0
  41. data/lib/whois/parsers/whois.1und1.info.rb +28 -0
  42. data/lib/whois/parsers/whois.35.com.rb +23 -0
  43. data/lib/whois/parsers/whois.aeda.net.ae.rb +64 -0
  44. data/lib/whois/parsers/whois.aero.rb +58 -0
  45. data/lib/whois/parsers/whois.afilias-grs.info.rb +21 -0
  46. data/lib/whois/parsers/whois.afilias.net.rb +41 -0
  47. data/lib/whois/parsers/whois.ai.rb +62 -0
  48. data/lib/whois/parsers/whois.amnic.net.rb +79 -0
  49. data/lib/whois/parsers/whois.ascio.com.rb +29 -0
  50. data/lib/whois/parsers/whois.ati.tn.rb +116 -0
  51. data/lib/whois/parsers/whois.audns.net.au.rb +118 -0
  52. data/lib/whois/parsers/whois.ax.rb +64 -0
  53. data/lib/whois/parsers/whois.biz.rb +25 -0
  54. data/lib/whois/parsers/whois.bnnic.bn.rb +75 -0
  55. data/lib/whois/parsers/whois.cat.rb +75 -0
  56. data/lib/whois/parsers/whois.cctld.by.rb +94 -0
  57. data/lib/whois/parsers/whois.cctld.uz.rb +79 -0
  58. data/lib/whois/parsers/whois.centralnic.com.rb +140 -0
  59. data/lib/whois/parsers/whois.cira.ca.rb +192 -0
  60. data/lib/whois/parsers/whois.cmc.iq.rb +25 -0
  61. data/lib/whois/parsers/whois.cnnic.cn.rb +108 -0
  62. data/lib/whois/parsers/whois.co.ca.rb +74 -0
  63. data/lib/whois/parsers/whois.co.pl.rb +82 -0
  64. data/lib/whois/parsers/whois.co.ug.rb +82 -0
  65. data/lib/whois/parsers/whois.comlaude.com.rb +113 -0
  66. data/lib/whois/parsers/whois.corporatedomains.com.rb +28 -0
  67. data/lib/whois/parsers/whois.denic.de.rb +164 -0
  68. data/lib/whois/parsers/whois.dk-hostmaster.dk.rb +88 -0
  69. data/lib/whois/parsers/whois.dns.be.rb +120 -0
  70. data/lib/whois/parsers/whois.dns.hr.rb +97 -0
  71. data/lib/whois/parsers/whois.dns.lu.rb +126 -0
  72. data/lib/whois/parsers/whois.dns.pl.rb +151 -0
  73. data/lib/whois/parsers/whois.dns.pt.rb +77 -0
  74. data/lib/whois/parsers/whois.domain-registry.nl.rb +123 -0
  75. data/lib/whois/parsers/whois.domain.kg.rb +76 -0
  76. data/lib/whois/parsers/whois.domainregistry.ie.rb +121 -0
  77. data/lib/whois/parsers/whois.domreg.lt.rb +68 -0
  78. data/lib/whois/parsers/whois.donuts.co.rb +61 -0
  79. data/lib/whois/parsers/whois.dot.cf.rb +71 -0
  80. data/lib/whois/parsers/whois.dot.tk.rb +70 -0
  81. data/lib/whois/parsers/whois.dotgov.gov.rb +61 -0
  82. data/lib/whois/parsers/whois.dotmobiregistry.net.rb +21 -0
  83. data/lib/whois/parsers/whois.dotpostregistry.net.rb +25 -0
  84. data/lib/whois/parsers/whois.dreamhost.com.rb +23 -0
  85. data/lib/whois/parsers/whois.educause.edu.rb +200 -0
  86. data/lib/whois/parsers/whois.eenet.ee.rb +72 -0
  87. data/lib/whois/parsers/whois.enom.com.rb +34 -0
  88. data/lib/whois/parsers/whois.eu.org.rb +58 -0
  89. data/lib/whois/parsers/whois.eu.rb +130 -0
  90. data/lib/whois/parsers/whois.fi.rb +117 -0
  91. data/lib/whois/parsers/whois.gandi.net.rb +30 -0
  92. data/lib/whois/parsers/whois.gg.rb +31 -0
  93. data/lib/whois/parsers/whois.godaddy.com.rb +112 -0
  94. data/lib/whois/parsers/whois.gov.za.rb +60 -0
  95. data/lib/whois/parsers/whois.hkirc.hk.rb +70 -0
  96. data/lib/whois/parsers/whois.iana.org.rb +102 -0
  97. data/lib/whois/parsers/whois.iis.nu.rb +26 -0
  98. data/lib/whois/parsers/whois.iis.se.rb +26 -0
  99. data/lib/whois/parsers/whois.in.ua.rb +75 -0
  100. data/lib/whois/parsers/whois.inregistry.net.rb +27 -0
  101. data/lib/whois/parsers/whois.isnic.is.rb +70 -0
  102. data/lib/whois/parsers/whois.isoc.org.il.rb +75 -0
  103. data/lib/whois/parsers/whois.ja.net.rb +75 -0
  104. data/lib/whois/parsers/whois.je.rb +25 -0
  105. data/lib/whois/parsers/whois.jprs.jp.rb +103 -0
  106. data/lib/whois/parsers/whois.kenic.or.ke.rb +91 -0
  107. data/lib/whois/parsers/whois.kr.rb +79 -0
  108. data/lib/whois/parsers/whois.markmonitor.com.rb +36 -0
  109. data/lib/whois/parsers/whois.monic.mo.rb +83 -0
  110. data/lib/whois/parsers/whois.museum.rb +79 -0
  111. data/lib/whois/parsers/whois.mynic.my.rb +72 -0
  112. data/lib/whois/parsers/whois.na-nic.com.na.rb +21 -0
  113. data/lib/whois/parsers/whois.nc.rb +122 -0
  114. data/lib/whois/parsers/whois.netcom.cm.rb +26 -0
  115. data/lib/whois/parsers/whois.networksolutions.com.rb +37 -0
  116. data/lib/whois/parsers/whois.nic.ac.rb +25 -0
  117. data/lib/whois/parsers/whois.nic.af.rb +25 -0
  118. data/lib/whois/parsers/whois.nic.ag.rb +21 -0
  119. data/lib/whois/parsers/whois.nic.as.rb +63 -0
  120. data/lib/whois/parsers/whois.nic.asia.rb +107 -0
  121. data/lib/whois/parsers/whois.nic.at.rb +64 -0
  122. data/lib/whois/parsers/whois.nic.bj.rb +126 -0
  123. data/lib/whois/parsers/whois.nic.bo.rb +73 -0
  124. data/lib/whois/parsers/whois.nic.cd.rb +34 -0
  125. data/lib/whois/parsers/whois.nic.ch.rb +109 -0
  126. data/lib/whois/parsers/whois.nic.ci.rb +70 -0
  127. data/lib/whois/parsers/whois.nic.cl.rb +71 -0
  128. data/lib/whois/parsers/whois.nic.co.rb +25 -0
  129. data/lib/whois/parsers/whois.nic.college.rb +25 -0
  130. data/lib/whois/parsers/whois.nic.coop.rb +70 -0
  131. data/lib/whois/parsers/whois.nic.cx.rb +25 -0
  132. data/lib/whois/parsers/whois.nic.cz.rb +42 -0
  133. data/lib/whois/parsers/whois.nic.design.rb +25 -0
  134. data/lib/whois/parsers/whois.nic.dm.rb +25 -0
  135. data/lib/whois/parsers/whois.nic.dz.rb +58 -0
  136. data/lib/whois/parsers/whois.nic.ec.rb +34 -0
  137. data/lib/whois/parsers/whois.nic.es.rb +105 -0
  138. data/lib/whois/parsers/whois.nic.fo.rb +43 -0
  139. data/lib/whois/parsers/whois.nic.fr.rb +25 -0
  140. data/lib/whois/parsers/whois.nic.gd.rb +31 -0
  141. data/lib/whois/parsers/whois.nic.gl.rb +25 -0
  142. data/lib/whois/parsers/whois.nic.gs.rb +31 -0
  143. data/lib/whois/parsers/whois.nic.hn.rb +25 -0
  144. data/lib/whois/parsers/whois.nic.ht.rb +25 -0
  145. data/lib/whois/parsers/whois.nic.hu.rb +78 -0
  146. data/lib/whois/parsers/whois.nic.im.rb +66 -0
  147. data/lib/whois/parsers/whois.nic.io.rb +48 -0
  148. data/lib/whois/parsers/whois.nic.ir.rb +66 -0
  149. data/lib/whois/parsers/whois.nic.it.rb +159 -0
  150. data/lib/whois/parsers/whois.nic.jobs.rb +25 -0
  151. data/lib/whois/parsers/whois.nic.ki.rb +25 -0
  152. data/lib/whois/parsers/whois.nic.kz.rb +67 -0
  153. data/lib/whois/parsers/whois.nic.la.rb +25 -0
  154. data/lib/whois/parsers/whois.nic.li.rb +64 -0
  155. data/lib/whois/parsers/whois.nic.lk.rb +109 -0
  156. data/lib/whois/parsers/whois.nic.lv.rb +65 -0
  157. data/lib/whois/parsers/whois.nic.ly.rb +76 -0
  158. data/lib/whois/parsers/whois.nic.md.rb +94 -0
  159. data/lib/whois/parsers/whois.nic.me.rb +85 -0
  160. data/lib/whois/parsers/whois.nic.mg.rb +31 -0
  161. data/lib/whois/parsers/whois.nic.ms.rb +25 -0
  162. data/lib/whois/parsers/whois.nic.mu.rb +25 -0
  163. data/lib/whois/parsers/whois.nic.mx.rb +79 -0
  164. data/lib/whois/parsers/whois.nic.name.rb +68 -0
  165. data/lib/whois/parsers/whois.nic.net.ng.rb +27 -0
  166. data/lib/whois/parsers/whois.nic.net.sa.rb +70 -0
  167. data/lib/whois/parsers/whois.nic.net.sb.rb +31 -0
  168. data/lib/whois/parsers/whois.nic.nf.rb +25 -0
  169. data/lib/whois/parsers/whois.nic.org.uy.rb +75 -0
  170. data/lib/whois/parsers/whois.nic.pm.rb +25 -0
  171. data/lib/whois/parsers/whois.nic.pr.rb +84 -0
  172. data/lib/whois/parsers/whois.nic.priv.at.rb +62 -0
  173. data/lib/whois/parsers/whois.nic.pw.rb +25 -0
  174. data/lib/whois/parsers/whois.nic.re.rb +25 -0
  175. data/lib/whois/parsers/whois.nic.sh.rb +25 -0
  176. data/lib/whois/parsers/whois.nic.sl.rb +76 -0
  177. data/lib/whois/parsers/whois.nic.sm.rb +76 -0
  178. data/lib/whois/parsers/whois.nic.sn.rb +113 -0
  179. data/lib/whois/parsers/whois.nic.so.rb +70 -0
  180. data/lib/whois/parsers/whois.nic.space.rb +25 -0
  181. data/lib/whois/parsers/whois.nic.st.rb +72 -0
  182. data/lib/whois/parsers/whois.nic.tc.rb +25 -0
  183. data/lib/whois/parsers/whois.nic.tech.rb +25 -0
  184. data/lib/whois/parsers/whois.nic.tel.rb +25 -0
  185. data/lib/whois/parsers/whois.nic.tl.rb +25 -0
  186. data/lib/whois/parsers/whois.nic.tm.rb +31 -0
  187. data/lib/whois/parsers/whois.nic.tr.rb +159 -0
  188. data/lib/whois/parsers/whois.nic.travel.rb +25 -0
  189. data/lib/whois/parsers/whois.nic.uk.rb +177 -0
  190. data/lib/whois/parsers/whois.nic.us.rb +25 -0
  191. data/lib/whois/parsers/whois.nic.ve.rb +87 -0
  192. data/lib/whois/parsers/whois.nic.wf.rb +25 -0
  193. data/lib/whois/parsers/whois.nic.xxx.rb +42 -0
  194. data/lib/whois/parsers/whois.nic.xyz.rb +25 -0
  195. data/lib/whois/parsers/whois.norid.no.rb +61 -0
  196. data/lib/whois/parsers/whois.pairnic.com.rb +28 -0
  197. data/lib/whois/parsers/whois.pandi.or.id.rb +25 -0
  198. data/lib/whois/parsers/whois.pir.org.rb +90 -0
  199. data/lib/whois/parsers/whois.pnina.ps.rb +31 -0
  200. data/lib/whois/parsers/whois.register.bg.rb +83 -0
  201. data/lib/whois/parsers/whois.register.com.rb +30 -0
  202. data/lib/whois/parsers/whois.register.si.rb +73 -0
  203. data/lib/whois/parsers/whois.registre.ma.rb +63 -0
  204. data/lib/whois/parsers/whois.registro.br.rb +73 -0
  205. data/lib/whois/parsers/whois.registry.gy.rb +25 -0
  206. data/lib/whois/parsers/whois.registry.hm.rb +72 -0
  207. data/lib/whois/parsers/whois.registry.net.za.rb +139 -0
  208. data/lib/whois/parsers/whois.registry.om.rb +40 -0
  209. data/lib/whois/parsers/whois.registry.qa.rb +25 -0
  210. data/lib/whois/parsers/whois.ripe.net.rb +68 -0
  211. data/lib/whois/parsers/whois.rnids.rs.rb +134 -0
  212. data/lib/whois/parsers/whois.rotld.ro.rb +65 -0
  213. data/lib/whois/parsers/whois.rrpproxy.net.rb +32 -0
  214. data/lib/whois/parsers/whois.safenames.net.rb +48 -0
  215. data/lib/whois/parsers/whois.schlund.info.rb +34 -0
  216. data/lib/whois/parsers/whois.sgnic.sg.rb +87 -0
  217. data/lib/whois/parsers/whois.sk-nic.sk.rb +101 -0
  218. data/lib/whois/parsers/whois.smallregistry.net.rb +131 -0
  219. data/lib/whois/parsers/whois.srs.net.nz.rb +159 -0
  220. data/lib/whois/parsers/whois.sx.rb +127 -0
  221. data/lib/whois/parsers/whois.tcinet.ru.rb +114 -0
  222. data/lib/whois/parsers/whois.thnic.co.th.rb +79 -0
  223. data/lib/whois/parsers/whois.tld.ee.rb +134 -0
  224. data/lib/whois/parsers/whois.tld.sy.rb +34 -0
  225. data/lib/whois/parsers/whois.tonic.to.rb +86 -0
  226. data/lib/whois/parsers/whois.tucows.com.rb +28 -0
  227. data/lib/whois/parsers/whois.twnic.net.tw.rb +72 -0
  228. data/lib/whois/parsers/whois.tznic.or.tz.rb +25 -0
  229. data/lib/whois/parsers/whois.ua.rb +240 -0
  230. data/lib/whois/parsers/whois.udag.net.rb +28 -0
  231. data/lib/whois/parsers/whois.uniregistry.net.rb +61 -0
  232. data/lib/whois/parsers/whois.usp.ac.fj.rb +72 -0
  233. data/lib/whois/parsers/whois.verisign-grs.com.rb +49 -0
  234. data/lib/whois/parsers/whois.website.ws.rb +74 -0
  235. data/lib/whois/parsers/whois.wildwestdomains.com.rb +37 -0
  236. data/lib/whois/parsers/whois.yoursrs.com.rb +125 -0
  237. data/lib/whois/parsers/whois.za.net.rb +72 -0
  238. data/lib/whois/parsers/whois.za.org.rb +72 -0
  239. data/lib/whois/parsers/whois1.nic.bi.rb +25 -0
  240. data/lib/whois/parsers/za_central_registry.rb +68 -0
  241. data/lib/whois/parsers.rb +4 -0
  242. data/lib/whois/safe_record.rb +169 -0
  243. data/lib/whois/scanners/base.rb +116 -0
  244. data/lib/whois/scanners/base_afilias.rb +51 -0
  245. data/lib/whois/scanners/base_cocca2.rb +43 -0
  246. data/lib/whois/scanners/base_icann_compliant.rb +45 -0
  247. data/lib/whois/scanners/base_iisse.rb +36 -0
  248. data/lib/whois/scanners/base_shared1.rb +31 -0
  249. data/lib/whois/scanners/base_shared2.rb +35 -0
  250. data/lib/whois/scanners/base_shared3.rb +37 -0
  251. data/lib/whois/scanners/base_whoisd.rb +44 -0
  252. data/lib/whois/scanners/iana.rb +89 -0
  253. data/lib/whois/scanners/scannable.rb +65 -0
  254. data/lib/whois/scanners/verisign.rb +100 -0
  255. data/lib/whois/scanners/whois.ati.tn.rb +32 -0
  256. data/lib/whois/scanners/whois.audns.net.au.rb +25 -0
  257. data/lib/whois/scanners/whois.cctld.by.rb +35 -0
  258. data/lib/whois/scanners/whois.centralnic.com.rb +32 -0
  259. data/lib/whois/scanners/whois.cira.ca.rb +72 -0
  260. data/lib/whois/scanners/whois.cnnic.cn.rb +42 -0
  261. data/lib/whois/scanners/whois.denic.de.rb +96 -0
  262. data/lib/whois/scanners/whois.dns.hr.rb +25 -0
  263. data/lib/whois/scanners/whois.domainregistry.ie.rb +46 -0
  264. data/lib/whois/scanners/whois.fi.rb +39 -0
  265. data/lib/whois/scanners/whois.nc.rb +32 -0
  266. data/lib/whois/scanners/whois.nic.cz.rb +22 -0
  267. data/lib/whois/scanners/whois.nic.it.rb +92 -0
  268. data/lib/whois/scanners/whois.pir.org.rb +17 -0
  269. data/lib/whois/scanners/whois.registry.net.za.rb +92 -0
  270. data/lib/whois/scanners/whois.rnids.rs.rb +52 -0
  271. data/lib/whois/scanners/whois.smallregistry.net.rb +50 -0
  272. data/lib/whois/scanners/whois.srs.net.nz.rb +23 -0
  273. data/lib/whois/scanners/whois.sx.rb +37 -0
  274. data/lib/whois/scanners/whois.tld.ee.rb +47 -0
  275. data/lib/whois/scanners/whois.tucows.com.rb +23 -0
  276. data/lib/whois/scanners/whois.yoursrs.com.rb +24 -0
  277. data/lib/whois-parser.rb +10 -0
  278. data/whois-parser.gemspec +37 -19
  279. metadata +318 -20
  280. data/.gitignore +0 -14
  281. data/Gemfile +0 -4
  282. data/Rakefile +0 -2
data/lib/whois/parser.rb CHANGED
@@ -1,7 +1,411 @@
1
- require "whois/parser/version"
1
+ #--
2
+ # Ruby Whois
3
+ #
4
+ # An intelligent pure Ruby WHOIS client and parser.
5
+ #
6
+ # Copyright (c) 2009-2015 Simone Carletti <weppos@weppos.net>
7
+ #++
2
8
 
9
+
10
+ require 'whois'
11
+ require 'active_support/core_ext/array/extract_options'
12
+ require 'active_support/core_ext/array/wrap'
13
+ require 'active_support/core_ext/class/attribute'
14
+ require 'active_support/core_ext/kernel/singleton_class'
15
+ require 'active_support/core_ext/object/blank'
16
+ require 'active_support/core_ext/time/calculations'
17
+ require_relative 'parser/version'
18
+ require_relative 'parser/errors'
19
+ require_relative 'parsers'
20
+
21
+
22
+ # The parsing controller that stays behind the {Whois::Record}.
23
+ #
24
+ # It provides object-oriented access to a WHOIS response.
25
+ # The list of properties and methods is available
26
+ # in the following constants:
27
+ #
28
+ # * {Whois::Parser::METHODS}
29
+ # * {Whois::Parser::PROPERTIES}
30
+ #
3
31
  module Whois
4
- module Parser
5
- # Your code goes here...
32
+ class Parser
33
+
34
+ METHODS = [
35
+ :contacts,
36
+ :changed?, :unchanged?,
37
+ # :response_incomplete?, :response_throttled?, :response_unavailable?,
38
+ # :referral_whois, :referral_url,
39
+ ]
40
+
41
+ PROPERTIES = [
42
+ :disclaimer,
43
+ :domain, :domain_id,
44
+ :status, :available?, :registered?,
45
+ :created_on, :updated_on, :expires_on,
46
+ :registrar,
47
+ :registrant_contacts, :admin_contacts, :technical_contacts,
48
+ :nameservers,
49
+ ]
50
+
51
+ PROPERTY_STATE_NOT_IMPLEMENTED = :not_implemented
52
+ PROPERTY_STATE_NOT_SUPPORTED = :not_supported
53
+ PROPERTY_STATE_SUPPORTED = :supported
54
+
55
+
56
+ # Returns the proper parser instance for given <tt>part</tt>.
57
+ # The parser class is selected according to the
58
+ # value of the <tt>#host</tt> attribute for given <tt>part</tt>.
59
+ #
60
+ # @param [Whois::Record::Part] part The part to get the parser for.
61
+ #
62
+ # @return [Whois::Parsers::Base]
63
+ # An instance of the specific parser for given part.
64
+ # The instance is expected to be a child of {Whois::Parsers::Base}.
65
+ #
66
+ # @example
67
+ #
68
+ # # Parser for a known host
69
+ # Parser.parser_for("whois.example.com")
70
+ # # => #<Whois::Parsers::WhoisExampleCom>
71
+ #
72
+ # # Parser for an unknown host
73
+ # Parser.parser_for("missing.example.com")
74
+ # # => #<Whois::Parsers::Blank>
75
+ #
76
+ def self.parser_for(part)
77
+ parser_klass(part.host).new(part)
78
+ rescue LoadError
79
+ Parsers.const_defined?("Blank") || autoload("blank")
80
+ Parsers::Blank.new(part)
81
+ end
82
+
83
+ # Detects the proper parser class according to given <tt>host</tt>
84
+ # and returns the class constant.
85
+ #
86
+ # This method autoloads missing parser classes. If you want to define
87
+ # a custom parser, simple make sure the class is loaded in the Ruby
88
+ # environment before this method is called.
89
+ #
90
+ # @param [String] host The server host.
91
+ #
92
+ # @return [Class] The instance of Class representing the parser Class
93
+ # corresponding to <tt>host</tt>. If <tt>host</tt> doesn't have
94
+ # a specific parser implementation, then returns
95
+ # the {Whois::Parsers::Blank} {Class}.
96
+ # The {Class} is expected to be a child of {Whois::Parsers::Base}.
97
+ # @raises LoadError If the class is not found.
98
+ #
99
+ # @example
100
+ #
101
+ # Parser.parser_klass("whois.example.com")
102
+ # # => Whois::Parsers::WhoisExampleCom
103
+ #
104
+ def self.parser_klass(host)
105
+ name = host_to_parser(host)
106
+ Parsers.const_defined?(name) || autoload(host)
107
+ Parsers.const_get(name)
108
+ end
109
+
110
+ # Converts <tt>host</tt> to the corresponding parser class name.
111
+ #
112
+ # @param [String] host The server host.
113
+ # @return [String] The class name.
114
+ #
115
+ # @example
116
+ #
117
+ # Parser.host_to_parser("whois.nic.it")
118
+ # # => "WhoisNicIt"
119
+ #
120
+ # Parser.host_to_parser("whois.nic-info.it")
121
+ # # => "WhoisNicInfoIt"
122
+ #
123
+ def self.host_to_parser(host)
124
+ host.to_s.downcase.
125
+ gsub(/[.-]/, '_').
126
+ gsub(/(?:^|_)(.)/) { $1.upcase }.
127
+ gsub(/\A(\d+)\z/) { "Host#{$1}" }
128
+ end
129
+
130
+ # Requires the file at <tt>whois/parsers/#{name}</tt>.
131
+ #
132
+ # @param [String] name The file name to load.
133
+ #
134
+ # @return [void]
135
+ #
136
+ def self.autoload(name)
137
+ require "whois/parsers/#{name}"
138
+ end
139
+
140
+
141
+ # @return [Whois::Record] The record referenced by this parser.
142
+ attr_reader :record
143
+
144
+
145
+ # Initializes and return a new parser from +record+.
146
+ #
147
+ # @param [Whois::Record] record
148
+ #
149
+ def initialize(record)
150
+ @record = record
151
+ end
152
+
153
+ # Checks if this class respond to given method.
154
+ #
155
+ # Overrides the default implementation to add support
156
+ # for {PROPERTIES} and {METHODS}.
157
+ #
158
+ # @return [Boolean]
159
+ def respond_to?(symbol, include_private = false)
160
+ respond_to_parser_method?(symbol) || super
161
+ end
162
+
163
+
164
+ # Returns an array with all host-specific parsers initialized for the parts
165
+ # contained into this parser.
166
+ # The array is lazy-initialized.
167
+ #
168
+ # @return [Array<Whois::Parsers::Base>]
169
+ #
170
+ def parsers
171
+ @parsers ||= init_parsers
172
+ end
173
+
174
+ # Checks if the <tt>property</tt> passed as symbol
175
+ # is supported in any of the parsers.
176
+ #
177
+ # @return [Boolean]
178
+ #
179
+ # @see Whois::Parsers::Base.property_supported?
180
+ #
181
+ def property_any_supported?(property)
182
+ parsers.any? { |parser| parser.property_supported?(property) }
183
+ end
184
+
185
+ # Checks if the <tt>property</tt> passed as symbol
186
+ # is "not implemented" in any of the parsers.
187
+ #
188
+ # @return [Boolean]
189
+ #
190
+ def property_any_not_implemented?(property)
191
+ parsers.any? { |parser| parser.class.property_state?(property, Whois::Parser::PROPERTY_STATE_NOT_IMPLEMENTED) }
192
+ end
193
+
194
+
195
+ # @!group Methods
196
+
197
+ # Collects and returns all the contacts from all the record parts.
198
+ #
199
+ # @return [Array<Whois::Record::Contact>]
200
+ #
201
+ # @see Whois::Record#contacts
202
+ # @see Whois::Parsers::Base#contacts
203
+ #
204
+ def contacts
205
+ parsers.map(&:contacts).flatten
206
+ end
207
+
208
+ # @!endgroup
209
+
210
+
211
+ # @!group Response
212
+
213
+ # Loop through all the record parts to check
214
+ # if at least one part changed.
215
+ #
216
+ # @param [Whois::Parser] other The other parser instance to compare.
217
+ # @return [Boolean]
218
+ #
219
+ # @see Whois::Record#changed?
220
+ # @see Whois::Parsers::Base#changed?
221
+ #
222
+ def changed?(other)
223
+ !unchanged?(other)
224
+ end
225
+
226
+ # The opposite of {#changed?}.
227
+ #
228
+ # @param [Whois::Parser] other The other parser instance to compare.
229
+ # @return [Boolean]
230
+ #
231
+ # @see Whois::Record#unchanged?
232
+ # @see Whois::Parsers::Base#unchanged?
233
+ #
234
+ def unchanged?(other)
235
+ unless other.is_a?(self.class)
236
+ raise(ArgumentError, "Can't compare `#{self.class}' with `#{other.class}'")
237
+ end
238
+
239
+ equal?(other) ||
240
+ parsers.size == other.parsers.size && all_in_parallel?(parsers, other.parsers) { |one, two| one.unchanged?(two) }
241
+ end
242
+
243
+
244
+ # Loop through all the parts to check if at least
245
+ # one part is an incomplete response.
246
+ #
247
+ # @return [Boolean]
248
+ #
249
+ # @see Whois::Record#response_incomplete?
250
+ # @see Whois::Parsers::Base#response_incomplete?
251
+ #
252
+ def response_incomplete?
253
+ any_is?(parsers, :response_incomplete?)
254
+ end
255
+
256
+ # Loop through all the parts to check if at least
257
+ # one part is a throttle response.
258
+ #
259
+ # @return [Boolean]
260
+ #
261
+ # @see Whois::Record#response_throttled?
262
+ # @see Whois::Parsers::Base#response_throttled?
263
+ #
264
+ def response_throttled?
265
+ any_is?(parsers, :response_throttled?)
266
+ end
267
+
268
+ # Loop through all the parts to check if at least
269
+ # one part is an unavailable response.
270
+ #
271
+ # @return [Boolean]
272
+ #
273
+ # @see Whois::Record#response_unavailable?
274
+ # @see Whois::Parsers::Base#response_unavailable?
275
+ #
276
+ def response_unavailable?
277
+ any_is?(parsers, :response_unavailable?)
278
+ end
279
+
280
+ # @!endgroup
281
+
282
+
283
+ private
284
+
285
+ # @api private
286
+ def self.define_property_method(method)
287
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
288
+ def #{method}(*args, &block)
289
+ delegate_property_to_parsers(:#{method}, *args, &block)
290
+ end
291
+ RUBY
292
+ end
293
+
294
+ # @api private
295
+ def self.define_method_method(method)
296
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
297
+ def #{method}(*args, &block)
298
+ delegate_method_to_parsers(:#{method}, *args, &block)
299
+ end
300
+ RUBY
301
+ end
302
+
303
+ def respond_to_parser_method?(symbol)
304
+ PROPERTIES.include?(symbol) || METHODS.include?(symbol)
305
+ end
306
+
307
+ def method_missing(method, *args, &block)
308
+ if PROPERTIES.include?(method)
309
+ self.class.define_property_method(method)
310
+ send(method, *args, &block)
311
+ elsif METHODS.include?(method)
312
+ self.class.define_method_method(method)
313
+ send(method, *args, &block)
314
+ else
315
+ super
316
+ end
317
+ end
318
+
319
+ def delegate_property_to_parsers(method, *args, &block)
320
+ if parsers.empty?
321
+ raise ParserError, "Unable to select a parser because the Record is empty"
322
+ elsif (parser = select_parser { |p| p.class.property_state?(method, PROPERTY_STATE_SUPPORTED) })
323
+ parser.send(method, *args, &block)
324
+ elsif (parser = select_parser { |p| p.class.property_state?(method, PROPERTY_STATE_NOT_SUPPORTED) })
325
+ parser.send(method, *args, &block)
326
+ else
327
+ raise AttributeNotImplemented, "Unable to find a parser for property `#{method}'"
328
+ end
329
+ end
330
+
331
+ def delegate_method_to_parsers(method, *args, &block)
332
+ if parsers.empty?
333
+ raise ParserError, "Unable to select a parser because the Record is empty"
334
+ elsif (parser = select_parser { |p| p.respond_to?(method) })
335
+ parser.send(method, *args, &block)
336
+ else
337
+ nil
338
+ end
339
+ end
340
+
341
+ # Loops through all record parts, for each part
342
+ # tries to guess the appropriate parser object whenever available,
343
+ # and returns the final array of server-specific parsers.
344
+ #
345
+ # Parsers are initialized in reverse order for performance reason.
346
+ #
347
+ # @return [Array<Class>] An array of Class,
348
+ # where each item is the parts reverse-N specific parser {Class}.
349
+ # Each {Class} is expected to be a child of {Whois::Parsers::Base}.
350
+ #
351
+ # @example
352
+ #
353
+ # parser.parts
354
+ # # => [whois.foo.com, whois.bar.com]
355
+ #
356
+ # parser.parsers
357
+ # # => [Whois::Parsers::WhoisBarCom, Whois::Parsers::WhoisFooCom]
358
+ #
359
+ # @api private
360
+ def init_parsers
361
+ record.parts.reverse.map { |part| self.class.parser_for(part) }
362
+ end
363
+
364
+ # Selects the first parser in {#parsers} where blocks evaluates to true.
365
+ #
366
+ # @return [Whois::Parsers::Base]
367
+ # The parser for which the block returns true.
368
+ # @return [nil]
369
+ # If the parser wasn't found.
370
+ #
371
+ # @yield [parser]
372
+ #
373
+ # @example
374
+ #
375
+ # select_parser { |parser| parser.class.property_state?(:nameserver, :any) }
376
+ # # => #<Whois::Parsers::WhoisExampleCom>
377
+ # select_parser { |parser| parser.class.property_state?(:nameservers, PROPERTY_STATE_SUPPORTED) }
378
+ # # => nil
379
+ #
380
+ # @api private
381
+ def select_parser(&block)
382
+ parsers.each do |parser|
383
+ return parser if block.call(parser)
384
+ end
385
+ nil
386
+ end
387
+
388
+ # @api private
389
+ def all_in_parallel?(*args)
390
+ count = args.first.size
391
+ index = 0
392
+
393
+ while index < count
394
+ return false unless yield(*args.map { |arg| arg[index] })
395
+ index += 1
396
+ end
397
+ true
398
+ end
399
+
400
+ # @api private
401
+ def any_is?(collection, symbol)
402
+ collection.any? { |item| item.is(symbol) }
403
+ end
404
+
6
405
  end
7
406
  end
407
+
408
+ require_relative 'parsers'
409
+ require_relative 'parsers/base'
410
+ require_relative 'parser_extensions'
411
+
@@ -0,0 +1,78 @@
1
+ require 'whois'
2
+
3
+
4
+ module Whois
5
+ class ParserExtensions
6
+
7
+ module Whois
8
+ def self.included(base)
9
+ base.extend ClassMethods
10
+ end
11
+
12
+ module ClassMethods
13
+ # Checks whether the object represented by <tt>object</tt> is available.
14
+ #
15
+ # Warning: this method is only available if a Whois parser exists
16
+ # for the top level domain of <tt>object</tt>.
17
+ # If no parser exists for <tt>object</tt>, you'll receive a
18
+ # warning message and the method will return <tt>nil</tt>.
19
+ # This is a technical limitation. Browse the lib/whois/record/parsers
20
+ # folder to view all available parsers.
21
+ #
22
+ # @param [String] object The string to be sent as query parameter.
23
+ # It is intended to be a domain name, otherwise this method
24
+ # may return unexpected responses.
25
+ # @return [Boolean]
26
+ #
27
+ # @example
28
+ # Whois.available?("google.com")
29
+ # # => false
30
+ #
31
+ # @example
32
+ # Whois.available?("google-is-not-available-try-again-later.com")
33
+ # # => true
34
+ #
35
+ def available?(object)
36
+ result = lookup(object).available?
37
+ if result.nil?
38
+ warn "This method is not supported for this kind of object.\n" +
39
+ "Use Whois.lookup('#{object}') instead."
40
+ end
41
+ result
42
+ end
43
+
44
+ # Checks whether the object represented by <tt>object</tt> is registered.
45
+ #
46
+ # Warning: this method is only available if a Whois parser exists
47
+ # for the top level domain of <tt>object</tt>.
48
+ # If no parser exists for <tt>object</tt>, you'll receive a warning message
49
+ # and the method will return <tt>nil</tt>.
50
+ # This is a technical limitation. Browse the lib/whois/record/parsers folder
51
+ # to view all available parsers.
52
+ #
53
+ # @param [String] object The string to be sent as query parameter.
54
+ # It is intended to be a domain name, otherwise this method
55
+ # may return unexpected responses.
56
+ # @return [Boolean]
57
+ #
58
+ # @example
59
+ # Whois.registered?("google.com")
60
+ # # => true
61
+ #
62
+ # @example
63
+ # Whois.registered?("google-is-not-available-try-again-later.com")
64
+ # # => false
65
+ #
66
+ def registered?(object)
67
+ result = lookup(object).registered?
68
+ if result.nil?
69
+ warn "This method is not supported for this kind of object.\n" +
70
+ "Use Whois.lookup('#{object}') instead."
71
+ end
72
+ result
73
+ end
74
+ end
75
+ end
76
+
77
+ end
78
+ end
@@ -0,0 +1,222 @@
1
+ require 'whois'
2
+
3
+
4
+ module Whois
5
+ class ParserExtensions
6
+
7
+ module WhoisRecord
8
+ def self.included(base)
9
+ base.extend ClassMethods
10
+ end
11
+
12
+ # Checks if this class respond to given method.
13
+ #
14
+ # Overrides the default implementation to add support
15
+ # for {Parser::PROPERTIES} and {Parser::METHODS}.
16
+ #
17
+ # @return [Boolean]
18
+ def respond_to?(symbol, include_private = false)
19
+ respond_to_parser_method?(symbol) || super
20
+ end
21
+
22
+
23
+ # Lazy-loads and returns the parser proxy for current record.
24
+ #
25
+ # @return [Whois::Record::Parser]
26
+ def parser
27
+ @parser ||= Parser.new(self)
28
+ end
29
+
30
+ # Returns a Hash containing all supported properties for this record
31
+ # along with corresponding values.
32
+ #
33
+ # @return [{ Symbol => Object }]
34
+ # @raise [Whois::AttributeNotSupported, Whois::AttributeNotImplemented]
35
+ def properties
36
+ warn("#{self.class}#properties is deprecated")
37
+ hash = {}
38
+ Parser::PROPERTIES.each { |property| hash[property] = send(property) }
39
+ hash
40
+ end
41
+
42
+ # Shortcut for <tt>#registrant_contacts.first</tt>.
43
+ #
44
+ # @see Whois::Record#registrant_contacts
45
+ #
46
+ # @return [Whois::Record::Contact]
47
+ # If the property is supported and a contact exists.
48
+ # @return [nil]
49
+ # If the the contact doesn't exist.
50
+ # @raise [Whois::AttributeNotSupported, Whois::AttributeNotImplemented]
51
+ def registrant_contact
52
+ parser.registrant_contacts.first
53
+ end
54
+
55
+ # Shortcut for <tt>#admin_contacts.first</tt>.
56
+ #
57
+ # @see Whois::Record#admin_contacts
58
+ #
59
+ # @return [Whois::Record::Contact]
60
+ # If the property is supported and a contact exists.
61
+ # @return [nil]
62
+ # If the contact doesn't exist.
63
+ # @raise [Whois::AttributeNotSupported, Whois::AttributeNotImplemented]
64
+ def admin_contact
65
+ parser.admin_contacts.first
66
+ end
67
+
68
+ # Shortcut for <tt>#technical_contacts.first</tt>.
69
+ #
70
+ # @see Whois::Record#technical_contacts
71
+ #
72
+ # @return [Whois::Record::Contact]
73
+ # If the property is supported and a contact exists.
74
+ # @return [nil]
75
+ # If the contact doesn't exist.
76
+ # @raise [Whois::AttributeNotSupported, Whois::AttributeNotImplemented]
77
+ def technical_contact
78
+ parser.technical_contacts.first
79
+ end
80
+
81
+ # Collects and returns all the contacts.
82
+ #
83
+ # @see Whois::Parser#contacts
84
+ #
85
+ # @return [Array<Whois::Record::Contact>]
86
+ def contacts
87
+ warn("#{self.class}#contacts is deprecated")
88
+ parser.contacts
89
+ end
90
+
91
+
92
+ # Checks whether this {Whois::Record} is different than +other+.
93
+ #
94
+ # Comparing the {Whois::Record} content is not as trivial as you may think.
95
+ # WHOIS servers can inject into the WHOIS response strings that changes at every request,
96
+ # such as the timestamp the request was generated or the number of requests left
97
+ # for your current IP.
98
+ #
99
+ # These strings causes a simple equal comparison to fail even if
100
+ # the registry data is the same.
101
+ #
102
+ # This method should provide a bulletproof way to detect whether this record
103
+ # changed compared with +other+.
104
+ #
105
+ # @see Whois::Parser#changed?
106
+ #
107
+ # @param [Whois::Record] other The other record instance to compare.
108
+ # @return [Boolean]
109
+ def changed?(other)
110
+ !unchanged?(other)
111
+ end
112
+
113
+ # The opposite of {#changed?}.
114
+ #
115
+ # @see Whois::Parser#unchanged?
116
+ #
117
+ # @param [Whois::Record] other The other record instance to compare.
118
+ # @return [Boolean]
119
+ def unchanged?(other)
120
+ unless other.is_a?(self.class)
121
+ raise(ArgumentError, "Can't compare `#{self.class}' with `#{other.class}'")
122
+ end
123
+
124
+ equal?(other) || parser.unchanged?(other.parser)
125
+ end
126
+
127
+ # Checks whether this is an incomplete response.
128
+ #
129
+ # @deprecated
130
+ # @see Whois::Parser#response_incomplete?
131
+ #
132
+ # @return [Boolean]
133
+ def response_incomplete?
134
+ warn("#{self.class}#response_incomplete? is deprecated. Use parser.response_incomplete?")
135
+ parser.response_incomplete?
136
+ end
137
+
138
+ # Checks whether this is a throttle response.
139
+ #
140
+ # @deprecated
141
+ # @see Whois::Parser#response_throttled?
142
+ #
143
+ # @return [Boolean]
144
+ def response_throttled?
145
+ warn("#{self.class}#response_throttled? is deprecated. Use parser.response_throttled?")
146
+ parser.response_throttled?
147
+ end
148
+
149
+ # Checks whether this is an unavailable response.
150
+ #
151
+ # @deprecated
152
+ # @see Whois::Parser#response_unavailable?
153
+ #
154
+ # @return [Boolean]
155
+ def response_unavailable?
156
+ warn("#{self.class}#response_unavailable? is deprecated. Use parser.response_unavailable?")
157
+ parser.response_unavailable?
158
+ end
159
+
160
+
161
+ # @deprecated
162
+ def property_any_supported?(property)
163
+ warn("#{self.class}#property_any_supported? is deprecated and has no effect. Use Whois::Parser.property_any_supported? if you need it.")
164
+ end
165
+
166
+
167
+ private
168
+
169
+ # @api private
170
+ def respond_to_parser_method?(symbol)
171
+ name = symbol.to_s =~ /\?$/ ? symbol.to_s[0..-2] : symbol
172
+ Parser::PROPERTIES.include?(name.to_sym) || Parser::METHODS.include?(name.to_sym)
173
+ end
174
+
175
+ # Delegates all method calls to the internal parser.
176
+ def method_missing(method, *args, &block)
177
+ if Parser::PROPERTIES.include?(method)
178
+ self.class.define_property_method(method)
179
+ send(method, *args, &block)
180
+ elsif Parser::METHODS.include?(method)
181
+ self.class.define_method_method(method)
182
+ send(method, *args, &block)
183
+ elsif method.to_s =~ /([a-z_]+)\?/ and (Parser::PROPERTIES + Parser::METHODS).include?($1.to_sym)
184
+ self.class.define_question_method($1)
185
+ send(method)
186
+ else
187
+ super
188
+ end
189
+ end
190
+
191
+ module ClassMethods
192
+ # @api private
193
+ def define_property_method(method)
194
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
195
+ def #{method}(*args, &block)
196
+ parser.#{method}(*args, &block)
197
+ end
198
+ RUBY
199
+ end
200
+
201
+ # @api private
202
+ def define_method_method(method)
203
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
204
+ def #{method}(*args, &block)
205
+ parser.#{method}(*args, &block)
206
+ end
207
+ RUBY
208
+ end
209
+
210
+ # @api private
211
+ def define_question_method(method)
212
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
213
+ def #{method}?
214
+ !#{method}.nil?
215
+ end
216
+ RUBY
217
+ end
218
+ end
219
+ end
220
+
221
+ end
222
+ end