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,175 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2020-2024 CERN.
4
+ # Copyright (C) 2021 Graz University of Technology.
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
+ """Commands to create and manage vocabularies."""
11
+
12
+ import click
13
+ from flask.cli import with_appcontext
14
+ from invenio_access.permissions import system_identity
15
+ from invenio_pidstore.errors import PIDDeletedError, PIDDoesNotExistError
16
+
17
+ from .datastreams import DataStreamFactory
18
+ from .factories import get_vocabulary_config
19
+
20
+
21
+ @click.group()
22
+ def vocabularies():
23
+ """Vocabularies command."""
24
+
25
+
26
+ def _process_vocab(config, num_samples=None):
27
+ """Import a vocabulary."""
28
+ ds = DataStreamFactory.create(
29
+ readers_config=config["readers"],
30
+ transformers_config=config.get("transformers"),
31
+ writers_config=config["writers"],
32
+ batch_size=config.get("batch_size", 1000),
33
+ write_many=config.get("write_many", False),
34
+ )
35
+
36
+ success, errored, filtered = 0, 0, 0
37
+ left = num_samples or -1
38
+ for result in ds.process():
39
+ left = left - 1
40
+ if result.filtered:
41
+ filtered += 1
42
+ if result.errors:
43
+ for err in result.errors:
44
+ click.secho(err, fg="red")
45
+ errored += 1
46
+ else:
47
+ success += 1
48
+ if left == 0:
49
+ click.secho(f"Number of samples reached {num_samples}", fg="green")
50
+ break
51
+ return success, errored, filtered
52
+
53
+
54
+ def _output_process(vocabulary, op, success, errored, filtered):
55
+ """Outputs the result of an operation."""
56
+ total = success + errored
57
+
58
+ color = "green"
59
+ if errored:
60
+ color = "yellow" if success else "red"
61
+
62
+ click.secho(
63
+ f"Vocabulary {vocabulary} {op}. Total items {total}. \n"
64
+ f"{success} items succeeded\n"
65
+ f"{errored} contained errors\n"
66
+ f"{filtered} were filtered.",
67
+ fg=color,
68
+ )
69
+
70
+
71
+ @vocabularies.command(name="import")
72
+ @click.option("-v", "--vocabulary", type=click.STRING, required=True)
73
+ @click.option("-f", "--filepath", type=click.STRING)
74
+ @click.option("-o", "--origin", type=click.STRING)
75
+ @click.option("-n", "--num-samples", type=click.INT)
76
+ @with_appcontext
77
+ def import_vocab(vocabulary, filepath=None, origin=None, num_samples=None):
78
+ """Import a vocabulary."""
79
+ if not filepath and not origin:
80
+ click.secho("One of --filepath or --origin must be present.", fg="red")
81
+ exit(1)
82
+
83
+ vc = get_vocabulary_config(vocabulary)
84
+ config = vc.get_config(filepath, origin)
85
+
86
+ success, errored, filtered = _process_vocab(config, num_samples)
87
+
88
+ _output_process(vocabulary, "imported", success, errored, filtered)
89
+
90
+
91
+ @vocabularies.command()
92
+ @click.option("-v", "--vocabulary", type=click.STRING, required=True)
93
+ @click.option("-f", "--filepath", type=click.STRING)
94
+ @click.option("-o", "--origin", type=click.STRING)
95
+ @with_appcontext
96
+ def update(vocabulary, filepath=None, origin=None):
97
+ """Import a vocabulary."""
98
+ if not filepath and not origin:
99
+ click.secho("One of --filepath or --origin must be present.", fg="red")
100
+ exit(1)
101
+ vc = get_vocabulary_config(vocabulary)
102
+ config = vc.get_config(filepath, origin)
103
+
104
+ for w_conf in config["writers"]:
105
+ if w_conf["type"] == "async":
106
+ w_conf_update = w_conf["args"]["writer"]
107
+ else:
108
+ w_conf_update = w_conf
109
+
110
+ if "args" in w_conf_update:
111
+ w_conf_update["args"]["update"] = True
112
+ else:
113
+ w_conf_update["args"] = {"update": True}
114
+
115
+ success, errored, filtered = _process_vocab(config)
116
+
117
+ _output_process(vocabulary, "updated", success, errored, filtered)
118
+
119
+
120
+ @vocabularies.command()
121
+ @click.option("-v", "--vocabulary", type=click.STRING, required=True)
122
+ @click.option("-f", "--filepath", type=click.STRING)
123
+ @click.option("-o", "--origin", type=click.STRING)
124
+ @click.option("-t", "--target", type=click.STRING)
125
+ @click.option("-n", "--num-samples", type=click.INT)
126
+ @with_appcontext
127
+ def convert(vocabulary, filepath=None, origin=None, target=None, num_samples=None):
128
+ """Convert a vocabulary to a new format."""
129
+ if not filepath and (not origin or not target):
130
+ click.secho(
131
+ "One of --filepath or --origin and --target must be present.", fg="red"
132
+ )
133
+ exit(1)
134
+
135
+ vc = get_vocabulary_config(vocabulary)
136
+ config = vc.get_config(filepath, origin)
137
+ if not filepath:
138
+ config["writers"] = [{"type": "yaml", "args": {"filepath": target}}]
139
+
140
+ success, errored, filtered = _process_vocab(config, num_samples)
141
+ _output_process(vocabulary, "converted", success, errored, filtered)
142
+
143
+
144
+ @vocabularies.command()
145
+ @click.option("-v", "--vocabulary", type=click.STRING, required=True)
146
+ @click.option(
147
+ "-i",
148
+ "--identifier",
149
+ type=click.STRING,
150
+ help="Identifier of the vocabulary item to delete.",
151
+ )
152
+ @click.option("--all", is_flag=True, default=False)
153
+ @with_appcontext
154
+ def delete(vocabulary, identifier, all):
155
+ """Delete all items or a specific one of the vocabulary."""
156
+ if not identifier and not all:
157
+ click.secho("An identifier or the --all flag must be present.", fg="red")
158
+ exit(1)
159
+
160
+ vc = get_vocabulary_config(vocabulary)
161
+ service = vc.get_service()
162
+ if identifier:
163
+ try:
164
+ if service.delete(system_identity, identifier):
165
+ click.secho(f"{identifier} deleted from {vocabulary}.", fg="green")
166
+ except (PIDDeletedError, PIDDoesNotExistError):
167
+ click.secho(f"PID {identifier} not found.")
168
+ elif all:
169
+ items = service.scan(system_identity)
170
+ for item in items.hits:
171
+ try:
172
+ if service.delete(system_identity, item["id"]):
173
+ click.secho(f"{item['id']} deleted from {vocabulary}.", fg="green")
174
+ except (PIDDeletedError, PIDDoesNotExistError):
175
+ click.secho(f"PID {item['id']} not found.")
@@ -0,0 +1,231 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2020-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
+ """Vocabularies configuration."""
12
+
13
+ import re
14
+
15
+ from idutils import is_doi, is_gnd, is_isni, is_orcid, is_ror, is_url
16
+ from invenio_i18n import lazy_gettext as _
17
+
18
+ from .datastreams.readers import (
19
+ CSVReader,
20
+ GzipReader,
21
+ JsonLinesReader,
22
+ JsonReader,
23
+ OAIPMHReader,
24
+ RDFReader,
25
+ SimpleHTTPReader,
26
+ SPARQLReader,
27
+ TarReader,
28
+ XMLReader,
29
+ YamlReader,
30
+ ZipReader,
31
+ )
32
+ from .datastreams.transformers import XMLTransformer
33
+ from .datastreams.writers import AsyncWriter, ServiceWriter, YamlWriter
34
+ from .resources import VocabulariesResourceConfig
35
+ from .services.config import VocabulariesServiceConfig
36
+
37
+ VOCABULARIES_RESOURCE_CONFIG = VocabulariesResourceConfig
38
+ """Configure the resource."""
39
+
40
+ VOCABULARIES_SERVICE_CONFIG = VocabulariesServiceConfig
41
+ """Configure the service."""
42
+
43
+ VOCABULARIES_IDENTIFIER_SCHEMES = {
44
+ "grid": {"label": _("GRID"), "validator": lambda x: True},
45
+ "gnd": {"label": _("GND"), "validator": is_gnd},
46
+ "isni": {"label": _("ISNI"), "validator": is_isni},
47
+ "ror": {"label": _("ROR"), "validator": is_ror},
48
+ }
49
+ """"Generic identifier schemes, usable by other vocabularies."""
50
+
51
+ edmo_regexp = re.compile(r"^https://edmo\.seadatanet\.org/report/\d+$")
52
+
53
+
54
+ def is_pic(val):
55
+ """Test if argument is a Participant Identification Code (PIC)."""
56
+ if len(val) != 9:
57
+ return False
58
+ return val.isdigit()
59
+
60
+
61
+ def is_edmo(val):
62
+ """Test if argument is a European Directory of Marine Organisations (EDMO) identifier."""
63
+ return edmo_regexp.match(val)
64
+
65
+
66
+ VOCABULARIES_AFFILIATION_SCHEMES = {
67
+ **VOCABULARIES_IDENTIFIER_SCHEMES,
68
+ "pic": {"label": _("PIC"), "validator": is_pic},
69
+ "edmo": {"label": _("EDMO"), "validator": is_edmo},
70
+ }
71
+ """Affiliations allowed identifier schemes."""
72
+
73
+ VOCABULARIES_FUNDER_SCHEMES = {
74
+ **VOCABULARIES_IDENTIFIER_SCHEMES,
75
+ "doi": {"label": _("DOI"), "validator": is_doi},
76
+ }
77
+ """Funders allowed identifier schemes."""
78
+
79
+ VOCABULARIES_FUNDER_DOI_PREFIX = "10.13039"
80
+ """DOI prefix for the identifier formed with the FundRef id."""
81
+
82
+ VOCABULARIES_AWARD_SCHEMES = {
83
+ "url": {"label": _("URL"), "validator": is_url},
84
+ "doi": {"label": _("DOI"), "validator": is_doi},
85
+ }
86
+ """Awards allowed identifier schemes."""
87
+
88
+ VOCABULARIES_AWARDS_OPENAIRE_FUNDERS = {
89
+ "aka_________": "05k73zm37",
90
+ "anr_________": "00rbzpz17",
91
+ "arc_________": "05mmh0f86",
92
+ "asap________": "03zj4c476",
93
+ "cihr________": "01gavpb45",
94
+ "corda_______": "00k4n6c32",
95
+ "corda_____he": "00k4n6c32",
96
+ "corda__h2020": "00k4n6c32",
97
+ "euenvagency_": "02k4b9v70",
98
+ "fct_________": "00snfqn58",
99
+ "fwf_________": "013tf3c58",
100
+ "inca________": "03m8vkq32",
101
+ "irb_hr______": "03n51vw80",
102
+ "lcs_________": "02ar66p97",
103
+ "mestd_______": "01znas443",
104
+ "nhmrc_______": "011kf5r70",
105
+ "nih_________": "01cwqze88",
106
+ "nserc_______": "01h531d29",
107
+ "nsf_________": "021nxhr62",
108
+ "nwo_________": "04jsz6e67",
109
+ "rcuk________": "00dq2kk65", # deprecated funder org
110
+ "sfi_________": "0271asj38",
111
+ "snsf________": "00yjd3n13",
112
+ "sshrc_______": "006cvnv84",
113
+ "tubitakf____": "04w9kkr77",
114
+ "twcf________": "00x0z1472",
115
+ "ukri________": "001aqnf71",
116
+ "wt__________": "029chgv08",
117
+ }
118
+ """Mapping of OpenAIRE and ROR funder codes."""
119
+
120
+ VOCABULARIES_AWARDS_EC_ROR_ID = "00k4n6c32"
121
+ """ROR ID for EC funder."""
122
+
123
+ VOCABULARIES_NAMES_SCHEMES = {
124
+ "orcid": {"label": _("ORCID"), "validator": is_orcid, "datacite": "ORCID"},
125
+ "isni": {"label": _("ISNI"), "validator": is_isni, "datacite": "ISNI"},
126
+ "gnd": {"label": _("GND"), "validator": is_gnd, "datacite": "GND"},
127
+ }
128
+ """Names allowed identifier schemes."""
129
+
130
+ VOCABULARIES_SUBJECTS_SCHEMES = {
131
+ "gnd": {"label": _("GND"), "validator": is_gnd, "datacite": "GND"},
132
+ "url": {"label": _("URL"), "validator": is_url},
133
+ }
134
+ """Subjects allowed identifier schemes."""
135
+
136
+ VOCABULARIES_CUSTOM_VOCABULARY_TYPES = [
137
+ "names",
138
+ "affiliations",
139
+ "awards",
140
+ "funders",
141
+ "subjects",
142
+ ]
143
+ """List of custom vocabulary types."""
144
+
145
+ VOCABULARIES_DATASTREAM_READERS = {
146
+ "csv": CSVReader,
147
+ "json": JsonReader,
148
+ "jsonl": JsonLinesReader,
149
+ "gzip": GzipReader,
150
+ "tar": TarReader,
151
+ "http": SimpleHTTPReader,
152
+ "rdf": RDFReader,
153
+ "sparql": SPARQLReader,
154
+ "yaml": YamlReader,
155
+ "zip": ZipReader,
156
+ "xml": XMLReader,
157
+ "oai-pmh": OAIPMHReader,
158
+ }
159
+ """Data Streams readers."""
160
+
161
+ VOCABULARIES_DATASTREAM_TRANSFORMERS = {
162
+ "xml": XMLTransformer,
163
+ }
164
+ """Data Streams transformers."""
165
+
166
+ VOCABULARIES_DATASTREAM_WRITERS = {
167
+ "service": ServiceWriter,
168
+ "yaml": YamlWriter,
169
+ "async": AsyncWriter,
170
+ }
171
+ """Data Streams writers."""
172
+
173
+ VOCABULARIES_TYPES_SORT_OPTIONS = {
174
+ "name": dict(
175
+ title=_("Name"),
176
+ fields=["id"],
177
+ ),
178
+ "count": dict(
179
+ title=_("Number of entries"),
180
+ fields=["count"],
181
+ ),
182
+ }
183
+ """Definitions of available Vocabulary types sort options. """
184
+
185
+ VOCABULARIES_TYPES_SEARCH = {
186
+ "facets": [],
187
+ "sort": ["name", "count"],
188
+ }
189
+ """Vocabulary type search configuration."""
190
+
191
+ VOCABULARIES_SUBJECTS_EUROSCIVOC_FILE_URL = "https://publications.europa.eu/resource/distribution/euroscivoc/rdf/skos_ap_eu/EuroSciVoc-skos-ap-eu.rdf"
192
+ """Subject EuroSciVoc file download link."""
193
+
194
+ VOCABULARIES_SUBJECTS_GEMET_FILE_URL = (
195
+ "https://www.eionet.europa.eu/gemet/latest/gemet.rdf.gz"
196
+ )
197
+ """Subject GEMET file download link."""
198
+
199
+ VOCABULARIES_SUBJECTS_NVS_FILE_URL = "http://vocab.nerc.ac.uk/collection/P02/current/?_profile=nvs&_mediatype=application/rdf+xml"
200
+ """Subject NVS-P02 file download link."""
201
+
202
+ VOCABULARIES_AFFILIATIONS_EDMO_COUNTRY_MAPPING = {
203
+ "Cape Verde": "Cabo Verde",
204
+ }
205
+ """Affiliations EDMO Country name remapping dictionary."""
206
+
207
+ VOCABULARIES_ORCID_ACCESS_KEY = "CHANGEME"
208
+ """ORCID access key to access the s3 bucket."""
209
+ VOCABULARIES_ORCID_SECRET_KEY = "CHANGEME"
210
+ """ORCID secret key to access the s3 bucket."""
211
+ VOCABULARIES_ORCID_SUMMARIES_BUCKET = "v3.0-summaries"
212
+ """ORCID summaries bucket name."""
213
+ VOCABULARIES_ORCID_SYNC_MAX_WORKERS = 32
214
+ """ORCID max number of simultaneous workers/connections."""
215
+ VOCABULARIES_ORCID_SYNC_SINCE = {
216
+ "days": 1,
217
+ }
218
+ """ORCID time shift to sync. Parameters accepted are the ones passed to 'datetime.timedelta'."""
219
+
220
+ VOCABULARIES_ORCID_ORG_IDS_MAPPING_PATH = None
221
+ """Path to the CSV file for mapping ORCiD organization IDs to affiliation IDs.
222
+
223
+ The path can be specified as either an absolute path or a relative path within the
224
+ Flask app instance folder (i.e. ``current_app.instance_path``).
225
+
226
+ The CSV file should have the following columns:
227
+
228
+ - `org_scheme`: The ORCiD organization ID.
229
+ - `org_id`: The ORCiD organization ID.
230
+ - `aff_id`: The affiliation ID to map to.
231
+ """
@@ -0,0 +1,9 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2020-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
+ """Contrib module."""
@@ -0,0 +1,20 @@
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
+ """Affiliations module."""
11
+
12
+ from .resources import AffiliationsResource, AffiliationsResourceConfig
13
+ from .services import AffiliationsService, AffiliationsServiceConfig
14
+
15
+ __all__ = [
16
+ "AffiliationsResource",
17
+ "AffiliationsResourceConfig",
18
+ "AffiliationsService",
19
+ "AffiliationsServiceConfig",
20
+ ]
@@ -0,0 +1,61 @@
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
+ """Vocabulary affiliations."""
10
+
11
+ from flask_resources import JSONSerializer, ResponseHandler
12
+ from invenio_db import db
13
+ from invenio_records.dumpers import SearchDumper
14
+ from invenio_records.dumpers.indexedat import IndexedAtDumperExt
15
+ from invenio_records_resources.factories.factory import RecordTypeFactory
16
+ from invenio_records_resources.records.systemfields import ModelPIDField
17
+ from invenio_records_resources.resources.records.headers import etag_headers
18
+
19
+ from invenio_vocabularies.services.permissions import PermissionPolicy
20
+
21
+ from .config import AffiliationsSearchOptions, service_components
22
+ from .schema import AffiliationSchema
23
+
24
+ record_type = RecordTypeFactory(
25
+ "Affiliation",
26
+ # Data layer
27
+ pid_field_cls=ModelPIDField,
28
+ pid_field_kwargs={
29
+ "model_field_name": "pid",
30
+ },
31
+ model_cls_attrs={
32
+ # cannot set to nullable=False because it would fail at
33
+ # service level when create({}), see records-resources.
34
+ "pid": db.Column(db.String(255), unique=True),
35
+ },
36
+ schema_version="1.0.0",
37
+ schema_path="local://affiliations/affiliation-v1.0.0.json",
38
+ index_name="affiliations-affiliation-v2.0.0",
39
+ record_dumper=SearchDumper(
40
+ model_fields={"pid": ("id", str)},
41
+ extensions=[
42
+ IndexedAtDumperExt(),
43
+ ],
44
+ ),
45
+ # Service layer
46
+ service_id="affiliations",
47
+ service_schema=AffiliationSchema,
48
+ search_options=AffiliationsSearchOptions,
49
+ service_components=service_components,
50
+ permission_policy_cls=PermissionPolicy,
51
+ # Resource layer
52
+ endpoint_route="/affiliations",
53
+ resource_cls_attrs={
54
+ "response_handlers": {
55
+ "application/json": ResponseHandler(JSONSerializer(), headers=etag_headers),
56
+ "application/vnd.inveniordm.v1+json": ResponseHandler(
57
+ JSONSerializer(), headers=etag_headers
58
+ ),
59
+ }
60
+ },
61
+ )
@@ -0,0 +1,13 @@
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
+ """Vocabulary affiliations."""
10
+
11
+ from .affiliations import record_type
12
+
13
+ Affiliation = record_type.record_cls
@@ -0,0 +1,79 @@
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
+ """Vocabulary affiliations configuration."""
10
+
11
+ from flask import current_app
12
+ from invenio_i18n import get_locale
13
+ from invenio_i18n import lazy_gettext as _
14
+ from invenio_records_resources.services import SearchOptions
15
+ from invenio_records_resources.services.records.components import DataComponent
16
+ from invenio_records_resources.services.records.queryparser import (
17
+ CompositeSuggestQueryParser,
18
+ )
19
+ from werkzeug.local import LocalProxy
20
+
21
+ from ...services.components import PIDComponent
22
+
23
+ affiliation_schemes = LocalProxy(
24
+ lambda: current_app.config["VOCABULARIES_AFFILIATION_SCHEMES"]
25
+ )
26
+ affiliation_edmo_country_mappings = LocalProxy(
27
+ lambda: current_app.config["VOCABULARIES_AFFILIATIONS_EDMO_COUNTRY_MAPPING"]
28
+ )
29
+ localized_title = LocalProxy(lambda: f"title.{get_locale()}^2")
30
+
31
+
32
+ class AffiliationsSearchOptions(SearchOptions):
33
+ """Search options."""
34
+
35
+ suggest_parser_cls = CompositeSuggestQueryParser.factory(
36
+ fields=[
37
+ # We boost the acronym fields, since they're smaller words and are more
38
+ # likely to be used in a query.
39
+ "acronym.keyword^50",
40
+ "acronym^10",
41
+ "name^10",
42
+ # Aliases can sometimes be shorter, so we boost them a bit.
43
+ "aliases^5",
44
+ localized_title,
45
+ # Allow to search identifiers directly (e.g. ROR)
46
+ "identifiers.identifier",
47
+ "country_name",
48
+ ],
49
+ )
50
+
51
+ sort_default = "bestmatch"
52
+
53
+ sort_default_no_query = "name"
54
+
55
+ sort_options = {
56
+ "bestmatch": dict(
57
+ title=_("Best match"),
58
+ fields=["_score"], # ES defaults to desc on `_score` field
59
+ ),
60
+ "name": dict(
61
+ title=_("Name"),
62
+ fields=["name_sort"],
63
+ ),
64
+ "newest": dict(
65
+ title=_("Newest"),
66
+ fields=["-created"],
67
+ ),
68
+ "oldest": dict(
69
+ title=_("Oldest"),
70
+ fields=["created"],
71
+ ),
72
+ }
73
+
74
+
75
+ service_components = [
76
+ # Order of components are important!
77
+ DataComponent,
78
+ PIDComponent,
79
+ ]