invenio-vocabularies 9.1.2__py2.py3-none-any.whl

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 (337) hide show
  1. invenio_vocabularies/__init__.py +16 -0
  2. invenio_vocabularies/administration/__init__.py +10 -0
  3. invenio_vocabularies/administration/views/__init__.py +10 -0
  4. invenio_vocabularies/administration/views/vocabularies.py +43 -0
  5. invenio_vocabularies/alembic/17c703ce1eb7_create_names_table.py +54 -0
  6. invenio_vocabularies/alembic/3ba812d80559_add_internal_name_id.py +36 -0
  7. invenio_vocabularies/alembic/4a9a4fd235f8_create_vocabulary_schemes.py +37 -0
  8. invenio_vocabularies/alembic/4f365fced43f_create_vocabularies_tables.py +92 -0
  9. invenio_vocabularies/alembic/55a700f897b6_add_names_and_afiliations_pid_column.py +96 -0
  10. invenio_vocabularies/alembic/6312f33645c1_create_affiliations_table.py +54 -0
  11. invenio_vocabularies/alembic/676dd587542d_create_funders_vocabulary_table.py +58 -0
  12. invenio_vocabularies/alembic/8ff82dfb0be8_create_vocabularies_branch.py +28 -0
  13. invenio_vocabularies/alembic/__init__.py +9 -0
  14. invenio_vocabularies/alembic/af2457652217_drop_unique_constraint_from_internal_id.py +37 -0
  15. invenio_vocabularies/alembic/e1146238edd3_create_awards_table.py +56 -0
  16. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/.eslintrc.yml +11 -0
  17. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/.prettierrc +1 -0
  18. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/index.js +7 -0
  19. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/package.json +25 -0
  20. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/AwardResults.js +95 -0
  21. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/CustomAwardForm.js +139 -0
  22. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/FunderDropdown.js +87 -0
  23. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/FundingField.js +244 -0
  24. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/FundingField.test.js +1 -0
  25. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/FundingFieldItem.js +152 -0
  26. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/FundingModal.js +246 -0
  27. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/NoAwardResults.js +37 -0
  28. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/index.js +8 -0
  29. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/index.js +7 -0
  30. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/index.js +7 -0
  31. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/index.js +7 -0
  32. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/i18next.js +36 -0
  33. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/_generatedTranslations.js +66 -0
  34. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/ar/messages.po +96 -0
  35. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/ar/translations.json +28 -0
  36. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/bg/messages.po +94 -0
  37. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/bg/translations.json +28 -0
  38. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/ca/messages.po +94 -0
  39. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/ca/translations.json +28 -0
  40. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/cs/messages.po +97 -0
  41. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/cs/translations.json +28 -0
  42. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/da/messages.po +94 -0
  43. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/da/translations.json +28 -0
  44. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/de/messages.po +98 -0
  45. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/de/translations.json +28 -0
  46. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/el/messages.po +94 -0
  47. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/el/translations.json +28 -0
  48. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/en/messages.po +88 -0
  49. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/en/translations.json +28 -0
  50. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/es/messages.po +96 -0
  51. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/es/translations.json +28 -0
  52. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/et/messages.po +95 -0
  53. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/et/translations.json +28 -0
  54. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/fa/messages.po +94 -0
  55. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/fa/translations.json +28 -0
  56. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/fr/messages.po +96 -0
  57. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/fr/translations.json +28 -0
  58. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/hr/messages.po +94 -0
  59. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/hr/translations.json +28 -0
  60. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/hu/messages.po +96 -0
  61. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/hu/translations.json +28 -0
  62. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/index.js +24 -0
  63. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/it/messages.po +96 -0
  64. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/it/translations.json +28 -0
  65. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/ja/messages.po +94 -0
  66. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/ja/translations.json +28 -0
  67. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/ka/messages.po +94 -0
  68. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/ka/translations.json +28 -0
  69. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/ko/messages.po +90 -0
  70. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/ko/translations.json +28 -0
  71. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/lt/messages.po +94 -0
  72. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/lt/translations.json +28 -0
  73. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/no/messages.po +94 -0
  74. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/no/translations.json +28 -0
  75. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/pl/messages.po +94 -0
  76. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/pl/translations.json +28 -0
  77. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/pt/messages.po +94 -0
  78. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/pt/translations.json +28 -0
  79. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/ro/messages.po +95 -0
  80. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/ro/translations.json +28 -0
  81. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/ru/messages.po +95 -0
  82. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/ru/translations.json +28 -0
  83. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/sk/messages.po +94 -0
  84. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/sk/translations.json +28 -0
  85. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/sv/messages.po +98 -0
  86. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/sv/translations.json +28 -0
  87. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/tr/messages.po +96 -0
  88. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/tr/translations.json +28 -0
  89. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/uk/messages.po +94 -0
  90. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/uk/translations.json +28 -0
  91. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/zh_CN/messages.po +96 -0
  92. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/zh_CN/translations.json +28 -0
  93. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/zh_TW/messages.po +94 -0
  94. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/zh_TW/translations.json +28 -0
  95. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/package.json +19 -0
  96. invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/translations.pot +88 -0
  97. invenio_vocabularies/cli.py +175 -0
  98. invenio_vocabularies/config.py +231 -0
  99. invenio_vocabularies/contrib/__init__.py +9 -0
  100. invenio_vocabularies/contrib/affiliations/__init__.py +20 -0
  101. invenio_vocabularies/contrib/affiliations/affiliations.py +61 -0
  102. invenio_vocabularies/contrib/affiliations/api.py +13 -0
  103. invenio_vocabularies/contrib/affiliations/config.py +79 -0
  104. invenio_vocabularies/contrib/affiliations/datastreams.py +301 -0
  105. invenio_vocabularies/contrib/affiliations/facets.py +36 -0
  106. invenio_vocabularies/contrib/affiliations/jsonschemas/__init__.py +9 -0
  107. invenio_vocabularies/contrib/affiliations/jsonschemas/affiliations/affiliation-v1.0.0.json +63 -0
  108. invenio_vocabularies/contrib/affiliations/mappings/__init__.py +10 -0
  109. invenio_vocabularies/contrib/affiliations/mappings/os-v1/__init__.py +9 -0
  110. invenio_vocabularies/contrib/affiliations/mappings/os-v1/affiliations/affiliation-v1.0.0.json +112 -0
  111. invenio_vocabularies/contrib/affiliations/mappings/os-v1/affiliations/affiliation-v2.0.0.json +171 -0
  112. invenio_vocabularies/contrib/affiliations/mappings/os-v2/__init__.py +9 -0
  113. invenio_vocabularies/contrib/affiliations/mappings/os-v2/affiliations/affiliation-v1.0.0.json +112 -0
  114. invenio_vocabularies/contrib/affiliations/mappings/os-v2/affiliations/affiliation-v2.0.0.json +171 -0
  115. invenio_vocabularies/contrib/affiliations/mappings/v7/__init__.py +9 -0
  116. invenio_vocabularies/contrib/affiliations/mappings/v7/affiliations/affiliation-v1.0.0.json +112 -0
  117. invenio_vocabularies/contrib/affiliations/models.py +13 -0
  118. invenio_vocabularies/contrib/affiliations/resources.py +16 -0
  119. invenio_vocabularies/contrib/affiliations/schema.py +71 -0
  120. invenio_vocabularies/contrib/affiliations/services.py +15 -0
  121. invenio_vocabularies/contrib/awards/__init__.py +19 -0
  122. invenio_vocabularies/contrib/awards/api.py +13 -0
  123. invenio_vocabularies/contrib/awards/awards.py +96 -0
  124. invenio_vocabularies/contrib/awards/config.py +59 -0
  125. invenio_vocabularies/contrib/awards/datastreams.py +372 -0
  126. invenio_vocabularies/contrib/awards/jsonschemas/__init__.py +9 -0
  127. invenio_vocabularies/contrib/awards/jsonschemas/awards/award-v1.0.0.json +91 -0
  128. invenio_vocabularies/contrib/awards/mappings/__init__.py +9 -0
  129. invenio_vocabularies/contrib/awards/mappings/os-v1/__init__.py +9 -0
  130. invenio_vocabularies/contrib/awards/mappings/os-v1/awards/award-v1.0.0.json +147 -0
  131. invenio_vocabularies/contrib/awards/mappings/os-v2/__init__.py +9 -0
  132. invenio_vocabularies/contrib/awards/mappings/os-v2/awards/award-v1.0.0.json +147 -0
  133. invenio_vocabularies/contrib/awards/mappings/v7/__init__.py +9 -0
  134. invenio_vocabularies/contrib/awards/mappings/v7/awards/award-v1.0.0.json +147 -0
  135. invenio_vocabularies/contrib/awards/models.py +13 -0
  136. invenio_vocabularies/contrib/awards/resources.py +16 -0
  137. invenio_vocabularies/contrib/awards/schema.py +119 -0
  138. invenio_vocabularies/contrib/awards/serializer.py +47 -0
  139. invenio_vocabularies/contrib/awards/services.py +15 -0
  140. invenio_vocabularies/contrib/common/__init__.py +9 -0
  141. invenio_vocabularies/contrib/common/openaire/__init__.py +9 -0
  142. invenio_vocabularies/contrib/common/openaire/datastreams.py +84 -0
  143. invenio_vocabularies/contrib/common/ror/__init__.py +9 -0
  144. invenio_vocabularies/contrib/common/ror/datastreams.py +230 -0
  145. invenio_vocabularies/contrib/funders/__init__.py +19 -0
  146. invenio_vocabularies/contrib/funders/api.py +13 -0
  147. invenio_vocabularies/contrib/funders/config.py +78 -0
  148. invenio_vocabularies/contrib/funders/datastreams.py +97 -0
  149. invenio_vocabularies/contrib/funders/facets.py +36 -0
  150. invenio_vocabularies/contrib/funders/funders.py +72 -0
  151. invenio_vocabularies/contrib/funders/jsonschemas/__init__.py +9 -0
  152. invenio_vocabularies/contrib/funders/jsonschemas/funders/funder-v1.0.0.json +65 -0
  153. invenio_vocabularies/contrib/funders/mappings/__init__.py +9 -0
  154. invenio_vocabularies/contrib/funders/mappings/os-v1/__init__.py +9 -0
  155. invenio_vocabularies/contrib/funders/mappings/os-v1/funders/funder-v1.0.0.json +90 -0
  156. invenio_vocabularies/contrib/funders/mappings/os-v1/funders/funder-v2.0.0.json +156 -0
  157. invenio_vocabularies/contrib/funders/mappings/os-v2/__init__.py +9 -0
  158. invenio_vocabularies/contrib/funders/mappings/os-v2/funders/funder-v1.0.0.json +90 -0
  159. invenio_vocabularies/contrib/funders/mappings/os-v2/funders/funder-v2.0.0.json +156 -0
  160. invenio_vocabularies/contrib/funders/mappings/v7/__init__.py +9 -0
  161. invenio_vocabularies/contrib/funders/mappings/v7/funders/funder-v1.0.0.json +90 -0
  162. invenio_vocabularies/contrib/funders/models.py +13 -0
  163. invenio_vocabularies/contrib/funders/resources.py +16 -0
  164. invenio_vocabularies/contrib/funders/schema.py +88 -0
  165. invenio_vocabularies/contrib/funders/serializer.py +33 -0
  166. invenio_vocabularies/contrib/funders/services.py +15 -0
  167. invenio_vocabularies/contrib/names/__init__.py +19 -0
  168. invenio_vocabularies/contrib/names/api.py +13 -0
  169. invenio_vocabularies/contrib/names/components.py +24 -0
  170. invenio_vocabularies/contrib/names/config.py +75 -0
  171. invenio_vocabularies/contrib/names/datastreams.py +483 -0
  172. invenio_vocabularies/contrib/names/jsonschemas/__init__.py +9 -0
  173. invenio_vocabularies/contrib/names/jsonschemas/names/name-v1.0.0.json +68 -0
  174. invenio_vocabularies/contrib/names/mappings/__init__.py +9 -0
  175. invenio_vocabularies/contrib/names/mappings/os-v1/__init__.py +9 -0
  176. invenio_vocabularies/contrib/names/mappings/os-v1/names/name-v1.0.0.json +101 -0
  177. invenio_vocabularies/contrib/names/mappings/os-v1/names/name-v2.0.0.json +165 -0
  178. invenio_vocabularies/contrib/names/mappings/os-v2/__init__.py +9 -0
  179. invenio_vocabularies/contrib/names/mappings/os-v2/names/name-v1.0.0.json +101 -0
  180. invenio_vocabularies/contrib/names/mappings/os-v2/names/name-v2.0.0.json +165 -0
  181. invenio_vocabularies/contrib/names/mappings/v7/__init__.py +9 -0
  182. invenio_vocabularies/contrib/names/mappings/v7/names/name-v1.0.0.json +101 -0
  183. invenio_vocabularies/contrib/names/models.py +13 -0
  184. invenio_vocabularies/contrib/names/names.py +80 -0
  185. invenio_vocabularies/contrib/names/permissions.py +30 -0
  186. invenio_vocabularies/contrib/names/resources.py +54 -0
  187. invenio_vocabularies/contrib/names/s3client.py +50 -0
  188. invenio_vocabularies/contrib/names/schema.py +121 -0
  189. invenio_vocabularies/contrib/names/services.py +64 -0
  190. invenio_vocabularies/contrib/subjects/__init__.py +22 -0
  191. invenio_vocabularies/contrib/subjects/api.py +14 -0
  192. invenio_vocabularies/contrib/subjects/config.py +90 -0
  193. invenio_vocabularies/contrib/subjects/datastreams.py +63 -0
  194. invenio_vocabularies/contrib/subjects/euroscivoc/__init__.py +9 -0
  195. invenio_vocabularies/contrib/subjects/euroscivoc/datastreams.py +101 -0
  196. invenio_vocabularies/contrib/subjects/facets.py +23 -0
  197. invenio_vocabularies/contrib/subjects/gemet/__init__.py +9 -0
  198. invenio_vocabularies/contrib/subjects/gemet/datastreams.py +140 -0
  199. invenio_vocabularies/contrib/subjects/jsonschemas/__init__.py +10 -0
  200. invenio_vocabularies/contrib/subjects/jsonschemas/subjects/subject-v1.0.0.json +69 -0
  201. invenio_vocabularies/contrib/subjects/mappings/__init__.py +9 -0
  202. invenio_vocabularies/contrib/subjects/mappings/os-v1/__init__.py +9 -0
  203. invenio_vocabularies/contrib/subjects/mappings/os-v1/subjects/subject-v1.0.0.json +96 -0
  204. invenio_vocabularies/contrib/subjects/mappings/os-v2/__init__.py +9 -0
  205. invenio_vocabularies/contrib/subjects/mappings/os-v2/subjects/subject-v1.0.0.json +96 -0
  206. invenio_vocabularies/contrib/subjects/mappings/v7/__init__.py +9 -0
  207. invenio_vocabularies/contrib/subjects/mappings/v7/subjects/subject-v1.0.0.json +96 -0
  208. invenio_vocabularies/contrib/subjects/mesh/__init__.py +9 -0
  209. invenio_vocabularies/contrib/subjects/mesh/datastreams.py +48 -0
  210. invenio_vocabularies/contrib/subjects/models.py +14 -0
  211. invenio_vocabularies/contrib/subjects/nvs/__init__.py +9 -0
  212. invenio_vocabularies/contrib/subjects/nvs/datastreams.py +114 -0
  213. invenio_vocabularies/contrib/subjects/resources.py +17 -0
  214. invenio_vocabularies/contrib/subjects/schema.py +101 -0
  215. invenio_vocabularies/contrib/subjects/services.py +30 -0
  216. invenio_vocabularies/contrib/subjects/subjects.py +55 -0
  217. invenio_vocabularies/datastreams/__init__.py +18 -0
  218. invenio_vocabularies/datastreams/datastreams.py +239 -0
  219. invenio_vocabularies/datastreams/errors.py +29 -0
  220. invenio_vocabularies/datastreams/factories.py +86 -0
  221. invenio_vocabularies/datastreams/readers.py +448 -0
  222. invenio_vocabularies/datastreams/tasks.py +115 -0
  223. invenio_vocabularies/datastreams/transformers.py +130 -0
  224. invenio_vocabularies/datastreams/writers.py +222 -0
  225. invenio_vocabularies/datastreams/xml.py +34 -0
  226. invenio_vocabularies/ext.py +179 -0
  227. invenio_vocabularies/factories.py +193 -0
  228. invenio_vocabularies/fixtures.py +52 -0
  229. invenio_vocabularies/jobs.py +207 -0
  230. invenio_vocabularies/proxies.py +27 -0
  231. invenio_vocabularies/records/__init__.py +9 -0
  232. invenio_vocabularies/records/api.py +53 -0
  233. invenio_vocabularies/records/jsonschemas/__init__.py +9 -0
  234. invenio_vocabularies/records/jsonschemas/vocabularies/definitions-v1.0.0.json +30 -0
  235. invenio_vocabularies/records/jsonschemas/vocabularies/vocabulary-v1.0.0.json +55 -0
  236. invenio_vocabularies/records/mappings/__init__.py +9 -0
  237. invenio_vocabularies/records/mappings/os-v1/__init__.py +9 -0
  238. invenio_vocabularies/records/mappings/os-v1/vocabularies/vocabulary-v1.0.0.json +109 -0
  239. invenio_vocabularies/records/mappings/os-v2/__init__.py +9 -0
  240. invenio_vocabularies/records/mappings/os-v2/vocabularies/vocabulary-v1.0.0.json +109 -0
  241. invenio_vocabularies/records/mappings/v7/__init__.py +9 -0
  242. invenio_vocabularies/records/mappings/v7/vocabularies/vocabulary-v1.0.0.json +109 -0
  243. invenio_vocabularies/records/models.py +90 -0
  244. invenio_vocabularies/records/pidprovider.py +118 -0
  245. invenio_vocabularies/records/systemfields/__init__.py +16 -0
  246. invenio_vocabularies/records/systemfields/pid.py +125 -0
  247. invenio_vocabularies/records/systemfields/relations.py +51 -0
  248. invenio_vocabularies/resources/__init__.py +23 -0
  249. invenio_vocabularies/resources/config.py +105 -0
  250. invenio_vocabularies/resources/resource.py +156 -0
  251. invenio_vocabularies/resources/schema.py +21 -0
  252. invenio_vocabularies/resources/serializer.py +39 -0
  253. invenio_vocabularies/services/__init__.py +19 -0
  254. invenio_vocabularies/services/components.py +58 -0
  255. invenio_vocabularies/services/config.py +173 -0
  256. invenio_vocabularies/services/custom_fields/__init__.py +17 -0
  257. invenio_vocabularies/services/custom_fields/subject.py +82 -0
  258. invenio_vocabularies/services/custom_fields/vocabulary.py +96 -0
  259. invenio_vocabularies/services/facets.py +114 -0
  260. invenio_vocabularies/services/generators.py +38 -0
  261. invenio_vocabularies/services/permissions.py +30 -0
  262. invenio_vocabularies/services/querystr.py +57 -0
  263. invenio_vocabularies/services/results.py +110 -0
  264. invenio_vocabularies/services/schema.py +163 -0
  265. invenio_vocabularies/services/service.py +189 -0
  266. invenio_vocabularies/services/tasks.py +38 -0
  267. invenio_vocabularies/templates/semantic-ui/invenio_vocabularies/subjects.html +23 -0
  268. invenio_vocabularies/templates/semantic-ui/invenio_vocabularies/vocabularies-list.html +12 -0
  269. invenio_vocabularies/templates/semantic-ui/invenio_vocabularies/vocabulary-details.html +71 -0
  270. invenio_vocabularies/translations/ar/LC_MESSAGES/messages.mo +0 -0
  271. invenio_vocabularies/translations/ar/LC_MESSAGES/messages.po +277 -0
  272. invenio_vocabularies/translations/bg/LC_MESSAGES/messages.mo +0 -0
  273. invenio_vocabularies/translations/bg/LC_MESSAGES/messages.po +275 -0
  274. invenio_vocabularies/translations/ca/LC_MESSAGES/messages.mo +0 -0
  275. invenio_vocabularies/translations/ca/LC_MESSAGES/messages.po +276 -0
  276. invenio_vocabularies/translations/cs/LC_MESSAGES/messages.mo +0 -0
  277. invenio_vocabularies/translations/cs/LC_MESSAGES/messages.po +281 -0
  278. invenio_vocabularies/translations/da/LC_MESSAGES/messages.mo +0 -0
  279. invenio_vocabularies/translations/da/LC_MESSAGES/messages.po +271 -0
  280. invenio_vocabularies/translations/de/LC_MESSAGES/messages.mo +0 -0
  281. invenio_vocabularies/translations/de/LC_MESSAGES/messages.po +293 -0
  282. invenio_vocabularies/translations/el/LC_MESSAGES/messages.mo +0 -0
  283. invenio_vocabularies/translations/el/LC_MESSAGES/messages.po +275 -0
  284. invenio_vocabularies/translations/es/LC_MESSAGES/messages.mo +0 -0
  285. invenio_vocabularies/translations/es/LC_MESSAGES/messages.po +281 -0
  286. invenio_vocabularies/translations/et/LC_MESSAGES/messages.mo +0 -0
  287. invenio_vocabularies/translations/et/LC_MESSAGES/messages.po +276 -0
  288. invenio_vocabularies/translations/fa/LC_MESSAGES/messages.mo +0 -0
  289. invenio_vocabularies/translations/fa/LC_MESSAGES/messages.po +275 -0
  290. invenio_vocabularies/translations/fr/LC_MESSAGES/messages.mo +0 -0
  291. invenio_vocabularies/translations/fr/LC_MESSAGES/messages.po +279 -0
  292. invenio_vocabularies/translations/hr/LC_MESSAGES/messages.mo +0 -0
  293. invenio_vocabularies/translations/hr/LC_MESSAGES/messages.po +275 -0
  294. invenio_vocabularies/translations/hu/LC_MESSAGES/messages.mo +0 -0
  295. invenio_vocabularies/translations/hu/LC_MESSAGES/messages.po +280 -0
  296. invenio_vocabularies/translations/it/LC_MESSAGES/messages.mo +0 -0
  297. invenio_vocabularies/translations/it/LC_MESSAGES/messages.po +277 -0
  298. invenio_vocabularies/translations/ja/LC_MESSAGES/messages.mo +0 -0
  299. invenio_vocabularies/translations/ja/LC_MESSAGES/messages.po +275 -0
  300. invenio_vocabularies/translations/ka/LC_MESSAGES/messages.mo +0 -0
  301. invenio_vocabularies/translations/ka/LC_MESSAGES/messages.po +275 -0
  302. invenio_vocabularies/translations/ko/LC_MESSAGES/messages.mo +0 -0
  303. invenio_vocabularies/translations/ko/LC_MESSAGES/messages.po +275 -0
  304. invenio_vocabularies/translations/lt/LC_MESSAGES/messages.mo +0 -0
  305. invenio_vocabularies/translations/lt/LC_MESSAGES/messages.po +275 -0
  306. invenio_vocabularies/translations/messages.pot +270 -0
  307. invenio_vocabularies/translations/no/LC_MESSAGES/messages.mo +0 -0
  308. invenio_vocabularies/translations/no/LC_MESSAGES/messages.po +275 -0
  309. invenio_vocabularies/translations/pl/LC_MESSAGES/messages.mo +0 -0
  310. invenio_vocabularies/translations/pl/LC_MESSAGES/messages.po +275 -0
  311. invenio_vocabularies/translations/pt/LC_MESSAGES/messages.mo +0 -0
  312. invenio_vocabularies/translations/pt/LC_MESSAGES/messages.po +275 -0
  313. invenio_vocabularies/translations/ro/LC_MESSAGES/messages.mo +0 -0
  314. invenio_vocabularies/translations/ro/LC_MESSAGES/messages.po +280 -0
  315. invenio_vocabularies/translations/ru/LC_MESSAGES/messages.mo +0 -0
  316. invenio_vocabularies/translations/ru/LC_MESSAGES/messages.po +276 -0
  317. invenio_vocabularies/translations/sk/LC_MESSAGES/messages.mo +0 -0
  318. invenio_vocabularies/translations/sk/LC_MESSAGES/messages.po +276 -0
  319. invenio_vocabularies/translations/sv/LC_MESSAGES/messages.mo +0 -0
  320. invenio_vocabularies/translations/sv/LC_MESSAGES/messages.po +280 -0
  321. invenio_vocabularies/translations/tr/LC_MESSAGES/messages.mo +0 -0
  322. invenio_vocabularies/translations/tr/LC_MESSAGES/messages.po +277 -0
  323. invenio_vocabularies/translations/uk/LC_MESSAGES/messages.mo +0 -0
  324. invenio_vocabularies/translations/uk/LC_MESSAGES/messages.po +275 -0
  325. invenio_vocabularies/translations/zh_CN/LC_MESSAGES/messages.mo +0 -0
  326. invenio_vocabularies/translations/zh_CN/LC_MESSAGES/messages.po +276 -0
  327. invenio_vocabularies/translations/zh_TW/LC_MESSAGES/messages.mo +0 -0
  328. invenio_vocabularies/translations/zh_TW/LC_MESSAGES/messages.po +275 -0
  329. invenio_vocabularies/views.py +53 -0
  330. invenio_vocabularies/webpack.py +51 -0
  331. invenio_vocabularies-9.1.2.dist-info/METADATA +517 -0
  332. invenio_vocabularies-9.1.2.dist-info/RECORD +337 -0
  333. invenio_vocabularies-9.1.2.dist-info/WHEEL +6 -0
  334. invenio_vocabularies-9.1.2.dist-info/entry_points.txt +73 -0
  335. invenio_vocabularies-9.1.2.dist-info/licenses/AUTHORS.rst +13 -0
  336. invenio_vocabularies-9.1.2.dist-info/licenses/LICENSE +21 -0
  337. invenio_vocabularies-9.1.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # This file is part of Invenio.
4
+ # Copyright (C) 2021 CERN.
5
+ #
6
+ # Invenio-Vocabularies is free software; you can redistribute it and/or
7
+ # modify it under the terms of the MIT License; see LICENSE file for more
8
+ # details.
9
+
10
+ """Names vocabulary resources."""
11
+
12
+ from flask import g
13
+ from flask_resources import resource_requestctx, response_handler, route
14
+ from invenio_records_resources.resources.records.resource import request_view_args
15
+ from marshmallow import fields
16
+
17
+ from .names import record_type
18
+
19
+
20
+ class NamesResourceConfig(record_type.resource_config_cls):
21
+ """Name resource."""
22
+
23
+ routes = record_type.resource_config_cls.routes
24
+ routes["item-names-resolve"] = "/<pid_type>/<pid_value>"
25
+ request_view_args = {
26
+ "pid_value": fields.Str(),
27
+ "pid_type": fields.Str(),
28
+ }
29
+
30
+
31
+ class NamesResource(record_type.resource_cls):
32
+ """Name resource."""
33
+
34
+ def create_url_rules(self):
35
+ """Create the URL rules for the record resource."""
36
+ routes = self.config.routes
37
+ url_rules = super(NamesResource, self).create_url_rules()
38
+ url_rules += [
39
+ route("GET", routes["item-names-resolve"], self.name_resolve_by_id),
40
+ ]
41
+
42
+ return url_rules
43
+
44
+ @request_view_args
45
+ @response_handler()
46
+ def name_resolve_by_id(self):
47
+ """Resolve an identifier."""
48
+ item = self.service.resolve(
49
+ id_=resource_requestctx.view_args["pid_value"],
50
+ id_type=resource_requestctx.view_args["pid_type"],
51
+ identity=g.identity,
52
+ )
53
+
54
+ return item.to_dict(), 200
@@ -0,0 +1,50 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # This file is part of Invenio.
4
+ # Copyright (C) 2024-2025 CERN.
5
+ #
6
+ # Invenio-Vocabularies is free software; you can redistribute it and/or
7
+ # modify it under the terms of the MIT License; see LICENSE file for more
8
+ # details.
9
+
10
+ """S3 client."""
11
+
12
+ from flask import current_app
13
+
14
+ try:
15
+ import s3fs
16
+ except ImportError:
17
+ s3fs = None
18
+
19
+
20
+ class S3Client:
21
+ """S3 client."""
22
+
23
+ def __init__(self, access_key, secret_key):
24
+ """Constructor."""
25
+ if s3fs is None:
26
+ raise Exception("s3fs is not installed.")
27
+
28
+ self.fs = s3fs.S3FileSystem(key=access_key, secret=secret_key)
29
+
30
+ def read_file(self, s3_path):
31
+ """Reads a file from S3."""
32
+ with self.fs.open(s3_path, "rb") as f:
33
+ return f.read()
34
+
35
+
36
+ class S3OrcidClient(S3Client):
37
+ """S3 ORCiD client."""
38
+
39
+ def __init__(self):
40
+ """Constructor."""
41
+ access_key = current_app.config["VOCABULARIES_ORCID_ACCESS_KEY"]
42
+ secret_key = current_app.config["VOCABULARIES_ORCID_SECRET_KEY"]
43
+ if access_key == "CHANGEME" or secret_key == "CHANGEME":
44
+ raise Exception(
45
+ "VOCABULARIES_ORCID_ACCESS_KEY and VOCABULARIES_ORCID_SECRET_KEY are not configured."
46
+ )
47
+ super().__init__(
48
+ access_key=access_key,
49
+ secret_key=secret_key,
50
+ )
@@ -0,0 +1,121 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2021-2024 CERN.
4
+ #
5
+ # Invenio-Vocabularies is free software; you can redistribute it and/or
6
+ # modify it under the terms of the MIT License; see LICENSE file for more
7
+ # details.
8
+
9
+ """Names schema."""
10
+
11
+ from functools import partial
12
+
13
+ from invenio_i18n import lazy_gettext as _
14
+ from marshmallow import (
15
+ EXCLUDE,
16
+ ValidationError,
17
+ fields,
18
+ post_dump,
19
+ post_load,
20
+ validates_schema,
21
+ )
22
+ from marshmallow_utils.fields import IdentifierSet, SanitizedUnicode
23
+ from marshmallow_utils.schemas import IdentifierSchema
24
+
25
+ from ...services.schema import BaseVocabularySchema, ModePIDFieldVocabularyMixin
26
+ from ..affiliations.schema import (
27
+ AffiliationRelationSchema as BaseAffiliationRelationSchema,
28
+ )
29
+ from .config import names_schemes
30
+
31
+
32
+ class AffiliationRelationSchema(BaseAffiliationRelationSchema):
33
+ """Affiliation relation schema."""
34
+
35
+ acronym = SanitizedUnicode(dump_only=True)
36
+
37
+ class Meta:
38
+ """Meta class."""
39
+
40
+ unknown = EXCLUDE
41
+
42
+
43
+ class NameSchema(BaseVocabularySchema, ModePIDFieldVocabularyMixin):
44
+ """Service schema for names.
45
+
46
+ Note that this vocabulary is very different from the base vocabulary
47
+ so it does not inherit from it.
48
+ """
49
+
50
+ internal_id = fields.Str(allow_none=True)
51
+ name = SanitizedUnicode()
52
+ given_name = SanitizedUnicode()
53
+ family_name = SanitizedUnicode()
54
+ identifiers = IdentifierSet(
55
+ fields.Nested(
56
+ partial(
57
+ IdentifierSchema,
58
+ # It is intended to allow org schemes to be sent as personal
59
+ # and viceversa. This is a trade off learnt from running
60
+ # Zenodo in production.
61
+ allowed_schemes=names_schemes,
62
+ )
63
+ )
64
+ )
65
+ affiliations = fields.List(fields.Nested(AffiliationRelationSchema))
66
+ props = fields.Dict(keys=fields.Str(), values=fields.Raw())
67
+
68
+ @validates_schema
69
+ def validate_names(self, data, **kwargs):
70
+ """Validate names."""
71
+ can_compose = data.get("family_name") and data.get("given_name")
72
+ name = data.get("name")
73
+ if not can_compose and not name:
74
+ messages = [
75
+ _(
76
+ "A name or the family name together with the given name must be present."
77
+ )
78
+ ]
79
+ raise ValidationError({"family_name": messages})
80
+
81
+ @validates_schema
82
+ def validate_affiliations(self, data, **kwargs):
83
+ """Validate and return distinct affiliations."""
84
+ affiliations = data.get("affiliations", [])
85
+ seen_names = set()
86
+ for affiliation in affiliations:
87
+ name = affiliation.get("name")
88
+ if not affiliation.get("id") and name:
89
+ if name in seen_names:
90
+ affiliations.remove(affiliation)
91
+ else:
92
+ seen_names.add(name)
93
+
94
+ if affiliations:
95
+ data["affiliations"] = affiliations
96
+
97
+ @post_load
98
+ def update_name(self, data, **kwargs):
99
+ """Update names for person.
100
+
101
+ Fill name from given_name and family_name if person.
102
+ """
103
+ family_name = data.get("family_name")
104
+ given_name = data.get("given_name")
105
+ if family_name and given_name:
106
+ data["name"] = f"{family_name}, {given_name}"
107
+
108
+ return data
109
+
110
+ @post_dump
111
+ def dump_name(self, data, **kwargs):
112
+ """Dumps the name if not present in the serialized data."""
113
+ name = data.get("name")
114
+ if not name:
115
+ family_name = data.get("family_name")
116
+ given_name = data.get("given_name")
117
+ if family_name and given_name:
118
+ data["name"] = f"{family_name}, {given_name}"
119
+ elif family_name:
120
+ data["name"] = family_name
121
+ return data
@@ -0,0 +1,64 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2021 CERN.
4
+ #
5
+ # Invenio-Vocabularies is free software; you can redistribute it and/or
6
+ # modify it under the terms of the MIT License; see LICENSE file for more
7
+ # details.
8
+
9
+ """Names services."""
10
+
11
+ from invenio_pidstore.errors import PIDDoesNotExistError
12
+ from invenio_search.engine import dsl
13
+
14
+ from .names import record_type
15
+
16
+ NamesServiceConfig = record_type.service_config_cls
17
+
18
+
19
+ class NamesService(record_type.service_cls):
20
+ """Name service."""
21
+
22
+ def resolve(self, identity, id_, id_type, many=False):
23
+ """Get the record with a given identifier.
24
+
25
+ param id_: The identifier value.
26
+ param id_type: The identifier type.
27
+ param many: If True, return a list of records.
28
+ """
29
+ search_query = dsl.Q(
30
+ "bool",
31
+ minimum_should_match=1,
32
+ must=[
33
+ dsl.Q("term", identifiers__identifier=id_),
34
+ dsl.Q("term", identifiers__scheme=id_type),
35
+ ],
36
+ )
37
+
38
+ # max_records = 1, we assume there cannot be duplicates
39
+ # the loading process needs to make sure of that
40
+ if many:
41
+ results = self._read_many(identity, search_query)
42
+ else:
43
+ results = self._read_many(identity, search_query, max_records=1)
44
+
45
+ # cant use the results_item because it returns dicts instead of records
46
+ total = results.hits.total["value"]
47
+ if total == 0:
48
+ # Not a PID but treated as such
49
+ raise PIDDoesNotExistError(pid_type=id_type, pid_value=id_)
50
+ if many:
51
+ for result in results:
52
+ record = self.record_cls.loads(result.to_dict())
53
+ self.require_permission(identity, "read", record=record)
54
+ return self.result_list(self, identity, results)
55
+ else:
56
+ record = self.record_cls.loads(results[0].to_dict())
57
+ self.require_permission(identity, "read", record=record)
58
+
59
+ return self.result_item(
60
+ self,
61
+ identity,
62
+ record,
63
+ links_tpl=self.links_item_tpl,
64
+ )
@@ -0,0 +1,22 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2020-2021 CERN.
4
+ # Copyright (C) 2021 Northwestern University.
5
+ #
6
+ # Invenio-Vocabularies is free software; you can redistribute it and/or
7
+ # modify it under the terms of the MIT License; see LICENSE file for more
8
+ # details.
9
+
10
+ """Subjects module."""
11
+
12
+ from .facets import SubjectsLabels
13
+ from .resources import SubjectsResource, SubjectsResourceConfig
14
+ from .services import SubjectsService, SubjectsServiceConfig
15
+
16
+ __all__ = [
17
+ "SubjectsLabels",
18
+ "SubjectsResource",
19
+ "SubjectsResourceConfig",
20
+ "SubjectsService",
21
+ "SubjectsServiceConfig",
22
+ ]
@@ -0,0 +1,14 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2021 CERN.
4
+ # Copyright (C) 2021 Northwestern University.
5
+ #
6
+ # Invenio-Vocabularies is free software; you can redistribute it and/or
7
+ # modify it under the terms of the MIT License; see LICENSE file for more
8
+ # details.
9
+
10
+ """Subject API."""
11
+
12
+ from .subjects import record_type
13
+
14
+ Subject = record_type.record_cls
@@ -0,0 +1,90 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2021-2025 CERN.
4
+ # Copyright (C) 2021 Northwestern University.
5
+ # Copyright (C) 2024 University of Münster.
6
+ #
7
+ # Invenio-Vocabularies is free software; you can redistribute it and/or
8
+ # modify it under the terms of the MIT License; see LICENSE file for more
9
+ # details.
10
+
11
+ """Subjects configuration."""
12
+
13
+ from flask import current_app
14
+ from invenio_i18n import get_locale
15
+ from invenio_i18n import lazy_gettext as _
16
+ from invenio_records_resources.services import SearchOptions
17
+ from invenio_records_resources.services.records.components import DataComponent
18
+ from invenio_records_resources.services.records.queryparser import (
19
+ CompositeSuggestQueryParser,
20
+ )
21
+ from werkzeug.local import LocalProxy
22
+
23
+ from ...services.components import PIDComponent
24
+
25
+ subject_schemes = LocalProxy(
26
+ lambda: current_app.config["VOCABULARIES_SUBJECTS_SCHEMES"]
27
+ )
28
+ localized_title = LocalProxy(lambda: f"title.{get_locale()}^20")
29
+
30
+
31
+ gemet_file_url = LocalProxy(
32
+ lambda: current_app.config["VOCABULARIES_SUBJECTS_GEMET_FILE_URL"]
33
+ )
34
+
35
+ euroscivoc_file_url = LocalProxy(
36
+ lambda: current_app.config["VOCABULARIES_SUBJECTS_EUROSCIVOC_FILE_URL"]
37
+ )
38
+
39
+ nvs_file_url = LocalProxy(
40
+ lambda: current_app.config["VOCABULARIES_SUBJECTS_NVS_FILE_URL"]
41
+ )
42
+
43
+
44
+ class SubjectsSearchOptions(SearchOptions):
45
+ """Search options."""
46
+
47
+ suggest_parser_cls = CompositeSuggestQueryParser.factory(
48
+ filter_field="scheme",
49
+ fields=[
50
+ "subject^100",
51
+ "scheme^20",
52
+ localized_title,
53
+ "synonyms^20",
54
+ ],
55
+ clauses=[
56
+ {"type": "cross_fields", "boost": 3},
57
+ {"type": "bool_prefix", "boost": 2, "fuzziness": "AUTO"},
58
+ {"type": "most_fields", "boost": 1, "fuzziness": "AUTO"},
59
+ ],
60
+ )
61
+
62
+ sort_default = "bestmatch"
63
+
64
+ sort_default_no_query = "subject"
65
+
66
+ sort_options = {
67
+ "bestmatch": dict(
68
+ title=_("Best match"),
69
+ fields=["_score"], # ES defaults to desc on `_score` field
70
+ ),
71
+ "subject": dict(
72
+ title=_("Name"),
73
+ fields=["subject_sort"],
74
+ ),
75
+ "newest": dict(
76
+ title=_("Newest"),
77
+ fields=["-created"],
78
+ ),
79
+ "oldest": dict(
80
+ title=_("Oldest"),
81
+ fields=["created"],
82
+ ),
83
+ }
84
+
85
+
86
+ service_components = [
87
+ # Order of components are important!
88
+ DataComponent,
89
+ PIDComponent,
90
+ ]
@@ -0,0 +1,63 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2024 University of Münster.
4
+ #
5
+ # Invenio-Vocabularies is free software; you can redistribute it and/or
6
+ # modify it under the terms of the MIT License; see LICENSE file for more
7
+ # details.
8
+
9
+ """Names datastreams, transformers, writers and readers."""
10
+
11
+ from invenio_access.permissions import system_identity
12
+ from invenio_i18n import lazy_gettext as _
13
+
14
+ from ...datastreams.writers import ServiceWriter
15
+ from .euroscivoc import datastreams as euroscivoc_datastreams
16
+ from .gemet import datastreams as gemet_datastreams
17
+ from .mesh import datastreams as mesh_datastreams
18
+ from .nvs import datastreams as nvs_datastreams
19
+
20
+
21
+ class SubjectsServiceWriter(ServiceWriter):
22
+ """Subjects Service Writer."""
23
+
24
+ def __init__(self, *args, **kwargs):
25
+ """Constructor."""
26
+ service_or_name = kwargs.pop("service_or_name", "subjects")
27
+ super().__init__(service_or_name=service_or_name, *args, **kwargs)
28
+
29
+ def _entry_id(self, entry):
30
+ """Get the id from an entry."""
31
+ return entry["id"]
32
+
33
+
34
+ VOCABULARIES_DATASTREAM_READERS = {
35
+ **mesh_datastreams.VOCABULARIES_DATASTREAM_READERS,
36
+ }
37
+ """Subjects Data Streams readers."""
38
+
39
+ VOCABULARIES_DATASTREAM_TRANSFORMERS = {
40
+ **mesh_datastreams.VOCABULARIES_DATASTREAM_TRANSFORMERS,
41
+ **euroscivoc_datastreams.VOCABULARIES_DATASTREAM_TRANSFORMERS,
42
+ **gemet_datastreams.VOCABULARIES_DATASTREAM_TRANSFORMERS,
43
+ **nvs_datastreams.VOCABULARIES_DATASTREAM_TRANSFORMERS,
44
+ }
45
+ """Subjects Data Streams transformers."""
46
+
47
+ VOCABULARIES_DATASTREAM_WRITERS = {
48
+ "subjects-service": SubjectsServiceWriter,
49
+ **mesh_datastreams.VOCABULARIES_DATASTREAM_WRITERS,
50
+ }
51
+ """Subjects Data Streams writers."""
52
+
53
+ DATASTREAM_CONFIG = {
54
+ "readers": [
55
+ {"type": "yaml"},
56
+ ],
57
+ "writers": [
58
+ {
59
+ "type": "subjects-service",
60
+ }
61
+ ],
62
+ }
63
+ """Data Stream configuration."""
@@ -0,0 +1,9 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2024 CERN.
4
+ #
5
+ # Invenio-Vocabularies is free software; you can redistribute it and/or
6
+ # modify it under the terms of the MIT License; see LICENSE file for more
7
+ # details.
8
+
9
+ """EuroSciVoc Subjects module."""
@@ -0,0 +1,101 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2024 CERN.
4
+ #
5
+ # Invenio-Vocabularies is free software; you can redistribute it and/or
6
+ # modify it under the terms of the MIT License; see LICENSE file for more
7
+ # details.
8
+
9
+ """EuroSciVoc subjects datastreams, readers, transformers, and writers."""
10
+
11
+ from invenio_vocabularies.datastreams.transformers import RDFTransformer
12
+
13
+ from ..config import euroscivoc_file_url
14
+
15
+
16
+ class EuroSciVocSubjectsTransformer(RDFTransformer):
17
+ """
18
+ Transformer class to convert EuroSciVoc RDF data to a dictionary format.
19
+
20
+ Input:
21
+ - Relevant fields:
22
+ - `skos:notation`: Primary identifier for the concept.
23
+ - `skos:prefLabel`: Preferred labels with language codes.
24
+ - `skos:altLabel`: Alternative labels.
25
+ - `skos:broader`: Broader concepts that this concept belongs to.
26
+
27
+ Output:
28
+ {
29
+ "id": "euroscivoc:1717", # EuroSciVoc-specific concept ID (skos:notation).
30
+ "scheme": "EuroSciVoc", # The scheme name indicating this is a EuroSciVoc concept.
31
+ "subject": "Satellite radio", # The primary subject label (first preferred label in English, skos:prefLabel).
32
+ "title": {
33
+ "it": "Radio satellitare", # Italian preferred label (skos:prefLabel).
34
+ "en": "Satellite radio", # English preferred label (skos:prefLabel).
35
+ },
36
+ "props": {
37
+ "parents": "euroscivoc:1225", # The broader concept (skos:broader), identified by its EuroSciVoc Concept ID.
38
+ },
39
+ "identifiers": [
40
+ {
41
+ "scheme": "url", # Type of identifier (URL).
42
+ "identifier": "http://data.europa.eu/8mn/euroscivoc/87ff3577-527a-4a40-9c76-2f9d3075e2ba", # URI of the concept (rdf:about).
43
+ }
44
+ ],
45
+ }
46
+ """
47
+
48
+ def _get_notation(self, subject, rdf_graph):
49
+ """Extract the numeric notation for a subject."""
50
+ for _, _, notation in rdf_graph.triples(
51
+ (subject, self.skos_core.notation, None)
52
+ ):
53
+ if str(notation).isdigit():
54
+ return str(notation)
55
+ return None
56
+
57
+ def _get_parent_notation(self, broader, rdf_graph):
58
+ """Extract parent notation using numeric notation."""
59
+ return self._get_notation(broader, rdf_graph)
60
+
61
+ def _transform_entry(self, subject, rdf_graph):
62
+ notation = self._get_notation(subject, rdf_graph)
63
+ id = f"euroscivoc:{notation}" if notation else None
64
+ labels = self._get_labels(subject, rdf_graph)
65
+ parents = ",".join(
66
+ f"euroscivoc:{n}"
67
+ for n in reversed(self._find_parents(subject, rdf_graph))
68
+ if n
69
+ )
70
+
71
+ return {
72
+ "id": id,
73
+ "scheme": "EuroSciVoc",
74
+ "subject": labels.get("en", "").capitalize(),
75
+ "title": labels,
76
+ "props": {"parents": parents} if parents else {},
77
+ "identifiers": self._get_identifiers(subject),
78
+ }
79
+
80
+
81
+ # Configuration for datastream
82
+
83
+ VOCABULARIES_DATASTREAM_TRANSFORMERS = {
84
+ "euroscivoc-transformer": EuroSciVocSubjectsTransformer
85
+ }
86
+
87
+ DATASTREAM_CONFIG = {
88
+ "readers": [
89
+ {
90
+ "type": "http",
91
+ "args": {
92
+ "origin": euroscivoc_file_url,
93
+ },
94
+ },
95
+ {
96
+ "type": "rdf",
97
+ },
98
+ ],
99
+ "transformers": [{"type": "euroscivoc-transformer"}],
100
+ "writers": [{"args": {"writer": {"type": "subjects-service"}}, "type": "async"}],
101
+ }
@@ -0,0 +1,23 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2021 Northwestern University.
4
+ #
5
+ # Invenio-Vocabularies is free software; you can redistribute it and/or
6
+ # modify it under the terms of the MIT License; see LICENSE file for more
7
+ # details.
8
+
9
+ """Subjects services."""
10
+
11
+
12
+ class SubjectsLabels:
13
+ """Fetching of subjects labels for facets."""
14
+
15
+ def __call__(self, ids):
16
+ """Return the mapping when evaluated.
17
+
18
+ In this case, the ids received are actually the vocabulary `scheme`
19
+ (top-level) and `subject` (nested). And since they are already
20
+ human-readable, we keep them as-is.
21
+ """
22
+ unique_ids = list(set(ids))
23
+ return {id_: id_ for id_ in unique_ids}
@@ -0,0 +1,9 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2024 CERN.
4
+ #
5
+ # Invenio-Vocabularies is free software; you can redistribute it and/or
6
+ # modify it under the terms of the MIT License; see LICENSE file for more
7
+ # details.
8
+
9
+ """GEMET Subjects module."""