eea.plotly 2.0__tar.gz → 2.1__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.
Files changed (145) hide show
  1. {eea_plotly-2.0/eea.plotly.egg-info → eea_plotly-2.1}/PKG-INFO +8 -1
  2. {eea_plotly-2.0 → eea_plotly-2.1}/docs/HISTORY.txt +7 -0
  3. eea_plotly-2.1/eea/__init__.py +4 -0
  4. eea_plotly-2.1/eea/plotly/__init__.py +9 -0
  5. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/behaviors.py +2 -2
  6. eea_plotly-2.1/eea/plotly/browser/__init__.py +1 -0
  7. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/browser/controlpanel.py +3 -0
  8. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/browser/preview.py +14 -23
  9. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/browser/preview_adapter/adapter.py +3 -5
  10. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/browser/preview_adapter/soer_miniature.py +19 -24
  11. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/controlpanel.py +16 -28
  12. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/deserializer/blocks.py +7 -7
  13. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/deserializer/dxcontent.py +23 -28
  14. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/deserializer/dxfields.py +3 -5
  15. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/interfaces.py +5 -4
  16. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/io_csv.py +6 -7
  17. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/io_json.py +1 -0
  18. eea_plotly-2.1/eea/plotly/locales/__init__.py +1 -0
  19. eea_plotly-2.1/eea/plotly/restapi/__init__.py +1 -0
  20. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/restapi/controlpanel/get.py +6 -17
  21. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/restapi/controlpanel/reset.py +8 -10
  22. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/restapi/visualization/get.py +6 -9
  23. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/serializer/blocks.py +21 -25
  24. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/serializer/dxfields.py +3 -3
  25. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/serializer/utils.py +8 -12
  26. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/setuphandlers.py +12 -15
  27. eea_plotly-2.1/eea/plotly/tests/__init__.py +1 -0
  28. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/tests/base.py +14 -20
  29. eea_plotly-2.1/eea/plotly/tests/test_doctests.py +31 -0
  30. eea_plotly-2.1/eea/plotly/upgrades/__init__.py +1 -0
  31. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/utils.py +8 -9
  32. eea_plotly-2.1/eea/plotly/version.txt +1 -0
  33. {eea_plotly-2.0 → eea_plotly-2.1/eea.plotly.egg-info}/PKG-INFO +8 -1
  34. {eea_plotly-2.0 → eea_plotly-2.1}/setup.py +20 -20
  35. eea_plotly-2.0/eea/__init__.py +0 -3
  36. eea_plotly-2.0/eea/plotly/__init__.py +0 -10
  37. eea_plotly-2.0/eea/plotly/browser/__init__.py +0 -2
  38. eea_plotly-2.0/eea/plotly/locales/__init__.py +0 -2
  39. eea_plotly-2.0/eea/plotly/restapi/__init__.py +0 -2
  40. eea_plotly-2.0/eea/plotly/tests/__init__.py +0 -2
  41. eea_plotly-2.0/eea/plotly/tests/test_doctests.py +0 -30
  42. eea_plotly-2.0/eea/plotly/upgrades/__init__.py +0 -2
  43. eea_plotly-2.0/eea/plotly/version.txt +0 -1
  44. {eea_plotly-2.0 → eea_plotly-2.1}/CONTRIBUTING.md +0 -0
  45. {eea_plotly-2.0 → eea_plotly-2.1}/MANIFEST.in +0 -0
  46. {eea_plotly-2.0 → eea_plotly-2.1}/README.rst +0 -0
  47. {eea_plotly-2.0 → eea_plotly-2.1}/docs/LICENSE.GPL +0 -0
  48. {eea_plotly-2.0 → eea_plotly-2.1}/docs/LICENSE.txt +0 -0
  49. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/README.txt +0 -0
  50. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/browser/configure.zcml +0 -0
  51. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/browser/pt/visualization_view.pt +0 -0
  52. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/configure.zcml +0 -0
  53. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/deserializer/configure.zcml +0 -0
  54. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/bg/LC_MESSAGES/eea.po +0 -0
  55. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/bg/LC_MESSAGES/plone.po +0 -0
  56. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/cs/LC_MESSAGES/eea.po +0 -0
  57. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/cs/LC_MESSAGES/plone.po +0 -0
  58. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/da/LC_MESSAGES/eea.po +0 -0
  59. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/da/LC_MESSAGES/plone.po +0 -0
  60. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/de/LC_MESSAGES/eea.po +0 -0
  61. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/de/LC_MESSAGES/plone.po +0 -0
  62. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/eea.pot +0 -0
  63. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/el/LC_MESSAGES/eea.po +0 -0
  64. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/el/LC_MESSAGES/plone.po +0 -0
  65. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/en/LC_MESSAGES/eea.po +0 -0
  66. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/en/LC_MESSAGES/plone.po +0 -0
  67. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/es/LC_MESSAGES/eea.po +0 -0
  68. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/es/LC_MESSAGES/plone.po +0 -0
  69. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/et/LC_MESSAGES/eea.po +0 -0
  70. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/et/LC_MESSAGES/plone.po +0 -0
  71. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/eu/LC_MESSAGES/eea.po +0 -0
  72. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/eu/LC_MESSAGES/plone.po +0 -0
  73. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/fi/LC_MESSAGES/eea.po +0 -0
  74. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/fi/LC_MESSAGES/plone.po +0 -0
  75. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/fr/LC_MESSAGES/eea.po +0 -0
  76. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/fr/LC_MESSAGES/plone.po +0 -0
  77. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/hr/LC_MESSAGES/eea.po +0 -0
  78. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/hr/LC_MESSAGES/plone.po +0 -0
  79. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/hu/LC_MESSAGES/eea.po +0 -0
  80. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/hu/LC_MESSAGES/plone.po +0 -0
  81. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/is/LC_MESSAGES/eea.po +0 -0
  82. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/is/LC_MESSAGES/plone.po +0 -0
  83. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/it/LC_MESSAGES/eea.po +0 -0
  84. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/it/LC_MESSAGES/plone.po +0 -0
  85. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/kl/LC_MESSAGES/eea.po +0 -0
  86. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/kl/LC_MESSAGES/plone.po +0 -0
  87. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/lt/LC_MESSAGES/eea.po +0 -0
  88. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/lt/LC_MESSAGES/plone.po +0 -0
  89. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/lv/LC_MESSAGES/eea.po +0 -0
  90. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/lv/LC_MESSAGES/plone.po +0 -0
  91. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/mt/LC_MESSAGES/eea.po +0 -0
  92. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/mt/LC_MESSAGES/plone.po +0 -0
  93. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/nl/LC_MESSAGES/eea.po +0 -0
  94. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/nl/LC_MESSAGES/plone.po +0 -0
  95. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/no/LC_MESSAGES/eea.po +0 -0
  96. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/no/LC_MESSAGES/plone.po +0 -0
  97. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/pl/LC_MESSAGES/eea.po +0 -0
  98. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/pl/LC_MESSAGES/plone.po +0 -0
  99. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/plone-manual.pot +0 -0
  100. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/pt/LC_MESSAGES/eea.po +0 -0
  101. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/pt/LC_MESSAGES/plone.po +0 -0
  102. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/pt_BR/LC_MESSAGES/eea.po +0 -0
  103. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/pt_BR/LC_MESSAGES/plone.po +0 -0
  104. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/ro/LC_MESSAGES/eea.po +0 -0
  105. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/ro/LC_MESSAGES/plone.po +0 -0
  106. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/ru/LC_MESSAGES/eea.po +0 -0
  107. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/ru/LC_MESSAGES/plone.po +0 -0
  108. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/sk/LC_MESSAGES/eea.po +0 -0
  109. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/sk/LC_MESSAGES/plone.po +0 -0
  110. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/sl/LC_MESSAGES/eea.po +0 -0
  111. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/sl/LC_MESSAGES/plone.po +0 -0
  112. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/sv/LC_MESSAGES/eea.po +0 -0
  113. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/sv/LC_MESSAGES/plone.po +0 -0
  114. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/tr/LC_MESSAGES/eea.po +0 -0
  115. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/tr/LC_MESSAGES/plone.po +0 -0
  116. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/update.sh +0 -0
  117. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/zh_TW/LC_MESSAGES/eea.po +0 -0
  118. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/locales/zh_TW/LC_MESSAGES/plone.po +0 -0
  119. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/permissions.zcml +0 -0
  120. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/profiles/default/browserlayer.xml +0 -0
  121. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/profiles/default/controlpanel.json +0 -0
  122. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/profiles/default/controlpanel.xml +0 -0
  123. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/profiles/default/metadata.xml +0 -0
  124. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/profiles/default/registry.xml +0 -0
  125. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/profiles/default/rolemap.xml +0 -0
  126. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/profiles/default/types/visualization.xml +0 -0
  127. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/profiles/default/types.xml +0 -0
  128. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/profiles/uninstall/browserlayer.xml +0 -0
  129. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/profiles/uninstall/controlpanel.xml +0 -0
  130. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/profiles/uninstall/registry.xml +0 -0
  131. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/profiles.zcml +0 -0
  132. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/restapi/configure.zcml +0 -0
  133. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/restapi/controlpanel/__init__.py +0 -0
  134. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/restapi/controlpanel/configure.zcml +0 -0
  135. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/restapi/visualization/configure.zcml +0 -0
  136. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/serializer/configure.zcml +0 -0
  137. {eea_plotly-2.0 → eea_plotly-2.1}/eea/plotly/upgrades/configure.zcml +0 -0
  138. {eea_plotly-2.0 → eea_plotly-2.1}/eea.plotly.egg-info/SOURCES.txt +0 -0
  139. {eea_plotly-2.0 → eea_plotly-2.1}/eea.plotly.egg-info/dependency_links.txt +0 -0
  140. {eea_plotly-2.0 → eea_plotly-2.1}/eea.plotly.egg-info/entry_points.txt +0 -0
  141. {eea_plotly-2.0 → eea_plotly-2.1}/eea.plotly.egg-info/namespace_packages.txt +0 -0
  142. {eea_plotly-2.0 → eea_plotly-2.1}/eea.plotly.egg-info/not-zip-safe +0 -0
  143. {eea_plotly-2.0 → eea_plotly-2.1}/eea.plotly.egg-info/requires.txt +0 -0
  144. {eea_plotly-2.0 → eea_plotly-2.1}/eea.plotly.egg-info/top_level.txt +0 -0
  145. {eea_plotly-2.0 → eea_plotly-2.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eea.plotly
3
- Version: 2.0
3
+ Version: 2.1
4
4
  Summary: volto-plotlycharts backend support
5
5
  Home-page: https://github.com/eea/eea.plotly
6
6
  Author: European Environment Agency: IDM2 A-Team
@@ -145,6 +145,13 @@ EEA_ - European Environment Agency (EU)
145
145
  Changelog
146
146
  =========
147
147
 
148
+ 2.1 - (2025-11-18)
149
+ ---------------------------
150
+ * Change: Replace Python linting to ruff
151
+ [mihaidobrescu1111 = refs #286821]
152
+ * Change: Add plone6 tests
153
+ [mihaidobrescu1111 = refs #293593]
154
+
148
155
  2.0 - (2025-08-27)
149
156
  ---------------------------
150
157
  * Change: fix csv file data decoding
@@ -1,6 +1,13 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ 2.1 - (2025-11-18)
5
+ ---------------------------
6
+ * Change: Replace Python linting to ruff
7
+ [mihaidobrescu1111 = refs #286821]
8
+ * Change: Add plone6 tests
9
+ [mihaidobrescu1111 = refs #293593]
10
+
4
11
  2.0 - (2025-08-27)
5
12
  ---------------------------
6
13
  * Change: fix csv file data decoding
@@ -0,0 +1,4 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Init"""
3
+
4
+ __import__("pkg_resources").declare_namespace(__name__)
@@ -0,0 +1,9 @@
1
+ """Main product initializer"""
2
+
3
+ from zope.i18nmessageid.message import MessageFactory
4
+
5
+ EEAMessageFactory = MessageFactory("eea")
6
+
7
+
8
+ def initialize(context):
9
+ """Initializer called when used as a Zope 2 product."""
@@ -1,4 +1,4 @@
1
- """ behavior module """
1
+ """behavior module"""
2
2
 
3
3
  import json
4
4
 
@@ -17,7 +17,7 @@ VIZ_SCHEMA = json.dumps({"type": "object", "properties": {}})
17
17
 
18
18
  @provider(IFormFieldProvider)
19
19
  class IPlotlyVisualization(model.Schema):
20
- """ A plotly visualization behavior provider """
20
+ """A plotly visualization behavior provider"""
21
21
 
22
22
  visualization = JSONField(
23
23
  title="Visualization", required=False, default={}, schema=VIZ_SCHEMA
@@ -0,0 +1 @@
1
+ """Browser"""
@@ -1,4 +1,5 @@
1
1
  """Control panel module"""
2
+
2
3
  from plone.app.registry.browser.controlpanel import ControlPanelFormWrapper
3
4
  from plone.app.registry.browser.controlpanel import RegistryEditForm
4
5
 
@@ -7,6 +8,7 @@ from eea.plotly.controlpanel import IPlotlySettings
7
8
 
8
9
  class PlotlyRegistryEditForm(RegistryEditForm):
9
10
  """Plotly Registry Edit Form"""
11
+
10
12
  schema = IPlotlySettings
11
13
  id = "plotly"
12
14
  label = "Plotly Settings"
@@ -14,4 +16,5 @@ class PlotlyRegistryEditForm(RegistryEditForm):
14
16
 
15
17
  class PlotlyControlPanelFormWrapper(ControlPanelFormWrapper):
16
18
  """Plotly Control Panel Form Wrapper"""
19
+
17
20
  form = PlotlyRegistryEditForm
@@ -15,12 +15,13 @@ from .preview_adapter.adapter import get_preview_adapter
15
15
 
16
16
 
17
17
  def deepUpdate(original, update):
18
- """ Recursively update a dictionary with another dictionary."""
18
+ """Recursively update a dictionary with another dictionary."""
19
19
  for key, value in update.items():
20
- if isinstance(
21
- value, dict) and key in original and isinstance(
22
- original[key],
23
- dict):
20
+ if (
21
+ isinstance(value, dict)
22
+ and key in original
23
+ and isinstance(original[key], dict)
24
+ ):
24
25
  deepUpdate(original[key], value)
25
26
  elif key in original:
26
27
  original[key] = value
@@ -44,17 +45,12 @@ class PlotlyPreview(BrowserView):
44
45
 
45
46
  if not self.visualization:
46
47
  self.request.response.setStatus(404)
47
- return {
48
- "message": "Visualization is not defined",
49
- "type": "NotFound"
50
- }
48
+ return {"message": "Visualization is not defined", "type": "NotFound"}
51
49
 
52
50
  if self.name:
53
51
  theme = None
54
52
  themes = api.portal.get_registry_record(
55
- "themes",
56
- interface=IPlotlySettings,
57
- default=[]
53
+ "themes", interface=IPlotlySettings, default=[]
58
54
  )
59
55
  for t in themes:
60
56
  if t.get("id") == self.name:
@@ -63,11 +59,10 @@ class PlotlyPreview(BrowserView):
63
59
  if theme and "layout" in self.visualization:
64
60
  data = theme.get("data", {})
65
61
  layout = theme.get("layout", {})
66
- for trIndex, tr in enumerate(
67
- self.visualization.get("data", [])):
62
+ for trIndex, tr in enumerate(self.visualization.get("data", [])):
68
63
  trType = tr.get("type", "")
69
64
  if trType in data:
70
- newTrIndex = min(trIndex, len(data[trType])-1)
65
+ newTrIndex = min(trIndex, len(data[trType]) - 1)
71
66
  newTr = data[trType][newTrIndex]
72
67
  deepUpdate(tr, newTr)
73
68
  deepUpdate(self.visualization["layout"], layout)
@@ -76,21 +71,17 @@ class PlotlyPreview(BrowserView):
76
71
  get_preview_adapter(self, self.name)
77
72
 
78
73
  fig = pio.from_json(
79
- json.dumps(self.visualization, cls=JSONEncoder),
80
- skip_invalid=True)
74
+ json.dumps(self.visualization, cls=JSONEncoder), skip_invalid=True
75
+ )
81
76
 
82
77
  if "template" not in self.visualization["layout"]:
83
78
  fig.update_layout(template=None)
84
79
 
85
- image = fig.to_image(
86
- format="svg", width=self.width, height=self.height)
80
+ image = fig.to_image(format="svg", width=self.width, height=self.height)
87
81
 
88
82
  sh = self.request.response.setHeader
89
83
 
90
- sh(
91
- "Content-Type",
92
- "image/svg+xml"
93
- )
84
+ sh("Content-Type", "image/svg+xml")
94
85
  sh("Content-Disposition", "inline; filename=%s.svg" % "x")
95
86
 
96
87
  return image
@@ -1,14 +1,12 @@
1
- """ Preview adapter for Plotly browser. """
1
+ """Preview adapter for Plotly browser."""
2
2
 
3
3
  adapters = {
4
- "soer_miniature": (
5
- "eea.plotly.browser.preview_adapter.soer_miniature.serialize"
6
- ),
4
+ "soer_miniature": ("eea.plotly.browser.preview_adapter.soer_miniature.serialize"),
7
5
  }
8
6
 
9
7
 
10
8
  def get_preview_adapter(context, name):
11
- """ Get the preview adapter for a given name.
9
+ """Get the preview adapter for a given name.
12
10
 
13
11
  Args:
14
12
  name (str): The name of the preview adapter.
@@ -1,4 +1,5 @@
1
- """ SOER miniature theme for Plotly visualizations. """
1
+ """SOER miniature theme for Plotly visualizations."""
2
+
2
3
  import math
3
4
 
4
5
  SOER_TRACES_COUNT = 5
@@ -36,7 +37,7 @@ def exact_step(vmin, vmax, target_ticks=5):
36
37
 
37
38
 
38
39
  def toFloat(v):
39
- """ Convert value to float """
40
+ """Convert value to float"""
40
41
  try:
41
42
  return float(v)
42
43
  except ValueError:
@@ -44,17 +45,17 @@ def toFloat(v):
44
45
 
45
46
 
46
47
  def getMin(arr):
47
- """ Get minimum value from array """
48
+ """Get minimum value from array"""
48
49
  return min(toFloat(v) for v in arr if v is not None)
49
50
 
50
51
 
51
52
  def getMax(arr):
52
- """ Get maximum value from array """
53
+ """Get maximum value from array"""
53
54
  return max(toFloat(v) for v in arr if v is not None)
54
55
 
55
56
 
56
57
  def serialize(context):
57
- """ Serialize the context for SOER miniature theme"""
58
+ """Serialize the context for SOER miniature theme"""
58
59
  if context.visualization is None:
59
60
  return False
60
61
 
@@ -62,8 +63,8 @@ def serialize(context):
62
63
  layout = context.visualization["layout"]
63
64
 
64
65
  top = (
65
- layout.get("margin", {}).get("t") or
66
- layout.get("template", {}).get("margin", {}).get("t")
66
+ layout.get("margin", {}).get("t")
67
+ or layout.get("template", {}).get("margin", {}).get("t")
67
68
  ) or 0
68
69
  nticks = max(int((context.height - top) / 100), 2)
69
70
 
@@ -89,7 +90,7 @@ def serialize(context):
89
90
  layout["template"]["layout"]["annotationdefaults"] = {
90
91
  "showarrow": False,
91
92
  "xref": "paper",
92
- "yref": "paper"
93
+ "yref": "paper",
93
94
  }
94
95
  return False
95
96
 
@@ -150,7 +151,7 @@ def serialize(context):
150
151
 
151
152
  if y4_len >= y_len:
152
153
  data[4]["x"] = new_x
153
- data[4]["y"] = data[4]["y"][y4_len - y_len:y4_len + 1]
154
+ data[4]["y"] = data[4]["y"][y4_len - y_len : y4_len + 1]
154
155
  elif data[4].get("x") is None or data[4].get("y") is None:
155
156
  data[4] = {
156
157
  "type": "scatter",
@@ -159,24 +160,21 @@ def serialize(context):
159
160
  "visible": True,
160
161
  "marker": {
161
162
  "color": "rgba(0, 0, 0, 1)",
162
- "line": {
163
- "color": "rgba(0, 0, 0, 1)"
164
- }
165
- }
163
+ "line": {"color": "rgba(0, 0, 0, 1)"},
164
+ },
166
165
  }
167
166
  data[4]["y"][len(data[4]["y"]) - 1] = new_y[-1]
168
167
 
169
168
  layout["xaxis"]["tickmode"] = "array"
170
169
  layout["xaxis"]["tickvals"] = [min_year, max_year, 2030]
171
- layout["xaxis"]["range"] = [
172
- min_year - 2, 2032]
170
+ layout["xaxis"]["range"] = [min_year - 2, 2032]
173
171
  layout["xaxis"]["autorange"] = True
174
172
 
175
173
  y_values = (
176
- (data[0].get("y") or []) +
177
- (data[1].get("y") or []) +
178
- (data[4].get("y") or []) +
179
- ((trace_6.get("y") or []) if trace_6 else [])
174
+ (data[0].get("y") or [])
175
+ + (data[1].get("y") or [])
176
+ + (data[4].get("y") or [])
177
+ + ((trace_6.get("y") or []) if trace_6 else [])
180
178
  )
181
179
 
182
180
  if y_values:
@@ -193,14 +191,11 @@ def serialize(context):
193
191
  layout["yaxis"]["tick0"] = min_y - step
194
192
  layout["yaxis"]["dtick"] = step
195
193
 
196
- layout["yaxis"]["range"] = [
197
- min_y - step, max_y + 2 * step]
194
+ layout["yaxis"]["range"] = [min_y - step, max_y + 2 * step]
198
195
  layout["yaxis"]["autorange"] = False
199
196
 
200
197
  if "text" in data[0]:
201
- data[0]["text"] = [
202
- (t if t is None else " " + str(t))
203
- for t in data[0]["text"]]
198
+ data[0]["text"] = [(t if t is None else " " + str(t)) for t in data[0]["text"]]
204
199
 
205
200
  data[1]["x"] = None
206
201
  data[1]["y"] = None
@@ -1,4 +1,5 @@
1
1
  """Plotly Controlpanel API"""
2
+
2
3
  import json
3
4
  from zope.interface import Interface
4
5
  from zope.component import adapter
@@ -7,58 +8,45 @@ from plone.restapi.controlpanels import RegistryConfigletPanel
7
8
  from eea.plotly.interfaces import IPlotlyLayer
8
9
  from eea.plotly import EEAMessageFactory as _
9
10
 
10
- TEMPLATES_SCHEMA = json.dumps({
11
- "type": "array",
12
- "items": {
13
- "type": "object",
14
- "properties": {}
15
- }
16
- })
11
+ TEMPLATES_SCHEMA = json.dumps(
12
+ {"type": "array", "items": {"type": "object", "properties": {}}}
13
+ )
17
14
 
18
- THEMES_SCHEMA = json.dumps({
19
- "type": "array",
20
- "items": {
21
- "type": "object",
22
- "properties": {}
23
- }
24
- })
15
+ THEMES_SCHEMA = json.dumps(
16
+ {"type": "array", "items": {"type": "object", "properties": {}}}
17
+ )
25
18
 
26
19
 
27
20
  class IPlotlySettings(Interface):
28
21
  """Client settings for EEA Plotly."""
22
+
29
23
  themes = JSONField(
30
- title=_(u"Themes"),
31
- description=_(
32
- u"The JSON representation of plotly themes."
33
- ),
24
+ title=_("Themes"),
25
+ description=_("The JSON representation of plotly themes."),
34
26
  schema=THEMES_SCHEMA,
35
27
  default=[],
36
28
  widget="plotly_themes",
37
- required=False
29
+ required=False,
38
30
  )
39
31
 
40
32
  templates = JSONField(
41
- title=_(u"Templates"),
42
- description=_(
43
- u"The JSON representation of plotly templates."
44
- ),
33
+ title=_("Templates"),
34
+ description=_("The JSON representation of plotly templates."),
45
35
  schema=TEMPLATES_SCHEMA,
46
36
  default=[],
47
37
  widget="plotly_templates",
48
- required=False
38
+ required=False,
49
39
  )
50
40
 
51
41
 
52
42
  @adapter(Interface, IPlotlyLayer)
53
43
  class PlotlyControlpanel(RegistryConfigletPanel):
54
44
  """Plotly Control Panel"""
45
+
55
46
  schema = IPlotlySettings
56
47
  schema_prefix = None
57
48
  configlet_id = "plotly"
58
49
  configlet_category_id = "Products"
59
50
  title = "Plotly Settings"
60
51
  group = "Products"
61
- data = {
62
- "themes": [],
63
- "templates": []
64
- }
52
+ data = {"themes": [], "templates": []}
@@ -1,4 +1,4 @@
1
- """ block-related utils """
1
+ """block-related utils"""
2
2
 
3
3
  from plone.restapi.behaviors import IBlocks
4
4
  from plone.restapi.interfaces import IBlockFieldDeserializationTransformer
@@ -22,11 +22,11 @@ class EmbedVisualizationDeserializationTransformer:
22
22
  self.request = request
23
23
 
24
24
  def __call__(self, value):
25
- delProperty(value, 'visualization')
26
- delProperty(value, 'properties')
27
- delProperty(value, 'image_scales')
28
- if 'vis_url' in value:
29
- value['vis_url'] = path2uid(
30
- context=self.context, link=getLink(value['vis_url'])
25
+ delProperty(value, "visualization")
26
+ delProperty(value, "properties")
27
+ delProperty(value, "image_scales")
28
+ if "vis_url" in value:
29
+ value["vis_url"] = path2uid(
30
+ context=self.context, link=getLink(value["vis_url"])
31
31
  )
32
32
  return value
@@ -1,4 +1,5 @@
1
- """ Deserialize Plotly visualization from JSON """
1
+ """Deserialize Plotly visualization from JSON"""
2
+
2
3
  from io import StringIO
3
4
  import json
4
5
  import plotly.io as pio
@@ -18,7 +19,7 @@ from eea.plotly.io_json import JSONEncoder
18
19
  @implementer(IDeserializeFromJson)
19
20
  @adapter(IPlotlyVisualization, Interface)
20
21
  class DeserializeVisualizationFromJson(DeserializeFromJson):
21
- """ Deserialize Plotly visualization from JSON """
22
+ """Deserialize Plotly visualization from JSON"""
22
23
 
23
24
  def jsonToBinary(self, data):
24
25
  """Convert JSON data to binary"""
@@ -50,34 +51,29 @@ class DeserializeVisualizationFromJson(DeserializeFromJson):
50
51
 
51
52
  CsvWriter(output).writerows(rows)
52
53
 
53
- return output.getvalue().encode('utf-8')
54
+ return output.getvalue().encode("utf-8")
54
55
 
55
56
  def __call__(
56
- self, validate_all=False, data=None, create=False,
57
- mask_validation_errors=True):
58
-
59
- super().__call__(
60
- validate_all, data, create, mask_validation_errors
61
- )
57
+ self, validate_all=False, data=None, create=False, mask_validation_errors=True
58
+ ):
59
+ super().__call__(validate_all, data, create, mask_validation_errors)
62
60
 
63
61
  ok = False
64
62
  for interface, names in self.modified.items():
65
- if (interface == IPlotlyVisualization and
66
- "IPlotlyVisualization.visualization" in names):
63
+ if (
64
+ interface == IPlotlyVisualization
65
+ and "IPlotlyVisualization.visualization" in names
66
+ ):
67
67
  ok = True
68
68
  break
69
69
 
70
70
  if not ok:
71
71
  return self.context
72
72
 
73
- data = self.jsonToBinary(self.context.visualization.get(
74
- "dataSources", {})
75
- )
73
+ data = self.jsonToBinary(self.context.visualization.get("dataSources", {}))
76
74
 
77
75
  self.context.file = NamedBlobFile(
78
- data=data if data else b"",
79
- filename="data.csv",
80
- contentType="text/csv"
76
+ data=data if data else b"", filename="data.csv", contentType="text/csv"
81
77
  )
82
78
 
83
79
  if "dataSources" in self.context.visualization:
@@ -89,28 +85,27 @@ class DeserializeVisualizationFromJson(DeserializeFromJson):
89
85
  Attributes(
90
86
  IPlotlyVisualization,
91
87
  "IPlotlyVisualization.visualization",
92
- "IPlotlyVisualization.file"
88
+ "IPlotlyVisualization.file",
93
89
  )
94
90
  )
95
91
  notify(ObjectModifiedEvent(self.context, *modified))
96
92
 
97
93
  # Handle preview image
98
94
  fig = pio.from_json(
99
- json.dumps({
100
- "data": self.context.visualization.get("data", []),
101
- "layout": self.context.visualization.get("layout", {}),
102
- "frames": self.context.visualization.get("frames", [])
103
- },
104
- cls=JSONEncoder
95
+ json.dumps(
96
+ {
97
+ "data": self.context.visualization.get("data", []),
98
+ "layout": self.context.visualization.get("layout", {}),
99
+ "frames": self.context.visualization.get("frames", []),
100
+ },
101
+ cls=JSONEncoder,
105
102
  ),
106
- skip_invalid=True
103
+ skip_invalid=True,
107
104
  )
108
105
 
109
106
  image = fig.to_image(format="svg", width=1200, height=900)
110
107
  self.context.preview_image = NamedBlobImage(
111
- data=image,
112
- filename="preview.svg",
113
- contentType="image/svg+xml"
108
+ data=image, filename="preview.svg", contentType="image/svg+xml"
114
109
  )
115
110
 
116
111
  return self.context
@@ -1,4 +1,4 @@
1
- """ dxfields deserializers """
1
+ """dxfields deserializers"""
2
2
 
3
3
  from zope.component import adapter
4
4
  from zope.interface import implementer
@@ -19,10 +19,8 @@ class VisualizationFieldDeserializer(DefaultFieldDeserializer):
19
19
  def __call__(self, value):
20
20
  value = sanitizeVisualization(value)
21
21
 
22
- if 'provider_url' in value:
22
+ if "provider_url" in value:
23
23
  url = value["provider_url"]
24
- value["provider_url"] = path2uid(
25
- context=self.context, link=getLink(url)
26
- )
24
+ value["provider_url"] = path2uid(context=self.context, link=getLink(url))
27
25
 
28
26
  return value
@@ -1,19 +1,20 @@
1
1
  """Module where all interfaces, events and exceptions live."""
2
+
2
3
  from zope.interface import Interface
3
4
  from zope.publisher.interfaces.browser import IDefaultBrowserLayer
4
5
 
5
6
 
6
7
  class IPlotlyLayer(IDefaultBrowserLayer):
7
- """ Marker interface that defines a browser layer. """
8
+ """Marker interface that defines a browser layer."""
8
9
 
9
10
 
10
11
  class IPlotlyVisualizationField(Interface):
11
- """ Marker interface for plotly visualization JSON field """
12
+ """Marker interface for plotly visualization JSON field"""
12
13
 
13
14
 
14
15
  class IPlotlyFileField(Interface):
15
- """ Marker interface for plotly file field """
16
+ """Marker interface for plotly file field"""
16
17
 
17
18
 
18
19
  class IPlotlyVisualization(Interface):
19
- """ Marker interface for plotly visualization """
20
+ """Marker interface for plotly visualization"""
@@ -1,6 +1,8 @@
1
1
  """CSV reader/writer that handles NULL values."""
2
+
2
3
  import csv
3
- NULL = 'NULL'
4
+
5
+ NULL = "NULL"
4
6
 
5
7
 
6
8
  class CsvWriter:
@@ -15,10 +17,7 @@ class CsvWriter:
15
17
 
16
18
  def writerow(self, row):
17
19
  """Write a single row to the CSV file."""
18
- self.csv_writer.writerow(
19
- [item if item is not None else NULL
20
- for item in row]
21
- )
20
+ self.csv_writer.writerow([item if item is not None else NULL for item in row])
22
21
 
23
22
  def writerows(self, rows):
24
23
  """Write multiple rows to the CSV file."""
@@ -31,10 +30,10 @@ class CsvReader:
31
30
 
32
31
  def __init__(self, *args, **kwrds):
33
32
  try:
34
- inputEntity = args[0] or kwrds.get('csvfile')
33
+ inputEntity = args[0] or kwrds.get("csvfile")
35
34
  sample = inputEntity.read(1024)
36
35
  inputEntity.seek(0)
37
- dialect = csv.Sniffer().sniff(sample, delimiters=',;\t|')
36
+ dialect = csv.Sniffer().sniff(sample, delimiters=",;\t|")
38
37
  except (csv.Error, TypeError):
39
38
  # No dialect found, use default
40
39
  dialect = csv.excel
@@ -1,4 +1,5 @@
1
1
  """JSON encoder that handles Decimal values."""
2
+
2
3
  import decimal
3
4
  import json
4
5
 
@@ -0,0 +1 @@
1
+ """i18n"""
@@ -0,0 +1 @@
1
+ """Restapi"""
@@ -1,4 +1,5 @@
1
1
  """RestAPI enpoint @plotly GET"""
2
+
2
3
  from plone import api
3
4
  from plone.restapi.services import Service
4
5
  from zope.interface import implementer
@@ -15,27 +16,18 @@ class PlotlySettingsGet(Service):
15
16
  def reply(self):
16
17
  """Reply"""
17
18
  if not IPlotlyLayer.providedBy(self.request):
18
- return {
19
- "themes": [],
20
- "templates": []
21
- }
19
+ return {"themes": [], "templates": []}
22
20
 
23
21
  themes = api.portal.get_registry_record(
24
- "themes",
25
- interface=IPlotlySettings,
26
- default=[]
22
+ "themes", interface=IPlotlySettings, default=[]
27
23
  )
28
24
 
29
25
  templates = api.portal.get_registry_record(
30
- "templates",
31
- interface=IPlotlySettings,
32
- default=[]
26
+ "templates", interface=IPlotlySettings, default=[]
33
27
  )
34
28
 
35
29
  for template in templates:
36
- layout = template.get(
37
- "visualization", {}).get(
38
- "layout", None)
30
+ layout = template.get("visualization", {}).get("layout", None)
39
31
  if layout:
40
32
  themeId = layout.get("template", {}).get("id", None)
41
33
  if not themeId and themes:
@@ -45,7 +37,4 @@ class PlotlySettingsGet(Service):
45
37
  if theme.get("id") == themeId:
46
38
  layout["template"] = theme
47
39
 
48
- return {
49
- "themes": themes,
50
- "templates": templates
51
- }
40
+ return {"themes": themes, "templates": templates}