invenio-banners 3.1.0__tar.gz → 3.2.0__tar.gz

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.

Potentially problematic release.


This version of invenio-banners might be problematic. Click here for more details.

Files changed (124) hide show
  1. invenio-banners-3.2.0/.github/workflows/tests.yml +28 -0
  2. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/CHANGES.rst +6 -0
  3. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/PKG-INFO +7 -1
  4. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/__init__.py +2 -1
  5. invenio-banners-3.2.0/invenio_banners/administration/banners.py +182 -0
  6. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/records/models.py +25 -26
  7. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/resources/errors.py +4 -4
  8. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/services/results.py +9 -1
  9. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/services/schemas.py +2 -2
  10. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/services/service.py +10 -5
  11. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/messages.pot +33 -29
  12. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners.egg-info/PKG-INFO +7 -1
  13. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/tests/resources/test_resources.py +55 -26
  14. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/tests/services/test_services.py +12 -6
  15. invenio-banners-3.1.0/.github/workflows/tests.yml +0 -69
  16. invenio-banners-3.1.0/invenio_banners/administration/banners.py +0 -242
  17. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/.dockerignore +0 -0
  18. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/.editorconfig +0 -0
  19. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/.git-blame-ignore-revs +0 -0
  20. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/.github/workflows/i18n-pull.yml +0 -0
  21. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/.github/workflows/i18n-push.yml +0 -0
  22. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/.github/workflows/pypi-publish.yml +0 -0
  23. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/.tx/config +0 -0
  24. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/AUTHORS.rst +0 -0
  25. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/CONTRIBUTING.rst +0 -0
  26. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/INSTALL.rst +0 -0
  27. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/LICENSE +0 -0
  28. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/MANIFEST.in +0 -0
  29. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/README.rst +0 -0
  30. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/babel.ini +0 -0
  31. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/docs/Makefile +0 -0
  32. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/docs/api.rst +0 -0
  33. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/docs/authors.rst +0 -0
  34. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/docs/changes.rst +0 -0
  35. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/docs/conf.py +0 -0
  36. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/docs/configuration.rst +0 -0
  37. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/docs/contributing.rst +0 -0
  38. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/docs/index.rst +0 -0
  39. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/docs/installation.rst +0 -0
  40. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/docs/license.rst +0 -0
  41. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/docs/make.bat +0 -0
  42. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/docs/requirements.txt +0 -0
  43. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/docs/usage.rst +0 -0
  44. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/administration/__init__.py +0 -0
  45. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/alembic/5e02314da32e_create_invenio_banners_db_table.py +0 -0
  46. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/alembic/e40d93d99040_create_invenio_banners_branch.py +0 -0
  47. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/config.py +0 -0
  48. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/ext.py +0 -0
  49. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/proxies.py +0 -0
  50. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/records/__init__.py +0 -0
  51. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/resources/__init__.py +0 -0
  52. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/resources/config.py +0 -0
  53. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/resources/resource.py +0 -0
  54. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/services/__init__.py +0 -0
  55. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/services/config.py +0 -0
  56. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/services/errors.py +0 -0
  57. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/services/permissions.py +0 -0
  58. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/templates/semantic-ui/invenio_banners/banner.html +0 -0
  59. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/af/LC_MESSAGES/messages.po +0 -0
  60. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/ar/LC_MESSAGES/messages.po +0 -0
  61. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/bg/LC_MESSAGES/messages.po +0 -0
  62. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/ca/LC_MESSAGES/messages.po +0 -0
  63. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/cs/LC_MESSAGES/messages.po +0 -0
  64. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/da/LC_MESSAGES/messages.po +0 -0
  65. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/de/LC_MESSAGES/messages.po +0 -0
  66. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/de_AT/LC_MESSAGES/messages.po +0 -0
  67. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/de_DE/LC_MESSAGES/messages.po +0 -0
  68. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/el/LC_MESSAGES/messages.po +0 -0
  69. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/en_AT/LC_MESSAGES/messages.po +0 -0
  70. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/en_HU/LC_MESSAGES/messages.po +0 -0
  71. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/es/LC_MESSAGES/messages.po +0 -0
  72. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/es_CU/LC_MESSAGES/messages.po +0 -0
  73. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/es_MX/LC_MESSAGES/messages.po +0 -0
  74. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/et/LC_MESSAGES/messages.po +0 -0
  75. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/et_EE/LC_MESSAGES/messages.po +0 -0
  76. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/fa/LC_MESSAGES/messages.po +0 -0
  77. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/fa_IR/LC_MESSAGES/messages.po +0 -0
  78. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/fr/LC_MESSAGES/messages.po +0 -0
  79. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/fr_CI/LC_MESSAGES/messages.po +0 -0
  80. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/fr_FR/LC_MESSAGES/messages.po +0 -0
  81. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/gl/LC_MESSAGES/messages.po +0 -0
  82. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/hi_IN/LC_MESSAGES/messages.po +0 -0
  83. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/hr/LC_MESSAGES/messages.po +0 -0
  84. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/hu/LC_MESSAGES/messages.po +0 -0
  85. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/hu_HU/LC_MESSAGES/messages.po +0 -0
  86. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/it/LC_MESSAGES/messages.po +0 -0
  87. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/ja/LC_MESSAGES/messages.po +0 -0
  88. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/ka/LC_MESSAGES/messages.po +0 -0
  89. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/lt/LC_MESSAGES/messages.po +0 -0
  90. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/ne/LC_MESSAGES/messages.po +0 -0
  91. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/no/LC_MESSAGES/messages.po +0 -0
  92. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/pl/LC_MESSAGES/messages.po +0 -0
  93. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/pt/LC_MESSAGES/messages.po +0 -0
  94. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/ro/LC_MESSAGES/messages.po +0 -0
  95. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/ru/LC_MESSAGES/messages.po +0 -0
  96. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/rw/LC_MESSAGES/messages.po +0 -0
  97. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/sk/LC_MESSAGES/messages.po +0 -0
  98. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/sv/LC_MESSAGES/messages.po +0 -0
  99. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/sv_SE/LC_MESSAGES/messages.po +0 -0
  100. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/tr/LC_MESSAGES/messages.po +0 -0
  101. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/uk/LC_MESSAGES/messages.po +0 -0
  102. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/uk_UA/LC_MESSAGES/messages.po +0 -0
  103. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/zh_CN/LC_MESSAGES/messages.po +0 -0
  104. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/translations/zh_TW/LC_MESSAGES/messages.po +0 -0
  105. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/utils.py +0 -0
  106. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners/views.py +0 -0
  107. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners.egg-info/SOURCES.txt +0 -0
  108. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners.egg-info/dependency_links.txt +0 -0
  109. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners.egg-info/entry_points.txt +0 -0
  110. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners.egg-info/not-zip-safe +0 -0
  111. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners.egg-info/requires.txt +0 -0
  112. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/invenio_banners.egg-info/top_level.txt +0 -0
  113. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/pyproject.toml +0 -0
  114. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/requirements-devel.txt +0 -0
  115. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/run-tests.sh +0 -0
  116. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/setup.cfg +0 -0
  117. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/setup.py +0 -0
  118. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/tests/conftest.py +0 -0
  119. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/tests/records/test_disable.py +0 -0
  120. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/tests/records/test_models.py +0 -0
  121. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/tests/resources/conftest.py +0 -0
  122. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/tests/services/conftest.py +0 -0
  123. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/tests/test_invenio_banners.py +0 -0
  124. {invenio-banners-3.1.0 → invenio-banners-3.2.0}/tests/test_macro.py +0 -0
@@ -0,0 +1,28 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # This file is part of Invenio.
4
+ # Copyright (C) 2020-2024 CERN.
5
+ #
6
+ # Invenio-Banners is free software; you can redistribute it and/or modify it
7
+ # under the terms of the MIT License; see LICENSE file for more details.
8
+
9
+ name: CI
10
+
11
+ on:
12
+ push:
13
+ branches: master
14
+ pull_request:
15
+ branches: master
16
+ schedule:
17
+ # * is a special character in YAML so you have to quote this string
18
+ - cron: "0 3 * * 6"
19
+ workflow_dispatch:
20
+ inputs:
21
+ reason:
22
+ description: "Reason"
23
+ required: false
24
+ default: "Manual trigger"
25
+
26
+ jobs:
27
+ Python:
28
+ uses: inveniosoftware/workflows/.github/workflows/tests-python.yml@master
@@ -7,6 +7,12 @@
7
7
  Changes
8
8
  =======
9
9
 
10
+ Version v3.2.0 (released 2024-11-05)
11
+
12
+ - feat(administration): use html editor for message
13
+ - global: change the code to be compatible with sqlalchemy >= 2.0
14
+ - global: add compatibility layer to move to flask >= 3.0
15
+
10
16
  Version v3.1.0 (released 2024-08-07)
11
17
 
12
18
  - http headers: use and adjust vnd.inveniordm.v1+json http accept header
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: invenio-banners
3
- Version: 3.1.0
3
+ Version: 3.2.0
4
4
  Summary: Invenio-Banners is a module used to create and show banners with useful messages to users.
5
5
  Home-page: https://github.com/inveniosoftware/invenio-banners
6
6
  Author: CERN
@@ -45,6 +45,12 @@ Description: ..
45
45
  Changes
46
46
  =======
47
47
 
48
+ Version v3.2.0 (released 2024-11-05)
49
+
50
+ - feat(administration): use html editor for message
51
+ - global: change the code to be compatible with sqlalchemy >= 2.0
52
+ - global: add compatibility layer to move to flask >= 3.0
53
+
48
54
  Version v3.1.0 (released 2024-08-07)
49
55
 
50
56
  - http headers: use and adjust vnd.inveniordm.v1+json http accept header
@@ -1,6 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright (C) 2020-2024 CERN.
4
+ # Copyright (C) 2024 Graz University of Technology.
4
5
  #
5
6
  # Invenio-Banners is free software; you can redistribute it and/or modify it
6
7
  # under the terms of the MIT License; see LICENSE file for more details.
@@ -9,6 +10,6 @@
9
10
 
10
11
  from .ext import InvenioBanners
11
12
 
12
- __version__ = "3.1.0"
13
+ __version__ = "3.2.0"
13
14
 
14
15
  __all__ = ("__version__", "InvenioBanners")
@@ -0,0 +1,182 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2023 CERN.
4
+ #
5
+ # Invenio-Banners 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
+ """Invenio administration banners view module."""
9
+
10
+ from invenio_administration.views.base import (
11
+ AdminResourceCreateView,
12
+ AdminResourceDetailView,
13
+ AdminResourceEditView,
14
+ AdminResourceListView,
15
+ )
16
+ from invenio_i18n import lazy_gettext as _
17
+
18
+
19
+ class BannerListView(AdminResourceListView):
20
+ """Search admin view."""
21
+
22
+ api_endpoint = "/banners"
23
+ name = "banners"
24
+ resource_config = "banners_resource"
25
+ title = "Banners"
26
+ menu_label = "Banners"
27
+ category = _("Site management")
28
+ pid_path = "id"
29
+ icon = "newspaper"
30
+
31
+ display_search = True
32
+ display_delete = True
33
+ display_create = True
34
+ display_edit = True
35
+
36
+ item_field_list = {
37
+ "id": {"text": _("Id"), "order": 1, "width": 1},
38
+ "start_datetime": {"text": _("Start time (UTC)"), "order": 2, "width": 2},
39
+ "end_datetime": {"text": _("End time (UTC)"), "order": 3, "width": 2},
40
+ "message": {"text": _("Message"), "order": 4, "width": 7},
41
+ "active": {"text": _("Active"), "order": 5, "width": 1},
42
+ "url_path": {"text": _("URL path"), "order": 6, "width": 2},
43
+ "category": {"text": _("Category"), "order": 7, "width": 1},
44
+ }
45
+
46
+ create_view_name = "banner_create"
47
+
48
+ search_config_name = "BANNERS_SEARCH"
49
+ search_sort_config_name = "BANNERS_SORT_OPTIONS"
50
+
51
+
52
+ common_form_fields = {
53
+ "start_datetime": {
54
+ "order": 1,
55
+ "text": _("Start time"),
56
+ "description": _(
57
+ "Date/time to make the banner active. "
58
+ "Input format: yyyy-mm-dd hh:mm:ss. "
59
+ "Set to future date/time to delay the banner. "
60
+ "Note: specify time in UTC time standard."
61
+ ),
62
+ "placeholder": _("YYYY-MM-DD hh:mm:ss"),
63
+ },
64
+ "end_datetime": {
65
+ "order": 2,
66
+ "text": _("End time"),
67
+ "description": _(
68
+ "Date/time to make the banner inactive. "
69
+ "Input format: yyyy-mm-dd hh:mm:ss. An empty value makes "
70
+ "the banner active until manually disabled via the active flag. "
71
+ "Note: specify time in UTC time standard."
72
+ ),
73
+ "placeholder": _("YYYY-MM-DD hh:mm:ss"),
74
+ },
75
+ "message": {
76
+ "order": 3,
77
+ "text": _("Message"),
78
+ "description": _(
79
+ "Message to be displayed on the banner. HTML format is supported."
80
+ ),
81
+ "rows": 10,
82
+ },
83
+ "url_path": {
84
+ "order": 4,
85
+ "text": _("URL path"),
86
+ "description": _(
87
+ "URL path prefix (including the first /) to define where "
88
+ "the message will be active on the site. For "
89
+ "example, if you enter `/records`, any URL starting with "
90
+ "`/records` will return an active banner (`/records`, "
91
+ "`/records/1234`, etc.). An empty value makes the banner "
92
+ "active for any URL."
93
+ ),
94
+ },
95
+ "category": {
96
+ "order": 5,
97
+ "text": _("Category"),
98
+ "description": _(
99
+ "Banner category. `Info` option displays a blue banner. "
100
+ "`Warning` option displays an orange banner. "
101
+ "`Other` option displays a gray banner."
102
+ ),
103
+ "options": [
104
+ {"title_l10n": "Info", "id": "info"},
105
+ {"title_l10n": "Warning", "id": "warning"},
106
+ {"title_l10n": "Other", "id": "other"},
107
+ ],
108
+ "placeholder": "Select a category",
109
+ },
110
+ "active": {
111
+ "order": 6,
112
+ "text": _("Active"),
113
+ "description": _(
114
+ "Tick it to activate the banner: banner will be "
115
+ "displayed according to start/end times. If not "
116
+ "activated, start/end times will be ignored."
117
+ ),
118
+ },
119
+ }
120
+
121
+
122
+ class BannerEditView(AdminResourceEditView):
123
+ """Configuration for Banner edit view."""
124
+
125
+ name = "banner_edit"
126
+ url = "/banners/<pid_value>/edit"
127
+ resource_config = "banners_resource"
128
+ pid_path = "id"
129
+ api_endpoint = "/banners"
130
+ title = "Edit Banner"
131
+
132
+ list_view_name = "banners"
133
+
134
+ form_fields = {
135
+ **common_form_fields,
136
+ "created": {"order": 7},
137
+ "updated": {"order": 8},
138
+ }
139
+
140
+
141
+ class BannerCreateView(AdminResourceCreateView):
142
+ """Configuration for Banner create view."""
143
+
144
+ name = "banner_create"
145
+ url = "/banners/create"
146
+ resource_config = "banners_resource"
147
+ pid_path = "id"
148
+ api_endpoint = "/banners"
149
+ title = "Create Banner"
150
+
151
+ list_view_name = "banners"
152
+
153
+ form_fields = {
154
+ **common_form_fields,
155
+ }
156
+
157
+
158
+ class BannerDetailView(AdminResourceDetailView):
159
+ """Admin banner detail view."""
160
+
161
+ url = "/banners/<pid_value>"
162
+ api_endpoint = "/banners"
163
+ name = "banner-details"
164
+ resource_config = "banners_resource"
165
+ title = "Banner Details"
166
+
167
+ display_delete = True
168
+ display_edit = True
169
+
170
+ list_view_name = "banners"
171
+ pid_path = "id"
172
+
173
+ item_field_list = {
174
+ "start_datetime": {"text": _("Start time"), "order": 1},
175
+ "end_datetime": {"text": _("End time"), "order": 2},
176
+ "message": {"text": _("Message"), "order": 3},
177
+ "url_path": {"text": _("URL path"), "order": 4},
178
+ "category": {"text": _("Category"), "order": 5},
179
+ "active": {"text": _("Active"), "order": 6},
180
+ "created": {"text": _("Created"), "order": 7},
181
+ "updated": {"text": _("Updated"), "order": 8},
182
+ }
@@ -1,6 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright (C) 2020-2023 CERN.
4
+ # Copyright (C) 2024 Graz University of Technology.
4
5
  #
5
6
  # Invenio-Banners is free software; you can redistribute it and/or modify it
6
7
  # under the terms of the MIT License; see LICENSE file for more details.
@@ -13,7 +14,6 @@ import sqlalchemy as sa
13
14
  from flask import current_app
14
15
  from invenio_db import db
15
16
  from sqlalchemy import or_
16
- from sqlalchemy.orm.exc import NoResultFound
17
17
  from sqlalchemy.sql import text
18
18
  from sqlalchemy_utils.models import Timestamp
19
19
 
@@ -24,7 +24,6 @@ class BannerModel(db.Model, Timestamp):
24
24
  """Defines a message to show to users."""
25
25
 
26
26
  __tablename__ = "banners"
27
- __versioned__ = {"versioning": False}
28
27
 
29
28
  id = db.Column(db.Integer, primary_key=True)
30
29
 
@@ -51,6 +50,7 @@ class BannerModel(db.Model, Timestamp):
51
50
  """Create a new banner."""
52
51
  _categories = [t[0] for t in current_app.config["BANNERS_CATEGORIES"]]
53
52
  assert data.get("category") in _categories
53
+
54
54
  with db.session.begin_nested():
55
55
  obj = cls(
56
56
  message=data.get("message"),
@@ -62,24 +62,24 @@ class BannerModel(db.Model, Timestamp):
62
62
  )
63
63
  db.session.add(obj)
64
64
 
65
- db.session.commit()
66
65
  return obj
67
66
 
68
67
  @classmethod
69
68
  def update(cls, data, id):
70
69
  """Update an existing banner."""
71
70
  with db.session.begin_nested():
72
- cls.query.filter_by(id=id).update(data)
73
-
74
- db.session.commit()
71
+ # NOTE:
72
+ # with db.session.get(cls, id) the model itself would be
73
+ # returned and this classmethod would be called
74
+ db.session.query(cls).filter_by(id=id).update(data)
75
75
 
76
76
  @classmethod
77
77
  def get(cls, id):
78
78
  """Get banner by its id."""
79
- try:
80
- return cls.query.filter_by(id=id).one()
81
- except NoResultFound:
82
- raise BannerNotExistsError(id)
79
+ if banner := db.session.get(cls, id):
80
+ return banner
81
+
82
+ raise BannerNotExistsError(id)
83
83
 
84
84
  @classmethod
85
85
  def delete(cls, banner):
@@ -87,15 +87,14 @@ class BannerModel(db.Model, Timestamp):
87
87
  with db.session.begin_nested():
88
88
  db.session.delete(banner)
89
89
 
90
- db.session.commit()
91
-
92
90
  @classmethod
93
91
  def get_active(cls, url_path):
94
92
  """Return active banners."""
95
93
  now = datetime.utcnow()
96
94
 
97
95
  query = (
98
- cls.query.filter(cls.active.is_(True))
96
+ db.session.query(cls)
97
+ .filter(cls.active.is_(True))
99
98
  .filter(cls.start_datetime <= now)
100
99
  .filter((cls.end_datetime.is_(None)) | (now <= cls.end_datetime))
101
100
  )
@@ -113,16 +112,17 @@ class BannerModel(db.Model, Timestamp):
113
112
  @classmethod
114
113
  def search(cls, search_params, filters):
115
114
  """Filter banners accordingly to query params."""
116
- banners = (
117
- BannerModel.query.filter(or_(*filters))
118
- .order_by(
119
- search_params["sort_direction"](text(",".join(search_params["sort"])))
120
- )
121
- .paginate(
122
- page=search_params["page"],
123
- per_page=search_params["size"],
124
- error_out=False,
125
- )
115
+ if filters == []:
116
+ filtered = db.session.query(BannerModel).filter()
117
+ else:
118
+ filtered = db.session.query(BannerModel).filter(or_(*filters))
119
+
120
+ banners = filtered.order_by(
121
+ search_params["sort_direction"](text(",".join(search_params["sort"])))
122
+ ).paginate(
123
+ page=search_params["page"],
124
+ per_page=search_params["size"],
125
+ error_out=False,
126
126
  )
127
127
 
128
128
  return banners
@@ -133,12 +133,11 @@ class BannerModel(db.Model, Timestamp):
133
133
  now = datetime.utcnow()
134
134
 
135
135
  query = (
136
- cls.query.filter(cls.active.is_(True))
136
+ db.session.query(cls)
137
+ .filter(cls.active.is_(True))
137
138
  .filter(cls.end_datetime.isnot(None))
138
139
  .filter(cls.end_datetime < now)
139
140
  )
140
141
 
141
142
  for old in query.all():
142
143
  old.active = False
143
-
144
- db.session.commit()
@@ -1,19 +1,19 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright (C) 2023 CERN.
4
+ # Copyright (C) 2024 Graz University of Technology.
4
5
  #
5
6
  # Invenio-Banners is free software; you can redistribute it and/or modify it
6
7
  # under the terms of the MIT License; see LICENSE file for more details.
7
8
 
8
9
  """Errors."""
9
10
 
10
- from flask_resources import HTTPJSONException, create_error_handler
11
-
12
- from ..services.errors import BannerNotExistsError
13
11
  import marshmallow as ma
14
12
  from flask_resources import HTTPJSONException, create_error_handler
15
13
  from invenio_records_resources.errors import validation_error_to_list_errors
16
14
 
15
+ from ..services.errors import BannerNotExistsError
16
+
17
17
 
18
18
  class HTTPJSONValidationException(HTTPJSONException):
19
19
  """HTTP exception serializing to JSON and reflecting Marshmallow errors."""
@@ -25,7 +25,7 @@ class HTTPJSONValidationException(HTTPJSONException):
25
25
  super().__init__(code=400, errors=validation_error_to_list_errors(exception))
26
26
 
27
27
 
28
- class ErrorHandlersMixin():
28
+ class ErrorHandlersMixin:
29
29
  """Mixin to define error handlers."""
30
30
 
31
31
  error_handlers = {
@@ -1,14 +1,22 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright (C) 2022-2023 CERN.
4
+ # Copyright (C) 2024 Graz University of Technology.
4
5
  #
5
6
  # Invenio-Banners is free software; you can redistribute it and/or modify it
6
7
  # under the terms of the MIT License; see LICENSE file for more details.
7
8
 
8
9
  """Service results."""
9
- from flask_sqlalchemy import Pagination
10
+
10
11
  from invenio_records_resources.services.records.results import RecordItem, RecordList
11
12
 
13
+ try:
14
+ # flask_sqlalchemy<3.0.0
15
+ from flask_sqlalchemy import Pagination
16
+ except ImportError:
17
+ # flask_sqlalchemy>=3.0.0
18
+ from flask_sqlalchemy.pagination import Pagination
19
+
12
20
 
13
21
  class BannerItem(RecordItem):
14
22
  """Single banner result."""
@@ -11,13 +11,13 @@ from datetime import datetime, timezone
11
11
 
12
12
  from invenio_records_resources.services.records.schema import BaseRecordSchema
13
13
  from marshmallow import fields, pre_load
14
- from marshmallow_utils.fields import TZDateTime
14
+ from marshmallow_utils.fields import SanitizedHTML, TZDateTime
15
15
 
16
16
 
17
17
  class BannerSchema(BaseRecordSchema):
18
18
  """Schema for banners."""
19
19
 
20
- message = fields.String(required=True)
20
+ message = SanitizedHTML(required=True)
21
21
  url_path = fields.String(allow_none=True)
22
22
  category = fields.String(required=True, metadata={"default": "info"})
23
23
  start_datetime = fields.DateTime(
@@ -1,6 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright (C) 2022-2023 CERN.
4
+ # Copyright (C) 2024 Graz University of Technology.
4
5
  #
5
6
  # Invenio-Banners is free software; you can redistribute it and/or modify it
6
7
  # under the terms of the MIT License; see LICENSE file for more details.
@@ -10,6 +11,7 @@
10
11
  import distutils.util
11
12
 
12
13
  import arrow
14
+ from invenio_db.uow import unit_of_work
13
15
  from invenio_records_resources.services import RecordService
14
16
  from invenio_records_resources.services.base import LinksTemplate
15
17
  from invenio_records_resources.services.base.utils import map_search_params
@@ -81,7 +83,8 @@ class BannerService(RecordService):
81
83
  links_item_tpl=self.links_item_tpl,
82
84
  )
83
85
 
84
- def create(self, identity, data, raise_errors=True):
86
+ @unit_of_work()
87
+ def create(self, identity, data, raise_errors=True, uow=None):
85
88
  """Create a banner."""
86
89
  self.require_permission(identity, "create")
87
90
 
@@ -99,17 +102,18 @@ class BannerService(RecordService):
99
102
  self, identity, banner, links_tpl=self.links_item_tpl, errors=errors
100
103
  )
101
104
 
102
- def delete(self, identity, id):
105
+ @unit_of_work()
106
+ def delete(self, identity, id, uow=None):
103
107
  """Delete a banner from database."""
104
108
  self.require_permission(identity, "delete")
105
109
 
106
110
  banner = self.record_cls.get(id)
107
-
108
111
  self.record_cls.delete(banner)
109
112
 
110
113
  return self.result_item(self, identity, banner, links_tpl=self.links_item_tpl)
111
114
 
112
- def update(self, identity, id, data):
115
+ @unit_of_work()
116
+ def update(self, identity, id, data, uow=None):
113
117
  """Update a banner."""
114
118
  self.require_permission(identity, "update")
115
119
 
@@ -131,7 +135,8 @@ class BannerService(RecordService):
131
135
  links_tpl=self.links_item_tpl,
132
136
  )
133
137
 
134
- def disable_expired(self, identity):
138
+ @unit_of_work()
139
+ def disable_expired(self, identity, uow=None):
135
140
  """Disable expired banners."""
136
141
  self.require_permission(identity, "disable")
137
142
  self.record_cls.disable_expired()
@@ -1,27 +1,27 @@
1
1
  # Translations template for invenio-banners.
2
- # Copyright (C) 2023 CERN
2
+ # Copyright (C) 2024 CERN
3
3
  # This file is distributed under the same license as the invenio-banners
4
4
  # project.
5
- # FIRST AUTHOR <EMAIL@ADDRESS>, 2023.
5
+ # FIRST AUTHOR <EMAIL@ADDRESS>, 2024.
6
6
  #
7
7
  #, fuzzy
8
8
  msgid ""
9
9
  msgstr ""
10
- "Project-Id-Version: invenio-banners 2.1.0\n"
10
+ "Project-Id-Version: invenio-banners 3.0.2\n"
11
11
  "Report-Msgid-Bugs-To: info@inveniosoftware.org\n"
12
- "POT-Creation-Date: 2023-06-30 11:25+0200\n"
12
+ "POT-Creation-Date: 2024-08-06 08:46+0000\n"
13
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
14
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
15
15
  "Language-Team: LANGUAGE <LL@li.org>\n"
16
16
  "MIME-Version: 1.0\n"
17
17
  "Content-Type: text/plain; charset=utf-8\n"
18
18
  "Content-Transfer-Encoding: 8bit\n"
19
- "Generated-By: Babel 2.12.1\n"
19
+ "Generated-By: Babel 2.15.0\n"
20
20
 
21
21
  #: invenio_banners/administration/banners.py:42
22
22
  #: invenio_banners/administration/banners.py:96
23
- #: invenio_banners/administration/banners.py:179
24
- #: invenio_banners/administration/banners.py:236 invenio_banners/config.py:37
23
+ #: invenio_banners/administration/banners.py:180
24
+ #: invenio_banners/administration/banners.py:237 invenio_banners/config.py:37
25
25
  msgid "URL path"
26
26
  msgstr ""
27
27
 
@@ -34,13 +34,17 @@ msgid "End DateTime"
34
34
  msgstr ""
35
35
 
36
36
  #: invenio_banners/administration/banners.py:41
37
- #: invenio_banners/administration/banners.py:123
38
- #: invenio_banners/administration/banners.py:207
39
- #: invenio_banners/administration/banners.py:238 invenio_banners/config.py:49
37
+ #: invenio_banners/administration/banners.py:124
38
+ #: invenio_banners/administration/banners.py:208
39
+ #: invenio_banners/administration/banners.py:239 invenio_banners/config.py:49
40
40
  #: invenio_banners/services/config.py:60
41
41
  msgid "Active"
42
42
  msgstr ""
43
43
 
44
+ #: invenio_banners/administration/banners.py:27
45
+ msgid "Site management"
46
+ msgstr ""
47
+
44
48
  #: invenio_banners/administration/banners.py:37
45
49
  msgid "Id"
46
50
  msgstr ""
@@ -55,27 +59,27 @@ msgstr ""
55
59
 
56
60
  #: invenio_banners/administration/banners.py:40
57
61
  #: invenio_banners/administration/banners.py:88
58
- #: invenio_banners/administration/banners.py:171
59
- #: invenio_banners/administration/banners.py:235
62
+ #: invenio_banners/administration/banners.py:172
63
+ #: invenio_banners/administration/banners.py:236
60
64
  msgid "Message"
61
65
  msgstr ""
62
66
 
63
67
  #: invenio_banners/administration/banners.py:43
64
68
  #: invenio_banners/administration/banners.py:108
65
- #: invenio_banners/administration/banners.py:191
66
- #: invenio_banners/administration/banners.py:237
69
+ #: invenio_banners/administration/banners.py:192
70
+ #: invenio_banners/administration/banners.py:238
67
71
  msgid "Category"
68
72
  msgstr ""
69
73
 
70
74
  #: invenio_banners/administration/banners.py:67
71
- #: invenio_banners/administration/banners.py:150
72
- #: invenio_banners/administration/banners.py:233
75
+ #: invenio_banners/administration/banners.py:151
76
+ #: invenio_banners/administration/banners.py:234
73
77
  #: invenio_banners/services/config.py:52
74
78
  msgid "Start time"
75
79
  msgstr ""
76
80
 
77
81
  #: invenio_banners/administration/banners.py:68
78
- #: invenio_banners/administration/banners.py:151
82
+ #: invenio_banners/administration/banners.py:152
79
83
  msgid ""
80
84
  "Input format: yyyy-mm-dd hh:mm:ss. Set to current or future date/time to "
81
85
  "delay the banner. Note: specify time in UTC time standard."
@@ -83,20 +87,20 @@ msgstr ""
83
87
 
84
88
  #: invenio_banners/administration/banners.py:73
85
89
  #: invenio_banners/administration/banners.py:84
86
- #: invenio_banners/administration/banners.py:156
87
- #: invenio_banners/administration/banners.py:167
90
+ #: invenio_banners/administration/banners.py:157
91
+ #: invenio_banners/administration/banners.py:168
88
92
  msgid "YYYY-MM-DD hh:mm:ss"
89
93
  msgstr ""
90
94
 
91
95
  #: invenio_banners/administration/banners.py:77
92
- #: invenio_banners/administration/banners.py:160
93
- #: invenio_banners/administration/banners.py:234
96
+ #: invenio_banners/administration/banners.py:161
97
+ #: invenio_banners/administration/banners.py:235
94
98
  #: invenio_banners/services/config.py:56
95
99
  msgid "End time"
96
100
  msgstr ""
97
101
 
98
102
  #: invenio_banners/administration/banners.py:78
99
- #: invenio_banners/administration/banners.py:161
103
+ #: invenio_banners/administration/banners.py:162
100
104
  msgid ""
101
105
  "Input format: yyyy-mm-dd hh:mm:ss. Date/time to make the banner inactive."
102
106
  " Empty value will make the banner active until manually disabled via the "
@@ -104,12 +108,12 @@ msgid ""
104
108
  msgstr ""
105
109
 
106
110
  #: invenio_banners/administration/banners.py:89
107
- #: invenio_banners/administration/banners.py:172
111
+ #: invenio_banners/administration/banners.py:173
108
112
  msgid "Message to be displayed on the banner. HTML format is supported."
109
113
  msgstr ""
110
114
 
111
115
  #: invenio_banners/administration/banners.py:97
112
- #: invenio_banners/administration/banners.py:180
116
+ #: invenio_banners/administration/banners.py:181
113
117
  msgid ""
114
118
  "Enter the URL path (including the first /) to define in which part of the"
115
119
  " site the message will be active. For example, if you enter `/records`, "
@@ -125,25 +129,25 @@ msgid ""
125
129
  "Other - all the rest types of massages in a gray color."
126
130
  msgstr ""
127
131
 
128
- #: invenio_banners/administration/banners.py:124
129
- #: invenio_banners/administration/banners.py:208
132
+ #: invenio_banners/administration/banners.py:125
133
+ #: invenio_banners/administration/banners.py:209
130
134
  msgid ""
131
135
  "Tick it to activate the banner: banner will bedisplayed according to "
132
136
  "start/end times. If not activated, start/end times will be ignored."
133
137
  msgstr ""
134
138
 
135
- #: invenio_banners/administration/banners.py:192
139
+ #: invenio_banners/administration/banners.py:193
136
140
  msgid ""
137
141
  "Banner category. Info option displays the banner with information message"
138
142
  " in a blue color. Warning - a warning information in an orange color. "
139
143
  "Other - all the rest types of messages in a gray color."
140
144
  msgstr ""
141
145
 
142
- #: invenio_banners/administration/banners.py:239
146
+ #: invenio_banners/administration/banners.py:240
143
147
  msgid "Created"
144
148
  msgstr ""
145
149
 
146
- #: invenio_banners/administration/banners.py:240
150
+ #: invenio_banners/administration/banners.py:241
147
151
  msgid "Updated"
148
152
  msgstr ""
149
153