relaton 2.1.0 → 3.0.0.pre.alpha.1

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 (625) hide show
  1. checksums.yaml +4 -4
  2. data/{docs/README.adoc → README.adoc} +109 -38
  3. data/lib/relaton/3gpp/bibdata.rb +9 -0
  4. data/lib/relaton/3gpp/bibitem.rb +9 -0
  5. data/lib/relaton/3gpp/bibliography.rb +48 -0
  6. data/lib/relaton/3gpp/data_fetcher.rb +255 -0
  7. data/lib/relaton/3gpp/doctype.rb +9 -0
  8. data/lib/relaton/3gpp/ext.rb +31 -0
  9. data/lib/relaton/3gpp/item.rb +12 -0
  10. data/lib/relaton/3gpp/item_data.rb +15 -0
  11. data/lib/relaton/3gpp/parser.rb +400 -0
  12. data/lib/relaton/3gpp/processor.rb +68 -0
  13. data/lib/relaton/3gpp/release.rb +34 -0
  14. data/lib/relaton/3gpp/util.rb +8 -0
  15. data/lib/relaton/3gpp.rb +25 -0
  16. data/lib/relaton/bib/converter/asciibib/to_asciibib.rb +663 -0
  17. data/lib/relaton/bib/converter/asciibib.rb +13 -0
  18. data/lib/relaton/bib/converter/bibtex/from_bibtex.rb +245 -0
  19. data/lib/relaton/bib/converter/bibtex/to_bibtex.rb +341 -0
  20. data/lib/relaton/bib/converter/bibtex.rb +23 -0
  21. data/lib/relaton/bib/converter/bibxml/from_rfcxml.rb +386 -0
  22. data/lib/relaton/bib/converter/bibxml/from_rfcxml_referencegroup.rb +71 -0
  23. data/lib/relaton/bib/converter/bibxml/to_rfcxml.rb +308 -0
  24. data/lib/relaton/bib/converter/bibxml/to_rfcxml_referencegroup.rb +52 -0
  25. data/lib/relaton/bib/converter/bibxml.rb +51 -0
  26. data/lib/relaton/bib/hash_parser_v1.rb +767 -0
  27. data/lib/relaton/bib/item_data.rb +229 -0
  28. data/lib/relaton/bib/model/abstract.rb +16 -0
  29. data/lib/relaton/bib/model/address.rb +22 -0
  30. data/lib/relaton/bib/model/affiliation.rb +16 -0
  31. data/lib/relaton/bib/model/bibdata.rb +11 -0
  32. data/lib/relaton/bib/model/bibdata_shared.rb +12 -0
  33. data/lib/relaton/bib/model/bibitem.rb +11 -0
  34. data/lib/relaton/bib/model/bibitem_shared.rb +12 -0
  35. data/lib/relaton/bib/model/contact.rb +18 -0
  36. data/lib/relaton/bib/model/contribution_info.rb +15 -0
  37. data/lib/relaton/bib/model/contributor.rb +29 -0
  38. data/lib/relaton/bib/model/copyright.rb +27 -0
  39. data/lib/relaton/bib/model/date.rb +31 -0
  40. data/lib/relaton/bib/model/depiction.rb +16 -0
  41. data/lib/relaton/bib/model/docidentifier.rb +34 -0
  42. data/lib/relaton/bib/model/doctype.rb +14 -0
  43. data/lib/relaton/bib/model/edition.rb +14 -0
  44. data/lib/relaton/bib/model/ext.rb +39 -0
  45. data/lib/relaton/bib/model/extent.rb +16 -0
  46. data/lib/relaton/bib/model/formattedref.rb +43 -0
  47. data/lib/relaton/bib/model/full_name_type.rb +64 -0
  48. data/lib/relaton/bib/model/fullname.rb +11 -0
  49. data/lib/relaton/bib/model/ics.rb +49 -0
  50. data/lib/relaton/bib/model/image.rb +28 -0
  51. data/lib/relaton/bib/model/item.rb +96 -0
  52. data/lib/relaton/bib/model/item_base.rb +20 -0
  53. data/lib/relaton/bib/model/item_shared.rb +88 -0
  54. data/lib/relaton/bib/model/keyword.rb +30 -0
  55. data/lib/relaton/bib/model/locality.rb +18 -0
  56. data/lib/relaton/bib/model/locality_stack.rb +14 -0
  57. data/lib/relaton/bib/model/localized_string.rb +48 -0
  58. data/lib/relaton/bib/model/localized_string_attrs.rb +24 -0
  59. data/lib/relaton/bib/model/logo.rb +14 -0
  60. data/lib/relaton/bib/model/medium.rb +22 -0
  61. data/lib/relaton/bib/model/note.rb +16 -0
  62. data/lib/relaton/bib/model/organization.rb +13 -0
  63. data/lib/relaton/bib/model/organization_type.rb +42 -0
  64. data/lib/relaton/bib/model/person.rb +36 -0
  65. data/lib/relaton/bib/model/phone.rb +14 -0
  66. data/lib/relaton/bib/model/place.rb +33 -0
  67. data/lib/relaton/bib/model/price.rb +14 -0
  68. data/lib/relaton/bib/model/relation.rb +43 -0
  69. data/lib/relaton/bib/model/series.rb +34 -0
  70. data/lib/relaton/bib/model/size.rb +23 -0
  71. data/lib/relaton/bib/model/source_locality_stack.rb +14 -0
  72. data/lib/relaton/bib/model/status.rb +27 -0
  73. data/lib/relaton/bib/model/structured_identifier.rb +48 -0
  74. data/lib/relaton/bib/model/subdivision.rb +16 -0
  75. data/lib/relaton/bib/model/title.rb +56 -0
  76. data/lib/relaton/bib/model/type/plain_date.rb +16 -0
  77. data/lib/relaton/bib/model/type/string_date.rb +48 -0
  78. data/lib/relaton/bib/model/uri.rb +18 -0
  79. data/lib/relaton/bib/model/validity.rb +16 -0
  80. data/lib/relaton/bib/model/version.rb +43 -0
  81. data/lib/relaton/bib/namespace_helper.rb +21 -0
  82. data/lib/relaton/bib/sanitizer.rb +68 -0
  83. data/lib/relaton/bib/util.rb +18 -0
  84. data/lib/relaton/bib/versions.json +35 -0
  85. data/lib/relaton/bib.rb +48 -0
  86. data/lib/relaton/bipm/bibliography.rb +82 -0
  87. data/lib/relaton/bipm/converter/asciibib.rb +64 -0
  88. data/lib/relaton/bipm/data_fetcher.rb +57 -0
  89. data/lib/relaton/bipm/data_outcomes_parser.rb +657 -0
  90. data/lib/relaton/bipm/id_parser.rb +277 -0
  91. data/lib/relaton/bipm/item_data.rb +47 -0
  92. data/lib/relaton/bipm/model/bibdata.rb +9 -0
  93. data/lib/relaton/bipm/model/bibitem.rb +9 -0
  94. data/lib/relaton/bipm/model/comment_period.rb +13 -0
  95. data/lib/relaton/bipm/model/doctype.rb +12 -0
  96. data/lib/relaton/bipm/model/ext.rb +38 -0
  97. data/lib/relaton/bipm/model/item.rb +11 -0
  98. data/lib/relaton/bipm/model/structured_identifier.rb +15 -0
  99. data/lib/relaton/bipm/processor.rb +69 -0
  100. data/lib/relaton/bipm/rawdata_bipm_metrologia/affiliations.rb +111 -0
  101. data/lib/relaton/bipm/rawdata_bipm_metrologia/fetcher.rb +174 -0
  102. data/lib/relaton/bipm/rawdata_bipm_metrologia/niso_jats_parser.rb +353 -0
  103. data/lib/relaton/bipm/si_brochure_parser.rb +186 -0
  104. data/lib/relaton/bipm/util.rb +8 -0
  105. data/lib/relaton/bipm.rb +32 -0
  106. data/lib/relaton/bsi/bibliography.rb +124 -0
  107. data/lib/relaton/bsi/hit.rb +14 -0
  108. data/lib/relaton/bsi/hit_collection.rb +114 -0
  109. data/lib/relaton/bsi/item_data.rb +13 -0
  110. data/lib/relaton/bsi/model/bibdata.rb +8 -0
  111. data/lib/relaton/bsi/model/bibitem.rb +8 -0
  112. data/lib/relaton/bsi/model/docidentifier.rb +9 -0
  113. data/lib/relaton/bsi/model/doctype.rb +14 -0
  114. data/lib/relaton/bsi/model/ext.rb +17 -0
  115. data/lib/relaton/bsi/model/item.rb +17 -0
  116. data/lib/relaton/bsi/model/item_base.rb +22 -0
  117. data/lib/relaton/bsi/model/relation.rb +9 -0
  118. data/lib/relaton/bsi/processor.rb +42 -0
  119. data/lib/relaton/bsi/schema.json +24882 -0
  120. data/lib/relaton/bsi/scraper.rb +288 -0
  121. data/lib/relaton/bsi/util.rb +8 -0
  122. data/lib/relaton/bsi.rb +25 -0
  123. data/lib/relaton/calconnect/bibliography.rb +95 -0
  124. data/lib/relaton/calconnect/data_fetcher.rb +106 -0
  125. data/lib/relaton/calconnect/hit.rb +14 -0
  126. data/lib/relaton/calconnect/hit_collection.rb +84 -0
  127. data/lib/relaton/calconnect/item_data.rb +12 -0
  128. data/lib/relaton/calconnect/model/bibdata.rb +8 -0
  129. data/lib/relaton/calconnect/model/bibitem.rb +8 -0
  130. data/lib/relaton/calconnect/model/doctype.rb +11 -0
  131. data/lib/relaton/calconnect/model/ext.rb +11 -0
  132. data/lib/relaton/calconnect/model/item.rb +13 -0
  133. data/lib/relaton/calconnect/processor.rb +66 -0
  134. data/lib/relaton/calconnect/scraper.rb +87 -0
  135. data/lib/relaton/calconnect/util.rb +8 -0
  136. data/lib/relaton/calconnect.rb +26 -0
  137. data/lib/relaton/ccsds/bibliography.rb +63 -0
  138. data/lib/relaton/ccsds/data/fetcher.rb +247 -0
  139. data/lib/relaton/ccsds/data/iso_references.rb +30 -0
  140. data/lib/relaton/ccsds/data/parser.rb +194 -0
  141. data/lib/relaton/ccsds/hit.rb +24 -0
  142. data/lib/relaton/ccsds/hit_collection.rb +42 -0
  143. data/lib/relaton/ccsds/item_data.rb +9 -0
  144. data/lib/relaton/ccsds/model/bibdata.rb +8 -0
  145. data/lib/relaton/ccsds/model/bibitem.rb +8 -0
  146. data/lib/relaton/ccsds/model/doctype.rb +9 -0
  147. data/lib/relaton/ccsds/model/ext.rb +19 -0
  148. data/lib/relaton/ccsds/model/item.rb +13 -0
  149. data/lib/relaton/ccsds/processor.rb +68 -0
  150. data/lib/relaton/ccsds/util.rb +10 -0
  151. data/lib/relaton/ccsds.rb +33 -0
  152. data/lib/relaton/cen/bibliography.rb +121 -0
  153. data/lib/relaton/cen/committees.yaml +66 -0
  154. data/lib/relaton/cen/hit.rb +16 -0
  155. data/lib/relaton/cen/hit_collection.rb +68 -0
  156. data/lib/relaton/cen/item_data.rb +7 -0
  157. data/lib/relaton/cen/model/bibdata.rb +8 -0
  158. data/lib/relaton/cen/model/bibitem.rb +8 -0
  159. data/lib/relaton/cen/model/docidentifier.rb +9 -0
  160. data/lib/relaton/cen/model/ext.rb +11 -0
  161. data/lib/relaton/cen/model/item.rb +14 -0
  162. data/lib/relaton/cen/model/structured_identifier.rb +9 -0
  163. data/lib/relaton/cen/processor.rb +40 -0
  164. data/lib/relaton/cen/scraper.rb +210 -0
  165. data/lib/relaton/cen/util.rb +8 -0
  166. data/lib/relaton/cen.rb +29 -0
  167. data/lib/relaton/cie/bibdata.rb +8 -0
  168. data/lib/relaton/cie/bibitem.rb +8 -0
  169. data/lib/relaton/cie/bibliography.rb +31 -0
  170. data/lib/relaton/cie/data_fetcher.rb +355 -0
  171. data/lib/relaton/cie/ext.rb +7 -0
  172. data/lib/relaton/cie/item.rb +11 -0
  173. data/lib/relaton/cie/item_data.rb +6 -0
  174. data/lib/relaton/cie/processor.rb +66 -0
  175. data/lib/relaton/cie/scrapper.rb +39 -0
  176. data/lib/relaton/cie/util.rb +8 -0
  177. data/lib/relaton/cie.rb +28 -0
  178. data/lib/relaton/core/array_wrapper.rb +20 -0
  179. data/lib/relaton/core/data_fetcher.rb +97 -0
  180. data/lib/relaton/core/date_parser.rb +42 -0
  181. data/lib/relaton/core/hash_keys_sybolizer.rb +19 -0
  182. data/lib/relaton/core/hit.rb +49 -0
  183. data/lib/relaton/core/hit_collection.rb +118 -0
  184. data/lib/relaton/core/processor.rb +48 -0
  185. data/lib/relaton/core/workers_pool.rb +45 -0
  186. data/lib/relaton/core.rb +9 -0
  187. data/lib/relaton/db/cache.rb +232 -0
  188. data/lib/relaton/db/config.rb +24 -0
  189. data/lib/relaton/db/registry.rb +119 -0
  190. data/lib/relaton/db/util.rb +9 -0
  191. data/lib/relaton/db/workers_pool.rb +22 -0
  192. data/lib/relaton/db.rb +20 -206
  193. data/lib/relaton/doi/crossref.rb +72 -0
  194. data/lib/relaton/doi/parser.rb +827 -0
  195. data/lib/relaton/doi/processor.rb +65 -0
  196. data/lib/relaton/doi/util.rb +8 -0
  197. data/lib/relaton/doi.rb +20 -0
  198. data/lib/relaton/ecma/bibdata.rb +8 -0
  199. data/lib/relaton/ecma/bibitem.rb +8 -0
  200. data/lib/relaton/ecma/bibliography.rb +81 -0
  201. data/lib/relaton/ecma/data_fetcher.rb +103 -0
  202. data/lib/relaton/ecma/data_parser.rb +49 -0
  203. data/lib/relaton/ecma/edition_parser.rb +80 -0
  204. data/lib/relaton/ecma/ext.rb +7 -0
  205. data/lib/relaton/ecma/item.rb +11 -0
  206. data/lib/relaton/ecma/item_data.rb +6 -0
  207. data/lib/relaton/ecma/memento_parser.rb +60 -0
  208. data/lib/relaton/ecma/page_fetcher.rb +27 -0
  209. data/lib/relaton/ecma/parser_common.rb +33 -0
  210. data/lib/relaton/ecma/processor.rb +66 -0
  211. data/lib/relaton/ecma/standard_parser.rb +134 -0
  212. data/lib/relaton/ecma/util.rb +8 -0
  213. data/lib/relaton/ecma.rb +24 -0
  214. data/lib/relaton/etsi/bibdata.rb +10 -0
  215. data/lib/relaton/etsi/bibitem.rb +10 -0
  216. data/lib/relaton/etsi/bibliography.rb +46 -0
  217. data/lib/relaton/etsi/data_fetcher.rb +128 -0
  218. data/lib/relaton/etsi/data_parser.rb +208 -0
  219. data/lib/relaton/etsi/doctype.rb +30 -0
  220. data/lib/relaton/etsi/ext.rb +31 -0
  221. data/lib/relaton/etsi/item.rb +15 -0
  222. data/lib/relaton/etsi/item_data.rb +6 -0
  223. data/lib/relaton/etsi/processor.rb +69 -0
  224. data/lib/relaton/etsi/pubid.rb +37 -0
  225. data/lib/relaton/etsi/status.rb +13 -0
  226. data/lib/relaton/etsi/util.rb +8 -0
  227. data/lib/relaton/etsi.rb +25 -0
  228. data/lib/relaton/gb/bibdata.rb +8 -0
  229. data/lib/relaton/gb/bibitem.rb +8 -0
  230. data/lib/relaton/gb/bibliography.rb +145 -0
  231. data/lib/relaton/gb/ccs.rb +14 -0
  232. data/lib/relaton/gb/committee.rb +13 -0
  233. data/lib/relaton/gb/docidentifier.rb +23 -0
  234. data/lib/relaton/gb/doctype.rb +9 -0
  235. data/lib/relaton/gb/ext.rb +36 -0
  236. data/lib/relaton/gb/gb_scraper.rb +61 -0
  237. data/lib/relaton/gb/gb_type.rb +20 -0
  238. data/lib/relaton/gb/hit.rb +48 -0
  239. data/lib/relaton/gb/hit_collection.rb +19 -0
  240. data/lib/relaton/gb/item.rb +13 -0
  241. data/lib/relaton/gb/item_data.rb +6 -0
  242. data/lib/relaton/gb/processor.rb +46 -0
  243. data/lib/relaton/gb/project_number.rb +38 -0
  244. data/lib/relaton/gb/scraper.rb +204 -0
  245. data/lib/relaton/gb/sec_scraper.rb +92 -0
  246. data/lib/relaton/gb/stage_name.rb +13 -0
  247. data/lib/relaton/gb/structured_identifier.rb +26 -0
  248. data/lib/relaton/gb/t_scraper.rb +126 -0
  249. data/lib/relaton/gb/util.rb +8 -0
  250. data/lib/relaton/gb/yaml/prefixes.yaml +200 -0
  251. data/lib/relaton/gb.rb +33 -0
  252. data/lib/relaton/iana/bibdata.rb +8 -0
  253. data/lib/relaton/iana/bibitem.rb +8 -0
  254. data/lib/relaton/iana/bibliography.rb +47 -0
  255. data/lib/relaton/iana/data_fetcher.rb +71 -0
  256. data/lib/relaton/iana/item.rb +7 -0
  257. data/lib/relaton/iana/item_data.rb +6 -0
  258. data/lib/relaton/iana/parser.rb +146 -0
  259. data/lib/relaton/iana/processor.rb +68 -0
  260. data/lib/relaton/iana/util.rb +8 -0
  261. data/lib/relaton/iana.rb +29 -0
  262. data/lib/relaton/iec/bibliography.rb +283 -0
  263. data/lib/relaton/iec/data_fetcher.rb +216 -0
  264. data/lib/relaton/iec/data_parser.rb +391 -0
  265. data/lib/relaton/iec/hit.rb +26 -0
  266. data/lib/relaton/iec/hit_collection.rb +138 -0
  267. data/lib/relaton/iec/item_data.rb +7 -0
  268. data/lib/relaton/iec/model/bibdata.rb +8 -0
  269. data/lib/relaton/iec/model/bibitem.rb +8 -0
  270. data/lib/relaton/iec/model/docidentifier.rb +131 -0
  271. data/lib/relaton/iec/model/doctype.rb +12 -0
  272. data/lib/relaton/iec/model/ext.rb +53 -0
  273. data/lib/relaton/iec/model/item.rb +20 -0
  274. data/lib/relaton/iec/model/item_base.rb +12 -0
  275. data/lib/relaton/iec/model/relation.rb +7 -0
  276. data/lib/relaton/iec/model/stage_name.rb +13 -0
  277. data/lib/relaton/iec/processor.rb +73 -0
  278. data/lib/relaton/iec/statuses.yml +199 -0
  279. data/lib/relaton/iec/util.rb +8 -0
  280. data/lib/relaton/iec.rb +98 -0
  281. data/lib/relaton/ieee/balloting_group.rb +13 -0
  282. data/lib/relaton/ieee/bibdata.rb +8 -0
  283. data/lib/relaton/ieee/bibitem.rb +8 -0
  284. data/lib/relaton/ieee/bibliography.rb +51 -0
  285. data/lib/relaton/ieee/converter/bibxml/from_rfcxml.rb +10 -0
  286. data/lib/relaton/ieee/converter/bibxml/from_rfcxml_referencegroup.rb +10 -0
  287. data/lib/relaton/ieee/converter/bibxml.rb +20 -0
  288. data/lib/relaton/ieee/data_fetcher.rb +630 -0
  289. data/lib/relaton/ieee/doctype.rb +9 -0
  290. data/lib/relaton/ieee/editorial_group.rb +19 -0
  291. data/lib/relaton/ieee/ext.rb +36 -0
  292. data/lib/relaton/ieee/idams_parser.rb +323 -0
  293. data/lib/relaton/ieee/item.rb +11 -0
  294. data/lib/relaton/ieee/item_data.rb +7 -0
  295. data/lib/relaton/ieee/processor.rb +68 -0
  296. data/lib/relaton/ieee/pub_id.rb +161 -0
  297. data/lib/relaton/ieee/rawbib_id_parser.rb +548 -0
  298. data/lib/relaton/ieee/util.rb +8 -0
  299. data/lib/relaton/ieee.rb +29 -0
  300. data/lib/relaton/ietf/bibdata.rb +8 -0
  301. data/lib/relaton/ietf/bibitem.rb +8 -0
  302. data/lib/relaton/ietf/bibliography.rb +35 -0
  303. data/lib/relaton/ietf/bibxml_parser.rb +232 -0
  304. data/lib/relaton/ietf/data_fetcher.rb +278 -0
  305. data/lib/relaton/ietf/doctype.rb +9 -0
  306. data/lib/relaton/ietf/ext.rb +63 -0
  307. data/lib/relaton/ietf/item.rb +16 -0
  308. data/lib/relaton/ietf/item_base.rb +18 -0
  309. data/lib/relaton/ietf/item_data.rb +6 -0
  310. data/lib/relaton/ietf/processing_instructions.rb +79 -0
  311. data/lib/relaton/ietf/processor.rb +68 -0
  312. data/lib/relaton/ietf/relation.rb +9 -0
  313. data/lib/relaton/ietf/rfc/abstract.rb +19 -0
  314. data/lib/relaton/ietf/rfc/author.rb +21 -0
  315. data/lib/relaton/ietf/rfc/entry.rb +410 -0
  316. data/lib/relaton/ietf/rfc/entry_date.rb +21 -0
  317. data/lib/relaton/ietf/rfc/format.rb +19 -0
  318. data/lib/relaton/ietf/rfc/index.rb +46 -0
  319. data/lib/relaton/ietf/rfc/is_also.rb +21 -0
  320. data/lib/relaton/ietf/rfc/keywords.rb +19 -0
  321. data/lib/relaton/ietf/rfc/rfc_index_namespace.rb +11 -0
  322. data/lib/relaton/ietf/scraper.rb +68 -0
  323. data/lib/relaton/ietf/util.rb +8 -0
  324. data/lib/relaton/ietf/wg_name_resolver.rb +42 -0
  325. data/lib/relaton/ietf.rb +27 -0
  326. data/lib/relaton/iho/bibdata.rb +8 -0
  327. data/lib/relaton/iho/bibitem.rb +8 -0
  328. data/lib/relaton/iho/bibliography.rb +114 -0
  329. data/lib/relaton/iho/comment_period.rb +13 -0
  330. data/lib/relaton/iho/docidentifier.rb +31 -0
  331. data/lib/relaton/iho/doctype.rb +10 -0
  332. data/lib/relaton/iho/ext.rb +20 -0
  333. data/lib/relaton/iho/hash_parser_v1.rb +144 -0
  334. data/lib/relaton/iho/item.rb +20 -0
  335. data/lib/relaton/iho/item_base.rb +18 -0
  336. data/lib/relaton/iho/item_data.rb +6 -0
  337. data/lib/relaton/iho/processor.rb +54 -0
  338. data/lib/relaton/iho/relation.rb +9 -0
  339. data/lib/relaton/iho/structured_identifier.rb +20 -0
  340. data/lib/relaton/iho/util.rb +8 -0
  341. data/lib/relaton/iho.rb +27 -0
  342. data/lib/relaton/index/config.rb +52 -0
  343. data/lib/relaton/index/file_io.rb +305 -0
  344. data/lib/relaton/index/file_storage.rb +61 -0
  345. data/lib/relaton/index/id_number.rb +30 -0
  346. data/lib/relaton/index/pool.rb +41 -0
  347. data/lib/relaton/index/type.rb +159 -0
  348. data/lib/relaton/index/util.rb +18 -0
  349. data/lib/relaton/index.rb +60 -0
  350. data/lib/relaton/isbn/isbn.rb +61 -0
  351. data/lib/relaton/isbn/open_library.rb +43 -0
  352. data/lib/relaton/isbn/parser.rb +88 -0
  353. data/lib/relaton/isbn/processor.rb +48 -0
  354. data/lib/relaton/isbn/util.rb +8 -0
  355. data/lib/relaton/isbn.rb +19 -0
  356. data/lib/relaton/iso/bibliography.rb +407 -0
  357. data/lib/relaton/iso/data_fetcher.rb +338 -0
  358. data/lib/relaton/iso/data_parser.rb +444 -0
  359. data/lib/relaton/iso/hash_parser_v1.rb +177 -0
  360. data/lib/relaton/iso/hit.rb +57 -0
  361. data/lib/relaton/iso/hit_collection.rb +184 -0
  362. data/lib/relaton/iso/item_data.rb +28 -0
  363. data/lib/relaton/iso/model/bibdata.rb +10 -0
  364. data/lib/relaton/iso/model/bibitem.rb +8 -0
  365. data/lib/relaton/iso/model/contributor.rb +6 -0
  366. data/lib/relaton/iso/model/contributor_info.rb +9 -0
  367. data/lib/relaton/iso/model/docidentifier.rb +134 -0
  368. data/lib/relaton/iso/model/doctype.rb +13 -0
  369. data/lib/relaton/iso/model/ext.rb +35 -0
  370. data/lib/relaton/iso/model/item.rb +17 -0
  371. data/lib/relaton/iso/model/item_base.rb +22 -0
  372. data/lib/relaton/iso/model/organization.rb +9 -0
  373. data/lib/relaton/iso/model/project_number.rb +22 -0
  374. data/lib/relaton/iso/model/relation.rb +9 -0
  375. data/lib/relaton/iso/model/stagename.rb +14 -0
  376. data/lib/relaton/iso/model/structured_identifier.rb +31 -0
  377. data/lib/relaton/iso/processor.rb +84 -0
  378. data/lib/relaton/iso/scraper.rb +619 -0
  379. data/lib/relaton/iso/type/pubid.rb +50 -0
  380. data/lib/relaton/iso/util.rb +8 -0
  381. data/lib/relaton/iso.rb +30 -0
  382. data/lib/relaton/itu/bibliography.rb +90 -0
  383. data/lib/relaton/itu/data_fetcher.rb +104 -0
  384. data/lib/relaton/itu/data_parser_r.rb +140 -0
  385. data/lib/relaton/itu/hit.rb +22 -0
  386. data/lib/relaton/itu/hit_collection.rb +127 -0
  387. data/lib/relaton/itu/item_data.rb +6 -0
  388. data/lib/relaton/itu/model/approval_stage.rb +13 -0
  389. data/lib/relaton/itu/model/bibdata.rb +8 -0
  390. data/lib/relaton/itu/model/bibitem.rb +8 -0
  391. data/lib/relaton/itu/model/docidentifier.rb +9 -0
  392. data/lib/relaton/itu/model/doctype.rb +13 -0
  393. data/lib/relaton/itu/model/ext.rb +47 -0
  394. data/lib/relaton/itu/model/item.rb +13 -0
  395. data/lib/relaton/itu/model/meeting.rb +13 -0
  396. data/lib/relaton/itu/model/meeting_date.rb +15 -0
  397. data/lib/relaton/itu/model/question.rb +13 -0
  398. data/lib/relaton/itu/model/recommendation_status.rb +11 -0
  399. data/lib/relaton/itu/model/structured_identifier.rb +19 -0
  400. data/lib/relaton/itu/processor.rb +66 -0
  401. data/lib/relaton/itu/pubid.rb +177 -0
  402. data/lib/relaton/itu/radio_regulations_parser.rb +70 -0
  403. data/lib/relaton/itu/recommendation_parser.rb +161 -0
  404. data/lib/relaton/itu/scraper.rb +193 -0
  405. data/lib/relaton/itu/util.rb +8 -0
  406. data/lib/relaton/itu.rb +33 -0
  407. data/lib/relaton/jis/bibdata.rb +8 -0
  408. data/lib/relaton/jis/bibitem.rb +8 -0
  409. data/lib/relaton/jis/bibliography.rb +75 -0
  410. data/lib/relaton/jis/data_fetcher.rb +181 -0
  411. data/lib/relaton/jis/docidentifier.rb +21 -0
  412. data/lib/relaton/jis/doctype.rb +9 -0
  413. data/lib/relaton/jis/ext.rb +13 -0
  414. data/lib/relaton/jis/hit.rb +93 -0
  415. data/lib/relaton/jis/hit_collection.rb +127 -0
  416. data/lib/relaton/jis/item.rb +22 -0
  417. data/lib/relaton/jis/item_base.rb +26 -0
  418. data/lib/relaton/jis/item_data.rb +8 -0
  419. data/lib/relaton/jis/processor.rb +55 -0
  420. data/lib/relaton/jis/relation.rb +11 -0
  421. data/lib/relaton/jis/scraper.rb +232 -0
  422. data/lib/relaton/jis/structured_identifier.rb +13 -0
  423. data/lib/relaton/jis/util.rb +8 -0
  424. data/lib/relaton/jis.rb +33 -0
  425. data/lib/relaton/logger/channels/gh_issue.rb +78 -0
  426. data/lib/relaton/logger/config.rb +34 -0
  427. data/lib/relaton/logger/formatter_json.rb +8 -0
  428. data/lib/relaton/logger/formatter_string.rb +12 -0
  429. data/lib/relaton/logger/log.rb +64 -0
  430. data/lib/relaton/logger/log_device.rb +27 -0
  431. data/lib/relaton/logger/pool.rb +24 -0
  432. data/lib/relaton/logger.rb +18 -0
  433. data/lib/relaton/nist/bibdata.rb +8 -0
  434. data/lib/relaton/nist/bibitem.rb +8 -0
  435. data/lib/relaton/nist/bibliography.rb +191 -0
  436. data/lib/relaton/nist/comment_period.rb +15 -0
  437. data/lib/relaton/nist/data_fetcher.rb +84 -0
  438. data/lib/relaton/nist/date.rb +7 -0
  439. data/lib/relaton/nist/doctype.rb +7 -0
  440. data/lib/relaton/nist/ext.rb +16 -0
  441. data/lib/relaton/nist/hit.rb +18 -0
  442. data/lib/relaton/nist/hit_collection.rb +362 -0
  443. data/lib/relaton/nist/item.rb +17 -0
  444. data/lib/relaton/nist/item_data.rb +6 -0
  445. data/lib/relaton/nist/mods_parser.rb +276 -0
  446. data/lib/relaton/nist/processor.rb +68 -0
  447. data/lib/relaton/nist/pubs_export.rb +69 -0
  448. data/lib/relaton/nist/relation.rb +7 -0
  449. data/lib/relaton/nist/scraper.rb +290 -0
  450. data/lib/relaton/nist/series.yaml +49 -0
  451. data/lib/relaton/nist/util.rb +8 -0
  452. data/lib/relaton/nist.rb +34 -0
  453. data/lib/relaton/oasis/bibdata.rb +8 -0
  454. data/lib/relaton/oasis/bibitem.rb +8 -0
  455. data/lib/relaton/oasis/bibliography.rb +60 -0
  456. data/lib/relaton/oasis/browser_agent.rb +71 -0
  457. data/lib/relaton/oasis/data_fetcher.rb +94 -0
  458. data/lib/relaton/oasis/data_parser.rb +305 -0
  459. data/lib/relaton/oasis/data_parser_utils.rb +296 -0
  460. data/lib/relaton/oasis/data_part_parser.rb +239 -0
  461. data/lib/relaton/oasis/doctype.rb +7 -0
  462. data/lib/relaton/oasis/ext.rb +19 -0
  463. data/lib/relaton/oasis/item.rb +11 -0
  464. data/lib/relaton/oasis/item_data.rb +6 -0
  465. data/lib/relaton/oasis/processor.rb +68 -0
  466. data/lib/relaton/oasis/util.rb +8 -0
  467. data/lib/relaton/oasis.rb +28 -0
  468. data/lib/relaton/ogc/bibdata.rb +8 -0
  469. data/lib/relaton/ogc/bibitem.rb +8 -0
  470. data/lib/relaton/ogc/bibliography.rb +64 -0
  471. data/lib/relaton/ogc/data_fetcher.rb +110 -0
  472. data/lib/relaton/ogc/docidentifier.rb +6 -0
  473. data/lib/relaton/ogc/doctype.rb +12 -0
  474. data/lib/relaton/ogc/ext.rb +15 -0
  475. data/lib/relaton/ogc/hit.rb +18 -0
  476. data/lib/relaton/ogc/hit_collection.rb +36 -0
  477. data/lib/relaton/ogc/item.rb +13 -0
  478. data/lib/relaton/ogc/item_data.rb +6 -0
  479. data/lib/relaton/ogc/processor.rb +58 -0
  480. data/lib/relaton/ogc/scraper.rb +225 -0
  481. data/lib/relaton/ogc/util.rb +8 -0
  482. data/lib/relaton/ogc.rb +26 -0
  483. data/lib/relaton/oiml/bibdata.rb +8 -0
  484. data/lib/relaton/oiml/bibitem.rb +8 -0
  485. data/lib/relaton/oiml/bibliography.rb +94 -0
  486. data/lib/relaton/oiml/docidentifier.rb +33 -0
  487. data/lib/relaton/oiml/doctype.rb +13 -0
  488. data/lib/relaton/oiml/ext.rb +42 -0
  489. data/lib/relaton/oiml/item.rb +20 -0
  490. data/lib/relaton/oiml/item_base.rb +18 -0
  491. data/lib/relaton/oiml/item_data.rb +6 -0
  492. data/lib/relaton/oiml/processor.rb +54 -0
  493. data/lib/relaton/oiml/relation.rb +9 -0
  494. data/lib/relaton/oiml/util.rb +8 -0
  495. data/lib/relaton/oiml.rb +24 -0
  496. data/lib/relaton/omg/bibdata.rb +8 -0
  497. data/lib/relaton/omg/bibitem.rb +8 -0
  498. data/lib/relaton/omg/bibliography.rb +31 -0
  499. data/lib/relaton/omg/ext.rb +7 -0
  500. data/lib/relaton/omg/item.rb +8 -0
  501. data/lib/relaton/omg/item_data.rb +6 -0
  502. data/lib/relaton/omg/processor.rb +34 -0
  503. data/lib/relaton/omg/scraper.rb +141 -0
  504. data/lib/relaton/omg/util.rb +8 -0
  505. data/lib/relaton/omg.rb +24 -0
  506. data/lib/relaton/plateau/bibdata.rb +8 -0
  507. data/lib/relaton/plateau/bibitem.rb +8 -0
  508. data/lib/relaton/plateau/bibliography.rb +24 -0
  509. data/lib/relaton/plateau/data_fetcher.rb +153 -0
  510. data/lib/relaton/plateau/doctype.rb +7 -0
  511. data/lib/relaton/plateau/ext.rb +23 -0
  512. data/lib/relaton/plateau/handbook_parser.rb +95 -0
  513. data/lib/relaton/plateau/hit.rb +13 -0
  514. data/lib/relaton/plateau/hit_collection.rb +59 -0
  515. data/lib/relaton/plateau/item.rb +12 -0
  516. data/lib/relaton/plateau/item_data.rb +6 -0
  517. data/lib/relaton/plateau/parser.rb +101 -0
  518. data/lib/relaton/plateau/processor.rb +49 -0
  519. data/lib/relaton/plateau/technical_report_parser.rb +91 -0
  520. data/lib/relaton/plateau/util.rb +8 -0
  521. data/lib/relaton/plateau.rb +28 -0
  522. data/lib/relaton/un/bibdata.rb +8 -0
  523. data/lib/relaton/un/bibitem.rb +8 -0
  524. data/lib/relaton/un/bibliography.rb +48 -0
  525. data/lib/relaton/un/doctype.rb +10 -0
  526. data/lib/relaton/un/ext.rb +30 -0
  527. data/lib/relaton/un/hit.rb +56 -0
  528. data/lib/relaton/un/hit_collection.rb +61 -0
  529. data/lib/relaton/un/item.rb +11 -0
  530. data/lib/relaton/un/item_data.rb +6 -0
  531. data/lib/relaton/un/parser.rb +108 -0
  532. data/lib/relaton/un/processor.rb +38 -0
  533. data/lib/relaton/un/session.rb +25 -0
  534. data/lib/relaton/un/token_generator.rb +105 -0
  535. data/lib/relaton/un/util.rb +8 -0
  536. data/lib/relaton/un/wasm/decoder.rb +434 -0
  537. data/lib/relaton/un/wasm/instance.rb +101 -0
  538. data/lib/relaton/un/wasm/interpreter.rb +613 -0
  539. data/lib/relaton/un/wasm/memory.rb +112 -0
  540. data/lib/relaton/un/wasm/module.rb +47 -0
  541. data/lib/relaton/un/wasm.rb +17 -0
  542. data/lib/relaton/un/wasm_v_bg.wasm +0 -0
  543. data/lib/relaton/un.rb +28 -0
  544. data/lib/relaton/version.rb +1 -1
  545. data/lib/relaton/w3c/bibdata.rb +8 -0
  546. data/lib/relaton/w3c/bibitem.rb +8 -0
  547. data/lib/relaton/w3c/bibliography.rb +54 -0
  548. data/lib/relaton/w3c/data_fetcher.rb +309 -0
  549. data/lib/relaton/w3c/data_parser.rb +379 -0
  550. data/lib/relaton/w3c/doctype.rb +7 -0
  551. data/lib/relaton/w3c/ext.rb +11 -0
  552. data/lib/relaton/w3c/item.rb +12 -0
  553. data/lib/relaton/w3c/item_data.rb +6 -0
  554. data/lib/relaton/w3c/processor.rb +49 -0
  555. data/lib/relaton/w3c/pubid.rb +73 -0
  556. data/lib/relaton/w3c/safe_realize.rb +59 -0
  557. data/lib/relaton/w3c/util.rb +8 -0
  558. data/lib/relaton/w3c.rb +25 -0
  559. data/lib/relaton/xsf/bibdata.rb +8 -0
  560. data/lib/relaton/xsf/bibitem.rb +8 -0
  561. data/lib/relaton/xsf/bibliography.rb +24 -0
  562. data/lib/relaton/xsf/data_fetcher.rb +56 -0
  563. data/lib/relaton/xsf/hit.rb +17 -0
  564. data/lib/relaton/xsf/hit_collection.rb +24 -0
  565. data/lib/relaton/xsf/item.rb +7 -0
  566. data/lib/relaton/xsf/item_data.rb +6 -0
  567. data/lib/relaton/xsf/processor.rb +50 -0
  568. data/lib/relaton/xsf/util.rb +9 -0
  569. data/lib/relaton/xsf.rb +30 -0
  570. data/lib/relaton-core.rb +1 -0
  571. data/lib/relaton.rb +44 -9
  572. metadata +708 -150
  573. data/.github/workflows/rake.yml +0 -14
  574. data/.github/workflows/release.yml +0 -24
  575. data/.github/workflows/rubocop.yml +0 -48
  576. data/.gitignore +0 -12
  577. data/.rspec +0 -3
  578. data/.rubocop.yml +0 -12
  579. data/CLAUDE.md +0 -70
  580. data/Gemfile +0 -21
  581. data/Rakefile +0 -6
  582. data/docs/CHANGELOG.adoc +0 -16
  583. data/docs/VERSIONING_POLICY.adoc +0 -38
  584. data/docs/navigation.adoc +0 -6
  585. data/lib/relaton/config.rb +0 -24
  586. data/lib/relaton/db_cache.rb +0 -230
  587. data/lib/relaton/registry.rb +0 -118
  588. data/lib/relaton/util.rb +0 -7
  589. data/lib/relaton/workers_pool.rb +0 -21
  590. data/relaton.gemspec +0 -61
  591. data/spec/relaton/config_spec.rb +0 -10
  592. data/spec/relaton/db_cache_spec.rb +0 -51
  593. data/spec/relaton/db_spec.rb +0 -556
  594. data/spec/relaton/registry_spec.rb +0 -178
  595. data/spec/relaton/util_spec.rb +0 -3
  596. data/spec/relaton_spec.rb +0 -725
  597. data/spec/spec_helper.rb +0 -45
  598. data/spec/support/gb_t_20223_2006.xml +0 -33
  599. data/spec/support/iso_111111119115_1.xml +0 -0
  600. data/spec/support/iso_19115_1.xml +0 -115
  601. data/spec/support/iso_19115_2.xml +0 -95
  602. data/spec/support/rfc_8341.xml +0 -46
  603. data/spec/vcr_cassetes/3gpp_tr_00_01u_umts_3_0_0.yml +0 -12720
  604. data/spec/vcr_cassetes/api_relaton_org.yml +0 -121
  605. data/spec/vcr_cassetes/api_relaton_org_unavailable.yml +0 -143
  606. data/spec/vcr_cassetes/cc_dir_10005_2019.yml +0 -199
  607. data/spec/vcr_cassetes/cie_001_1980.yml +0 -401
  608. data/spec/vcr_cassetes/cipm_meeting_43.yml +0 -1513
  609. data/spec/vcr_cassetes/doi_10_6028_nist_ir_8245.yml +0 -86
  610. data/spec/vcr_cassetes/ecma_6.yml +0 -112
  611. data/spec/vcr_cassetes/en_10160_1999.yml +0 -13624
  612. data/spec/vcr_cassetes/gb_t_20223_2006.yml +0 -733
  613. data/spec/vcr_cassetes/ieee_528_2019.yml +0 -2786
  614. data/spec/vcr_cassetes/iso_111111119115_1.yml +0 -12951
  615. data/spec/vcr_cassetes/iso_19115_1.yml +0 -13177
  616. data/spec/vcr_cassetes/iso_19115_1_2.yml +0 -369
  617. data/spec/vcr_cassetes/iso_19115_1_std.yml +0 -13177
  618. data/spec/vcr_cassetes/iso_19115_all_parts.yml +0 -229
  619. data/spec/vcr_cassetes/iso_19133_2005.yml +0 -148
  620. data/spec/vcr_cassetes/iso_combined_applied.yml +0 -364
  621. data/spec/vcr_cassetes/iso_combined_included.yml +0 -364
  622. data/spec/vcr_cassetes/iso_dis.yml +0 -157
  623. data/spec/vcr_cassetes/ogc_19_025r1.yml +0 -371
  624. data/spec/vcr_cassetes/omg_ami4ccm_1_0.yml +0 -317
  625. data/spec/vcr_cassetes/rfc_8341.yml +0 -1272
@@ -0,0 +1,355 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "English"
4
+ require "fileutils"
5
+ require "ferrum"
6
+ require "nokogiri"
7
+ require "relaton/index"
8
+ require "relaton/bib"
9
+ require "relaton/core/data_fetcher"
10
+ require_relative "../cie"
11
+
12
+ module Relaton
13
+ module Cie
14
+ # Thin Ferrum-backed HTTP agent that mimics the Mechanize#get interface
15
+ # used elsewhere in DataFetcher. Drives headless Chrome with stealth
16
+ # tweaks so the CIE catalogue host (Cloudflare-protected accuristech)
17
+ # serves real HTML instead of a "Just a moment..." challenge.
18
+ class BrowserAgent
19
+ UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 " \
20
+ "(KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
21
+ CHALLENGE_MARKERS = ["Just a moment", "challenge-platform"].freeze
22
+ MAX_CHALLENGE_WAIT = 30
23
+
24
+ def initialize
25
+ @browser = Ferrum::Browser.new(
26
+ headless: true,
27
+ timeout: 90,
28
+ process_timeout: 90,
29
+ window_size: [1366, 768],
30
+ browser_options: {
31
+ "disable-blink-features" => "AutomationControlled",
32
+ "disable-quic" => nil,
33
+ "no-sandbox" => nil
34
+ }
35
+ )
36
+ @browser.headers.set(
37
+ "Accept-Language" => "en-US,en;q=0.9",
38
+ "Accept" => "text/html,application/xhtml+xml,application/xml;q=0.9," \
39
+ "image/webp,*/*;q=0.8",
40
+ "User-Agent" => UA
41
+ )
42
+ # Pre-mask the most common headless-Chrome tells before any page JS runs.
43
+ @browser.evaluate_on_new_document(<<~JS)
44
+ Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
45
+ Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] });
46
+ Object.defineProperty(navigator, 'plugins', { get: () => [1,2,3,4,5] });
47
+ window.chrome = { runtime: {} };
48
+ JS
49
+ end
50
+
51
+ def get(url)
52
+ @browser.go_to(url)
53
+ wait_for_challenge
54
+ Nokogiri::HTML(@browser.body)
55
+ end
56
+
57
+ def quit
58
+ @browser&.quit
59
+ ensure
60
+ @browser = nil
61
+ end
62
+
63
+ private
64
+
65
+ def wait_for_challenge
66
+ MAX_CHALLENGE_WAIT.times do
67
+ return unless CHALLENGE_MARKERS.any? { |m| @browser.body.include?(m) }
68
+
69
+ sleep 1
70
+ end
71
+ end
72
+ end
73
+
74
+ class DataFetcher < Relaton::Core::DataFetcher
75
+ URL = "https://www.techstreet.com/cie/searches/31156444?page=1&per_page=100"
76
+
77
+ def agent
78
+ @agent ||= BrowserAgent.new
79
+ end
80
+
81
+ def index
82
+ @index ||= Index.find_or_create :cie, file: "index-v1.yaml"
83
+ end
84
+
85
+ def log_error(msg)
86
+ Util.error msg
87
+ end
88
+
89
+ # @param hit [Nokogiri::HTML::Document]
90
+ # @param doc [Mechanize::Page]
91
+ # @return [Array<Relaton::Bib::Docidentifier>]
92
+ def fetch_docid(hit, doc)
93
+ code, code2 = parse_code hit, doc
94
+ docid = []
95
+ if code && !code.strip.empty?
96
+ docid << Bib::Docidentifier.new(type: "CIE", content: code, primary: true)
97
+ @errors[:docid_1] &&= false
98
+ else
99
+ @errors[:docid_1] &&= true
100
+ end
101
+ if code2 && !code2.strip.empty?
102
+ type2 = code2.match(/\w+/).to_s
103
+ docid << Relaton::Bib::Docidentifier.new(type: type2, content: code2.strip)
104
+ @errors[:docid_2] &&= false
105
+ else
106
+ @errors[:docid_2] &&= true
107
+ end
108
+ isbn = doc.at('//h3[contains(.,"ISBN")]/following-sibling::span')&.text
109
+ if isbn && !isbn.strip.empty?
110
+ docid << Bib::Docidentifier.new(type: "ISBN", content: isbn)
111
+ @errors[:docid_isbn] &&= false
112
+ else
113
+ @errors[:docid_isbn] &&= true
114
+ end
115
+ docid
116
+ end
117
+
118
+ def parse_code(hit, doc = nil)
119
+ code = hit.at("h3/a").text.strip.squeeze(" ").sub(/\u25b9/, "").gsub(" / ", "/")
120
+ c2idx = %r{(?:\(|/)(?<c2>(?:ISO|IEC)\s[^()]+)} =~ code
121
+ code = code[0...c2idx].strip if c2idx
122
+ [primary_code(code, doc), c2]
123
+ end
124
+
125
+ def primary_code(code, doc = nil)
126
+ /^(?<code1>[^(]+)(?:\((?<code2>[a-zA-Z]+\d+,(?:\sPages)?[^)]+))?/ =~ code
127
+ if code1&.match?(/^CIE/)
128
+ parse_cie_code code1, code2, doc
129
+ elsif (pcode = doc&.at('//h3[.="Product Code(s):"]/following-sibling::span'))
130
+ "CIE #{pcode.text.strip.match(/[^,]+/)}"
131
+ else
132
+ num = code.match(/(?<=\()\w{2}\d+,.+(?=\))/).to_s.gsub(/,(?=\s)/, "").gsub(/,(?=\S)/, " ")
133
+ "CIE #{num}"
134
+ end
135
+ end
136
+
137
+ def parse_cie_code(code1, code2, doc = nil) # rubocop:disable Metrics/CyclomaticComplexity
138
+ code = code1.size > 25 && code2 ? "CIE #{code2.sub(/,(\sPages)?/, '')}" : code1
139
+ add = doc&.at("//hgroup/h2")&.text&.match(/(Add)endum\s(\d+)$/)
140
+ return code unless add
141
+
142
+ "#{code} #{add[1]} #{add[2]}"
143
+ end
144
+
145
+ def fetch_docnumber(hit)
146
+ parse_code(hit).first.sub(/^CIE\s(?:ISO\s)?/, "")
147
+ end
148
+
149
+ # @param doc [Mechanize::Page]
150
+ # @return [Array<Relaton::Bib::Title>]
151
+ def fetch_title(doc)
152
+ t = doc.at("//hgroup/h2/text()", "//hgroup/h1/text()")
153
+ unless t && !t.text.strip.empty?
154
+ @errors[:title] &&= true
155
+ return []
156
+ end
157
+
158
+ result = Bib::Title.from_string t.text.strip
159
+ @errors[:title] &&= result.empty?
160
+ result
161
+ end
162
+
163
+ # @param doc [Mechanize::Page]
164
+ # @return [Array<Relaton::Bib::Date>]
165
+ def fetch_date(doc)
166
+ result = doc.xpath("//h3[.='Published:']/following-sibling::span").map do |d|
167
+ pd = d.text.strip
168
+ on = pd.match?(/^\d{4}(?:[^-]|$)/) ? pd : Date.strptime(pd, "%m/%d/%Y").strftime("%Y-%m-%d")
169
+ Bib::Date.new(type: "published", at: on)
170
+ end
171
+ @errors[:date] &&= result.empty?
172
+ result
173
+ end
174
+
175
+ # @param doc [Mechanize::Page]
176
+ # @return [String]
177
+ def fetch_edition(doc)
178
+ ed = doc.at("//h3[.='Edition:']/following-sibling::span")
179
+ @errors[:edition] &&= true
180
+ return unless ed
181
+
182
+ content = ed.text.slice(/^\d+(?=(st|nd|rd|th))/)
183
+ if content
184
+ @errors[:edition] = false
185
+ Bib::Edition.new(content: content)
186
+ end
187
+ end
188
+
189
+ # @param doc [Mechanize::Page]
190
+ # @return [Array<Relaton::Cie::Relation>]
191
+ def fetch_relation(doc) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
192
+ rels = doc.xpath('//section[@class="history"]/ol/li[not(contains(@class,"selected-product"))]').map do |rel|
193
+ ref = rel.at("a")
194
+ url = "https://www.techstreet.com#{ref[:href]}"
195
+ title = Bib::Title.from_string ref.at('p/span[@class="title"]').text
196
+ did = ref.at("h3").text
197
+ docid = [Bib::Docidentifier.new(type: "CIE", content: did, primary: true)]
198
+ on = ref.at("p/time")
199
+ date = [Bib::Date.new(type: "published", at: on[:datetime])]
200
+ source = [Bib::Uri.new(type: "src", content: url)]
201
+ bibitem = ItemData.new docidentifier: docid, title: title, source: source, date: date
202
+ type = ref.at('//li/i[contains(@class,"historical")]') ? "updates" : "updatedBy"
203
+ Bib::Relation.new(type: type, bibitem: bibitem)
204
+ end
205
+ @errors[:relation] &&= rels.empty?
206
+ rels
207
+ end
208
+
209
+ # @param url [String]
210
+ # @return [Array<Relaton::Bib::Uri>]
211
+ def fetch_source(url)
212
+ @errors[:source] &&= url.nil? || url.empty?
213
+ return [] if url.nil? || url.empty?
214
+
215
+ [Bib::Uri.new(type: "src", content: url)]
216
+ end
217
+
218
+ # @param doc [Mechanize::Page]
219
+ # @return [Array<Relaton::Bib::LocalizedMarkedUpString>]
220
+ def fetch_abstract(doc)
221
+ content = doc.at('//div[contains(@class,"description")]')&.text&.strip
222
+ if content.nil? || content.empty?
223
+ @errors[:abstract] &&= true
224
+ return []
225
+ end
226
+
227
+ result = [Bib::Abstract.new(content: content, language: "en", script: "Latn")]
228
+ @errors[:abstract] &&= result.empty?
229
+ result
230
+ end
231
+
232
+ # @param doc [Mechanize::Page]
233
+ # @return [Array<Relaton::Bib::Contributor>]
234
+ def fetch_contributor(doc) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity
235
+ authors = doc.xpath('//hgroup/p[not(@class="pub_date")]').text.gsub "\"", ""
236
+ contribs = []
237
+ until authors.empty?
238
+ /^(?<sname1>\S+(?:\sder?\s)?[^\s,]+)
239
+ (?:,?\s(?<sname2>[\w-]{2,})(?=,\s+\w\.))?
240
+ (?:,?\s(?<fname>W-T\.[\w-]{2,})(?!,\s+\w\.))?
241
+ (?:(?:\s?,\s?|\s)(?<init>(?:\w(?:\s?\.|\s|,|$)[\s-]?)+))?
242
+ (?:(?:[,;]\s*|\s+|\.|(?<=\s))(?:and\s)?)?/x =~ authors
243
+ raise StandardError, "Author name not found in \"#{authors}\"" unless $LAST_MATCH_INFO
244
+
245
+ authors.sub! $LAST_MATCH_INFO.to_s, ""
246
+ sname = [sname1, sname2].compact.join " "
247
+ surname = Bib::LocalizedString.new content: sname, language: "en", script: "Latn"
248
+ forename = []
249
+ forename << Bib::FullNameType::Forename.new(content: fname, language: "en", script: "Latn") if fname
250
+ (init&.strip || "").split(/(?:,|\.)(?:-|\s)?/).each do |int|
251
+ forename << Bib::FullNameType::Forename.new(content: "", initial: int.strip, language: "en", script: "Latn")
252
+ end
253
+ fullname = Bib::FullName.new surname: surname, forename: forename
254
+ person = Bib::Person.new name: fullname
255
+ role = Bib::Contributor::Role.new type: "author"
256
+ contribs << Bib::Contributor.new(person: person, role: [role])
257
+ @errors[:contributor_author] &&= contribs.empty?
258
+ end
259
+ org_name = Bib::TypedLocalizedString.new(content: "Commission Internationale de L'Eclairage")
260
+ abbrev = Bib::LocalizedString.new content: "CIE"
261
+ org_uri = Bib::Uri.new content: "cie.co.at"
262
+ org = Bib::Organization.new(name: [org_name], abbreviation: abbrev, uri: [org_uri])
263
+ org_role = Bib::Contributor::Role.new type: "publisher"
264
+ contribs << Bib::Contributor.new(organization: org, role: [org_role])
265
+ end
266
+
267
+ def fetch_ext
268
+ Ext.new(doctype: fetch_doctype, flavor: "cie")
269
+ end
270
+
271
+ def fetch_doctype
272
+ Bib::Doctype.new(content: "document")
273
+ end
274
+
275
+ # @param bib [RelatonCie::BibliographicItem]
276
+ def write_file(bib) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
277
+ id = bib.docidentifier[0].content
278
+ file = output_file id
279
+ if @files.include? file
280
+ Util.warn do
281
+ "File #{file} exists. Docid: #{bib.docidentifier[0].content}\n" \
282
+ "Link: #{bib.source.detect { |l| l.type == 'src' }.content}"
283
+ end
284
+ else @files << file
285
+ end
286
+ index.add_or_update bib.docidentifier[0].content, file
287
+ File.write file, serialize(bib), encoding: "UTF-8"
288
+ end
289
+
290
+ def to_xml(bib) = bib.to_xml(bibdata: true)
291
+ def to_yaml(bib) = bib.to_yaml
292
+ def to_bibxml(bib) = bib.to_rfcxml
293
+
294
+ # @param hit [Nokogiri::HTML::Element]
295
+ def parse_page(hit) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
296
+ url = hit.at('h3/a')[:href]
297
+ doc = time_req { agent.get url }
298
+ item = ItemData.new(
299
+ type: "standard", source: fetch_source(url), docnumber: fetch_docnumber(hit),
300
+ docidentifier: fetch_docid(hit, doc), title: fetch_title(doc),
301
+ abstract: fetch_abstract(doc), date: fetch_date(doc),
302
+ edition: fetch_edition(doc), contributor: fetch_contributor(doc),
303
+ relation: fetch_relation(doc), language: "en", script: "Latn",
304
+ ext: fetch_ext
305
+ )
306
+ write_file item
307
+ rescue StandardError => e
308
+ Util.error do
309
+ "Document: #{url}\n#{e.message}\n#{e.backtrace}"
310
+ end
311
+ end
312
+
313
+ def fetch(_source = nil)
314
+ fetch_doc
315
+ report_errors
316
+ ensure
317
+ @agent&.quit
318
+ end
319
+
320
+ def fetch_doc(url = URL)
321
+ result = time_req { agent.get url }
322
+ result.xpath("//li[@data-product]").each { |hit| parse_page hit }
323
+ np = result.at '//a[@class="next_page"]'
324
+ if np
325
+ next_href = np[:href]
326
+ next_url = next_href.start_with?("http") ? next_href : "https://www.techstreet.com#{next_href}"
327
+ fetch_doc next_url
328
+ else
329
+ index.save
330
+ end
331
+ end
332
+
333
+ RETRIABLE_ERRORS = [
334
+ SocketError,
335
+ Ferrum::TimeoutError,
336
+ Ferrum::PendingConnectionsError,
337
+ Ferrum::StatusError
338
+ ].freeze
339
+
340
+ def time_req
341
+ tries = 0
342
+ begin
343
+ tries += 1
344
+ sleep [4 - (Time.now - @last_request_time).to_i, 0].max if @last_request_time
345
+ yield
346
+ rescue *RETRIABLE_ERRORS => e
347
+ retry if tries < 4
348
+ raise e
349
+ ensure
350
+ @last_request_time = Time.now
351
+ end
352
+ end
353
+ end
354
+ end
355
+ end
@@ -0,0 +1,7 @@
1
+ module Relaton
2
+ module Cie
3
+ class Ext < Bib::Ext
4
+ def get_schema_version = Relaton.schema_versions["relaton-model-cie"]
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ require_relative "ext"
2
+
3
+ module Relaton
4
+ module Cie
5
+ class Item < Bib::Item
6
+ model ItemData
7
+
8
+ attribute :ext, Ext
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ module Relaton
2
+ module Cie
3
+ class ItemData < Bib::ItemData
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,66 @@
1
+ require "relaton/core/processor"
2
+
3
+ module Relaton
4
+ module Cie
5
+ class Processor < Relaton::Core::Processor
6
+ def initialize # rubocop:disable Lint/MissingSuper
7
+ @short = :relaton_cie
8
+ @prefix = "CIE"
9
+ @defaultprefix = /^CIE(-|\s)/
10
+ @idtype = "CIE"
11
+ @datasets = %w[cie-techstreet]
12
+ end
13
+
14
+ # @param code [String]
15
+ # @param date [String, NilClass] year
16
+ # @param opts [Hash]
17
+ # @return [Relaton::Cie::ItemData, nil]
18
+ def get(code, date, opts)
19
+ require_relative "../cie"
20
+ Bibliography.get(code, date, opts)
21
+ end
22
+
23
+ #
24
+ # Fetch all the docukents from a source
25
+ #
26
+ # @param [String] _source source name
27
+ # @param [Hash] opts
28
+ # @option opts [String] :output directory to output documents
29
+ # @option opts [String] :format
30
+ #
31
+ def fetch_data(_source, opts)
32
+ require_relative "data_fetcher"
33
+ DataFetcher.fetch(**opts)
34
+ end
35
+
36
+ # @param xml [String]
37
+ # @return [Relaton::Cie::ItemData]
38
+ def from_xml(xml)
39
+ require_relative "../cie"
40
+ Item.from_xml xml
41
+ end
42
+
43
+ # @param hash [String]
44
+ # @return [Relaton::Cie::ItemData]
45
+ def from_yaml(yaml)
46
+ require_relative "../cie"
47
+ Item.from_yaml yaml
48
+ end
49
+
50
+ # Returns hash of XML grammar
51
+ # @return [String]
52
+ def grammar_hash
53
+ require_relative "../cie"
54
+ @grammar_hash ||= Cie.grammar_hash
55
+ end
56
+
57
+ #
58
+ # Remove index file
59
+ #
60
+ def remove_index_file
61
+ require_relative "../cie"
62
+ Relaton::Index.find_or_create(:cie, url: true, file: "#{INDEXFILE}.yaml").remove_file
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,39 @@
1
+ require "mechanize"
2
+
3
+ module Relaton
4
+ module Cie
5
+ module Scrapper
6
+ ENDPOINT = "https://raw.githubusercontent.com/relaton/relaton-data-cie/refs/heads/v2/".freeze
7
+
8
+ class << self
9
+ # @param code [String]
10
+ # @return [Relaton::Cie::ItemData]
11
+ def scrape_page(code)
12
+ index = Index.find_or_create :cie, url: "#{ENDPOINT}#{INDEXFILE}.zip", file: "#{INDEXFILE}.yaml"
13
+ row = index.search(code).min_by { |r| r[:id] }
14
+ return unless row
15
+
16
+ parse_page "#{ENDPOINT}#{row[:file]}", code
17
+ end
18
+
19
+ private
20
+
21
+ # @param url [String]
22
+ # @param code [String]
23
+ # @retrurn [Relato::Cie::ItemData]
24
+ def parse_page(url, code)
25
+ resp = Mechanize.new.get url
26
+ Item.from_yaml(resp.body).tap { |item| item.fetched = Date.today.to_s }
27
+ rescue Mechanize::ResponseCodeError => e
28
+ return if e.response_code == "404"
29
+
30
+ raise Relaton::RequestError, "No document found for #{code} reference. #{e.message}"
31
+ rescue Mechanize::RedirectLimitReachedError, Timeout::Error,
32
+ Mechanize::UnauthorizedError, Mechanize::UnsupportedSchemeError,
33
+ Mechanize::ResponseReadError, Mechanize::ChunkedTerminationError => e
34
+ raise Relaton::RequestError, "No document found for #{code} reference. #{e.message}"
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,8 @@
1
+ module Relaton
2
+ module Cie
3
+ module Util
4
+ extend Relaton::Bib::Util
5
+ PROGNAME = "relaton-cie".freeze
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,28 @@
1
+ require "nokogiri"
2
+ # require "parslet"
3
+ require "relaton/index"
4
+ require "relaton/bib"
5
+ # require "relaton_bib/name_parser"
6
+ require_relative "version"
7
+ require_relative "cie/util"
8
+ require_relative "cie/item_data"
9
+ require_relative "cie/item"
10
+ require_relative "cie/bibitem"
11
+ require_relative "cie/bibdata"
12
+ require_relative "cie/bibliography"
13
+ require_relative "cie/scrapper"
14
+
15
+ module Relaton
16
+ module Cie
17
+ INDEXFILE = "index-v1".freeze
18
+
19
+ # Returns hash of XML reammar
20
+ # @return [String]
21
+ def self.grammar_hash
22
+ # gem_path = File.expand_path "..", __dir__
23
+ # grammars_path = File.join gem_path, "grammars", "*"
24
+ # grammars = Dir[grammars_path].sort.map { |gp| File.read gp }.join
25
+ Digest::MD5.hexdigest Relaton::VERSION # grammars
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ module Relaton
2
+ module Core
3
+ module ArrayWrapper
4
+ #
5
+ # Wrap into Array if not Array
6
+ #
7
+ # @param [Object] content
8
+ #
9
+ # @return [Array<Object>]
10
+ #
11
+ def array(content)
12
+ case content
13
+ when Array then content
14
+ when nil then []
15
+ else [content]
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,97 @@
1
+ require "fileutils"
2
+
3
+ module Relaton
4
+ module Core
5
+ class DataFetcher
6
+ # attr_accessor :docs
7
+ #
8
+ # Initialize fetcher
9
+ #
10
+ # @param [String] output path to output directory
11
+ # @param [String] format output format (yaml, xml, bibxml)
12
+ #
13
+ def initialize(output, format)
14
+ @output = output
15
+ @format = format
16
+ @ext = format.sub "bibxml", "xml"
17
+ @files = Set.new
18
+ # @docs = []
19
+ @errors = Hash.new(true)
20
+ end
21
+
22
+ # API method for external service
23
+ #
24
+ # @return the value returned by the instance `#fetch`, so callers can act
25
+ # on the outcome (e.g. relaton-iso returns whether it rebuilt).
26
+ def self.fetch(source = nil, output: "data", format: "yaml")
27
+ t1 = Time.now
28
+ puts "Started at: #{t1}"
29
+ FileUtils.mkdir_p output
30
+ result = new(output, format).fetch(source)
31
+ t2 = Time.now
32
+ puts "Stopped at: #{t2}"
33
+ puts "Done in: #{(t2 - t1).round} sec."
34
+ result
35
+ end
36
+
37
+ def fetch(source = nil)
38
+ raise NotImplementedError, "#{self.class}#fetch method must be implemented"
39
+ end
40
+
41
+ def gh_issue
42
+ return @gh_issue if defined? @gh_issue
43
+
44
+ channel = gh_issue_channel
45
+ if channel[0]
46
+ @gh_issue = Relaton::Logger::Channels::GhIssue.new(*channel)
47
+ Relaton.logger_pool[:gh_issue] = Relaton::Logger::Log.new(@gh_issue, levels: [:error])
48
+ end
49
+ @gh_issue
50
+ end
51
+
52
+ def gh_issue_channel
53
+ [ENV.fetch("GITHUB_REPOSITORY", nil), "Error fetching documents"]
54
+ end
55
+
56
+ def report_errors
57
+ gh_issue # register the channel before logging
58
+ @errors.select { |_, v| v }.each_key { |k| log_error "Failed to fetch #{k}" }
59
+ @gh_issue&.create_issue
60
+ end
61
+
62
+ def log_error(_msg)
63
+ raise NoMatchingPatternError, "#{self.class}#log_error method must be implemented"
64
+ end
65
+
66
+ # @param [String] document ID
67
+ # @return [String] filename based on PubID identifier
68
+ def output_file(docid)
69
+ id = docid.downcase.gsub(/[.\s\/:()-]+/, "-").delete_suffix("-")
70
+ File.join @output, "#{id}.#{@ext}"
71
+ end
72
+
73
+ #
74
+ # Serialize bibliographic item
75
+ #
76
+ # @param [RelatonCcsds::BibliographicItem] bib <description>
77
+ #
78
+ # @return [String] serialized bibliographic item
79
+ #
80
+ def serialize(bib)
81
+ send "to_#{@format}", bib
82
+ end
83
+
84
+ def to_yaml(bib)
85
+ raise NotImplementedError, "#{self.class}#to_yaml method must be implemented"
86
+ end
87
+
88
+ def to_xml(bib)
89
+ raise NotImplementedError, "#{self.class}#to_xml method must be implemented"
90
+ end
91
+
92
+ def to_bibxml(bib)
93
+ raise NotImplementedError, "#{self.class}#to_bibxml method must be implemented"
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,42 @@
1
+ module Relaton
2
+ module Core
3
+ module DateParser
4
+ # @param date [String, Integer, Date] date
5
+ # @param str [Boolean] return string or Date
6
+ # @return [Date, String, nil] date
7
+ def parse_date(date, str: true) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
8
+ return date if date.is_a?(Date)
9
+
10
+ case date.to_s
11
+ when /(?<date>\w+\s\d{4})/ # February 2012
12
+ format_date $~[:date], "%B %Y", str, "%Y-%m"
13
+ when /(?<date>\w+\s\d{1,2},\s\d{4})/ # February 11, 2012
14
+ format_date $~[:date], "%B %d, %Y", str, "%Y-%m-%d"
15
+ when /(?<date>\d{4}-\d{1,2}-\d{1,2})/ # 2012-02-03 or 2012-2-3
16
+ format_date $~[:date], "%Y-%m-%d", str
17
+ when /(?<date>\d{4}-\d{1,2})/ # 2012-02 or 2012-2
18
+ format_date $~[:date], "%Y-%m", str
19
+ when /(?<date>\d{4})/ # 2012
20
+ format_date $~[:date], "%Y", str
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ #
27
+ # Parse date string to Date object and format it
28
+ #
29
+ # @param [String] date date string
30
+ # @param [String] format format string
31
+ # @param [Boolean] str return string if true in other case return Date
32
+ # @param [String, nil] outformat output format
33
+ #
34
+ # @return [Date, String] date object or formatted date string
35
+ #
36
+ def format_date(date, format, str, outformat = nil)
37
+ date = Date.strptime(date, format)
38
+ str ? date.strftime(outformat || format) : date
39
+ end
40
+ end
41
+ end
42
+ end