invenio-app-ils 1.0.0a54__py2.py3-none-any.whl → 6.1.0__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 (331) hide show
  1. invenio_app_ils/__init__.py +2 -2
  2. invenio_app_ils/acquisition/api.py +3 -1
  3. invenio_app_ils/acquisition/config.py +10 -21
  4. invenio_app_ils/acquisition/jsonresolvers/order_order_lines.py +1 -0
  5. invenio_app_ils/acquisition/mappings/os-v1/acq_orders/order-v1.0.0.json +364 -0
  6. invenio_app_ils/acquisition/mappings/os-v2/__init__.py +0 -0
  7. invenio_app_ils/acquisition/mappings/os-v2/acq_orders/order-v1.0.0.json +364 -0
  8. invenio_app_ils/acquisition/mappings/v7/acq_orders/order-v1.0.0.json +14 -0
  9. invenio_app_ils/acquisition/search.py +5 -15
  10. invenio_app_ils/assets/semantic-ui/less/theme.config +103 -0
  11. invenio_app_ils/assets/semantic-ui/templates/.gitkeep +0 -0
  12. invenio_app_ils/circulation/api.py +153 -67
  13. invenio_app_ils/circulation/config.py +29 -25
  14. invenio_app_ils/circulation/indexer.py +14 -19
  15. invenio_app_ils/circulation/loaders/__init__.py +2 -0
  16. invenio_app_ils/circulation/loaders/schemas/json/loan_checkout.py +2 -3
  17. invenio_app_ils/circulation/loaders/schemas/json/loan_request.py +82 -16
  18. invenio_app_ils/circulation/loaders/schemas/json/loan_self_checkout.py +19 -0
  19. invenio_app_ils/circulation/notifications/api.py +23 -19
  20. invenio_app_ils/circulation/notifications/messages.py +6 -6
  21. invenio_app_ils/circulation/notifications/tasks.py +1 -2
  22. invenio_app_ils/circulation/receivers.py +2 -5
  23. invenio_app_ils/circulation/search.py +23 -22
  24. invenio_app_ils/circulation/serializers/__init__.py +2 -2
  25. invenio_app_ils/circulation/serializers/csv.py +1 -3
  26. invenio_app_ils/circulation/serializers/custom_fields.py +5 -9
  27. invenio_app_ils/circulation/serializers/json.py +2 -6
  28. invenio_app_ils/circulation/serializers/response.py +12 -12
  29. invenio_app_ils/circulation/stats/views.py +5 -15
  30. invenio_app_ils/circulation/tasks.py +2 -6
  31. invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/self_checkout.html +19 -0
  32. invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/update_dates.html +19 -0
  33. invenio_app_ils/circulation/utils.py +23 -17
  34. invenio_app_ils/circulation/views.py +103 -39
  35. invenio_app_ils/cli.py +220 -260
  36. invenio_app_ils/closures/api.py +72 -7
  37. invenio_app_ils/closures/serializers/__init__.py +16 -0
  38. invenio_app_ils/closures/serializers/response.py +35 -0
  39. invenio_app_ils/closures/serializers/schema.py +28 -0
  40. invenio_app_ils/closures/tasks.py +4 -11
  41. invenio_app_ils/closures/views.py +66 -0
  42. invenio_app_ils/config.py +207 -150
  43. invenio_app_ils/document_requests/api.py +6 -21
  44. invenio_app_ils/document_requests/loaders/__init__.py +4 -12
  45. invenio_app_ils/document_requests/mappings/{v6 → os-v1}/__init__.py +2 -2
  46. invenio_app_ils/document_requests/mappings/os-v1/document_requests/document_request-v1.0.0.json +196 -0
  47. invenio_app_ils/document_requests/mappings/os-v2/__init__.py +8 -0
  48. invenio_app_ils/document_requests/mappings/os-v2/document_requests/document_request-v1.0.0.json +196 -0
  49. invenio_app_ils/document_requests/notifications/api.py +2 -7
  50. invenio_app_ils/document_requests/notifications/messages.py +3 -7
  51. invenio_app_ils/document_requests/search.py +2 -6
  52. invenio_app_ils/document_requests/views.py +4 -10
  53. invenio_app_ils/documents/api.py +19 -25
  54. invenio_app_ils/documents/indexer.py +13 -20
  55. invenio_app_ils/documents/jsonresolvers/document_circulation.py +11 -33
  56. invenio_app_ils/documents/jsonresolvers/document_eitem.py +1 -0
  57. invenio_app_ils/documents/jsonresolvers/document_item.py +8 -9
  58. invenio_app_ils/documents/jsonresolvers/document_stock.py +7 -7
  59. invenio_app_ils/documents/loaders/jsonschemas/document.py +3 -14
  60. invenio_app_ils/documents/mappings/{v6 → os-v1}/__init__.py +1 -1
  61. invenio_app_ils/documents/mappings/os-v1/documents/document-v1.0.0.json +932 -0
  62. invenio_app_ils/documents/mappings/os-v1/documents/document-v2.0.0.json +1066 -0
  63. invenio_app_ils/documents/mappings/os-v2/__init__.py +8 -0
  64. invenio_app_ils/documents/mappings/os-v2/documents/document-v1.0.0.json +932 -0
  65. invenio_app_ils/documents/mappings/os-v2/documents/document-v2.0.0.json +1066 -0
  66. invenio_app_ils/documents/mappings/v7/documents/document-v1.0.0.json +102 -11
  67. invenio_app_ils/documents/mappings/v7/documents/document-v2.0.0.json +1066 -0
  68. invenio_app_ils/documents/schemas/documents/document-v2.0.0.json +732 -0
  69. invenio_app_ils/eitems/api.py +41 -7
  70. invenio_app_ils/eitems/loaders/jsonschemas/eitems.py +6 -6
  71. invenio_app_ils/eitems/mappings/{v6 → os-v1}/__init__.py +1 -1
  72. invenio_app_ils/eitems/mappings/os-v1/eitems/eitem-v1.0.0.json +139 -0
  73. invenio_app_ils/eitems/mappings/os-v1/eitems/eitem-v2.0.0.json +142 -0
  74. invenio_app_ils/eitems/mappings/os-v1/eitems/eitem-v3.0.0.json +179 -0
  75. invenio_app_ils/{series/mappings/v6 → eitems/mappings/os-v2}/__init__.py +1 -1
  76. invenio_app_ils/eitems/mappings/os-v2/eitems/eitem-v1.0.0.json +139 -0
  77. invenio_app_ils/eitems/mappings/os-v2/eitems/eitem-v2.0.0.json +142 -0
  78. invenio_app_ils/eitems/mappings/os-v2/eitems/eitem-v3.0.0.json +179 -0
  79. invenio_app_ils/eitems/mappings/v7/eitems/eitem-v1.0.0.json +12 -2
  80. invenio_app_ils/eitems/mappings/v7/eitems/eitem-v2.0.0.json +142 -0
  81. invenio_app_ils/eitems/mappings/v7/eitems/eitem-v3.0.0.json +179 -0
  82. invenio_app_ils/eitems/schemas/eitems/eitem-v2.0.0.json +120 -0
  83. invenio_app_ils/eitems/schemas/eitems/eitem-v3.0.0.json +120 -0
  84. invenio_app_ils/eitems/search.py +3 -9
  85. invenio_app_ils/errors.py +119 -6
  86. invenio_app_ils/ext.py +15 -18
  87. invenio_app_ils/facets.py +13 -15
  88. invenio_app_ils/files/receivers.py +1 -1
  89. invenio_app_ils/files/views.py +1 -2
  90. invenio_app_ils/ill/api.py +1 -2
  91. invenio_app_ils/ill/config.py +10 -16
  92. invenio_app_ils/ill/jsonresolvers/borrowing_request_document.py +2 -3
  93. invenio_app_ils/ill/jsonresolvers/borrowing_request_patron.py +1 -3
  94. invenio_app_ils/ill/jsonresolvers/borrowing_request_provider.py +1 -3
  95. invenio_app_ils/ill/loaders/__init__.py +3 -9
  96. invenio_app_ils/ill/loaders/jsonschemas/patron_loan_actions.py +1 -8
  97. invenio_app_ils/ill/loaders/jsonschemas/patron_loan_extension_actions.py +3 -8
  98. invenio_app_ils/ill/mappings/{v6 → os-v1}/__init__.py +1 -1
  99. invenio_app_ils/ill/mappings/os-v1/ill_borrowing_requests/borrowing_request-v1.0.0.json +254 -0
  100. invenio_app_ils/{acquisition/mappings/v6 → ill/mappings/os-v2}/__init__.py +1 -1
  101. invenio_app_ils/ill/mappings/os-v2/ill_borrowing_requests/borrowing_request-v1.0.0.json +254 -0
  102. invenio_app_ils/ill/mappings/v7/ill_borrowing_requests/borrowing_request-v1.0.0.json +14 -0
  103. invenio_app_ils/ill/notifications/api.py +1 -4
  104. invenio_app_ils/ill/search.py +3 -9
  105. invenio_app_ils/ill/serializers/__init__.py +1 -3
  106. invenio_app_ils/ill/views.py +2 -4
  107. invenio_app_ils/internal_locations/api.py +1 -4
  108. invenio_app_ils/internal_locations/mappings/{v6 → os-v1}/__init__.py +1 -1
  109. invenio_app_ils/internal_locations/mappings/os-v1/internal_locations/internal_location-v1.0.0.json +108 -0
  110. invenio_app_ils/internal_locations/mappings/os-v2/__init__.py +8 -0
  111. invenio_app_ils/internal_locations/mappings/os-v2/internal_locations/internal_location-v1.0.0.json +108 -0
  112. invenio_app_ils/internal_locations/search.py +1 -3
  113. invenio_app_ils/items/api.py +18 -15
  114. invenio_app_ils/items/indexer.py +1 -3
  115. invenio_app_ils/items/jsonresolvers/item_document.py +1 -1
  116. invenio_app_ils/items/jsonresolvers/item_internal_location.py +2 -6
  117. invenio_app_ils/items/loaders/jsonschemas/items.py +2 -0
  118. {tests/api/circulation → invenio_app_ils/items/mappings/os-v1}/__init__.py +1 -1
  119. invenio_app_ils/items/mappings/os-v1/items/item-v1.0.0.json +285 -0
  120. invenio_app_ils/items/mappings/os-v1/items/item-v2.0.0.json +326 -0
  121. {tests/api/ill → invenio_app_ils/items/mappings/os-v2}/__init__.py +1 -1
  122. invenio_app_ils/items/mappings/os-v2/items/item-v1.0.0.json +285 -0
  123. invenio_app_ils/items/mappings/os-v2/items/item-v2.0.0.json +326 -0
  124. invenio_app_ils/items/mappings/v7/items/item-v1.0.0.json +11 -0
  125. invenio_app_ils/items/mappings/v7/items/item-v2.0.0.json +326 -0
  126. invenio_app_ils/items/schemas/items/item-v1.0.0.json +22 -0
  127. invenio_app_ils/items/schemas/items/item-v2.0.0.json +172 -0
  128. invenio_app_ils/items/search.py +18 -11
  129. invenio_app_ils/items/serializers/item.py +7 -6
  130. invenio_app_ils/literature/api.py +1 -3
  131. invenio_app_ils/literature/search.py +3 -5
  132. invenio_app_ils/literature/serializers/csv.py +1 -3
  133. invenio_app_ils/literature/serializers/json.py +1 -3
  134. invenio_app_ils/locations/api.py +2 -4
  135. invenio_app_ils/locations/indexer.py +3 -9
  136. invenio_app_ils/locations/loaders/__init__.py +1 -3
  137. invenio_app_ils/locations/loaders/jsonschemas/location.py +4 -11
  138. invenio_app_ils/locations/mappings/{v6 → os-v1}/__init__.py +1 -1
  139. invenio_app_ils/locations/mappings/os-v1/locations/location-v1.0.0.json +90 -0
  140. invenio_app_ils/locations/mappings/os-v2/__init__.py +8 -0
  141. invenio_app_ils/locations/mappings/os-v2/locations/location-v1.0.0.json +90 -0
  142. invenio_app_ils/notifications/messages.py +4 -3
  143. invenio_app_ils/notifications/tasks.py +1 -3
  144. invenio_app_ils/notifications/views.py +2 -2
  145. invenio_app_ils/patrons/anonymization.py +53 -32
  146. invenio_app_ils/patrons/api.py +3 -5
  147. invenio_app_ils/patrons/cli.py +1 -2
  148. invenio_app_ils/patrons/indexer.py +4 -13
  149. invenio_app_ils/patrons/mappings/os-v1/__init__.py +8 -0
  150. invenio_app_ils/patrons/mappings/os-v1/patrons/patron-v1.0.0.json +42 -0
  151. invenio_app_ils/patrons/mappings/os-v2/__init__.py +8 -0
  152. invenio_app_ils/patrons/mappings/os-v2/patrons/patron-v1.0.0.json +42 -0
  153. invenio_app_ils/patrons/views.py +4 -14
  154. invenio_app_ils/permissions.py +93 -35
  155. invenio_app_ils/providers/api.py +2 -6
  156. invenio_app_ils/providers/config.py +11 -19
  157. invenio_app_ils/providers/indexer.py +2 -6
  158. invenio_app_ils/providers/mappings/{v6 → os-v1}/__init__.py +1 -1
  159. invenio_app_ils/providers/mappings/os-v1/providers/provider-v1.0.0.json +57 -0
  160. invenio_app_ils/providers/mappings/os-v2/__init__.py +8 -0
  161. invenio_app_ils/providers/mappings/os-v2/providers/provider-v1.0.0.json +57 -0
  162. invenio_app_ils/providers/mappings/v7/__init__.py +1 -1
  163. invenio_app_ils/providers/proxies.py +1 -3
  164. invenio_app_ils/records/api.py +3 -9
  165. invenio_app_ils/records/loaders/schemas/changed_by.py +1 -3
  166. invenio_app_ils/records/loaders/schemas/identifiers.py +23 -0
  167. invenio_app_ils/records/metadata_extensions.py +1 -4
  168. invenio_app_ils/records/permissions.py +8 -2
  169. invenio_app_ils/records/serializers/__init__.py +1 -4
  170. invenio_app_ils/records/views.py +4 -7
  171. invenio_app_ils/records_relations/api.py +11 -34
  172. invenio_app_ils/records_relations/indexer.py +1 -3
  173. invenio_app_ils/records_relations/retriever.py +14 -9
  174. invenio_app_ils/records_relations/views.py +16 -50
  175. invenio_app_ils/relations/api.py +17 -16
  176. invenio_app_ils/search_permissions.py +24 -24
  177. invenio_app_ils/series/api.py +10 -12
  178. invenio_app_ils/series/loaders/jsonschemas/series.py +3 -2
  179. invenio_app_ils/{items/mappings/v6 → series/mappings/os-v1}/__init__.py +1 -1
  180. invenio_app_ils/series/mappings/os-v1/series/series-v1.0.0.json +324 -0
  181. invenio_app_ils/series/mappings/os-v1/series/series-v2.0.0.json +396 -0
  182. {tests/api/acquisition → invenio_app_ils/series/mappings/os-v2}/__init__.py +1 -1
  183. invenio_app_ils/series/mappings/os-v2/series/series-v1.0.0.json +324 -0
  184. invenio_app_ils/series/mappings/os-v2/series/series-v2.0.0.json +396 -0
  185. invenio_app_ils/series/mappings/v7/series/series-v1.0.0.json +35 -3
  186. invenio_app_ils/series/mappings/v7/series/series-v2.0.0.json +396 -0
  187. invenio_app_ils/series/schemas/series/series-v2.0.0.json +354 -0
  188. invenio_app_ils/stats/aggregations/aggr_file_download/os-v1/aggr-file-download-v1.json +60 -0
  189. invenio_app_ils/stats/aggregations/aggr_file_download/os-v2/__init__.py +9 -0
  190. invenio_app_ils/stats/aggregations/aggr_file_download/os-v2/aggr-file-download-v1.json +60 -0
  191. invenio_app_ils/stats/event_builders.py +73 -0
  192. invenio_app_ils/stats/file_download/os-v1/file-download-v1.json +72 -0
  193. invenio_app_ils/stats/file_download/os-v2/__init__.py +9 -0
  194. invenio_app_ils/stats/file_download/os-v2/file-download-v1.json +72 -0
  195. invenio_app_ils/stats/processors.py +30 -0
  196. invenio_app_ils/stats/templates/aggregations/__init__.py +8 -0
  197. invenio_app_ils/stats/templates/aggregations/ils_record_changes/__init__.py +8 -0
  198. invenio_app_ils/stats/templates/aggregations/ils_record_changes/os-v2/__init__.py +8 -0
  199. invenio_app_ils/stats/templates/aggregations/ils_record_changes/os-v2/aggr-ils-record-changes-v1.json +41 -0
  200. {tests → invenio_app_ils/stats/templates/events}/__init__.py +2 -2
  201. invenio_app_ils/stats/templates/events/ils_record_changes/__init__.py +8 -0
  202. invenio_app_ils/stats/templates/events/ils_record_changes/os-v2/__init__.py +8 -0
  203. invenio_app_ils/stats/templates/events/ils_record_changes/os-v2/ils-record-changes-v1.json +41 -0
  204. invenio_app_ils/templates/logged_out.html +12 -0
  205. invenio_app_ils/views.py +18 -4
  206. invenio_app_ils/vocabularies/api.py +1 -1
  207. invenio_app_ils/vocabularies/cli.py +6 -18
  208. invenio_app_ils/vocabularies/data/acq_order_line_payment_modes.json +5 -0
  209. invenio_app_ils/vocabularies/data/identifier_schemes.json +5 -0
  210. invenio_app_ils/vocabularies/indexer.py +1 -4
  211. invenio_app_ils/vocabularies/jsonresolvers/licenses.py +2 -11
  212. invenio_app_ils/vocabularies/mappings/os-v1/__init__.py +8 -0
  213. invenio_app_ils/vocabularies/mappings/os-v1/vocabularies/vocabulary-v1.0.0.json +23 -0
  214. invenio_app_ils/vocabularies/mappings/os-v2/__init__.py +8 -0
  215. invenio_app_ils/vocabularies/mappings/os-v2/vocabularies/vocabulary-v1.0.0.json +23 -0
  216. invenio_app_ils/vocabularies/sources/base.py +1 -3
  217. invenio_app_ils/webpack.py +27 -0
  218. invenio_app_ils-6.1.0.dist-info/METADATA +627 -0
  219. {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info}/RECORD +227 -249
  220. {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info}/WHEEL +1 -1
  221. {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info}/entry_points.txt +9 -5
  222. {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info}/top_level.txt +0 -1
  223. invenio_app_ils/acquisition/mappings/v6/acq_orders/order-v1.0.0.json +0 -352
  224. invenio_app_ils/document_requests/mappings/v6/document_requests/document_request-v1.0.0.json +0 -199
  225. invenio_app_ils/documents/mappings/v6/documents/document-v1.0.0.json +0 -843
  226. invenio_app_ils/eitems/mappings/v6/eitems/eitem-v1.0.0.json +0 -131
  227. invenio_app_ils/ill/mappings/v6/ill_borrowing_requests/borrowing_request-v1.0.0.json +0 -242
  228. invenio_app_ils/internal_locations/mappings/v6/internal_locations/internal_location-v1.0.0.json +0 -110
  229. invenio_app_ils/items/mappings/v6/items/item-v1.0.0.json +0 -276
  230. invenio_app_ils/locations/mappings/v6/locations/location-v1.0.0.json +0 -92
  231. invenio_app_ils/notifications/admin.py +0 -57
  232. invenio_app_ils/patrons/mappings/v6/__init__.py +0 -8
  233. invenio_app_ils/patrons/mappings/v6/patrons/patron-v1.0.0.json +0 -44
  234. invenio_app_ils/providers/mappings/v6/providers/provider-v1.0.0.json +0 -59
  235. invenio_app_ils/series/mappings/v6/series/series-v1.0.0.json +0 -298
  236. invenio_app_ils/stats/aggregations/aggr_file_download/v6/aggr-file-download-v1.json +0 -59
  237. invenio_app_ils/stats/file_download/v6/file-download-v1.json +0 -74
  238. invenio_app_ils/version.py +0 -14
  239. invenio_app_ils/vocabularies/mappings/v6/__init__.py +0 -8
  240. invenio_app_ils/vocabularies/mappings/v6/vocabularies/vocabulary-v1.0.0.json +0 -25
  241. invenio_app_ils-1.0.0a54.dist-info/METADATA +0 -95
  242. tests/api/__init__.py +0 -8
  243. tests/api/acquisition/test_acq_orders_crud.py +0 -102
  244. tests/api/acquisition/test_acq_orders_permissions.py +0 -104
  245. tests/api/acquisition/test_acq_providers_permissions.py +0 -83
  246. tests/api/circulation/test_expired_loans.py +0 -88
  247. tests/api/circulation/test_loan_checkout.py +0 -216
  248. tests/api/circulation/test_loan_default_durations.py +0 -57
  249. tests/api/circulation/test_loan_document_resolver.py +0 -18
  250. tests/api/circulation/test_loan_extend.py +0 -132
  251. tests/api/circulation/test_loan_item_permissions.py +0 -139
  252. tests/api/circulation/test_loan_item_resolver.py +0 -26
  253. tests/api/circulation/test_loan_list_permissions.py +0 -104
  254. tests/api/circulation/test_loan_patron_resolver.py +0 -38
  255. tests/api/circulation/test_loan_request.py +0 -234
  256. tests/api/circulation/test_loan_update.py +0 -150
  257. tests/api/circulation/test_notifications.py +0 -229
  258. tests/api/conftest.py +0 -236
  259. tests/api/document_requests/__init__.py +0 -8
  260. tests/api/document_requests/test_document_requests.py +0 -131
  261. tests/api/document_requests/test_document_requests_permissions.py +0 -177
  262. tests/api/document_requests/test_notifications_filter.py +0 -36
  263. tests/api/ill/test_ill_brw_crud.py +0 -84
  264. tests/api/ill/test_ill_brw_reqs_patron_loan_create_action.py +0 -207
  265. tests/api/ill/test_ill_brw_reqs_patron_loan_extension_actions.py +0 -298
  266. tests/api/ill/test_ill_brw_reqs_permissions.py +0 -169
  267. tests/api/ill/test_ill_providers_permissions.py +0 -82
  268. tests/api/ils/__init__.py +0 -8
  269. tests/api/ils/documents/__init__.py +0 -8
  270. tests/api/ils/documents/test_document_crud.py +0 -57
  271. tests/api/ils/documents/test_document_permissions.py +0 -106
  272. tests/api/ils/documents/test_document_resolvers.py +0 -35
  273. tests/api/ils/eitems/__init__.py +0 -8
  274. tests/api/ils/eitems/test_eitems_crud.py +0 -41
  275. tests/api/ils/eitems/test_eitems_permissions.py +0 -84
  276. tests/api/ils/eitems/test_files.py +0 -172
  277. tests/api/ils/items/__init__.py +0 -8
  278. tests/api/ils/items/test_apis.py +0 -43
  279. tests/api/ils/items/test_items_crud.py +0 -60
  280. tests/api/ils/items/test_items_permissions.py +0 -107
  281. tests/api/ils/items/test_items_update.py +0 -47
  282. tests/api/ils/records_relations/__init__.py +0 -8
  283. tests/api/ils/records_relations/helpers.py +0 -115
  284. tests/api/ils/records_relations/test_records_relations_parentchild.py +0 -560
  285. tests/api/ils/records_relations/test_records_relations_sequence.py +0 -302
  286. tests/api/ils/records_relations/test_records_relations_siblings.py +0 -678
  287. tests/api/ils/series/__init__.py +0 -8
  288. tests/api/ils/series/test_series_permissions.py +0 -95
  289. tests/api/ils/test_anonymization.py +0 -189
  290. tests/api/ils/test_apis.py +0 -76
  291. tests/api/ils/test_closures.py +0 -324
  292. tests/api/ils/test_errors.py +0 -126
  293. tests/api/ils/test_facets.py +0 -84
  294. tests/api/ils/test_internal_locations.py +0 -96
  295. tests/api/ils/test_loaders.py +0 -55
  296. tests/api/ils/test_metadata_extensions.py +0 -205
  297. tests/api/ils/test_notifications.py +0 -183
  298. tests/api/ils/test_notifications_mails.py +0 -39
  299. tests/api/ils/test_notifications_permissions.py +0 -55
  300. tests/api/ils/test_patrons.py +0 -106
  301. tests/api/ils/test_record_delete.py +0 -46
  302. tests/api/ils/test_record_permissions.py +0 -135
  303. tests/api/ils/test_resolvers.py +0 -207
  304. tests/api/ils/test_stats.py +0 -160
  305. tests/api/ils/test_tasks.py +0 -211
  306. tests/api/ils/test_vocabularies.py +0 -35
  307. tests/conftest.py +0 -123
  308. tests/data/acq_orders.json +0 -89
  309. tests/data/acq_providers.json +0 -12
  310. tests/data/document_requests.json +0 -77
  311. tests/data/documents.json +0 -237
  312. tests/data/eitems.json +0 -66
  313. tests/data/ill_borrowing_requests.json +0 -77
  314. tests/data/ill_providers.json +0 -12
  315. tests/data/internal_locations.json +0 -22
  316. tests/data/items.json +0 -271
  317. tests/data/loans.json +0 -133
  318. tests/data/loans_most_loaned.json +0 -128
  319. tests/data/locations.json +0 -20
  320. tests/data/series.json +0 -33
  321. tests/helpers.py +0 -104
  322. tests/templates/notifications/title_body.html +0 -8
  323. tests/templates/notifications/title_body_html.html +0 -13
  324. tests/templates/notifications/title_body_html_ctx.html +0 -13
  325. tests/templates/notifications/title_only.html +0 -3
  326. tests/test_version.py +0 -17
  327. /tests/templates/notifications/blank.html → /invenio_app_ils/acquisition/mappings/os-v1/__init__.py +0 -0
  328. /invenio_app_ils/stats/aggregations/aggr_file_download/{v6 → os-v1}/__init__.py +0 -0
  329. /invenio_app_ils/stats/file_download/{v6 → os-v1}/__init__.py +0 -0
  330. {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info/licenses}/AUTHORS.rst +0 -0
  331. {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info/licenses}/LICENSE +0 -0
invenio_app_ils/cli.py CHANGED
@@ -7,6 +7,7 @@
7
7
 
8
8
  """CLI for Invenio App ILS."""
9
9
 
10
+ import importlib.resources
10
11
  import json
11
12
  import os
12
13
  import pathlib
@@ -18,19 +19,20 @@ from random import randint
18
19
  import arrow
19
20
  import click
20
21
  import lorem
21
- import pkg_resources
22
22
  from flask import current_app
23
23
  from flask.cli import with_appcontext
24
+ from invenio_access.permissions import system_identity
24
25
  from invenio_accounts.models import User
25
26
  from invenio_circulation.api import Loan
26
27
  from invenio_circulation.pidstore.pids import CIRCULATION_LOAN_PID_TYPE
27
28
  from invenio_db import db
29
+ from invenio_i18n.proxies import current_i18n
28
30
  from invenio_indexer.api import RecordIndexer
29
- from invenio_pages import Page
31
+ from invenio_pages.proxies import current_pages_service
32
+ from invenio_pages.records.errors import PageNotFoundError
30
33
  from invenio_pidstore.models import PersistentIdentifier, PIDStatus
31
34
  from invenio_pidstore.providers.recordid_v2 import RecordIdProviderV2
32
35
  from invenio_search import current_search
33
- from invenio_userprofiles.models import UserProfile
34
36
  from lorem.text import TextLorem
35
37
 
36
38
  from invenio_app_ils.errors import RecordRelationsError
@@ -40,18 +42,12 @@ from .document_requests.api import DOCUMENT_REQUEST_PID_TYPE, DocumentRequest
40
42
  from .documents.api import DOCUMENT_PID_TYPE, Document
41
43
  from .eitems.api import EITEM_PID_TYPE, EItem
42
44
  from .ill.api import BORROWING_REQUEST_PID_TYPE, BorrowingRequest
43
- from .internal_locations.api import (
44
- INTERNAL_LOCATION_PID_TYPE,
45
- InternalLocation,
46
- )
45
+ from .internal_locations.api import INTERNAL_LOCATION_PID_TYPE, InternalLocation
47
46
  from .items.api import ITEM_PID_TYPE, Item
48
47
  from .locations.api import LOCATION_PID_TYPE, Location
49
48
  from .providers.api import PROVIDER_PID_TYPE, Provider
50
49
  from .proxies import current_app_ils
51
- from .records_relations.api import (
52
- RecordRelationsParentChild,
53
- RecordRelationsSiblings,
54
- )
50
+ from .records_relations.api import RecordRelationsParentChild, RecordRelationsSiblings
55
51
  from .relations.api import Relation
56
52
  from .series.api import SERIES_PID_TYPE, Series
57
53
 
@@ -60,9 +56,7 @@ CURRENT_DIR = pathlib.Path(__file__).parent.absolute()
60
56
 
61
57
  def minter(pid_type, pid_field, record):
62
58
  """Mint the given PID for the given record."""
63
- pid = PersistentIdentifier.get(
64
- pid_type="recid", pid_value=record[pid_field]
65
- )
59
+ pid = PersistentIdentifier.get(pid_type="recid", pid_value=record[pid_field])
66
60
  pid.status = PIDStatus.REGISTERED
67
61
  pid.object_type = "rec"
68
62
  pid.object_uuid = record.id
@@ -244,9 +238,7 @@ class ItemGenerator(Generator):
244
238
  size = self.holder.items["total"]
245
239
  iloc_pids = self.holder.pids("internal_locations", "pid")
246
240
  doc_pids = self.holder.pids("documents", "pid")
247
- shelf_lorem = TextLorem(
248
- wsep="-", srange=(2, 3), words="Ax Bs Cw 8080".split()
249
- )
241
+ shelf_lorem = TextLorem(wsep="-", srange=(2, 3), words="Ax Bs Cw 8080".split())
250
242
  objs = [
251
243
  {
252
244
  "pid": self.create_pid(),
@@ -271,9 +263,7 @@ class ItemGenerator(Generator):
271
263
  k=10,
272
264
  )
273
265
  ),
274
- "circulation_restriction": random.choice(
275
- Item.CIRCULATION_RESTRICTIONS
276
- ),
266
+ "circulation_restriction": random.choice(Item.CIRCULATION_RESTRICTIONS),
277
267
  }
278
268
  for pid in range(1, size + 1)
279
269
  ]
@@ -316,6 +306,7 @@ class EItemGenerator(Generator):
316
306
  "value": "demo",
317
307
  },
318
308
  "document_pid": random.choice(doc_pids),
309
+ "eitem_type": random.choice(EItem.EITEM_TYPES),
319
310
  "description": "{}".format(lorem.text()),
320
311
  "internal_notes": "{}".format(lorem.text()),
321
312
  "urls": [
@@ -509,9 +500,7 @@ class DocumentGenerator(Generator):
509
500
 
510
501
  def generate_document(self, index, **kwargs):
511
502
  """Generate document data."""
512
- publication_year = kwargs.get(
513
- "publication_year", str(randint(1700, 2020))
514
- )
503
+ publication_year = kwargs.get("publication_year", str(randint(1700, 2020)))
515
504
  imprint = random.choice(self.IMPRINTS)
516
505
  isbn = random.choice(self.ISBNS)
517
506
  n_authors = randint(1, len(self.AUTHORS))
@@ -537,15 +526,11 @@ class DocumentGenerator(Generator):
537
526
  )
538
527
  ],
539
528
  "edition": str(index),
540
- "keywords": [
541
- {"source": lorem.sentence(), "value": lorem.sentence()}
542
- ],
529
+ "keywords": [{"source": lorem.sentence(), "value": lorem.sentence()}],
543
530
  "conference_info": self.CONFERENCE_INFO,
544
531
  "number_of_pages": str(random.randint(0, 300)),
545
532
  "identifiers": [{"scheme": "ISBN", "value": isbn}],
546
- "alternative_identifiers": [
547
- {"scheme": "ARXIV", "value": "1234.1234"}
548
- ],
533
+ "alternative_identifiers": [{"scheme": "ARXIV", "value": "1234.1234"}],
549
534
  "imprint": {
550
535
  **imprint,
551
536
  "date": "{}-08-02".format(publication_year),
@@ -727,9 +712,7 @@ class LoanGenerator(Generator):
727
712
  """Persist."""
728
713
  recs = []
729
714
  for obj in self.holder.loans["objs"]:
730
- rec = self._persist(
731
- CIRCULATION_LOAN_PID_TYPE, "pid", Loan.create(obj)
732
- )
715
+ rec = self._persist(CIRCULATION_LOAN_PID_TYPE, "pid", Loan.create(obj))
733
716
  recs.append(rec)
734
717
  db.session.commit()
735
718
  return recs
@@ -750,9 +733,7 @@ class SeriesGenerator(Generator):
750
733
  obj["edition"] = str(index)
751
734
  for _ in range(randint(1, 2)):
752
735
  obj["identifiers"].append(
753
- dict(
754
- scheme="ISBN", value=random.choice(DocumentGenerator.ISBNS)
755
- )
736
+ dict(scheme="ISBN", value=random.choice(DocumentGenerator.ISBNS))
756
737
  )
757
738
 
758
739
  def random_serial(self, obj):
@@ -825,9 +806,7 @@ class SeriesGenerator(Generator):
825
806
  "abstract": lorem.text(),
826
807
  "languages": [
827
808
  lang["key"]
828
- for lang in random.sample(
829
- self.holder.languages, randint(1, 3)
830
- )
809
+ for lang in random.sample(self.holder.languages, randint(1, 3))
831
810
  ],
832
811
  "identifiers": [],
833
812
  "created_by": {"type": "script", "value": "demo"},
@@ -837,9 +816,7 @@ class SeriesGenerator(Generator):
837
816
  self.holder.tags, randint(1, len(self.holder.tags) - 1)
838
817
  )
839
818
  ],
840
- "keywords": [
841
- {"source": lorem.sentence(), "value": lorem.sentence()}
842
- ],
819
+ "keywords": [{"source": lorem.sentence(), "value": lorem.sentence()}],
843
820
  "series_type": random.choice(Series.SERIES_TYPES),
844
821
  }
845
822
  if moi == "SERIAL":
@@ -874,11 +851,7 @@ class RecordRelationsGenerator(Generator):
874
851
  """Generate parent-child relations."""
875
852
 
876
853
  def random_docs():
877
- docs = [
878
- doc
879
- for doc in documents
880
- if doc["document_type"] != "SERIAL_ISSUE"
881
- ]
854
+ docs = [doc for doc in documents if doc["document_type"] != "SERIAL_ISSUE"]
882
855
  return random.sample(docs, randint(1, min(5, len(docs))))
883
856
 
884
857
  objs = self.holder.related_records["objs"]
@@ -894,9 +867,7 @@ class RecordRelationsGenerator(Generator):
894
867
  objs.append(serial_parent)
895
868
  rr = RecordRelationsParentChild()
896
869
  serial_relation = Relation.get_relation_by_name("serial")
897
- multipart_relation = Relation.get_relation_by_name(
898
- "multipart_monograph"
899
- )
870
+ multipart_relation = Relation.get_relation_by_name("multipart_monograph")
900
871
  re_volume = re.compile(r"Volume (?P<volume>\d+)", re.IGNORECASE)
901
872
  for index, child in enumerate(serial_children):
902
873
  m = re_volume.match(child["title"])
@@ -925,9 +896,7 @@ class RecordRelationsGenerator(Generator):
925
896
  rr = RecordRelationsSiblings()
926
897
 
927
898
  def add_random_relations(relation_type):
928
- random_docs = random.sample(
929
- documents, randint(2, min(5, len(documents)))
930
- )
899
+ random_docs = random.sample(documents, randint(2, min(5, len(documents))))
931
900
 
932
901
  for record in random_docs:
933
902
  for doc in documents:
@@ -971,9 +940,7 @@ class DocumentRequestGenerator(Generator):
971
940
 
972
941
  def random_pending_borrowing_request(self):
973
942
  """Get a random document PID."""
974
- return random.choice(
975
- self.holder.pids("pending_borrowing_requests", "pid")
976
- )
943
+ return random.choice(self.holder.pids("pending_borrowing_requests", "pid"))
977
944
 
978
945
  def generate(self):
979
946
  """Generate."""
@@ -992,9 +959,7 @@ class DocumentRequestGenerator(Generator):
992
959
  "medium": "PAPER",
993
960
  }
994
961
  if state == "DECLINED":
995
- obj["decline_reason"] = random.choice(
996
- DocumentRequest.DECLINE_TYPES
997
- )
962
+ obj["decline_reason"] = random.choice(DocumentRequest.DECLINE_TYPES)
998
963
  if obj["decline_reason"] == "IN_CATALOG":
999
964
  obj["document_pid"] = self.random_document_pid()
1000
965
  elif state == "ACCEPTED":
@@ -1098,15 +1063,11 @@ class BorrowingRequestGenerator(Generator):
1098
1063
 
1099
1064
  t = now + timedelta(days=400)
1100
1065
  if obj["status"] != "PENDING":
1101
- obj["request_date"] = (
1102
- self.random_date(now, t).date().isoformat()
1103
- )
1066
+ obj["request_date"] = self.random_date(now, t).date().isoformat()
1104
1067
  obj["expected_delivery_date"] = (
1105
1068
  self.random_date(now, t).date().isoformat()
1106
1069
  )
1107
- obj["received_date"] = (
1108
- self.random_date(now, t).date().isoformat()
1109
- )
1070
+ obj["received_date"] = self.random_date(now, t).date().isoformat()
1110
1071
  obj["due_date"] = self.random_date(now, t).date().isoformat()
1111
1072
  obj["payment"] = {
1112
1073
  "debit_cost_main_currency": self.random_price("CHF"),
@@ -1201,9 +1162,7 @@ class OrderGenerator(Generator):
1201
1162
  ordered = randint(1, 5)
1202
1163
  yield dict(
1203
1164
  copies_ordered=ordered,
1204
- copies_received=randint(1, ordered)
1205
- if status == "RECEIVED"
1206
- else 0,
1165
+ copies_received=randint(1, ordered) if status == "RECEIVED" else 0,
1207
1166
  document_pid=doc_pids[i],
1208
1167
  is_donation=random.choice([True, False]),
1209
1168
  is_patron_suggestion=random.choice([True, False]),
@@ -1229,16 +1188,12 @@ class OrderGenerator(Generator):
1229
1188
  obj = {
1230
1189
  "pid": self.create_pid(),
1231
1190
  "created_by_pid": self.holder.librarian_pid,
1232
- "provider_pid": random.choice(self.holder.vendors["objs"])[
1233
- "pid"
1234
- ],
1191
+ "provider_pid": random.choice(self.holder.vendors["objs"])["pid"],
1235
1192
  "status": status,
1236
1193
  "order_date": order_date.date().isoformat(),
1237
1194
  "notes": lorem.sentence(),
1238
1195
  "grand_total": self.random_price("EUR", min_value=50.0),
1239
- "grand_total_main_currency": self.random_price(
1240
- "CHF", min_value=60.0
1241
- ),
1196
+ "grand_total_main_currency": self.random_price("CHF", min_value=60.0),
1242
1197
  "funds": list(set(lorem.sentence().split())),
1243
1198
  "payment": {
1244
1199
  "mode": "CREDIT_CARD",
@@ -1246,9 +1201,7 @@ class OrderGenerator(Generator):
1246
1201
  "order_lines": order_lines,
1247
1202
  }
1248
1203
  obj["expected_delivery_date"] = (
1249
- self.random_date(now, now + timedelta(days=400))
1250
- .date()
1251
- .isoformat()
1204
+ self.random_date(now, now + timedelta(days=400)).date().isoformat()
1252
1205
  )
1253
1206
  if obj["status"] == "CANCELLED":
1254
1207
  obj["cancel_reason"] = lorem.sentence()
@@ -1275,17 +1228,6 @@ def demo():
1275
1228
  """Demo data CLI."""
1276
1229
 
1277
1230
 
1278
- @demo.command()
1279
- def locations():
1280
- """Create demo locations."""
1281
- click.echo("Creating locations...")
1282
- fake_holder = type("FakeHolder", (object,), {"location": {}})
1283
- loc_generator = LocationGenerator(fake_holder, minter)
1284
- loc_generator.generate()
1285
- rec = loc_generator.persist()
1286
- RecordIndexer().index(rec)
1287
-
1288
-
1289
1231
  @demo.command()
1290
1232
  @click.option("--docs", "n_docs", default=20)
1291
1233
  @click.option("--items", "n_items", default=50)
@@ -1298,6 +1240,8 @@ def locations():
1298
1240
  @click.option("--orders", "n_orders", default=30)
1299
1241
  @click.option("--libraries", "n_libraries", default=10)
1300
1242
  @click.option("--borrowing-requests", "n_borrowing_requests", default=10)
1243
+ @click.option("--verbose", is_flag=True, help="Verbose output.")
1244
+ @click.option("--skip-admin", "skip_admin", is_flag=True)
1301
1245
  @with_appcontext
1302
1246
  def data(
1303
1247
  n_docs,
@@ -1311,6 +1255,8 @@ def data(
1311
1255
  n_orders,
1312
1256
  n_libraries,
1313
1257
  n_borrowing_requests,
1258
+ verbose,
1259
+ skip_admin=False,
1314
1260
  ):
1315
1261
  """Insert demo data."""
1316
1262
  click.secho("Generating demo data", fg="yellow")
@@ -1342,9 +1288,9 @@ def data(
1342
1288
  ]
1343
1289
 
1344
1290
  holder = Holder(
1345
- patrons_pids=["1", "2", "5", "6"],
1291
+ patrons_pids=["1", "2", "5", "4"],
1346
1292
  languages=languages,
1347
- librarian_pid="4",
1293
+ librarian_pid="3",
1348
1294
  tags=tags,
1349
1295
  total_intloc=n_intlocs,
1350
1296
  total_items=n_items,
@@ -1359,6 +1305,99 @@ def data(
1359
1305
  total_libraries=n_libraries,
1360
1306
  )
1361
1307
 
1308
+ # Create roles to restrict access
1309
+ _run_command("roles create admin", verbose)
1310
+ _run_command("roles create librarian", verbose)
1311
+ _run_command("roles create librarian-readonly", verbose)
1312
+
1313
+ # Create users
1314
+ patron1_profile = {"full_name": "Yannic Vilma"}
1315
+ _run_command(
1316
+ f"users create patron1@test.ch -a --password=123456 --profile '{json.dumps(patron1_profile)}'",
1317
+ verbose,
1318
+ )
1319
+
1320
+ patron2_profile = {"full_name": "Diana Adi"}
1321
+ _run_command(
1322
+ f"users create patron2@test.ch -a --password=123456 --profile '{json.dumps(patron2_profile)}'",
1323
+ verbose,
1324
+ )
1325
+
1326
+ librarian_profile = {"full_name": "Hector Nabu"}
1327
+ _run_command(
1328
+ f"users create librarian@test.ch -a --password=123456 --profile '{json.dumps(librarian_profile)}'",
1329
+ verbose,
1330
+ )
1331
+
1332
+ readonly_profile = {"full_name": "Ro Only"}
1333
+ _run_command(
1334
+ f"users create readonly@test.ch -a --password=123456 --profile '{json.dumps(readonly_profile)}'",
1335
+ verbose,
1336
+ )
1337
+
1338
+ patron3_profile = {"full_name": "Medrod Tara"}
1339
+ _run_command(
1340
+ f"users create patron3@test.ch -a --password=123456 --profile '{json.dumps(patron3_profile)}'",
1341
+ verbose,
1342
+ )
1343
+
1344
+ patron4_profile = {"full_name": "Devi Cupid"}
1345
+ _run_command(
1346
+ f"users create patron4@test.ch -a --password=123456 --profile '{json.dumps(patron4_profile)}'",
1347
+ verbose,
1348
+ )
1349
+
1350
+ if not skip_admin:
1351
+ admin_profile = {"full_name": "Zeki Ryoichi"}
1352
+ _run_command(
1353
+ f"users create admin@test.ch -a --password=123456 --profile '{json.dumps(admin_profile)}'",
1354
+ verbose,
1355
+ )
1356
+ _run_command("roles add admin@test.ch admin", verbose)
1357
+
1358
+ # assign roles
1359
+ _run_command("roles add librarian@test.ch librarian", verbose)
1360
+ _run_command("roles add readonly@test.ch librarian-readonly", verbose)
1361
+
1362
+ # Index vocabularies
1363
+ vocabularies_dir = os.path.join(CURRENT_DIR, "vocabularies", "data")
1364
+ json_files = " ".join(
1365
+ os.path.join(vocabularies_dir, name)
1366
+ for name in os.listdir(vocabularies_dir)
1367
+ if name.endswith(".json")
1368
+ )
1369
+ _run_command("vocabulary index json --force {}".format(json_files), verbose)
1370
+ _run_command("vocabulary index opendefinition spdx --force", verbose)
1371
+ _run_command("vocabulary index opendefinition opendefinition --force", verbose)
1372
+
1373
+ # index languages
1374
+ _run_command("vocabulary index languages --force", verbose)
1375
+
1376
+ # Assign actions
1377
+ _run_command("access allow superuser-access role admin", verbose)
1378
+ _run_command("access allow ils-backoffice-access role librarian", verbose)
1379
+ _run_command(
1380
+ "access allow ils-backoffice-readonly-access role librarian-readonly", verbose
1381
+ )
1382
+
1383
+ # Create demo locations
1384
+ click.echo("Creating locations and internal locations...")
1385
+ fake_holder = type("FakeHolder", (object,), {"location": {}})
1386
+ loc_generator = LocationGenerator(fake_holder, minter)
1387
+ loc_generator.generate()
1388
+ rec = loc_generator.persist()
1389
+ indexer.index(rec)
1390
+ current_search.flush_and_refresh(index="*")
1391
+
1392
+ # Index patrons
1393
+ _run_command("patrons index", verbose)
1394
+
1395
+ # Create files location
1396
+ _run_command("files location --default ils /tmp/ils-files", verbose)
1397
+
1398
+ # Create static pages
1399
+ _run_command("fixtures pages", verbose)
1400
+
1362
1401
  # InternalLocations
1363
1402
  intlocs_generator = InternalLocationGenerator(holder, minter)
1364
1403
  intlocs_generator.generate()
@@ -1432,9 +1471,7 @@ def data(
1432
1471
 
1433
1472
  # index internal locations
1434
1473
  indexer.bulk_index([str(r.id) for r in rec_intlocs])
1435
- click.echo(
1436
- "Sent to the indexing queue {0} locations".format(len(rec_intlocs))
1437
- )
1474
+ click.echo("Sent to the indexing queue {0} locations".format(len(rec_intlocs)))
1438
1475
 
1439
1476
  # index series
1440
1477
  indexer.bulk_index([str(r.id) for r in rec_series])
@@ -1447,6 +1484,7 @@ def data(
1447
1484
  click.secho("Now indexing...", fg="green")
1448
1485
  # process queue so items can resolve circulation status correctly
1449
1486
  indexer.process_bulk_queue()
1487
+ current_search.flush_and_refresh(index="*")
1450
1488
 
1451
1489
  # index eitems
1452
1490
  indexer.bulk_index([str(r.id) for r in rec_eitems])
@@ -1459,12 +1497,11 @@ def data(
1459
1497
  click.secho("Now indexing...", fg="green")
1460
1498
  # process queue so documents can resolve circulation correctly
1461
1499
  indexer.process_bulk_queue()
1500
+ current_search.flush_and_refresh(index="*")
1462
1501
 
1463
1502
  # index libraries
1464
1503
  indexer.bulk_index([str(r.id) for r in rec_libraries])
1465
- click.echo(
1466
- "Sent to the indexing queue {0} libraries".format(len(rec_libraries))
1467
- )
1504
+ click.echo("Sent to the indexing queue {0} libraries".format(len(rec_libraries)))
1468
1505
 
1469
1506
  # index borrowing requests
1470
1507
  indexer.bulk_index([str(r.id) for r in rec_borrowing_requests])
@@ -1476,22 +1513,16 @@ def data(
1476
1513
 
1477
1514
  click.secho("Now indexing...", fg="green")
1478
1515
  indexer.process_bulk_queue()
1479
-
1480
- # flush all indices after indexing, otherwise ES won't be ready for tests
1481
1516
  current_search.flush_and_refresh(index="*")
1482
1517
 
1483
1518
  # index documents
1484
1519
  indexer.bulk_index([str(r.id) for r in rec_docs])
1485
- click.echo(
1486
- "Sent to the indexing queue {0} documents".format(len(rec_docs))
1487
- )
1520
+ click.echo("Sent to the indexing queue {0} documents".format(len(rec_docs)))
1488
1521
 
1489
1522
  # index document requests
1490
1523
  indexer.bulk_index([str(r.id) for r in rec_requests])
1491
1524
  click.echo(
1492
- "Sent to the indexing queue {0} document requests".format(
1493
- len(rec_requests)
1494
- )
1525
+ "Sent to the indexing queue {0} document requests".format(len(rec_requests))
1495
1526
  )
1496
1527
 
1497
1528
  # index loans again
@@ -1504,9 +1535,7 @@ def data(
1504
1535
 
1505
1536
  # index vendors
1506
1537
  indexer.bulk_index([str(r.id) for r in rec_vendors])
1507
- click.echo(
1508
- "Sent to the indexing queue {0} vendors".format(len(rec_vendors))
1509
- )
1538
+ click.echo("Sent to the indexing queue {0} vendors".format(len(rec_vendors)))
1510
1539
 
1511
1540
  # index orders
1512
1541
  indexer.bulk_index([str(r.id) for r in rec_orders])
@@ -1514,194 +1543,125 @@ def data(
1514
1543
 
1515
1544
  click.secho("Now indexing...", fg="green")
1516
1545
  indexer.process_bulk_queue()
1546
+ current_search.flush_and_refresh(index="*")
1517
1547
 
1518
1548
 
1519
- def create_userprofile_for(email, username, full_name):
1520
- """Create a fake user profile."""
1521
- user = User.query.filter_by(email=email).one_or_none()
1522
- if user:
1523
- profile = UserProfile(user_id=int(user.get_id()))
1524
- profile.username = username
1525
- profile.full_name = full_name
1526
- db.session.add(profile)
1527
- db.session.commit()
1528
-
1529
-
1530
- @click.group()
1531
- def fixtures():
1532
- """Create initial data and demo records."""
1533
-
1549
+ def _run_command(command, verbose, catch_exceptions=False):
1550
+ from invenio_base.app import create_cli
1534
1551
 
1535
- @fixtures.command()
1536
- @with_appcontext
1537
- def pages():
1538
- """Register static pages."""
1552
+ click.secho("ils {}...".format(command), fg="green")
1539
1553
 
1540
- def page_data(page):
1541
- return (
1542
- pkg_resources.resource_stream(
1543
- "invenio_app_ils", os.path.join("static_pages", page)
1544
- )
1545
- .read()
1546
- .decode("utf8")
1547
- )
1554
+ cli = create_cli()
1555
+ runner = current_app.test_cli_runner()
1548
1556
 
1549
- pages = [
1550
- Page(
1551
- url="/about",
1552
- title="About",
1553
- description="About",
1554
- content="InvenioILS about page",
1555
- template_name="invenio_pages/default.html",
1556
- ),
1557
- Page(
1558
- url="/contact",
1559
- title="Contact",
1560
- description="Contact",
1561
- content="You can contact InvenioILS developers on "
1562
- '<a href="https://gitter.im/inveniosoftware/invenio">'
1563
- "our chatroom</a>",
1564
- template_name="invenio_pages/default.html",
1565
- ),
1566
- Page(
1567
- url="/guide/search",
1568
- title="Search guide",
1569
- description="Search guide",
1570
- content=page_data("search_guide.html"),
1571
- template_name="invenio_pages/default.html",
1572
- ),
1573
- ]
1574
- with db.session.begin_nested():
1575
- Page.query.delete()
1576
- db.session.add_all(pages)
1577
- db.session.commit()
1578
- click.echo("static pages created :)")
1557
+ res = runner.invoke(cli, command, catch_exceptions=catch_exceptions)
1558
+ if verbose:
1559
+ click.secho(res.output)
1579
1560
 
1580
1561
 
1581
1562
  @click.command()
1582
1563
  @click.option("--recreate-db", is_flag=True, help="Recreating DB.")
1583
- @click.option(
1584
- "--skip-demo-data", is_flag=True, help="Skip creating demo data."
1585
- )
1586
- @click.option(
1587
- "--skip-file-location", is_flag=True, help="Skip creating file location."
1588
- )
1589
- @click.option("--skip-patrons", is_flag=True, help="Skip creating patrons.")
1590
- @click.option(
1591
- "--skip-vocabularies", is_flag=True, help="Skip creating vocabularies."
1592
- )
1593
- @click.option("--skip-pages", is_flag=True, help="Skip creating static pages.")
1564
+ @click.option("--skip-demo-data", is_flag=True, help="Skip creating demo data.")
1594
1565
  @click.option("--verbose", is_flag=True, help="Verbose output.")
1566
+ @click.option("--skip-admin", "skip_admin", is_flag=True)
1595
1567
  @with_appcontext
1596
1568
  def setup(
1597
1569
  recreate_db,
1598
1570
  skip_demo_data,
1599
- skip_file_location,
1600
- skip_patrons,
1601
- skip_vocabularies,
1602
- skip_pages,
1603
1571
  verbose,
1572
+ skip_admin=False,
1604
1573
  ):
1605
1574
  """ILS setup command."""
1606
1575
  import redis
1607
1576
  from flask import current_app
1608
- from invenio_base.app import create_cli
1609
1577
 
1610
1578
  click.secho("ils setup started...", fg="blue")
1611
1579
 
1612
1580
  # Clean redis
1613
- redis.StrictRedis.from_url(
1614
- current_app.config["CACHE_REDIS_URL"]
1615
- ).flushall()
1581
+ redis.StrictRedis.from_url(current_app.config["CACHE_REDIS_URL"]).flushall()
1616
1582
  click.secho("redis cache cleared...", fg="red")
1617
1583
 
1618
- cli = create_cli()
1619
- runner = current_app.test_cli_runner()
1620
-
1621
- def run_command(command, catch_exceptions=False):
1622
- click.secho("ils {}...".format(command), fg="green")
1623
- res = runner.invoke(cli, command, catch_exceptions=catch_exceptions)
1624
- if verbose:
1625
- click.secho(res.output)
1626
-
1627
1584
  # Remove and create db and indexes
1628
1585
  if recreate_db:
1629
- run_command("db destroy --yes-i-know", catch_exceptions=True)
1630
- run_command("db init")
1586
+ _run_command("db destroy --yes-i-know", verbose=verbose, catch_exceptions=True)
1587
+ _run_command("db init", verbose)
1631
1588
  else:
1632
- run_command("db drop --yes-i-know")
1633
- run_command("db create")
1634
- run_command("index destroy --force --yes-i-know")
1635
- run_command("index init --force")
1636
- run_command("index queue init purge")
1589
+ _run_command("db drop --yes-i-know", verbose)
1590
+ _run_command("db create", verbose)
1591
+ _run_command("index destroy --force --yes-i-know", verbose)
1592
+ _run_command("index init --force", verbose)
1593
+ _run_command("index queue init purge", verbose)
1594
+ # Generate demo data
1595
+ if not skip_demo_data:
1596
+ cmd = "demo data {}".format("--verbose" if verbose else "")
1597
+ cmd = f'{cmd} {"--skip-admin" if skip_admin else ""}'
1598
+ _run_command(cmd, verbose)
1637
1599
 
1638
- # Create roles to restrict access
1639
- run_command("roles create admin")
1640
- run_command("roles create librarian")
1641
-
1642
- if not skip_patrons:
1643
- # Create users
1644
- run_command(
1645
- "users create patron1@test.ch -a --password=123456"
1646
- ) # ID 1
1647
- create_userprofile_for("patron1@test.ch", "patron1", "Yannic Vilma")
1648
- run_command(
1649
- "users create patron2@test.ch -a --password=123456"
1650
- ) # ID 2
1651
- create_userprofile_for("patron2@test.ch", "patron2", "Diana Adi")
1652
- run_command("users create admin@test.ch -a --password=123456") # ID 3
1653
- create_userprofile_for("admin@test.ch", "admin", "Zeki Ryoichi")
1654
- run_command(
1655
- "users create librarian@test.ch -a --password=123456"
1656
- ) # ID 4
1657
- create_userprofile_for("librarian@test.ch", "librarian", "Hector Nabu")
1658
- run_command(
1659
- "users create patron3@test.ch -a --password=123456"
1660
- ) # ID 5
1661
- create_userprofile_for("patron3@test.ch", "patron3", "Medrod Tara")
1662
- run_command(
1663
- "users create patron4@test.ch -a --password=123456"
1664
- ) # ID 6
1665
- create_userprofile_for("patron4@test.ch", "patron4", "Devi Cupid")
1666
-
1667
- # Assign roles
1668
- run_command("roles add admin@test.ch admin")
1669
- run_command("roles add librarian@test.ch librarian")
1670
-
1671
- if not skip_vocabularies:
1672
- vocabularies_dir = os.path.join(CURRENT_DIR, "vocabularies", "data")
1673
- json_files = " ".join(
1674
- os.path.join(vocabularies_dir, name)
1675
- for name in os.listdir(vocabularies_dir)
1676
- if name.endswith(".json")
1677
- )
1678
- run_command("vocabulary index json --force {}".format(json_files))
1679
- run_command("vocabulary index opendefinition spdx --force")
1680
- run_command("vocabulary index opendefinition opendefinition --force")
1600
+ click.secho("ils setup finished successfully", fg="blue")
1681
1601
 
1682
- # index languages
1683
- run_command("vocabulary index languages --force")
1684
1602
 
1685
- # Assign actions
1686
- run_command("access allow superuser-access role admin")
1687
- run_command("access allow ils-backoffice-access role librarian")
1603
+ @click.group()
1604
+ def fixtures():
1605
+ """Create initial data and demo records."""
1688
1606
 
1689
- # Create one location as first
1690
- run_command("demo locations")
1691
1607
 
1692
- # Index patrons
1693
- run_command("patrons index")
1608
+ @fixtures.command()
1609
+ @with_appcontext
1610
+ def pages():
1611
+ """Register static pages."""
1694
1612
 
1695
- # Create files location
1696
- if not skip_file_location:
1697
- run_command("files location --default ils /tmp/ils-files")
1613
+ def get_page_content(page):
1614
+ with importlib.resources.files("invenio_app_ils").joinpath(
1615
+ "static_pages", page
1616
+ ).open("rb") as f:
1617
+ return f.read().decode("utf8")
1698
1618
 
1699
- # Generate demo data
1700
- if not skip_demo_data:
1701
- run_command("demo data")
1619
+ pages_data = [
1620
+ {
1621
+ "url": "/about",
1622
+ "title": "About",
1623
+ "description": "About",
1624
+ "content": "InvenioILS about page",
1625
+ },
1626
+ {
1627
+ "url": "/contact",
1628
+ "title": "Contact",
1629
+ "description": "Contact",
1630
+ "content": (
1631
+ "You can contact InvenioILS developers on "
1632
+ '<a href="https://gitter.im/inveniosoftware/invenio">'
1633
+ "our chatroom</a>"
1634
+ ),
1635
+ },
1636
+ {
1637
+ "url": "/guide/search",
1638
+ "title": "Search guide",
1639
+ "description": "Search guide",
1640
+ "template": "search_guide.html",
1641
+ },
1642
+ ]
1702
1643
 
1703
- # Create static pages
1704
- if not skip_pages:
1705
- run_command("fixtures pages")
1644
+ supported_languages = current_i18n.get_languages()
1645
+
1646
+ for entry in pages_data:
1647
+ url = entry["url"]
1648
+ for lang in supported_languages:
1649
+ lang_code = lang[0]
1650
+ try:
1651
+ current_pages_service.read_by_url(system_identity, url, lang_code)
1652
+ except PageNotFoundError:
1653
+ page = {
1654
+ "url": url,
1655
+ "title": entry.get("title", ""),
1656
+ "description": entry.get("description", ""),
1657
+ "lang": lang_code,
1658
+ "template_name": current_app.config["PAGES_DEFAULT_TEMPLATE"],
1659
+ "content": (
1660
+ get_page_content(entry["template"])
1661
+ if entry.get("template")
1662
+ else entry.get("content", "")
1663
+ ),
1664
+ }
1665
+ current_pages_service.create(system_identity, page)
1706
1666
 
1707
- click.secho("ils setup finished successfully", fg="blue")
1667
+ click.echo("Static pages created :)")