relaton 2.2.0.pre.alpha.1 → 3.0.0.pre.alpha.2

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 (702) hide show
  1. checksums.yaml +4 -4
  2. data/{docs/README.adoc → README.adoc} +165 -38
  3. data/bin/console +0 -1
  4. data/lib/relaton/3gpp/bibdata.rb +9 -0
  5. data/lib/relaton/3gpp/bibitem.rb +9 -0
  6. data/lib/relaton/3gpp/bibliography.rb +123 -0
  7. data/lib/relaton/3gpp/data_fetcher.rb +303 -0
  8. data/lib/relaton/3gpp/docidentifier.rb +114 -0
  9. data/lib/relaton/3gpp/doctype.rb +9 -0
  10. data/lib/relaton/3gpp/ext.rb +31 -0
  11. data/lib/relaton/3gpp/item.rb +18 -0
  12. data/lib/relaton/3gpp/item_data.rb +15 -0
  13. data/lib/relaton/3gpp/parser.rb +400 -0
  14. data/lib/relaton/3gpp/processor.rb +71 -0
  15. data/lib/relaton/3gpp/release.rb +34 -0
  16. data/lib/relaton/3gpp/util.rb +8 -0
  17. data/lib/relaton/3gpp.rb +29 -0
  18. data/lib/relaton/adobe/bibdata.rb +8 -0
  19. data/lib/relaton/adobe/bibitem.rb +8 -0
  20. data/lib/relaton/adobe/bibliography.rb +92 -0
  21. data/lib/relaton/adobe/docidentifier.rb +49 -0
  22. data/lib/relaton/adobe/doctype.rb +14 -0
  23. data/lib/relaton/adobe/ext.rb +32 -0
  24. data/lib/relaton/adobe/item.rb +15 -0
  25. data/lib/relaton/adobe/item_base.rb +18 -0
  26. data/lib/relaton/adobe/item_data.rb +6 -0
  27. data/lib/relaton/adobe/processor.rb +45 -0
  28. data/lib/relaton/adobe/util.rb +8 -0
  29. data/lib/relaton/adobe.rb +37 -0
  30. data/lib/relaton/bib/converter/asciibib/to_asciibib.rb +663 -0
  31. data/lib/relaton/bib/converter/asciibib.rb +13 -0
  32. data/lib/relaton/bib/converter/bibtex/from_bibtex.rb +245 -0
  33. data/lib/relaton/bib/converter/bibtex/to_bibtex.rb +341 -0
  34. data/lib/relaton/bib/converter/bibtex.rb +23 -0
  35. data/lib/relaton/bib/converter/bibxml/from_rfcxml.rb +386 -0
  36. data/lib/relaton/bib/converter/bibxml/from_rfcxml_referencegroup.rb +71 -0
  37. data/lib/relaton/bib/converter/bibxml/to_rfcxml.rb +308 -0
  38. data/lib/relaton/bib/converter/bibxml/to_rfcxml_referencegroup.rb +52 -0
  39. data/lib/relaton/bib/converter/bibxml.rb +51 -0
  40. data/lib/relaton/bib/hash_parser_v1.rb +767 -0
  41. data/lib/relaton/bib/item_data.rb +229 -0
  42. data/lib/relaton/bib/model/abstract.rb +16 -0
  43. data/lib/relaton/bib/model/address.rb +22 -0
  44. data/lib/relaton/bib/model/affiliation.rb +16 -0
  45. data/lib/relaton/bib/model/bibdata.rb +11 -0
  46. data/lib/relaton/bib/model/bibdata_shared.rb +12 -0
  47. data/lib/relaton/bib/model/bibitem.rb +11 -0
  48. data/lib/relaton/bib/model/bibitem_shared.rb +12 -0
  49. data/lib/relaton/bib/model/contact.rb +18 -0
  50. data/lib/relaton/bib/model/contribution_info.rb +15 -0
  51. data/lib/relaton/bib/model/contributor.rb +29 -0
  52. data/lib/relaton/bib/model/copyright.rb +27 -0
  53. data/lib/relaton/bib/model/date.rb +31 -0
  54. data/lib/relaton/bib/model/depiction.rb +16 -0
  55. data/lib/relaton/bib/model/docidentifier.rb +49 -0
  56. data/lib/relaton/bib/model/doctype.rb +14 -0
  57. data/lib/relaton/bib/model/edition.rb +14 -0
  58. data/lib/relaton/bib/model/ext.rb +39 -0
  59. data/lib/relaton/bib/model/extent.rb +16 -0
  60. data/lib/relaton/bib/model/formattedref.rb +43 -0
  61. data/lib/relaton/bib/model/full_name_type.rb +64 -0
  62. data/lib/relaton/bib/model/fullname.rb +11 -0
  63. data/lib/relaton/bib/model/ics.rb +49 -0
  64. data/lib/relaton/bib/model/image.rb +28 -0
  65. data/lib/relaton/bib/model/item.rb +96 -0
  66. data/lib/relaton/bib/model/item_base.rb +20 -0
  67. data/lib/relaton/bib/model/item_shared.rb +88 -0
  68. data/lib/relaton/bib/model/keyword.rb +30 -0
  69. data/lib/relaton/bib/model/locality.rb +18 -0
  70. data/lib/relaton/bib/model/locality_stack.rb +14 -0
  71. data/lib/relaton/bib/model/localized_string.rb +48 -0
  72. data/lib/relaton/bib/model/localized_string_attrs.rb +24 -0
  73. data/lib/relaton/bib/model/logo.rb +14 -0
  74. data/lib/relaton/bib/model/medium.rb +22 -0
  75. data/lib/relaton/bib/model/note.rb +16 -0
  76. data/lib/relaton/bib/model/organization.rb +13 -0
  77. data/lib/relaton/bib/model/organization_type.rb +42 -0
  78. data/lib/relaton/bib/model/person.rb +36 -0
  79. data/lib/relaton/bib/model/phone.rb +14 -0
  80. data/lib/relaton/bib/model/place.rb +33 -0
  81. data/lib/relaton/bib/model/price.rb +14 -0
  82. data/lib/relaton/bib/model/relation.rb +43 -0
  83. data/lib/relaton/bib/model/series.rb +34 -0
  84. data/lib/relaton/bib/model/size.rb +23 -0
  85. data/lib/relaton/bib/model/source_locality_stack.rb +14 -0
  86. data/lib/relaton/bib/model/status.rb +27 -0
  87. data/lib/relaton/bib/model/structured_identifier.rb +49 -0
  88. data/lib/relaton/bib/model/subdivision.rb +16 -0
  89. data/lib/relaton/bib/model/title.rb +56 -0
  90. data/lib/relaton/bib/model/type/plain_date.rb +16 -0
  91. data/lib/relaton/bib/model/type/string_date.rb +48 -0
  92. data/lib/relaton/bib/model/uri.rb +18 -0
  93. data/lib/relaton/bib/model/validity.rb +16 -0
  94. data/lib/relaton/bib/model/version.rb +43 -0
  95. data/lib/relaton/bib/namespace_helper.rb +21 -0
  96. data/lib/relaton/bib/sanitizer.rb +264 -0
  97. data/lib/relaton/bib/util.rb +18 -0
  98. data/lib/relaton/bib/versions.json +35 -0
  99. data/lib/relaton/bib.rb +46 -0
  100. data/lib/relaton/bipm/bibliography.rb +231 -0
  101. data/lib/relaton/bipm/converter/asciibib.rb +64 -0
  102. data/lib/relaton/bipm/data_fetcher.rb +81 -0
  103. data/lib/relaton/bipm/data_outcomes_parser.rb +656 -0
  104. data/lib/relaton/bipm/id_parser.rb +278 -0
  105. data/lib/relaton/bipm/item_data.rb +47 -0
  106. data/lib/relaton/bipm/model/bibdata.rb +9 -0
  107. data/lib/relaton/bipm/model/bibitem.rb +9 -0
  108. data/lib/relaton/bipm/model/comment_period.rb +13 -0
  109. data/lib/relaton/bipm/model/doctype.rb +12 -0
  110. data/lib/relaton/bipm/model/ext.rb +38 -0
  111. data/lib/relaton/bipm/model/item.rb +11 -0
  112. data/lib/relaton/bipm/model/structured_identifier.rb +36 -0
  113. data/lib/relaton/bipm/processor.rb +69 -0
  114. data/lib/relaton/bipm/rawdata_bipm_metrologia/affiliations.rb +111 -0
  115. data/lib/relaton/bipm/rawdata_bipm_metrologia/fetcher.rb +172 -0
  116. data/lib/relaton/bipm/rawdata_bipm_metrologia/niso_jats_parser.rb +353 -0
  117. data/lib/relaton/bipm/si_brochure_parser.rb +188 -0
  118. data/lib/relaton/bipm/util.rb +8 -0
  119. data/lib/relaton/bipm.rb +38 -0
  120. data/lib/relaton/bsi/bibliography.rb +196 -0
  121. data/lib/relaton/bsi/hit.rb +28 -0
  122. data/lib/relaton/bsi/hit_collection.rb +113 -0
  123. data/lib/relaton/bsi/item_data.rb +13 -0
  124. data/lib/relaton/bsi/model/bibdata.rb +8 -0
  125. data/lib/relaton/bsi/model/bibitem.rb +8 -0
  126. data/lib/relaton/bsi/model/docidentifier.rb +107 -0
  127. data/lib/relaton/bsi/model/doctype.rb +14 -0
  128. data/lib/relaton/bsi/model/ext.rb +17 -0
  129. data/lib/relaton/bsi/model/item.rb +17 -0
  130. data/lib/relaton/bsi/model/item_base.rb +22 -0
  131. data/lib/relaton/bsi/model/relation.rb +9 -0
  132. data/lib/relaton/bsi/processor.rb +43 -0
  133. data/lib/relaton/bsi/schema.json +24882 -0
  134. data/lib/relaton/bsi/scraper.rb +288 -0
  135. data/lib/relaton/bsi/util.rb +8 -0
  136. data/lib/relaton/bsi.rb +25 -0
  137. data/lib/relaton/calconnect/bibliography.rb +93 -0
  138. data/lib/relaton/calconnect/data_fetcher.rb +174 -0
  139. data/lib/relaton/calconnect/docidentifier.rb +80 -0
  140. data/lib/relaton/calconnect/hit.rb +14 -0
  141. data/lib/relaton/calconnect/hit_collection.rb +92 -0
  142. data/lib/relaton/calconnect/item_data.rb +12 -0
  143. data/lib/relaton/calconnect/model/bibdata.rb +8 -0
  144. data/lib/relaton/calconnect/model/bibitem.rb +8 -0
  145. data/lib/relaton/calconnect/model/doctype.rb +11 -0
  146. data/lib/relaton/calconnect/model/ext.rb +11 -0
  147. data/lib/relaton/calconnect/model/item.rb +20 -0
  148. data/lib/relaton/calconnect/processor.rb +72 -0
  149. data/lib/relaton/calconnect/scraper.rb +87 -0
  150. data/lib/relaton/calconnect/util.rb +8 -0
  151. data/lib/relaton/calconnect.rb +36 -0
  152. data/lib/relaton/ccsds/bibliography.rb +63 -0
  153. data/lib/relaton/ccsds/data/fetcher.rb +252 -0
  154. data/lib/relaton/ccsds/data/iso_references.rb +30 -0
  155. data/lib/relaton/ccsds/data/parser.rb +194 -0
  156. data/lib/relaton/ccsds/hit.rb +24 -0
  157. data/lib/relaton/ccsds/hit_collection.rb +47 -0
  158. data/lib/relaton/ccsds/item_data.rb +9 -0
  159. data/lib/relaton/ccsds/model/bibdata.rb +8 -0
  160. data/lib/relaton/ccsds/model/bibitem.rb +8 -0
  161. data/lib/relaton/ccsds/model/docidentifier.rb +121 -0
  162. data/lib/relaton/ccsds/model/doctype.rb +9 -0
  163. data/lib/relaton/ccsds/model/ext.rb +19 -0
  164. data/lib/relaton/ccsds/model/item.rb +15 -0
  165. data/lib/relaton/ccsds/processor.rb +68 -0
  166. data/lib/relaton/ccsds/util.rb +10 -0
  167. data/lib/relaton/ccsds.rb +33 -0
  168. data/lib/relaton/cen/bibliography.rb +149 -0
  169. data/lib/relaton/cen/committees.yaml +66 -0
  170. data/lib/relaton/cen/hit.rb +31 -0
  171. data/lib/relaton/cen/hit_collection.rb +116 -0
  172. data/lib/relaton/cen/item_data.rb +7 -0
  173. data/lib/relaton/cen/model/bibdata.rb +8 -0
  174. data/lib/relaton/cen/model/bibitem.rb +8 -0
  175. data/lib/relaton/cen/model/docidentifier.rb +100 -0
  176. data/lib/relaton/cen/model/ext.rb +11 -0
  177. data/lib/relaton/cen/model/item.rb +14 -0
  178. data/lib/relaton/cen/model/structured_identifier.rb +9 -0
  179. data/lib/relaton/cen/processor.rb +45 -0
  180. data/lib/relaton/cen/scraper.rb +218 -0
  181. data/lib/relaton/cen/util.rb +8 -0
  182. data/lib/relaton/cen.rb +30 -0
  183. data/lib/relaton/cie/bibdata.rb +8 -0
  184. data/lib/relaton/cie/bibitem.rb +8 -0
  185. data/lib/relaton/cie/bibliography.rb +31 -0
  186. data/lib/relaton/cie/data_fetcher.rb +540 -0
  187. data/lib/relaton/cie/ext.rb +7 -0
  188. data/lib/relaton/cie/item.rb +11 -0
  189. data/lib/relaton/cie/item_data.rb +6 -0
  190. data/lib/relaton/cie/processor.rb +68 -0
  191. data/lib/relaton/cie/scrapper.rb +52 -0
  192. data/lib/relaton/cie/util.rb +8 -0
  193. data/lib/relaton/cie.rb +29 -0
  194. data/lib/relaton/core/array_wrapper.rb +20 -0
  195. data/lib/relaton/core/data_fetcher.rb +244 -0
  196. data/lib/relaton/core/date_parser.rb +42 -0
  197. data/lib/relaton/core/governor.rb +320 -0
  198. data/lib/relaton/core/hash_keys_sybolizer.rb +19 -0
  199. data/lib/relaton/core/hit.rb +49 -0
  200. data/lib/relaton/core/hit_collection.rb +118 -0
  201. data/lib/relaton/core/pacer.rb +134 -0
  202. data/lib/relaton/core/processor.rb +67 -0
  203. data/lib/relaton/core/request_error.rb +14 -0
  204. data/lib/relaton/core/workers_pool.rb +45 -0
  205. data/lib/relaton/core.rb +12 -0
  206. data/lib/relaton/db/registry.rb +44 -4
  207. data/lib/relaton/db.rb +0 -1
  208. data/lib/relaton/doi/crossref.rb +89 -0
  209. data/lib/relaton/doi/parser.rb +921 -0
  210. data/lib/relaton/doi/processor.rb +65 -0
  211. data/lib/relaton/doi/util.rb +8 -0
  212. data/lib/relaton/doi.rb +20 -0
  213. data/lib/relaton/easc/bibdata.rb +8 -0
  214. data/lib/relaton/easc/bibitem.rb +8 -0
  215. data/lib/relaton/easc/bibliography.rb +95 -0
  216. data/lib/relaton/easc/docidentifier.rb +100 -0
  217. data/lib/relaton/easc/doctype.rb +14 -0
  218. data/lib/relaton/easc/ext.rb +44 -0
  219. data/lib/relaton/easc/item.rb +13 -0
  220. data/lib/relaton/easc/item_base.rb +18 -0
  221. data/lib/relaton/easc/item_data.rb +6 -0
  222. data/lib/relaton/easc/processor.rb +46 -0
  223. data/lib/relaton/easc/util.rb +8 -0
  224. data/lib/relaton/easc.rb +35 -0
  225. data/lib/relaton/ecma/bibdata.rb +8 -0
  226. data/lib/relaton/ecma/bibitem.rb +8 -0
  227. data/lib/relaton/ecma/bibliography.rb +149 -0
  228. data/lib/relaton/ecma/data_fetcher.rb +162 -0
  229. data/lib/relaton/ecma/data_parser.rb +49 -0
  230. data/lib/relaton/ecma/docidentifier.rb +124 -0
  231. data/lib/relaton/ecma/edition_parser.rb +80 -0
  232. data/lib/relaton/ecma/ext.rb +7 -0
  233. data/lib/relaton/ecma/item.rb +13 -0
  234. data/lib/relaton/ecma/item_data.rb +6 -0
  235. data/lib/relaton/ecma/memento_parser.rb +60 -0
  236. data/lib/relaton/ecma/page_fetcher.rb +39 -0
  237. data/lib/relaton/ecma/parser_common.rb +33 -0
  238. data/lib/relaton/ecma/processor.rb +69 -0
  239. data/lib/relaton/ecma/standard_parser.rb +134 -0
  240. data/lib/relaton/ecma/util.rb +8 -0
  241. data/lib/relaton/ecma.rb +33 -0
  242. data/lib/relaton/etsi/bibdata.rb +10 -0
  243. data/lib/relaton/etsi/bibitem.rb +10 -0
  244. data/lib/relaton/etsi/bibliography.rb +111 -0
  245. data/lib/relaton/etsi/data_fetcher.rb +167 -0
  246. data/lib/relaton/etsi/data_parser.rb +208 -0
  247. data/lib/relaton/etsi/doctype.rb +30 -0
  248. data/lib/relaton/etsi/ext.rb +31 -0
  249. data/lib/relaton/etsi/item.rb +15 -0
  250. data/lib/relaton/etsi/item_data.rb +6 -0
  251. data/lib/relaton/etsi/processor.rb +71 -0
  252. data/lib/relaton/etsi/pubid.rb +37 -0
  253. data/lib/relaton/etsi/status.rb +13 -0
  254. data/lib/relaton/etsi/util.rb +8 -0
  255. data/lib/relaton/etsi.rb +26 -0
  256. data/lib/relaton/gb/bibdata.rb +8 -0
  257. data/lib/relaton/gb/bibitem.rb +8 -0
  258. data/lib/relaton/gb/bibliography.rb +171 -0
  259. data/lib/relaton/gb/ccs.rb +14 -0
  260. data/lib/relaton/gb/committee.rb +13 -0
  261. data/lib/relaton/gb/docidentifier.rb +72 -0
  262. data/lib/relaton/gb/doctype.rb +9 -0
  263. data/lib/relaton/gb/ext.rb +36 -0
  264. data/lib/relaton/gb/gb_scraper.rb +61 -0
  265. data/lib/relaton/gb/gb_type.rb +20 -0
  266. data/lib/relaton/gb/hit.rb +48 -0
  267. data/lib/relaton/gb/hit_collection.rb +19 -0
  268. data/lib/relaton/gb/item.rb +13 -0
  269. data/lib/relaton/gb/item_data.rb +6 -0
  270. data/lib/relaton/gb/processor.rb +49 -0
  271. data/lib/relaton/gb/project_number.rb +38 -0
  272. data/lib/relaton/gb/scraper.rb +221 -0
  273. data/lib/relaton/gb/sec_scraper.rb +92 -0
  274. data/lib/relaton/gb/stage_name.rb +13 -0
  275. data/lib/relaton/gb/structured_identifier.rb +26 -0
  276. data/lib/relaton/gb/t_scraper.rb +126 -0
  277. data/lib/relaton/gb/util.rb +8 -0
  278. data/lib/relaton/gb/yaml/prefixes.yaml +200 -0
  279. data/lib/relaton/gb.rb +33 -0
  280. data/lib/relaton/gost/bibdata.rb +8 -0
  281. data/lib/relaton/gost/bibitem.rb +8 -0
  282. data/lib/relaton/gost/bibliography.rb +107 -0
  283. data/lib/relaton/gost/docidentifier.rb +80 -0
  284. data/lib/relaton/gost/doctype.rb +16 -0
  285. data/lib/relaton/gost/ext.rb +46 -0
  286. data/lib/relaton/gost/item.rb +15 -0
  287. data/lib/relaton/gost/item_base.rb +18 -0
  288. data/lib/relaton/gost/item_data.rb +6 -0
  289. data/lib/relaton/gost/processor.rb +49 -0
  290. data/lib/relaton/gost/util.rb +8 -0
  291. data/lib/relaton/gost.rb +36 -0
  292. data/lib/relaton/iala/bibdata.rb +8 -0
  293. data/lib/relaton/iala/bibitem.rb +8 -0
  294. data/lib/relaton/iala/bibliography.rb +146 -0
  295. data/lib/relaton/iala/docidentifier.rb +89 -0
  296. data/lib/relaton/iala/doctype.rb +18 -0
  297. data/lib/relaton/iala/ext.rb +32 -0
  298. data/lib/relaton/iala/item.rb +21 -0
  299. data/lib/relaton/iala/item_base.rb +18 -0
  300. data/lib/relaton/iala/item_data.rb +6 -0
  301. data/lib/relaton/iala/processor.rb +43 -0
  302. data/lib/relaton/iala/relation.rb +7 -0
  303. data/lib/relaton/iala/util.rb +8 -0
  304. data/lib/relaton/iala.rb +35 -0
  305. data/lib/relaton/iana/bibdata.rb +8 -0
  306. data/lib/relaton/iana/bibitem.rb +8 -0
  307. data/lib/relaton/iana/bibliography.rb +100 -0
  308. data/lib/relaton/iana/data_fetcher.rb +101 -0
  309. data/lib/relaton/iana/item.rb +7 -0
  310. data/lib/relaton/iana/item_data.rb +6 -0
  311. data/lib/relaton/iana/parser.rb +146 -0
  312. data/lib/relaton/iana/processor.rb +70 -0
  313. data/lib/relaton/iana/util.rb +8 -0
  314. data/lib/relaton/iana.rb +40 -0
  315. data/lib/relaton/iec/bibliography.rb +283 -0
  316. data/lib/relaton/iec/data_fetcher.rb +222 -0
  317. data/lib/relaton/iec/data_parser.rb +391 -0
  318. data/lib/relaton/iec/hit.rb +26 -0
  319. data/lib/relaton/iec/hit_collection.rb +138 -0
  320. data/lib/relaton/iec/item_data.rb +7 -0
  321. data/lib/relaton/iec/model/bibdata.rb +8 -0
  322. data/lib/relaton/iec/model/bibitem.rb +8 -0
  323. data/lib/relaton/iec/model/docidentifier.rb +135 -0
  324. data/lib/relaton/iec/model/doctype.rb +12 -0
  325. data/lib/relaton/iec/model/ext.rb +53 -0
  326. data/lib/relaton/iec/model/item.rb +20 -0
  327. data/lib/relaton/iec/model/item_base.rb +12 -0
  328. data/lib/relaton/iec/model/relation.rb +7 -0
  329. data/lib/relaton/iec/model/stage_name.rb +13 -0
  330. data/lib/relaton/iec/processor.rb +74 -0
  331. data/lib/relaton/iec/statuses.yml +199 -0
  332. data/lib/relaton/iec/util.rb +8 -0
  333. data/lib/relaton/iec.rb +98 -0
  334. data/lib/relaton/ieee/balloting_group.rb +13 -0
  335. data/lib/relaton/ieee/bibdata.rb +8 -0
  336. data/lib/relaton/ieee/bibitem.rb +8 -0
  337. data/lib/relaton/ieee/bibliography.rb +73 -0
  338. data/lib/relaton/ieee/converter/bibxml/from_rfcxml.rb +10 -0
  339. data/lib/relaton/ieee/converter/bibxml/from_rfcxml_referencegroup.rb +10 -0
  340. data/lib/relaton/ieee/converter/bibxml.rb +20 -0
  341. data/lib/relaton/ieee/data_fetcher.rb +771 -0
  342. data/lib/relaton/ieee/doctype.rb +9 -0
  343. data/lib/relaton/ieee/editorial_group.rb +19 -0
  344. data/lib/relaton/ieee/ext.rb +36 -0
  345. data/lib/relaton/ieee/idams_parser.rb +330 -0
  346. data/lib/relaton/ieee/item.rb +11 -0
  347. data/lib/relaton/ieee/item_data.rb +7 -0
  348. data/lib/relaton/ieee/processor.rb +71 -0
  349. data/lib/relaton/ieee/rawbib_id_parser.rb +753 -0
  350. data/lib/relaton/ieee/util.rb +8 -0
  351. data/lib/relaton/ieee.rb +30 -0
  352. data/lib/relaton/ietf/bibdata.rb +8 -0
  353. data/lib/relaton/ietf/bibitem.rb +8 -0
  354. data/lib/relaton/ietf/bibliography.rb +35 -0
  355. data/lib/relaton/ietf/bibxml_parser.rb +232 -0
  356. data/lib/relaton/ietf/data_fetcher.rb +561 -0
  357. data/lib/relaton/ietf/doctype.rb +9 -0
  358. data/lib/relaton/ietf/ext.rb +63 -0
  359. data/lib/relaton/ietf/item.rb +16 -0
  360. data/lib/relaton/ietf/item_base.rb +18 -0
  361. data/lib/relaton/ietf/item_data.rb +6 -0
  362. data/lib/relaton/ietf/processing_instructions.rb +79 -0
  363. data/lib/relaton/ietf/processor.rb +72 -0
  364. data/lib/relaton/ietf/relation.rb +9 -0
  365. data/lib/relaton/ietf/rfc/abstract.rb +19 -0
  366. data/lib/relaton/ietf/rfc/author.rb +21 -0
  367. data/lib/relaton/ietf/rfc/entry.rb +446 -0
  368. data/lib/relaton/ietf/rfc/entry_date.rb +21 -0
  369. data/lib/relaton/ietf/rfc/format.rb +19 -0
  370. data/lib/relaton/ietf/rfc/index.rb +46 -0
  371. data/lib/relaton/ietf/rfc/is_also.rb +21 -0
  372. data/lib/relaton/ietf/rfc/keywords.rb +19 -0
  373. data/lib/relaton/ietf/rfc/rfc_index_namespace.rb +11 -0
  374. data/lib/relaton/ietf/scraper.rb +101 -0
  375. data/lib/relaton/ietf/util.rb +8 -0
  376. data/lib/relaton/ietf/wg_name_resolver.rb +42 -0
  377. data/lib/relaton/ietf.rb +30 -0
  378. data/lib/relaton/iho/bibdata.rb +8 -0
  379. data/lib/relaton/iho/bibitem.rb +8 -0
  380. data/lib/relaton/iho/bibliography.rb +114 -0
  381. data/lib/relaton/iho/comment_period.rb +13 -0
  382. data/lib/relaton/iho/docidentifier.rb +31 -0
  383. data/lib/relaton/iho/doctype.rb +10 -0
  384. data/lib/relaton/iho/ext.rb +20 -0
  385. data/lib/relaton/iho/hash_parser_v1.rb +144 -0
  386. data/lib/relaton/iho/item.rb +20 -0
  387. data/lib/relaton/iho/item_base.rb +18 -0
  388. data/lib/relaton/iho/item_data.rb +6 -0
  389. data/lib/relaton/iho/processor.rb +54 -0
  390. data/lib/relaton/iho/relation.rb +9 -0
  391. data/lib/relaton/iho/structured_identifier.rb +20 -0
  392. data/lib/relaton/iho/util.rb +8 -0
  393. data/lib/relaton/iho.rb +27 -0
  394. data/lib/relaton/index/config.rb +52 -0
  395. data/lib/relaton/index/file_io.rb +305 -0
  396. data/lib/relaton/index/file_storage.rb +66 -0
  397. data/lib/relaton/index/pool.rb +46 -0
  398. data/lib/relaton/index/shard_source.rb +201 -0
  399. data/lib/relaton/index/type.rb +210 -0
  400. data/lib/relaton/index/util.rb +18 -0
  401. data/lib/relaton/index.rb +61 -0
  402. data/lib/relaton/isbn/isbn.rb +61 -0
  403. data/lib/relaton/isbn/open_library.rb +43 -0
  404. data/lib/relaton/isbn/parser.rb +88 -0
  405. data/lib/relaton/isbn/processor.rb +48 -0
  406. data/lib/relaton/isbn/util.rb +8 -0
  407. data/lib/relaton/isbn.rb +19 -0
  408. data/lib/relaton/iso/bibliography.rb +412 -0
  409. data/lib/relaton/iso/data_fetcher.rb +338 -0
  410. data/lib/relaton/iso/data_parser.rb +458 -0
  411. data/lib/relaton/iso/hash_parser_v1.rb +177 -0
  412. data/lib/relaton/iso/hit.rb +57 -0
  413. data/lib/relaton/iso/hit_collection.rb +196 -0
  414. data/lib/relaton/iso/item_data.rb +50 -0
  415. data/lib/relaton/iso/model/bibdata.rb +10 -0
  416. data/lib/relaton/iso/model/bibitem.rb +8 -0
  417. data/lib/relaton/iso/model/contributor.rb +6 -0
  418. data/lib/relaton/iso/model/contributor_info.rb +9 -0
  419. data/lib/relaton/iso/model/docidentifier.rb +146 -0
  420. data/lib/relaton/iso/model/doctype.rb +13 -0
  421. data/lib/relaton/iso/model/ext.rb +35 -0
  422. data/lib/relaton/iso/model/item.rb +17 -0
  423. data/lib/relaton/iso/model/item_base.rb +22 -0
  424. data/lib/relaton/iso/model/organization.rb +9 -0
  425. data/lib/relaton/iso/model/project_number.rb +22 -0
  426. data/lib/relaton/iso/model/relation.rb +9 -0
  427. data/lib/relaton/iso/model/stagename.rb +14 -0
  428. data/lib/relaton/iso/model/structured_identifier.rb +31 -0
  429. data/lib/relaton/iso/processor.rb +85 -0
  430. data/lib/relaton/iso/scraper.rb +635 -0
  431. data/lib/relaton/iso/type/pubid.rb +50 -0
  432. data/lib/relaton/iso/util.rb +8 -0
  433. data/lib/relaton/iso.rb +30 -0
  434. data/lib/relaton/itu/bibliography.rb +95 -0
  435. data/lib/relaton/itu/data_crawler_r.rb +664 -0
  436. data/lib/relaton/itu/data_fetcher.rb +550 -0
  437. data/lib/relaton/itu/data_merge_r.rb +149 -0
  438. data/lib/relaton/itu/data_parser_r.rb +214 -0
  439. data/lib/relaton/itu/data_parser_t.rb +228 -0
  440. data/lib/relaton/itu/family_cache.rb +177 -0
  441. data/lib/relaton/itu/governor.rb +56 -0
  442. data/lib/relaton/itu/hit.rb +28 -0
  443. data/lib/relaton/itu/hit_collection.rb +299 -0
  444. data/lib/relaton/itu/item_data.rb +6 -0
  445. data/lib/relaton/itu/model/approval_stage.rb +13 -0
  446. data/lib/relaton/itu/model/bibdata.rb +8 -0
  447. data/lib/relaton/itu/model/bibitem.rb +8 -0
  448. data/lib/relaton/itu/model/docidentifier.rb +75 -0
  449. data/lib/relaton/itu/model/doctype.rb +13 -0
  450. data/lib/relaton/itu/model/ext.rb +47 -0
  451. data/lib/relaton/itu/model/item.rb +13 -0
  452. data/lib/relaton/itu/model/meeting.rb +13 -0
  453. data/lib/relaton/itu/model/meeting_date.rb +15 -0
  454. data/lib/relaton/itu/model/question.rb +13 -0
  455. data/lib/relaton/itu/model/recommendation_status.rb +11 -0
  456. data/lib/relaton/itu/model/structured_identifier.rb +38 -0
  457. data/lib/relaton/itu/processor.rb +72 -0
  458. data/lib/relaton/itu/pubid.rb +199 -0
  459. data/lib/relaton/itu/radio_regulations_parser.rb +70 -0
  460. data/lib/relaton/itu/recommendation_fields.rb +334 -0
  461. data/lib/relaton/itu/recommendation_parser.rb +30 -0
  462. data/lib/relaton/itu/scraper.rb +203 -0
  463. data/lib/relaton/itu/util.rb +8 -0
  464. data/lib/relaton/itu.rb +34 -0
  465. data/lib/relaton/jcgm/bibdata.rb +8 -0
  466. data/lib/relaton/jcgm/bibitem.rb +8 -0
  467. data/lib/relaton/jcgm/bibliography.rb +97 -0
  468. data/lib/relaton/jcgm/data_fetcher.rb +81 -0
  469. data/lib/relaton/jcgm/docidentifier.rb +102 -0
  470. data/lib/relaton/jcgm/doctype.rb +12 -0
  471. data/lib/relaton/jcgm/ext.rb +23 -0
  472. data/lib/relaton/jcgm/item.rb +20 -0
  473. data/lib/relaton/jcgm/item_base.rb +18 -0
  474. data/lib/relaton/jcgm/item_data.rb +6 -0
  475. data/lib/relaton/jcgm/meetings_parser.rb +175 -0
  476. data/lib/relaton/jcgm/processor.rb +71 -0
  477. data/lib/relaton/jcgm/relation.rb +9 -0
  478. data/lib/relaton/jcgm/structured_identifier.rb +40 -0
  479. data/lib/relaton/jcgm/util.rb +8 -0
  480. data/lib/relaton/jcgm.rb +24 -0
  481. data/lib/relaton/jis/bibdata.rb +8 -0
  482. data/lib/relaton/jis/bibitem.rb +8 -0
  483. data/lib/relaton/jis/bibliography.rb +73 -0
  484. data/lib/relaton/jis/data_fetcher.rb +183 -0
  485. data/lib/relaton/jis/docidentifier.rb +120 -0
  486. data/lib/relaton/jis/doctype.rb +9 -0
  487. data/lib/relaton/jis/ext.rb +13 -0
  488. data/lib/relaton/jis/hit.rb +88 -0
  489. data/lib/relaton/jis/hit_collection.rb +128 -0
  490. data/lib/relaton/jis/item.rb +22 -0
  491. data/lib/relaton/jis/item_base.rb +26 -0
  492. data/lib/relaton/jis/item_data.rb +8 -0
  493. data/lib/relaton/jis/processor.rb +55 -0
  494. data/lib/relaton/jis/relation.rb +11 -0
  495. data/lib/relaton/jis/scraper.rb +232 -0
  496. data/lib/relaton/jis/structured_identifier.rb +13 -0
  497. data/lib/relaton/jis/util.rb +8 -0
  498. data/lib/relaton/jis.rb +32 -0
  499. data/lib/relaton/logger/channels/gh_issue.rb +143 -0
  500. data/lib/relaton/logger/config.rb +34 -0
  501. data/lib/relaton/logger/formatter_json.rb +8 -0
  502. data/lib/relaton/logger/formatter_string.rb +12 -0
  503. data/lib/relaton/logger/log.rb +64 -0
  504. data/lib/relaton/logger/log_device.rb +27 -0
  505. data/lib/relaton/logger/pool.rb +24 -0
  506. data/lib/relaton/logger.rb +18 -0
  507. data/lib/relaton/nist/bibdata.rb +8 -0
  508. data/lib/relaton/nist/bibitem.rb +8 -0
  509. data/lib/relaton/nist/bibliography.rb +191 -0
  510. data/lib/relaton/nist/comment_period.rb +15 -0
  511. data/lib/relaton/nist/data_fetcher.rb +134 -0
  512. data/lib/relaton/nist/date.rb +7 -0
  513. data/lib/relaton/nist/docidentifier.rb +165 -0
  514. data/lib/relaton/nist/doctype.rb +7 -0
  515. data/lib/relaton/nist/ext.rb +16 -0
  516. data/lib/relaton/nist/hit.rb +18 -0
  517. data/lib/relaton/nist/hit_collection.rb +362 -0
  518. data/lib/relaton/nist/item.rb +19 -0
  519. data/lib/relaton/nist/item_base.rb +16 -0
  520. data/lib/relaton/nist/item_data.rb +6 -0
  521. data/lib/relaton/nist/mods_parser.rb +302 -0
  522. data/lib/relaton/nist/processor.rb +69 -0
  523. data/lib/relaton/nist/pubs_export.rb +69 -0
  524. data/lib/relaton/nist/relation.rb +10 -0
  525. data/lib/relaton/nist/scraper.rb +293 -0
  526. data/lib/relaton/nist/series.yaml +49 -0
  527. data/lib/relaton/nist/util.rb +8 -0
  528. data/lib/relaton/nist.rb +34 -0
  529. data/lib/relaton/oasis/bibdata.rb +8 -0
  530. data/lib/relaton/oasis/bibitem.rb +8 -0
  531. data/lib/relaton/oasis/bibliography.rb +201 -0
  532. data/lib/relaton/oasis/browser_agent.rb +71 -0
  533. data/lib/relaton/oasis/data_fetcher.rb +130 -0
  534. data/lib/relaton/oasis/data_parser.rb +305 -0
  535. data/lib/relaton/oasis/data_parser_utils.rb +330 -0
  536. data/lib/relaton/oasis/data_part_parser.rb +239 -0
  537. data/lib/relaton/oasis/docidentifier.rb +54 -0
  538. data/lib/relaton/oasis/doctype.rb +7 -0
  539. data/lib/relaton/oasis/ext.rb +19 -0
  540. data/lib/relaton/oasis/item.rb +14 -0
  541. data/lib/relaton/oasis/item_data.rb +6 -0
  542. data/lib/relaton/oasis/processor.rb +74 -0
  543. data/lib/relaton/oasis/util.rb +8 -0
  544. data/lib/relaton/oasis.rb +41 -0
  545. data/lib/relaton/ogc/bibdata.rb +8 -0
  546. data/lib/relaton/ogc/bibitem.rb +8 -0
  547. data/lib/relaton/ogc/bibliography.rb +64 -0
  548. data/lib/relaton/ogc/data_fetcher.rb +131 -0
  549. data/lib/relaton/ogc/docidentifier.rb +111 -0
  550. data/lib/relaton/ogc/doctype.rb +12 -0
  551. data/lib/relaton/ogc/ext.rb +15 -0
  552. data/lib/relaton/ogc/hit.rb +18 -0
  553. data/lib/relaton/ogc/hit_collection.rb +111 -0
  554. data/lib/relaton/ogc/item.rb +13 -0
  555. data/lib/relaton/ogc/item_data.rb +6 -0
  556. data/lib/relaton/ogc/processor.rb +59 -0
  557. data/lib/relaton/ogc/scraper.rb +225 -0
  558. data/lib/relaton/ogc/util.rb +8 -0
  559. data/lib/relaton/ogc.rb +30 -0
  560. data/lib/relaton/oiml/bibdata.rb +8 -0
  561. data/lib/relaton/oiml/bibitem.rb +8 -0
  562. data/lib/relaton/oiml/bibliography.rb +169 -0
  563. data/lib/relaton/oiml/docidentifier.rb +48 -0
  564. data/lib/relaton/oiml/doctype.rb +13 -0
  565. data/lib/relaton/oiml/ext.rb +42 -0
  566. data/lib/relaton/oiml/item.rb +20 -0
  567. data/lib/relaton/oiml/item_base.rb +18 -0
  568. data/lib/relaton/oiml/item_data.rb +6 -0
  569. data/lib/relaton/oiml/processor.rb +54 -0
  570. data/lib/relaton/oiml/relation.rb +9 -0
  571. data/lib/relaton/oiml/util.rb +8 -0
  572. data/lib/relaton/oiml.rb +24 -0
  573. data/lib/relaton/omg/bibdata.rb +8 -0
  574. data/lib/relaton/omg/bibitem.rb +8 -0
  575. data/lib/relaton/omg/bibliography.rb +31 -0
  576. data/lib/relaton/omg/docidentifier.rb +67 -0
  577. data/lib/relaton/omg/ext.rb +7 -0
  578. data/lib/relaton/omg/item.rb +9 -0
  579. data/lib/relaton/omg/item_data.rb +6 -0
  580. data/lib/relaton/omg/processor.rb +35 -0
  581. data/lib/relaton/omg/scraper.rb +186 -0
  582. data/lib/relaton/omg/util.rb +8 -0
  583. data/lib/relaton/omg.rb +25 -0
  584. data/lib/relaton/plateau/bibdata.rb +8 -0
  585. data/lib/relaton/plateau/bibitem.rb +8 -0
  586. data/lib/relaton/plateau/bibliography.rb +31 -0
  587. data/lib/relaton/plateau/data_fetcher.rb +176 -0
  588. data/lib/relaton/plateau/doctype.rb +7 -0
  589. data/lib/relaton/plateau/ext.rb +23 -0
  590. data/lib/relaton/plateau/handbook_parser.rb +102 -0
  591. data/lib/relaton/plateau/hit.rb +21 -0
  592. data/lib/relaton/plateau/hit_collection.rb +79 -0
  593. data/lib/relaton/plateau/item.rb +12 -0
  594. data/lib/relaton/plateau/item_data.rb +6 -0
  595. data/lib/relaton/plateau/parser.rb +101 -0
  596. data/lib/relaton/plateau/processor.rb +51 -0
  597. data/lib/relaton/plateau/technical_report_parser.rb +98 -0
  598. data/lib/relaton/plateau/util.rb +8 -0
  599. data/lib/relaton/plateau.rb +29 -0
  600. data/lib/relaton/sdo/config.rb +34 -0
  601. data/lib/relaton/sdo/fetcher.rb +52 -0
  602. data/lib/relaton/sdo/logo.rb +95 -0
  603. data/lib/relaton/sdo/name.rb +26 -0
  604. data/lib/relaton/sdo/organization.rb +71 -0
  605. data/lib/relaton/sdo/store.rb +49 -0
  606. data/lib/relaton/sdo.rb +29 -0
  607. data/lib/relaton/un/bibdata.rb +8 -0
  608. data/lib/relaton/un/bibitem.rb +8 -0
  609. data/lib/relaton/un/bibliography.rb +48 -0
  610. data/lib/relaton/un/doctype.rb +10 -0
  611. data/lib/relaton/un/ext.rb +30 -0
  612. data/lib/relaton/un/hit.rb +56 -0
  613. data/lib/relaton/un/hit_collection.rb +61 -0
  614. data/lib/relaton/un/item.rb +11 -0
  615. data/lib/relaton/un/item_data.rb +6 -0
  616. data/lib/relaton/un/parser.rb +108 -0
  617. data/lib/relaton/un/processor.rb +38 -0
  618. data/lib/relaton/un/session.rb +25 -0
  619. data/lib/relaton/un/token_generator.rb +105 -0
  620. data/lib/relaton/un/util.rb +8 -0
  621. data/lib/relaton/un/wasm/decoder.rb +434 -0
  622. data/lib/relaton/un/wasm/instance.rb +101 -0
  623. data/lib/relaton/un/wasm/interpreter.rb +613 -0
  624. data/lib/relaton/un/wasm/memory.rb +112 -0
  625. data/lib/relaton/un/wasm/module.rb +47 -0
  626. data/lib/relaton/un/wasm.rb +17 -0
  627. data/lib/relaton/un/wasm_v_bg.wasm +0 -0
  628. data/lib/relaton/un.rb +28 -0
  629. data/lib/relaton/version.rb +1 -1
  630. data/lib/relaton/w3c/bibdata.rb +8 -0
  631. data/lib/relaton/w3c/bibitem.rb +8 -0
  632. data/lib/relaton/w3c/bibliography.rb +174 -0
  633. data/lib/relaton/w3c/data_fetcher.rb +487 -0
  634. data/lib/relaton/w3c/data_parser.rb +379 -0
  635. data/lib/relaton/w3c/docidentifier.rb +48 -0
  636. data/lib/relaton/w3c/doctype.rb +7 -0
  637. data/lib/relaton/w3c/ext.rb +11 -0
  638. data/lib/relaton/w3c/governor.rb +32 -0
  639. data/lib/relaton/w3c/item.rb +15 -0
  640. data/lib/relaton/w3c/item_data.rb +6 -0
  641. data/lib/relaton/w3c/processor.rb +49 -0
  642. data/lib/relaton/w3c/pubid.rb +85 -0
  643. data/lib/relaton/w3c/safe_realize.rb +148 -0
  644. data/lib/relaton/w3c/util.rb +8 -0
  645. data/lib/relaton/w3c.rb +36 -0
  646. data/lib/relaton/xsf/bibdata.rb +8 -0
  647. data/lib/relaton/xsf/bibitem.rb +8 -0
  648. data/lib/relaton/xsf/bibliography.rb +84 -0
  649. data/lib/relaton/xsf/data_fetcher.rb +106 -0
  650. data/lib/relaton/xsf/docidentifier.rb +46 -0
  651. data/lib/relaton/xsf/hit.rb +17 -0
  652. data/lib/relaton/xsf/hit_collection.rb +52 -0
  653. data/lib/relaton/xsf/item.rb +13 -0
  654. data/lib/relaton/xsf/item_data.rb +6 -0
  655. data/lib/relaton/xsf/processor.rb +51 -0
  656. data/lib/relaton/xsf/util.rb +9 -0
  657. data/lib/relaton/xsf.rb +34 -0
  658. data/lib/relaton-core.rb +1 -0
  659. data/lib/relaton.rb +85 -0
  660. metadata +775 -161
  661. data/.github/workflows/rake.yml +0 -14
  662. data/.github/workflows/release.yml +0 -24
  663. data/.github/workflows/rubocop.yml +0 -48
  664. data/.gitignore +0 -12
  665. data/.rspec +0 -3
  666. data/CLAUDE.md +0 -78
  667. data/Gemfile +0 -29
  668. data/Rakefile +0 -6
  669. data/docs/CHANGELOG.adoc +0 -16
  670. data/docs/VERSIONING_POLICY.adoc +0 -38
  671. data/docs/navigation.adoc +0 -6
  672. data/lib/relaton/db/version.rb +0 -5
  673. data/relaton.gemspec +0 -72
  674. data/spec/relaton/config_spec.rb +0 -10
  675. data/spec/relaton/db_cache_spec.rb +0 -51
  676. data/spec/relaton/db_spec.rb +0 -567
  677. data/spec/relaton/registry_spec.rb +0 -178
  678. data/spec/relaton/util_spec.rb +0 -3
  679. data/spec/relaton_meta_spec.rb +0 -25
  680. data/spec/relaton_spec.rb +0 -800
  681. data/spec/spec_helper.rb +0 -45
  682. data/spec/support/gb_t_20223_2006.xml +0 -33
  683. data/spec/support/iso_111111119115_1.xml +0 -0
  684. data/spec/support/iso_19115_1.xml +0 -115
  685. data/spec/support/iso_19115_2.xml +0 -95
  686. data/spec/support/rfc_8341.xml +0 -46
  687. data/spec/vcr_cassetes/api_relaton_org.yml +0 -121
  688. data/spec/vcr_cassetes/api_relaton_org_unavailable.yml +0 -140
  689. data/spec/vcr_cassetes/cc_dir_10005_2019.yml +0 -202
  690. data/spec/vcr_cassetes/cipm_meeting_43.yml +0 -1505
  691. data/spec/vcr_cassetes/gb_t_20223_2006.yml +0 -729
  692. data/spec/vcr_cassetes/iso_111111119115_1.yml +0 -12951
  693. data/spec/vcr_cassetes/iso_19115_1.yml +0 -17334
  694. data/spec/vcr_cassetes/iso_19115_1_2.yml +0 -322
  695. data/spec/vcr_cassetes/iso_19115_1_std.yml +0 -17334
  696. data/spec/vcr_cassetes/iso_19115_all_parts.yml +0 -185
  697. data/spec/vcr_cassetes/iso_19133_2005.yml +0 -144
  698. data/spec/vcr_cassetes/iso_combined_applied.yml +0 -318
  699. data/spec/vcr_cassetes/iso_combined_included.yml +0 -318
  700. data/spec/vcr_cassetes/ogc_19_025r1.yml +0 -374
  701. data/spec/vcr_cassetes/omg_ami4ccm_1_0.yml +0 -317
  702. data/spec/vcr_cassetes/rfc_8341.yml +0 -1278
@@ -0,0 +1,293 @@
1
+ require "yaml"
2
+ require "net/http"
3
+
4
+ module Relaton
5
+ module Nist
6
+ class Scraper
7
+ extend Core::DateParser
8
+
9
+ class << self
10
+ DOMAIN = "https://csrc.nist.gov".freeze
11
+
12
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
13
+
14
+ # Parse page.
15
+ # @param hit_data [Hash]
16
+ # @return [Relaton::Nist::ItemData]
17
+ def parse_page(hit_data)
18
+ hit_data[:path] ? fetch_gh(hit_data) : parse_json(hit_data)
19
+ end
20
+
21
+ def fetch_gh(hit_data)
22
+ uri = URI.parse "#{HitCollection::GHNISTDATA}#{hit_data[:path]}"
23
+ yaml = Net::HTTP.get(uri)
24
+ Item.from_yaml(yaml)
25
+ end
26
+
27
+ def parse_json(hit_data)
28
+ item_data = from_json hit_data
29
+ titles = fetch_titles(hit_data)
30
+ item_data[:fetched] = ::Date.today.to_s
31
+ item_data[:type] = "standard"
32
+ item_data[:title] = titles
33
+ ItemData.new(**item_data)
34
+ end
35
+
36
+ private
37
+
38
+ def from_json(hit_data)
39
+ json = hit_data[:json]
40
+ {
41
+ source: fetch_link(json),
42
+ docidentifier: fetch_docid(hit_data),
43
+ date: fetch_dates(json, hit_data[:release_date]),
44
+ contributor: fetch_contributors(json),
45
+ edition: fetch_edition(json),
46
+ language: [json["language"]],
47
+ script: [json["script"]],
48
+ status: fetch_status(json),
49
+ copyright: fetch_copyright(json["published-date"]),
50
+ relation: fetch_relations_json(hit_data),
51
+ place: fetch_place,
52
+ keyword: fetch_keywords(json),
53
+ ext: Ext.new(
54
+ doctype: Doctype.new(content: "standard"),
55
+ flavor: "nist",
56
+ commentperiod: fetch_commentperiod_json(json),
57
+ ),
58
+ }
59
+ end
60
+
61
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
62
+
63
+ # Fetch docid.
64
+ # @param hit [Hash]
65
+ # @return [Array<Bib::Docidentifier>]
66
+ def fetch_docid(hit)
67
+ # All ids share the Nist::Docidentifier collection type so YAML
68
+ # serialization stays valid; the DOI is not canonical NIST pubid form,
69
+ # so the class keeps it as the raw string (see Docidentifier#content=).
70
+ ids = [Docidentifier.new(content: hit[:code], type: "NIST", primary: true)]
71
+ doi = hit[:json]["doi"]&.split("/")&.last
72
+ ids << Docidentifier.new(content: doi, type: "DOI") if doi
73
+ ids
74
+ end
75
+
76
+ # Fetch status.
77
+ # @param doc [Hash]
78
+ # @return [Bib::Status]
79
+ def fetch_status(doc)
80
+ stage = doc["status"]
81
+ subst = doc["substage"]
82
+ iter = iteration(doc["iteration"])
83
+ Bib::Status.new(
84
+ stage: Bib::Status::Stage.new(content: stage),
85
+ substage: subst ? Bib::Status::Stage.new(content: subst) : nil,
86
+ iteration: iter.to_s,
87
+ )
88
+ end
89
+
90
+ def iteration(iter)
91
+ case iter
92
+ when "initial", "ipd" then 1
93
+ when /(\d)pd/i then $1
94
+ else iter
95
+ end
96
+ end
97
+
98
+ # Fetch titles.
99
+ # @param hit_data [Hash]
100
+ # @return [Array<Bib::Title>]
101
+ def fetch_titles(hit_data)
102
+ [Bib::Title.new(content: hit_data[:title], language: "en", script: "Latn")]
103
+ end
104
+
105
+ # Fetch dates
106
+ # @param doc [Hash]
107
+ # @param release_date [Date]
108
+ # @return [Array<Bib::Date>]
109
+ def fetch_dates(doc, release_date) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
110
+ dates = [Bib::Date.new(type: "published", at: release_date.to_s)]
111
+
112
+ issued = safe_parse_date doc["issued-date"]
113
+ updated = safe_parse_date doc["updated-date"]
114
+ dates << Bib::Date.new(type: "updated", at: updated.to_s) if updated
115
+ obsoleted = safe_parse_date doc["obsoleted-date"]
116
+ dates << Bib::Date.new(type: "obsoleted", at: obsoleted.to_s) if obsoleted
117
+ dates << Bib::Date.new(type: "issued", at: issued.to_s) if issued
118
+ dates
119
+ end
120
+
121
+ def safe_parse_date(str)
122
+ return unless str
123
+
124
+ parse_date(str, str: false)
125
+ end
126
+
127
+ # @param doc [Hash]
128
+ # @return [Array<Bib::Contributor>]
129
+ def fetch_contributors(doc)
130
+ contribs = []
131
+ contribs += contributors_json(
132
+ doc["authors"], "author", doc["language"], doc["script"],
133
+ )
134
+ contribs + contributors_json(
135
+ doc["editors"], "editor", doc["language"], doc["script"],
136
+ )
137
+ end
138
+
139
+ # @param doc [Array<Hash>]
140
+ # @param role [String]
141
+ # @return [Array<Bib::Contributor>]
142
+ def contributors_json(doc, role, lang = "en", script = "Latn") # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
143
+ doc.map do |contr|
144
+ if contr["affiliation"]
145
+ abbrev = if contr["affiliation"]["acronym"]
146
+ Bib::LocalizedString.new(content: contr["affiliation"]["acronym"])
147
+ end
148
+ org = Bib::Organization.new(
149
+ name: [Bib::TypedLocalizedString.new(content: contr["affiliation"]["name"])],
150
+ abbreviation: abbrev,
151
+ )
152
+ end
153
+ if contr["surname"]
154
+ affiliation = []
155
+ affiliation << Bib::Affiliation.new(organization: org) if org
156
+ entity = Bib::Person.new(
157
+ name: full_name(contr, lang, script), affiliation: affiliation,
158
+ )
159
+ Bib::Contributor.new(
160
+ person: entity,
161
+ role: [Bib::Contributor::Role.new(type: role)],
162
+ )
163
+ elsif org
164
+ Bib::Contributor.new(
165
+ organization: org,
166
+ role: [Bib::Contributor::Role.new(type: role)],
167
+ )
168
+ end
169
+ end.compact
170
+ end
171
+
172
+ # @param name [Hash]
173
+ # @param lang [String]
174
+ # @param script [String]
175
+ # @return [Bib::FullName]
176
+ def full_name(name, lang, script)
177
+ Bib::FullName.new(
178
+ surname: Bib::LocalizedString.new(content: name["surname"], language: lang, script: script),
179
+ forename: name_parts_forename(name["givenName"], lang, script),
180
+ addition: name_parts(name["suffix"], lang, script),
181
+ prefix: name_parts(name["title"], lang, script),
182
+ completename: Bib::LocalizedString.new(content: name["fullName"], language: lang, script: script),
183
+ )
184
+ end
185
+
186
+ # @param part [String, NilClass]
187
+ # @param lang [String]
188
+ # @param script [String]
189
+ # @return [Array<Bib::LocalizedString>]
190
+ def name_parts(part, lang, script)
191
+ return [] unless part
192
+
193
+ [Bib::LocalizedString.new(content: part, language: lang, script: script)]
194
+ end
195
+
196
+ # @param part [String, NilClass]
197
+ # @param lang [String]
198
+ # @param script [String]
199
+ # @return [Array<Bib::FullNameType::Forename>]
200
+ def name_parts_forename(part, lang, script)
201
+ return [] unless part
202
+
203
+ [Bib::FullNameType::Forename.new(content: part, language: lang, script: script)]
204
+ end
205
+
206
+ # @param doc [Hash]
207
+ # @return [String, NilClass]
208
+ def fetch_edition(doc)
209
+ return unless doc["edition"] || doc["revision"]
210
+
211
+ rev = doc["edition"] || doc["revision"]
212
+ Bib::Edition.new(content: "Revision #{rev}")
213
+ end
214
+
215
+ # Fetch copyright.
216
+ # @param doc [String]
217
+ # @return [Array<Bib::Copyright>]
218
+ def fetch_copyright(doc)
219
+ from = doc&.match(/\d{4}/)&.to_s
220
+ owner = Bib::ContributionInfo.new(
221
+ organization: Bib::Organization.new(
222
+ name: [Bib::TypedLocalizedString.new(content: "National Institute of Standards and Technology")],
223
+ abbreviation: Bib::LocalizedString.new(content: "NIST"),
224
+ uri: [Bib::Uri.new(content: "www.nist.gov")],
225
+ ),
226
+ )
227
+ [Bib::Copyright.new(owner: [owner], from: from)]
228
+ end
229
+
230
+ # Fetch links.
231
+ # @param doc [Hash]
232
+ # @return [Array<Bib::Uri>]
233
+ def fetch_link(doc)
234
+ links = []
235
+ links << Bib::Uri.new(type: "src", content: doc["uri"]) if doc["uri"]
236
+ if doc["doi"]
237
+ links << Bib::Uri.new(type: "doi", content: "https://doi.org/#{doc['doi']}")
238
+ end
239
+ links
240
+ end
241
+
242
+ # @return [Array<Bib::Place>]
243
+ def fetch_place
244
+ [Bib::Place.new(city: "Gaithersburg", region: [Bib::Place::RegionType.new(iso: "MD")])]
245
+ end
246
+
247
+ def fetch_relations_json(hit) # rubocop:disable Metrics/AbcSize
248
+ doc = hit[:json]
249
+ relations = doc["supersedes"].map do |r|
250
+ doc_relation "supersedes", hit[:code], r["uri"]
251
+ end
252
+
253
+ relations + doc["superseded-by"].map do |r|
254
+ doc_relation "updates", hit[:code], r["uri"]
255
+ end
256
+ end
257
+
258
+ # @param type [String]
259
+ # @param ref [String]
260
+ # @param uri [String]
261
+ # @return [Nist::Relation]
262
+ def doc_relation(type, ref, uri, lang = "en", script = "Latn") # rubocop:disable Metrics/MethodLength
263
+ if type == "supersedes"
264
+ descr = Bib::LocalizedMarkedUpString.new(content: "supersedes", language: lang, script: script)
265
+ t = "obsoletes"
266
+ else t = type
267
+ end
268
+ ids = [Docidentifier.new(content: ref, type: "NIST", primary: true)]
269
+ link = [Bib::Uri.new(type: "src", content: uri)]
270
+ bib = ItemData.new(formattedref: Bib::Formattedref.new(content: ref), source: link, docidentifier: ids)
271
+ Relation.new(type: t, description: descr, bibitem: bib)
272
+ end
273
+
274
+ # @param doc [Hash]
275
+ # @return [Array<Bib::Keyword>]
276
+ def fetch_keywords(doc)
277
+ doc["keywords"].map do |kw|
278
+ text = kw.is_a?(String) ? kw : kw.text
279
+ Bib::Keyword.new(vocab: Bib::LocalizedString.new(content: text))
280
+ end
281
+ end
282
+
283
+ # @param json [Hash]
284
+ # @return [Nist::CommentPeriod, NilClass]
285
+ def fetch_commentperiod_json(json)
286
+ return unless json["comment-from"]
287
+
288
+ CommentPeriod.new from: json["comment-from"], to: json["comment-to"]
289
+ end
290
+ end
291
+ end
292
+ end
293
+ end
@@ -0,0 +1,49 @@
1
+ ---
2
+ AMS: Advanced Manufacturing Series
3
+ BRPD: Basic Radio Propagation Predictions Series
4
+ BH: Building and Housing Reports
5
+ BMS: Building Materials and Structures Reports
6
+ BSS: Building Science Series
7
+ CRPL: CRPL Solar-Geophysical Data
8
+ IP: CRPL Ionospheric Predictions
9
+ CIRC: Circulars
10
+ CIS: Consumer Information Series
11
+ CS: Commercial Standards
12
+ CSM: Commercial Standards Monthly
13
+ CSWP: Cybersecurity White Papers
14
+ EAB: Economic Analysis Briefs
15
+ FIPS: Federal Information Processing Standards Publications
16
+ GCR: Grant/Contractor Reports
17
+ HB: Handbooks
18
+ HR: Hydraulic Research in the United States
19
+ IRPL: Interservice Radio Propagation Laboratory
20
+ LCIRC: Letter Circular
21
+ MONO: Monographs
22
+ MP: Miscellaneous Publications
23
+ NCSTAR: National Construction Safety Team Act Reports
24
+ NSRDS: National Standard Reference Data Series
25
+ IR: IR (Interagency/Internal Reports)
26
+ OWMWP: Office of Weights and Measures White Papers
27
+ PC: Photographic Circulars
28
+ RPT: NBS Reports
29
+ SIBS: Special Interior Ballistics Studies
30
+ SP: Special Publications (General)
31
+ SP250: 'SP 250: Calibration Services'
32
+ SP260: 'SP 260: Standard Reference Materials'
33
+ SP300: 'SP 300: Precision Measurement and Calibration'
34
+ SP400: 'SP 400: Semiconductor Measurement Technology'
35
+ SP480: 'SP 480: Law Enforcement Technology'
36
+ SP500: 'SP 500: Computer Systems Technology'
37
+ SP700: 'SP 700: Industrial Measurement Series'
38
+ SP800: 'SP 800: Computer Security Series'
39
+ SP823: 'SP 823: Integrated Services Digital Network Series'
40
+ SP960: 'SP 960: NIST Recommended Practice Guides'
41
+ SP1200: 'SP 1200: Protocols'
42
+ SP1500: 'SP 1500: Working Group Papers'
43
+ SP1800: 'SP 1800: NIST Cybersecurity Practice Guides'
44
+ SP1900: 'SP 1900: Cyber-Physical Systems'
45
+ SP2000: 'SP 2000: Standards Coordination'
46
+ SP2100: 'SP 2100: Conference Proceedings'
47
+ TIBM: Technical Information on Building Materials
48
+ TN: Technical Notes
49
+ TTB: Technology Transfer Brief
@@ -0,0 +1,8 @@
1
+ module Relaton
2
+ module Nist
3
+ module Util
4
+ extend Relaton::Bib::Util
5
+ PROGNAME = "relaton-nist".freeze
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,34 @@
1
+ require "pubid"
2
+ require "relaton/index"
3
+ require "relaton/bib"
4
+ require_relative "version"
5
+ require_relative "nist/util"
6
+ require_relative "nist/item_data"
7
+ require_relative "nist/item"
8
+ require_relative "nist/relation"
9
+ require_relative "nist/bibitem"
10
+ require_relative "nist/bibdata"
11
+ require_relative "nist/pubs_export"
12
+ require_relative "nist/hit"
13
+ require_relative "nist/hit_collection"
14
+ require_relative "nist/scraper"
15
+ require_relative "nist/bibliography"
16
+ # require_relative "nist/tech_pubs_parser"
17
+
18
+ module Relaton
19
+ module Nist
20
+ # Pubid-based index (index-v2): `:id` is a Pubid::Nist::Identifier hash, so
21
+ # search narrows by number via binary search. The legacy string index-v1
22
+ # (for older gem versions) is rebuilt separately by the relaton-data-nist
23
+ # crawler, not by this gem's DataFetcher.
24
+ INDEXFILE = "index-v2"
25
+
26
+ class Error < StandardError; end
27
+
28
+ # Returns hash of XML grammar
29
+ # @return [String]
30
+ def self.grammar_hash
31
+ Digest::MD5.hexdigest Relaton::VERSION
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,8 @@
1
+ module Relaton
2
+ module Oasis
3
+ class Bibdata < Item
4
+ model ItemData
5
+ include Bib::BibdataShared
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Relaton
2
+ module Oasis
3
+ class Bibitem < Item
4
+ model ItemData
5
+ include Bib::BibitemShared
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,201 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+
5
+ module Relaton
6
+ module Oasis
7
+ module Bibliography
8
+ ENDPOINT = "https://raw.githubusercontent.com/relaton/relaton-data-oasis/refs/heads/v2/"
9
+
10
+ # The publisher token every OASIS printed id starts with, and the one
11
+ # thing `Pubid::Oasis`'s grammar requires. See #parse_ref.
12
+ PREFIX = "OASIS "
13
+
14
+ # The components a reference may omit. `number` (the specification name)
15
+ # is deliberately absent — see #ignored.
16
+ OPTIONAL = %i[version stage part label].freeze
17
+
18
+ class << self
19
+ def search(text, _year = nil, _opts = {}) # rubocop:disable Metrics/MethodLength
20
+ Util.info "Fetching from Relaton repository ...", key: text
21
+ row = find_index_entry(text)
22
+ unless row
23
+ Util.info "Not found.", key: text
24
+ return
25
+ end
26
+
27
+ uri = URI("#{ENDPOINT}#{row[:file]}")
28
+ parse_item(fetch_yaml(uri), text)
29
+ rescue SocketError, Errno::EINVAL, Errno::ECONNRESET, EOFError,
30
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
31
+ Net::ProtocolError, Net::ReadTimeout,
32
+ OpenSSL::SSL::SSLError, Errno::ETIMEDOUT => e
33
+ raise Relaton::RequestError,
34
+ "Could not access #{uri}: #{e.message}"
35
+ end
36
+
37
+ def get(ref, year = nil, opts = {})
38
+ search(ref, year, opts)
39
+ end
40
+
41
+ private
42
+
43
+ #
44
+ # The pubid `index-v2`. `pubid_class:` is what makes `Relaton::Index`
45
+ # deserialize the rows into identifiers, sort them by
46
+ # `id.root.number`, and let `Type#search` bsearch; `file:` names the
47
+ # local cache, and `Processor#remove_index_file` must name the same
48
+ # one, or `Db#clear` leaves this cache in place.
49
+ #
50
+ # @return [Relaton::Index::Type]
51
+ #
52
+ def index
53
+ Relaton::Index.find_or_create(
54
+ :oasis, url: "#{ENDPOINT}#{INDEXFILE}.zip",
55
+ file: "#{INDEXFILE}.yaml",
56
+ pubid_class: ::Pubid::Oasis::Identifier
57
+ )
58
+ end
59
+
60
+ #
61
+ # Find the row that best answers a reference.
62
+ #
63
+ # **Pass the pubid, not the string.** `Type#search_candidates` narrows
64
+ # only when the argument is not a `String`, so passing the reference
65
+ # text would disable the binary search however the index was built.
66
+ #
67
+ # Selection is `Type#search`'s default with no block — pubid's
68
+ # asymmetric subset match (`Pubid::SubsetMatch`): the reference on the
69
+ # left, and a component it omits (`version`, `stage`, `part`, `label`)
70
+ # matches any value, which is what `#ranking_key` then orders.
71
+ #
72
+ # A reference pubid cannot parse finds nothing, and there is no
73
+ # substring fallback. `#parse_ref` supplies the publisher token, so
74
+ # after normalization the only unparseable inputs are a blank string
75
+ # and one over pubid's 1000-character cap — and a substring scan for
76
+ # `""` matches every row in the index, which is worse than a miss.
77
+ # This is also the v1 -> v2 semantic change IANA recorded: v1 matched
78
+ # by substring, so `OASIS amqp` resolved to some `amqp-core` record;
79
+ # v2 matches identifiers, so a partial name no longer resolves.
80
+ #
81
+ # @param text [String] the reference as the caller wrote it
82
+ # @return [Hash, nil] the index row, or nil
83
+ #
84
+ def find_index_entry(text)
85
+ pubid = parse_ref text
86
+ return unless pubid
87
+
88
+ rows = index.search(pubid)
89
+ rows.max_by { |row| ranking_key pubid, row[:id] }
90
+ end
91
+
92
+ #
93
+ # An OASIS printed id carries the publisher token, and pubid rejects a
94
+ # bare slug — but a caller may well write one ("mqtt-v5.0"), and
95
+ # `Db#fetch` hands the reference through verbatim. Supplying the token
96
+ # is normalization, not identification, so it happens here rather than
97
+ # in the grammar.
98
+ #
99
+ # The token is stripped **case-insensitively** and re-added in its
100
+ # canonical form. pubid's grammar matches the literal `OASIS `, so a
101
+ # lowercase `oasis stix` would otherwise keep its own token, be given a
102
+ # second one, and search for the specification named `oasis stix`.
103
+ # Everything after the token stays verbatim: an OASIS slug is
104
+ # case-sensitive (`STIX`, `amqp-core`, `OpenDocument`).
105
+ #
106
+ # An unrecognized reference **raises**; like ISO, ETSI and 3GPP we let it
107
+ # propagate. relaton-cli rescues `Pubid::Errors::Error` and renders
108
+ # `"..." is not a recognized standards identifier`
109
+ # (`gems/relaton-cli/lib/relaton/cli/command.rb:324`), and `Db#fetch`
110
+ # logs it through the `StandardError` arm at `lib/relaton/db.rb:122`.
111
+ # Rescuing here would collapse "this identifier is malformed" into "no
112
+ # such document", leaving a caller unable to tell them apart.
113
+ #
114
+ # @param text [String]
115
+ # @return [Pubid::Oasis::Identifier]
116
+ # @raise [Pubid::Errors::ParseError]
117
+ #
118
+ def parse_ref(text)
119
+ slug = text.to_s.strip.sub(/\A#{Regexp.escape PREFIX}/i, "")
120
+ ::Pubid::Oasis::Identifier.parse "#{PREFIX}#{slug}"
121
+ end
122
+
123
+ #
124
+ # The components the reference left out, which the row may therefore
125
+ # carry freely. `#find_index_entry` no longer needs this list — pubid's
126
+ # `===` reads the omission from the reference itself — but
127
+ # `#ranking_key` still counts the components the caller did not ask for.
128
+ # `number` — the specification name — is never optional: it is the whole
129
+ # identity of an OASIS record and the key the index bsearches on.
130
+ #
131
+ # @param pubid [Pubid::Oasis::Identifier]
132
+ # @return [Array<Symbol>]
133
+ #
134
+ def ignored(pubid)
135
+ OPTIONAL.select { |attr| pubid.public_send(attr).nil? }
136
+ end
137
+
138
+ #
139
+ # Order the matched rows. Ignoring a component means "don't care", so a
140
+ # loose reference matches the more specific rows too and this key
141
+ # decides between them:
142
+ #
143
+ # 1. an **exact printed id** always wins. Five published records are a
144
+ # bare specification name that also has versioned siblings — `OASIS
145
+ # EDXL`, `OData`, `OSLC`, `SAML`, `WSS` — and each is a real
146
+ # document in its own right. Without this key the "newest version"
147
+ # rule below answers a request for the bare record with its newest
148
+ # sibling; three of the five did exactly that. Published ids are
149
+ # unique (0 duplicates in 605 rows), so at most one row scores here;
150
+ # 2. then the **newest version**, segments compared as integers —
151
+ # `v2.1` beats `v1.2.1`, and `v10` beats `v9`, which a string
152
+ # compare gets wrong;
153
+ # 3. then the **least specific** row, i.e. the fewest components the
154
+ # reference did not ask for — a bare `OASIS STIX` wants `STIX-v2.1`,
155
+ # not `STIX-v2.1-CS02`, and `OASIS STIX-v1.2.1-CS01` wants that
156
+ # record itself, not its `-Pt3-Core` part;
157
+ # 4. then the **later stage revision** (`CS02` over `CS01`). Only the
158
+ # digits are compared: OASIS stage letters have no ranking this code
159
+ # is entitled to invent;
160
+ # 5. then the printed id, so the result never depends on index order.
161
+ #
162
+ # Checked against every published row: all 605 resolve to their own
163
+ # record, with and without the publisher token.
164
+ #
165
+ # @param pubid [Pubid::Oasis::Identifier] the parsed reference
166
+ # @param id [Pubid::Oasis::Identifier] a matched row's id
167
+ # @return [Array]
168
+ #
169
+ def ranking_key(pubid, id)
170
+ exact = id.to_s == pubid.to_s ? 1 : 0
171
+ extra = ignored(pubid).count { |attr| id.public_send(attr) }
172
+ [exact, digits(id.version), -extra, digits(id.stage), id.to_s]
173
+ end
174
+
175
+ # Integer segments of a version or stage token, for numeric ordering
176
+ # ("v1.2.1" -> [1, 2, 1], "CS02" -> [2], nil -> []).
177
+ #
178
+ # @param token [String, nil]
179
+ # @return [Array<Integer>]
180
+ def digits(token)
181
+ token.to_s.scan(/\d+/).map(&:to_i)
182
+ end
183
+
184
+ def fetch_yaml(uri)
185
+ resp = Net::HTTP.get_response uri
186
+ unless resp.code == "200"
187
+ raise Relaton::RequestError,
188
+ "Could not access #{uri}: HTTP #{resp.code}"
189
+ end
190
+ resp.body
191
+ end
192
+
193
+ def parse_item(yaml, text)
194
+ item = Item.from_yaml yaml
195
+ Util.info "Found: `#{item.docidentifier.first.content}`", key: text
196
+ item.tap { |i| i.fetched = Date.today.to_s }
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,71 @@
1
+ require "ferrum"
2
+ require "nokogiri"
3
+
4
+ module Relaton
5
+ module Oasis
6
+ # Thin Ferrum-backed agent that drives headless Chrome with stealth tweaks
7
+ # so the Cloudflare-protected oasis-open.org host serves real HTML instead
8
+ # of a "Just a moment..." challenge. Mirrors the pattern used by
9
+ # Relaton::Cie::BrowserAgent.
10
+ class BrowserAgent
11
+ UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 " \
12
+ "(KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
13
+ CHALLENGE_MARKERS = ["Just a moment", "challenge-platform"].freeze
14
+ MAX_CHALLENGE_WAIT = 30
15
+
16
+ def initialize
17
+ @browser = Ferrum::Browser.new(
18
+ headless: true,
19
+ timeout: 90,
20
+ process_timeout: 90,
21
+ window_size: [1366, 768],
22
+ browser_options: {
23
+ "disable-blink-features" => "AutomationControlled",
24
+ "disable-quic" => nil,
25
+ "no-sandbox" => nil,
26
+ },
27
+ )
28
+ @browser.headers.set(
29
+ "Accept-Language" => "en-US,en;q=0.9",
30
+ "Accept" => "text/html,application/xhtml+xml,application/xml;q=0.9," \
31
+ "image/webp,*/*;q=0.8",
32
+ "User-Agent" => UA,
33
+ )
34
+ @browser.evaluate_on_new_document(<<~JS)
35
+ Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
36
+ Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] });
37
+ Object.defineProperty(navigator, 'plugins', { get: () => [1,2,3,4,5] });
38
+ window.chrome = { runtime: {} };
39
+ JS
40
+ end
41
+
42
+ def get(url)
43
+ @browser.go_to(url)
44
+ wait_for_challenge
45
+ Nokogiri::HTML(@browser.body)
46
+ end
47
+
48
+ # HTTP status code of the most recent navigation's main resource,
49
+ # or nil if no navigation has happened yet.
50
+ def last_status
51
+ @browser&.network&.status
52
+ end
53
+
54
+ def quit
55
+ @browser&.quit
56
+ ensure
57
+ @browser = nil
58
+ end
59
+
60
+ private
61
+
62
+ def wait_for_challenge
63
+ MAX_CHALLENGE_WAIT.times do
64
+ return unless CHALLENGE_MARKERS.any? { |m| @browser.body.include?(m) }
65
+
66
+ sleep 1
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end