invenio-app-ils 4.5.0__py2.py3-none-any.whl → 5.0.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 (115) hide show
  1. invenio_app_ils/__init__.py +1 -1
  2. invenio_app_ils/assets/semantic-ui/less/theme.config +103 -0
  3. invenio_app_ils/circulation/api.py +9 -5
  4. invenio_app_ils/circulation/config.py +1 -0
  5. invenio_app_ils/circulation/loaders/schemas/json/loan_checkout.py +1 -1
  6. invenio_app_ils/circulation/loaders/schemas/json/loan_request.py +2 -2
  7. invenio_app_ils/circulation/notifications/api.py +9 -1
  8. invenio_app_ils/circulation/notifications/messages.py +2 -1
  9. invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/update_dates.html +19 -0
  10. invenio_app_ils/cli.py +92 -64
  11. invenio_app_ils/config.py +10 -2
  12. invenio_app_ils/documents/loaders/jsonschemas/document.py +1 -1
  13. invenio_app_ils/eitems/loaders/jsonschemas/eitems.py +2 -2
  14. invenio_app_ils/patrons/anonymization.py +0 -4
  15. invenio_app_ils/series/loaders/jsonschemas/series.py +1 -1
  16. invenio_app_ils/webpack.py +27 -0
  17. {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/METADATA +56 -43
  18. {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/RECORD +24 -112
  19. {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/entry_points.txt +3 -0
  20. {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/top_level.txt +0 -1
  21. invenio_app_ils/notifications/admin.py +0 -57
  22. tests/__init__.py +0 -8
  23. tests/api/__init__.py +0 -8
  24. tests/api/acquisition/__init__.py +0 -8
  25. tests/api/acquisition/test_acq_orders_crud.py +0 -99
  26. tests/api/acquisition/test_acq_orders_permissions.py +0 -104
  27. tests/api/acquisition/test_acq_providers_permissions.py +0 -83
  28. tests/api/circulation/__init__.py +0 -8
  29. tests/api/circulation/test_expired_loans.py +0 -88
  30. tests/api/circulation/test_loan_bulk_extend.py +0 -169
  31. tests/api/circulation/test_loan_checkout.py +0 -422
  32. tests/api/circulation/test_loan_default_durations.py +0 -43
  33. tests/api/circulation/test_loan_document_resolver.py +0 -18
  34. tests/api/circulation/test_loan_extend.py +0 -122
  35. tests/api/circulation/test_loan_item_permissions.py +0 -135
  36. tests/api/circulation/test_loan_item_resolver.py +0 -26
  37. tests/api/circulation/test_loan_list_permissions.py +0 -98
  38. tests/api/circulation/test_loan_patron_resolver.py +0 -38
  39. tests/api/circulation/test_loan_request.py +0 -338
  40. tests/api/circulation/test_loan_update.py +0 -150
  41. tests/api/circulation/test_notifications.py +0 -221
  42. tests/api/conftest.py +0 -227
  43. tests/api/document_requests/__init__.py +0 -8
  44. tests/api/document_requests/test_document_requests.py +0 -131
  45. tests/api/document_requests/test_document_requests_permissions.py +0 -159
  46. tests/api/document_requests/test_notifications_filter.py +0 -35
  47. tests/api/ill/__init__.py +0 -8
  48. tests/api/ill/test_ill_brw_crud.py +0 -74
  49. tests/api/ill/test_ill_brw_reqs_patron_loan_create_action.py +0 -198
  50. tests/api/ill/test_ill_brw_reqs_patron_loan_extension_actions.py +0 -280
  51. tests/api/ill/test_ill_brw_reqs_permissions.py +0 -163
  52. tests/api/ill/test_ill_providers_permissions.py +0 -82
  53. tests/api/ils/__init__.py +0 -8
  54. tests/api/ils/documents/__init__.py +0 -8
  55. tests/api/ils/documents/test_document_crud.py +0 -57
  56. tests/api/ils/documents/test_document_permissions.py +0 -100
  57. tests/api/ils/documents/test_document_resolvers.py +0 -35
  58. tests/api/ils/eitems/__init__.py +0 -8
  59. tests/api/ils/eitems/test_eitems_crud.py +0 -42
  60. tests/api/ils/eitems/test_eitems_permissions.py +0 -85
  61. tests/api/ils/eitems/test_files.py +0 -162
  62. tests/api/ils/items/__init__.py +0 -8
  63. tests/api/ils/items/test_apis.py +0 -43
  64. tests/api/ils/items/test_items_crud.py +0 -99
  65. tests/api/ils/items/test_items_permissions.py +0 -107
  66. tests/api/ils/records_relations/__init__.py +0 -8
  67. tests/api/ils/records_relations/helpers.py +0 -115
  68. tests/api/ils/records_relations/test_records_relations_parentchild.py +0 -560
  69. tests/api/ils/records_relations/test_records_relations_sequence.py +0 -294
  70. tests/api/ils/records_relations/test_records_relations_siblings.py +0 -751
  71. tests/api/ils/series/__init__.py +0 -8
  72. tests/api/ils/series/test_series_permissions.py +0 -95
  73. tests/api/ils/test_anonymization.py +0 -181
  74. tests/api/ils/test_apis.py +0 -76
  75. tests/api/ils/test_closures.py +0 -353
  76. tests/api/ils/test_errors.py +0 -125
  77. tests/api/ils/test_facets.py +0 -88
  78. tests/api/ils/test_internal_locations.py +0 -96
  79. tests/api/ils/test_loaders.py +0 -51
  80. tests/api/ils/test_metadata_extensions.py +0 -206
  81. tests/api/ils/test_notifications.py +0 -173
  82. tests/api/ils/test_notifications_mails.py +0 -37
  83. tests/api/ils/test_notifications_permissions.py +0 -55
  84. tests/api/ils/test_patrons.py +0 -102
  85. tests/api/ils/test_record_delete.py +0 -42
  86. tests/api/ils/test_record_permissions.py +0 -132
  87. tests/api/ils/test_resolvers.py +0 -205
  88. tests/api/ils/test_stats.py +0 -142
  89. tests/api/ils/test_tasks.py +0 -209
  90. tests/api/ils/test_vocabularies.py +0 -35
  91. tests/conftest.py +0 -221
  92. tests/data/acq_orders.json +0 -110
  93. tests/data/acq_providers.json +0 -12
  94. tests/data/document_requests.json +0 -77
  95. tests/data/documents.json +0 -238
  96. tests/data/eitems.json +0 -71
  97. tests/data/ill_borrowing_requests.json +0 -77
  98. tests/data/ill_providers.json +0 -12
  99. tests/data/internal_locations.json +0 -22
  100. tests/data/items.json +0 -304
  101. tests/data/loans.json +0 -133
  102. tests/data/loans_most_loaned.json +0 -128
  103. tests/data/locations.json +0 -26
  104. tests/data/series.json +0 -33
  105. tests/helpers.py +0 -107
  106. tests/templates/notifications/title_body.html +0 -8
  107. tests/templates/notifications/title_body_html.html +0 -13
  108. tests/templates/notifications/title_body_html_ctx.html +0 -13
  109. tests/templates/notifications/title_only.html +0 -3
  110. tests/test_post_logout_redirect.py +0 -23
  111. tests/test_version.py +0 -17
  112. /tests/templates/notifications/blank.html → /invenio_app_ils/assets/semantic-ui/templates/.gitkeep +0 -0
  113. {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/WHEEL +0 -0
  114. {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/licenses/AUTHORS.rst +0 -0
  115. {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -7,6 +7,6 @@
7
7
 
8
8
  """invenio-app-ils."""
9
9
 
10
- __version__ = "4.5.0"
10
+ __version__ = "5.0.0"
11
11
 
12
12
  __all__ = ("__version__",)
@@ -0,0 +1,103 @@
1
+ /*
2
+
3
+ WARNING: THIS FILE IS NOT ACTUALLY USED (IT IS A REFERENCE EXAMPLE ONLY)
4
+
5
+ This file (theme.config) should be provided by your Invenio instance.
6
+ Examples of how this should be done can be found in
7
+ cookiecutter-invenio-instance and cookiecutter-invenio-rdm.
8
+
9
+ */
10
+ /*
11
+
12
+ ████████╗██╗ ██╗███████╗███╗ ███╗███████╗███████╗
13
+ ╚══██╔══╝██║ ██║██╔════╝████╗ ████║██╔════╝██╔════╝
14
+ ██║ ███████║█████╗ ██╔████╔██║█████╗ ███████╗
15
+ ██║ ██╔══██║██╔══╝ ██║╚██╔╝██║██╔══╝ ╚════██║
16
+ ██║ ██║ ██║███████╗██║ ╚═╝ ██║███████╗███████║
17
+ ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝╚══════╝
18
+
19
+ */
20
+
21
+ /*******************************
22
+ Theme Selection
23
+ *******************************/
24
+
25
+ /* To override a theme for an individual element
26
+ specify theme name below
27
+ */
28
+
29
+ /* Global */
30
+ @site : 'default';
31
+ @reset : 'default';
32
+
33
+ /* Elements */
34
+ @button : 'default';
35
+ @container : 'default';
36
+ @divider : 'default';
37
+ @flag : 'default';
38
+ @header : 'default';
39
+ @icon : 'default';
40
+ @image : 'default';
41
+ @input : 'default';
42
+ @label : 'default';
43
+ @list : 'default';
44
+ @loader : 'default';
45
+ @placeholder : 'default';
46
+ @rail : 'default';
47
+ @reveal : 'default';
48
+ @segment : 'default';
49
+ @step : 'default';
50
+
51
+ /* Collections */
52
+ @breadcrumb : 'default';
53
+ @form : 'default';
54
+ @grid : 'default';
55
+ @menu : 'default';
56
+ @message : 'default';
57
+ @table : 'default';
58
+
59
+ /* Modules */
60
+ @accordion : 'default';
61
+ @checkbox : 'default';
62
+ @dimmer : 'default';
63
+ @dropdown : 'default';
64
+ @embed : 'default';
65
+ @modal : 'default';
66
+ @nag : 'default';
67
+ @popup : 'default';
68
+ @progress : 'default';
69
+ @rating : 'default';
70
+ @search : 'default';
71
+ @shape : 'default';
72
+ @sidebar : 'default';
73
+ @sticky : 'default';
74
+ @tab : 'default';
75
+ @transition : 'default';
76
+
77
+ /* Views */
78
+ @ad : 'default';
79
+ @card : 'default';
80
+ @comment : 'default';
81
+ @feed : 'default';
82
+ @item : 'default';
83
+ @statistic : 'default';
84
+
85
+ /*******************************
86
+ Folders
87
+ *******************************/
88
+
89
+ /* Path to theme packages */
90
+ @themesFolder : '~semantic-ui-less/themes';
91
+
92
+ /* Path to site override folder */
93
+ @siteFolder : '../../less/invenio_theme/theme';
94
+
95
+ /*******************************
96
+ Import Theme
97
+ *******************************/
98
+
99
+ @import (multiple) "themes/invenio/theme.less";
100
+
101
+ @fontPath : "../../../themes/@{theme}/assets/fonts";
102
+
103
+ /* End Config */
@@ -26,6 +26,9 @@ from invenio_db import db
26
26
  from invenio_pidstore.models import PIDStatus
27
27
  from invenio_pidstore.providers.recordid_v2 import RecordIdProviderV2
28
28
 
29
+ from invenio_app_ils.circulation.notifications.api import (
30
+ send_dates_updated_notification,
31
+ )
29
32
  from invenio_app_ils.circulation.search import (
30
33
  get_all_expiring_or_overdue_loans_by_patron_pid,
31
34
  )
@@ -375,14 +378,12 @@ def update_dates_loan(
375
378
  ):
376
379
  """Updates the dates of a loan."""
377
380
  state = record["state"]
378
- is_active_or_completed = (
379
- state in CIRCULATION_STATES_LOAN_ACTIVE
380
- or state in CIRCULATION_STATES_LOAN_COMPLETED
381
- )
381
+ is_active = state in CIRCULATION_STATES_LOAN_ACTIVE
382
+ is_completed = state in CIRCULATION_STATES_LOAN_COMPLETED
382
383
 
383
384
  data = copy(record)
384
385
 
385
- if is_active_or_completed:
386
+ if is_active or is_completed:
386
387
  today = date.today().strftime("%Y-%m-%d")
387
388
  if request_start_date or request_expire_date:
388
389
  raise IlsException(
@@ -417,6 +418,9 @@ def update_dates_loan(
417
418
  db.session.commit()
418
419
  current_circulation.loan_indexer().index(record)
419
420
 
421
+ if is_active:
422
+ send_dates_updated_notification(record)
423
+
420
424
  return record
421
425
 
422
426
 
@@ -81,6 +81,7 @@ ILS_CIRCULATION_LOAN_WILL_EXPIRE_DAYS = 7
81
81
  #: Optional delivery methods when requesting a new loan. Set to empty object to
82
82
  # disable it
83
83
  ILS_CIRCULATION_DELIVERY_METHODS = {
84
+ "NOT-SPECIFIED": "Not specified",
84
85
  "PICKUP": "Pick it up at the library desk",
85
86
  "DELIVERY": "Have it delivered to my office",
86
87
  "SELF-CHECKOUT": "Self-checkout",
@@ -26,7 +26,7 @@ class LoanCheckoutSchemaV1(LoanBaseSchemaV1):
26
26
  item_pid = fields.Nested(LoanItemPIDSchemaV1, required=True)
27
27
  start_date = DateString()
28
28
  end_date = DateString()
29
- force = fields.Bool(missing=False)
29
+ force = fields.Bool(load_default=False)
30
30
 
31
31
  @validates("force")
32
32
  def validate_force(self, value, **kwargs):
@@ -107,8 +107,8 @@ class LoanRequestSchemaV1(LoanBaseSchemaV1):
107
107
  """Loan request schema."""
108
108
 
109
109
  delivery = fields.Nested(LoanRequestDeliverySchemaV1)
110
- request_expire_date = DateString(missing=request_expire_date_default)
111
- request_start_date = DateString(missing=request_start_date_default)
110
+ request_expire_date = DateString(load_default=request_expire_date_default)
111
+ request_start_date = DateString(load_default=request_start_date_default)
112
112
 
113
113
  @validates_schema()
114
114
  def validates_schema(self, data, **kwargs):
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2021 CERN.
3
+ # Copyright (C) 2021-2025 CERN.
4
4
  #
5
5
  # invenio-app-ils is free software; you can redistribute it and/or modify it
6
6
  # under the terms of the MIT License; see LICENSE file for more details.
@@ -64,6 +64,14 @@ def send_expiring_loan_reminder_notification(loan, expiring_in_days):
64
64
  )
65
65
 
66
66
 
67
+ def send_dates_updated_notification(loan):
68
+ """Send reminder notification."""
69
+ send_loan_notification(
70
+ action="update_dates",
71
+ loan=loan,
72
+ )
73
+
74
+
67
75
  def send_bulk_extend_notification(
68
76
  extended_loans,
69
77
  not_extended_loans,
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2021 CERN.
3
+ # Copyright (C) 2021-2025 CERN.
4
4
  #
5
5
  # invenio-app-ils is free software; you can redistribute it and/or modify it
6
6
  # under the terms of the MIT License; see LICENSE file for more details.
@@ -29,6 +29,7 @@ class NotificationLoanMsg(NotificationMsg):
29
29
  checkin="checkin.html",
30
30
  extend="extend.html",
31
31
  cancel="cancel.html",
32
+ update_dates="update_dates.html",
32
33
  overdue_reminder="overdue_reminder.html",
33
34
  expiring_reminder="will_expire_in_reminder.html",
34
35
  bulk_extend="bulk_extend.html",
@@ -0,0 +1,19 @@
1
+ {% block title %}
2
+ InvenioILS: loan dates changed for "{{ document.title|safe }}"
3
+ {% endblock %}
4
+
5
+ {% block body_plain %}
6
+ Dear {{ patron.name }},
7
+
8
+ The dates of your loan for "{{ document.full_title }}" <{{ spa_routes.HOST }}{{ spa_routes.PATHS['literature']|format(pid=document.pid) }}> have been changed.
9
+
10
+ The new dates are {{ loan.start_date }} to {{ loan.end_date }}.
11
+ {% endblock %}
12
+
13
+ {% block body_html %}
14
+ Dear {{ patron.name }}, <br/><br/>
15
+
16
+ The dates of your loan for <a href="{{ spa_routes.HOST }}{{ spa_routes.PATHS['literature']|format(pid=document.pid) }}">"{{ document.full_title }}"</a> have been <b>changed</b>. <br/>
17
+
18
+ The new dates are <b>{{ loan.start_date }}</b> to <b>{{ loan.end_date }}</b>.<br/>
19
+ {% endblock %}
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
@@ -1308,21 +1310,42 @@ def data(
1308
1310
  _run_command("roles create librarian", verbose)
1309
1311
 
1310
1312
  # Create users
1311
- _run_command("users create patron1@test.ch -a --password=123456", verbose) # ID 1
1312
- create_userprofile_for("patron1@test.ch", "patron1", "Yannic Vilma")
1313
- _run_command("users create patron2@test.ch -a --password=123456", verbose) # ID 2
1314
- create_userprofile_for("patron2@test.ch", "patron2", "Diana Adi")
1315
-
1316
- _run_command("users create librarian@test.ch -a --password=123456", verbose) # ID 3
1317
- create_userprofile_for("librarian@test.ch", "librarian", "Hector Nabu")
1318
- _run_command("users create patron3@test.ch -a --password=123456", verbose) # ID 4
1319
- create_userprofile_for("patron3@test.ch", "patron3", "Medrod Tara")
1320
- _run_command("users create patron4@test.ch -a --password=123456", verbose) # ID 5
1321
- create_userprofile_for("patron4@test.ch", "patron4", "Devi Cupid")
1313
+ patron1_profile = {"full_name": "Yannic Vilma"}
1314
+ _run_command(
1315
+ f"users create patron1@test.ch -a --password=123456 --profile '{json.dumps(patron1_profile)}'",
1316
+ verbose,
1317
+ )
1318
+
1319
+ patron2_profile = {"full_name": "Diana Adi"}
1320
+ _run_command(
1321
+ f"users create patron2@test.ch -a --password=123456 --profile '{json.dumps(patron2_profile)}'",
1322
+ verbose,
1323
+ )
1324
+
1325
+ librarian_profile = {"full_name": "Hector Nabu"}
1326
+ _run_command(
1327
+ f"users create librarian@test.ch -a --password=123456 --profile '{json.dumps(librarian_profile)}'",
1328
+ verbose,
1329
+ )
1330
+
1331
+ patron3_profile = {"full_name": "Medrod Tara"}
1332
+ _run_command(
1333
+ f"users create patron3@test.ch -a --password=123456 --profile '{json.dumps(patron3_profile)}'",
1334
+ verbose,
1335
+ )
1336
+
1337
+ patron4_profile = {"full_name": "Devi Cupid"}
1338
+ _run_command(
1339
+ f"users create patron4@test.ch -a --password=123456 --profile '{json.dumps(patron4_profile)}'",
1340
+ verbose,
1341
+ )
1322
1342
 
1323
1343
  if not skip_admin:
1324
- _run_command("users create admin@test.ch -a --password=123456", verbose) # ID 6
1325
- create_userprofile_for("admin@test.ch", "admin", "Zeki Ryoichi")
1344
+ admin_profile = {"full_name": "Zeki Ryoichi"}
1345
+ _run_command(
1346
+ f"users create admin@test.ch -a --password=123456 --profile '{json.dumps(admin_profile)}'",
1347
+ verbose,
1348
+ )
1326
1349
  _run_command("roles add admin@test.ch admin", verbose)
1327
1350
 
1328
1351
  # assign roles
@@ -1512,17 +1535,6 @@ def data(
1512
1535
  current_search.flush_and_refresh(index="*")
1513
1536
 
1514
1537
 
1515
- def create_userprofile_for(email, username, full_name):
1516
- """Create a fake user profile."""
1517
- user = User.query.filter_by(email=email).one_or_none()
1518
- if user:
1519
- profile = UserProfile(user_id=int(user.get_id()))
1520
- profile.username = username
1521
- profile.full_name = full_name
1522
- db.session.add(profile)
1523
- db.session.commit()
1524
-
1525
-
1526
1538
  def _run_command(command, verbose, catch_exceptions=False):
1527
1539
  from invenio_base.app import create_cli
1528
1540
 
@@ -1587,42 +1599,58 @@ def fixtures():
1587
1599
  def pages():
1588
1600
  """Register static pages."""
1589
1601
 
1590
- def page_data(page):
1591
- return (
1592
- pkg_resources.resource_stream(
1593
- "invenio_app_ils", os.path.join("static_pages", page)
1594
- )
1595
- .read()
1596
- .decode("utf8")
1597
- )
1602
+ def get_page_content(page):
1603
+ with importlib.resources.files("invenio_app_ils").joinpath(
1604
+ "static_pages", page
1605
+ ).open("rb") as f:
1606
+ return f.read().decode("utf8")
1598
1607
 
1599
- pages = [
1600
- Page(
1601
- url="/about",
1602
- title="About",
1603
- description="About",
1604
- content="InvenioILS about page",
1605
- template_name="invenio_pages/default.html",
1606
- ),
1607
- Page(
1608
- url="/contact",
1609
- title="Contact",
1610
- description="Contact",
1611
- content="You can contact InvenioILS developers on "
1612
- '<a href="https://gitter.im/inveniosoftware/invenio">'
1613
- "our chatroom</a>",
1614
- template_name="invenio_pages/default.html",
1615
- ),
1616
- Page(
1617
- url="/guide/search",
1618
- title="Search guide",
1619
- description="Search guide",
1620
- content=page_data("search_guide.html"),
1621
- template_name="invenio_pages/default.html",
1622
- ),
1608
+ pages_data = [
1609
+ {
1610
+ "url": "/about",
1611
+ "title": "About",
1612
+ "description": "About",
1613
+ "content": "InvenioILS about page",
1614
+ },
1615
+ {
1616
+ "url": "/contact",
1617
+ "title": "Contact",
1618
+ "description": "Contact",
1619
+ "content": (
1620
+ "You can contact InvenioILS developers on "
1621
+ '<a href="https://gitter.im/inveniosoftware/invenio">'
1622
+ "our chatroom</a>"
1623
+ ),
1624
+ },
1625
+ {
1626
+ "url": "/guide/search",
1627
+ "title": "Search guide",
1628
+ "description": "Search guide",
1629
+ "template": "search_guide.html",
1630
+ },
1623
1631
  ]
1624
- with db.session.begin_nested():
1625
- Page.query.delete()
1626
- db.session.add_all(pages)
1627
- db.session.commit()
1628
- click.echo("static pages created :)")
1632
+
1633
+ supported_languages = current_i18n.get_languages()
1634
+
1635
+ for entry in pages_data:
1636
+ url = entry["url"]
1637
+ for lang in supported_languages:
1638
+ lang_code = lang[0]
1639
+ try:
1640
+ current_pages_service.read_by_url(system_identity, url, lang_code)
1641
+ except PageNotFoundError:
1642
+ page = {
1643
+ "url": url,
1644
+ "title": entry.get("title", ""),
1645
+ "description": entry.get("description", ""),
1646
+ "lang": lang_code,
1647
+ "template_name": current_app.config["PAGES_DEFAULT_TEMPLATE"],
1648
+ "content": (
1649
+ get_page_content(entry["template"])
1650
+ if entry.get("template")
1651
+ else entry.get("content", "")
1652
+ ),
1653
+ }
1654
+ current_pages_service.create(system_identity, page)
1655
+
1656
+ click.echo("Static pages created :)")
invenio_app_ils/config.py CHANGED
@@ -125,7 +125,7 @@ DEBUG_TB_INTERCEPT_REDIRECTS = False
125
125
  # Rate limiting
126
126
  ###############################################################################
127
127
  #: Storage for rate limiter.
128
- RATELIMIT_STORAGE_URL = "redis://localhost:6379/3"
128
+ RATELIMIT_STORAGE_URI = "redis://localhost:6379/3"
129
129
  #: Rate limit for logged in users.
130
130
  RATELIMIT_AUTHENTICATED_USER = "5000 per hour;150 per minute"
131
131
  #: Rate limit for non logged in users.
@@ -299,7 +299,7 @@ SESSION_COOKIE_SAMESITE = "Lax"
299
299
  #: provided, the allowed hosts variable is set to localhost. In production it
300
300
  #: should be set to the correct host and it is strongly recommended to only
301
301
  #: route correct hosts to the application.
302
- APP_ALLOWED_HOSTS = ["localhost", "127.0.0.1"]
302
+ TRUSTED_HOSTS = ["localhost", "127.0.0.1"]
303
303
 
304
304
  #: Single Page Application host and routes, useful in templates/emails
305
305
  SPA_HOST = "https://127.0.0.1:3000"
@@ -1075,3 +1075,11 @@ DB_VERSIONING_USER_MODEL = None
1075
1075
 
1076
1076
  # Feature Toggles
1077
1077
  ILS_SELF_CHECKOUT_ENABLED = False
1078
+
1079
+ # Use default frontpage
1080
+ THEME_FRONTPAGE = False
1081
+
1082
+ # Default template to render.
1083
+ PAGES_DEFAULT_TEMPLATE = "invenio_pages/default.html"
1084
+ # default app theme
1085
+ APP_THEME = ["semantic-ui"]
@@ -237,7 +237,7 @@ class DocumentSchemaV1(RecordMetadataSchemaJSONV1):
237
237
  physical_description = fields.Str()
238
238
  publication_info = fields.List(fields.Nested(PublicationInfoSchema))
239
239
  publication_year = fields.Str(required=True)
240
- restricted = fields.Bool(missing=False)
240
+ restricted = fields.Bool(load_default=False)
241
241
  source = fields.Str()
242
242
  subjects = fields.List(fields.Nested(SubjectSchema))
243
243
  table_of_content = fields.List(fields.Str())
@@ -27,7 +27,7 @@ class URLSchema(Schema):
27
27
  unknown = EXCLUDE
28
28
 
29
29
  description = fields.Str()
30
- login_required = fields.Bool(missing=True)
30
+ login_required = fields.Bool(load_default=True)
31
31
  value = fields.URL(required=True)
32
32
 
33
33
 
@@ -63,7 +63,7 @@ class EItemSchemaV1(RecordMetadataSchemaJSONV1):
63
63
  files = fields.List(fields.Nested(FileSchema))
64
64
  identifiers = fields.List(fields.Nested(IdentifierSchema))
65
65
  internal_notes = fields.Str()
66
- open_access = fields.Bool(missing=True)
66
+ open_access = fields.Bool(load_default=True)
67
67
  source = fields.Str()
68
68
  urls = fields.List(fields.Nested(URLSchema))
69
69
 
@@ -60,7 +60,6 @@ def get_patron_activity(patron_pid):
60
60
  patron_loans = dump(get_loans_by_patron_pid(patron_pid))
61
61
 
62
62
  patron_profile = UserProfile.get_by_userid(patron_pid).__dict__
63
- del patron_profile["_sa_instance_state"]
64
63
 
65
64
  patron_data = {
66
65
  "patron": patron,
@@ -254,9 +253,6 @@ def delete_user_account(patron_pid):
254
253
  )
255
254
  dropped += ra.delete() or 0
256
255
 
257
- dropped += (
258
- UserProfile.query.filter(UserProfile.user_id == patron_pid).delete() or 0
259
- )
260
256
  dropped += (
261
257
  LoginInformation.query.filter(
262
258
  LoginInformation.user_id == patron_pid
@@ -40,7 +40,7 @@ class AccessUrlSchema(Schema):
40
40
  description = fields.Str()
41
41
  open_access = fields.Bool()
42
42
  value = fields.URL()
43
- login_required = fields.Bool(missing=False)
43
+ login_required = fields.Bool(load_default=False)
44
44
 
45
45
 
46
46
  class PhysicalVolumes(Schema):
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2025 CERN.
4
+ #
5
+ # Invenio App RDM is free software; you can redistribute it and/or modify it
6
+ # under the terms of the MIT License; see LICENSE file for more details.
7
+
8
+ """JS/CSS Webpack bundles for theme."""
9
+
10
+ from invenio_assets.webpack import WebpackThemeBundle
11
+
12
+ theme = WebpackThemeBundle(
13
+ __name__,
14
+ "assets",
15
+ default="semantic-ui",
16
+ themes={
17
+ "semantic-ui": dict(
18
+ aliases={
19
+ # Define Semantic-UI theme configuration needed by
20
+ # Invenio-Theme in order to build Semantic UI (in theme.js
21
+ # entry point)
22
+ # This is a workaround for invenio-app-ils until a better solution is found
23
+ "../../theme.config$": "less/theme.config",
24
+ },
25
+ ),
26
+ },
27
+ )