lino 25.8.3__py3-none-any.whl → 25.9.0__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 (61) hide show
  1. lino/__init__.py +1 -1
  2. lino/api/dd.py +0 -1
  3. lino/core/__init__.py +0 -1
  4. lino/core/actions.py +1 -1
  5. lino/core/actors.py +8 -0
  6. lino/core/elems.py +1 -1
  7. lino/core/fields.py +4 -1
  8. lino/core/model.py +2 -11
  9. lino/core/requests.py +8 -7
  10. lino/core/site.py +0 -79
  11. lino/core/user_types.py +1 -10
  12. lino/help_texts.py +1 -5
  13. lino/management/commands/initdb.py +0 -3
  14. lino/modlib/__init__.py +0 -1
  15. lino/modlib/bootstrap5/README.txt +1 -1
  16. lino/modlib/bootstrap5/__init__.py +34 -38
  17. lino/modlib/bootstrap5/config/bootstrap5/base.html +4 -0
  18. lino/modlib/bootstrap5/models.py +23 -23
  19. lino/modlib/bootstrap5/views.py +2 -107
  20. lino/modlib/checkdata/choicelists.py +1 -1
  21. lino/modlib/comments/fixtures/demo2.py +1 -0
  22. lino/modlib/comments/ui.py +7 -7
  23. lino/modlib/extjs/__init__.py +2 -4
  24. lino/modlib/extjs/config/extjs/index.html +1 -1
  25. lino/modlib/extjs/ext_renderer.py +1 -7
  26. lino/modlib/extjs/views.py +2 -0
  27. lino/modlib/help/models.py +1 -12
  28. lino/modlib/linod/mixins.py +3 -2
  29. lino/modlib/memo/__init__.py +10 -9
  30. lino/modlib/memo/mixins.py +38 -21
  31. lino/modlib/memo/models.py +10 -7
  32. lino/modlib/memo/parser.py +3 -1
  33. lino/modlib/notify/models.py +6 -9
  34. lino/modlib/publisher/__init__.py +12 -7
  35. lino/modlib/publisher/choicelists.py +9 -64
  36. lino/modlib/publisher/config/publisher/page.pub.html +73 -7
  37. lino/modlib/publisher/fixtures/std.py +14 -1
  38. lino/modlib/publisher/mixins.py +41 -12
  39. lino/modlib/publisher/models.py +74 -75
  40. lino/modlib/publisher/renderer.py +28 -12
  41. lino/modlib/publisher/ui.py +35 -35
  42. lino/modlib/publisher/views.py +59 -24
  43. lino/modlib/system/models.py +3 -2
  44. lino/modlib/uploads/__init__.py +1 -0
  45. lino/modlib/uploads/mixins.py +2 -2
  46. lino/modlib/uploads/models.py +55 -21
  47. lino/modlib/uploads/ui.py +1 -0
  48. lino/modlib/uploads/utils.py +2 -2
  49. lino/modlib/users/__init__.py +2 -3
  50. lino/modlib/users/actions.py +12 -17
  51. lino/modlib/users/models.py +37 -36
  52. lino/modlib/weasyprint/choicelists.py +6 -0
  53. lino/utils/diag.py +5 -3
  54. lino/utils/html.py +103 -0
  55. lino/utils/mldbc/mixins.py +2 -2
  56. lino/utils/soup.py +16 -8
  57. {lino-25.8.3.dist-info → lino-25.9.0.dist-info}/METADATA +1 -1
  58. {lino-25.8.3.dist-info → lino-25.9.0.dist-info}/RECORD +61 -61
  59. {lino-25.8.3.dist-info → lino-25.9.0.dist-info}/WHEEL +0 -0
  60. {lino-25.8.3.dist-info → lino-25.9.0.dist-info}/licenses/AUTHORS.rst +0 -0
  61. {lino-25.8.3.dist-info → lino-25.9.0.dist-info}/licenses/COPYING +0 -0
@@ -2,7 +2,6 @@
2
2
  # Copyright 2013-2023 Rumma & Ko Ltd
3
3
  # License: GNU Affero General Public License v3 (see file COPYING for details)
4
4
 
5
- from lino.modlib.publisher.choicelists import PageFillers
6
5
  from django.contrib.humanize.templatetags.humanize import naturaltime
7
6
  from django.contrib.contenttypes.models import ContentType
8
7
  from django.db import models
@@ -66,18 +65,22 @@ class CommentDetail(dd.DetailLayout):
66
65
 
67
66
  more = dd.Panel(
68
67
  """
69
- #body more2
68
+ more1 more2
70
69
  """,
71
70
  label=_("More"),
72
71
  )
73
72
 
74
- more2 = """
73
+ more1 = """
75
74
  id user group
76
75
  owner_type owner_id
77
- created modified
78
76
  comment_type
79
77
  ReactionsByComment
80
78
  """
79
+ more2 = """
80
+ created modified
81
+ memo.MentionsByTarget
82
+ memo.MentionsByOwner
83
+ """
81
84
 
82
85
 
83
86
  class Comments(dd.Table):
@@ -314,6 +317,3 @@ class Reactions(dd.Table):
314
317
  class ReactionsByComment(Reactions):
315
318
  master_key = "comment"
316
319
  default_display_modes = {None: constants.DISPLAY_MODE_SUMMARY}
317
-
318
-
319
- PageFillers.add_item(RecentComments)
@@ -28,7 +28,8 @@ from django.utils.translation import gettext_lazy as _
28
28
  class Plugin(Plugin):
29
29
  """Extends :class:`lino.core.plugin.Plugin`."""
30
30
 
31
- needs_plugins = ["lino.modlib.bootstrap5"]
31
+ # needs_plugins = ["lino.modlib.bootstrap5"]
32
+ needs_plugins = ["lino.modlib.jinja"]
32
33
 
33
34
  enter_submits_form = False
34
35
  """Whether the :kbd:`ENTER` key (or :kbd:`CTRL+ENTER` when in a
@@ -216,9 +217,6 @@ class Plugin(Plugin):
216
217
  from django.urls import re_path as url
217
218
  from . import views
218
219
 
219
- # if self.site.developer_site_cache:
220
- # self.renderer.build_site_cache()
221
-
222
220
  rx = "^"
223
221
 
224
222
  urlpatterns = [
@@ -130,7 +130,7 @@
130
130
  {{ ln }}{% endfor -%}
131
131
  {%- endfor -%}
132
132
  {# Main Lino js code #}
133
- {{ javascript(site.build_site_cache_url(*ext_renderer.lino_js_parts())) }}
133
+ {{ javascript(site.build_media_url(*ext_renderer.lino_js_parts())) }}
134
134
  {# javascript(site.buildurl('linolib.js')) #}
135
135
  {# ###### OnReady JS code ###### #}
136
136
  <script type="text/javascript">
@@ -420,10 +420,7 @@ class ExtRenderer(JsCacheRenderer):
420
420
  user = request.subst_user
421
421
 
422
422
  def getit():
423
- if (
424
- settings.SITE.developer_site_cache
425
- and not settings.SITE.never_build_site_cache
426
- ):
423
+ if settings.SITE.developer_site_cache:
427
424
  self.build_js_cache(False)
428
425
 
429
426
  # Render template
@@ -1478,9 +1475,6 @@ class ExtRenderer(JsCacheRenderer):
1478
1475
  )
1479
1476
  yield "LANGUAGE_CHOICES = %s;" % py2js(list(settings.SITE.LANGUAGE_CHOICES))
1480
1477
  yield "MEDIA_URL = %s;" % py2js(settings.SITE.build_media_url())
1481
- # if settings.SITE.never_build_site_cache:
1482
- # yield "GEN_TIMESTAMP = '%s';" % settings.SITE.kernel.lino_version
1483
- # else:
1484
1478
  yield "GEN_TIMESTAMP = %s;" % py2js(settings.SITE.kernel.lino_version)
1485
1479
 
1486
1480
  return "\n".join(fn())
@@ -597,11 +597,13 @@ class ApiList(View):
597
597
 
598
598
  if True:
599
599
  kw.update(title=str(ar.get_title()))
600
+ # kw.update(title=str(ar.get_breadcrumbs()))
600
601
  else:
601
602
  # 20190704 work in progress.
602
603
  # add open_in_own_window button after title of slave panel
603
604
  kw.update(
604
605
  title=str(ar.get_title())
606
+ # title=str(ar.get_breadcrumbs())
605
607
  + " "
606
608
  + tostring(ar.open_in_own_window_button())
607
609
  )
@@ -28,17 +28,6 @@ class OpenHelpWindow(dd.Action):
28
28
  help_text = _("Open Help Window")
29
29
  show_in_plain = True
30
30
 
31
- # def js_handler(self, actor):
32
- # parts = ['cache', 'help']
33
- # if get_language() != settings.SITE.DEFAULT_LANGUAGE.django_code:
34
- # parts.append(get_language())
35
- # parts.append(str(actor) + ".html")
36
- # url = settings.SITE.build_site_cache_url(*parts)
37
- # # return "let _ = window.open('%s');" % url
38
- # # return "() => window.open('%s')" % url
39
- # return "function (){window.open('%s')}" % url
40
- # # return "window.open('%s')" % url
41
-
42
31
  def run_from_ui(self, ar, **kwargs):
43
32
  # print("20210612")
44
33
  parts = ["cache", "help"]
@@ -46,7 +35,7 @@ class OpenHelpWindow(dd.Action):
46
35
  parts.append(get_language())
47
36
  parts.append(str(ar.actor) + ".html")
48
37
  # parts.append("index.html")
49
- url = settings.SITE.build_site_cache_url(*parts)
38
+ url = settings.SITE.build_media_url(*parts)
50
39
  ar.set_response(success=True)
51
40
  ar.success(open_url=url)
52
41
 
@@ -179,10 +179,11 @@ class Runnable(Sequenced, RecurrenceSet):
179
179
  await ar.adebug("Terminated %s with warning %s", self, str(e))
180
180
  self.message = out.getvalue()
181
181
  except Exception as e:
182
+ tb = "".join(traceback.format_exception(e))
182
183
  self.message = out.getvalue()
183
- self.message += "\n" + "".join(traceback.format_exception(e))
184
+ self.message += "\n" + tb
184
185
  self.disabled = True
185
- await ar.awarning("Disabled %s after exception %s", self, e)
186
+ await ar.awarning("Disabled %s after exception:\n%s", self, tb)
186
187
  # ar.warning("Disabled %s after exception %s", astr(self), e)
187
188
  # now = await sync_to_async(dd.now)()
188
189
  self.last_end_time = timezone.now()
@@ -1,4 +1,4 @@
1
- # Copyright 2008-2023 Rumma & Ko Ltd
1
+ # Copyright 2008-2025 Rumma & Ko Ltd
2
2
  # License: GNU Affero General Public License v3 (see file COPYING for details)
3
3
  """See :doc:`/specs/memo`.
4
4
 
@@ -15,6 +15,7 @@ Adds functionality for using memo commands in your text fields.
15
15
  # from importlib import import_module
16
16
  # from rstgen.utils import py2url_txt
17
17
  from lino.api import ad
18
+ from lino.core import constants
18
19
  from .parser import Parser, split_name_rest
19
20
  from lino.utils.html import tostring
20
21
 
@@ -94,20 +95,20 @@ class Plugin(ad.Plugin):
94
95
  kwargs = dict() # , nosummary=True)
95
96
  dv = self.site.models.resolve(s)
96
97
  sar = dv.create_request(parent=ar, limit=dv.preview_limit)
97
- rv = ""
98
- # rv += "20230325 [show {}]".format(dv)
99
- for e in sar.renderer.table2story(sar, **kwargs):
100
- rv += tostring(e)
101
- return rv
98
+ return sar.show(**kwargs)
99
+ # kwargs.update(display_mode=constants.DISPLAY_MODE_STORY)
100
+ # return sar.show_story(**kwargs)
101
+ # rv = ""
102
+ # # rv += "20230325 [show {}]".format(dv)
103
+ # for e in sar.renderer.table2story(sar, **kwargs):
104
+ # rv += tostring(e)
105
+ # return rv
102
106
 
103
107
  self.parser.register_command("show", show2html)
104
108
 
105
109
  if False:
106
110
  # letting website users execute arbitrary code is a security risk
107
111
  def eval2html(ar, s, cmdname, mentions, context):
108
- from django.conf import settings # context of exec command
109
-
110
- sar = ar.spawn_request(renderer=settings.SITE.kernel.html_renderer)
111
112
  return eval(compile(s, cmdname, "eval"))
112
113
 
113
114
  self.parser.register_command("eval", eval2html)
@@ -1,7 +1,9 @@
1
1
  # -*- coding: UTF-8 -*-
2
- # Copyright 2016-2024 Rumma & Ko Ltd
2
+ # Copyright 2016-2025 Rumma & Ko Ltd
3
3
  # License: GNU Affero General Public License v3 (see file COPYING for details)
4
4
 
5
+ # import difflib
6
+ # import sys
5
7
  from lxml.html import fragments_fromstring
6
8
  import lxml
7
9
 
@@ -19,6 +21,7 @@ from lino.core.fields import RichTextField, PreviewTextField
19
21
  from lino.utils.html import E, tostring, mark_safe
20
22
  from lino.utils.restify import restify
21
23
  from lino.utils.soup import truncate_comment
24
+ from lino.utils.soup import MORE_MARKER
22
25
  from lino.utils.mldbc.fields import BabelTextField
23
26
  from lino.modlib.checkdata.choicelists import Checker
24
27
  from lino.api import rt, dd, _
@@ -130,6 +133,7 @@ class MemoReferrable(dd.Model):
130
133
 
131
134
  # class BasePreviewable(MentionGenerator):
132
135
  class BasePreviewable(dd.Model):
136
+
133
137
  class Meta:
134
138
  abstract = True
135
139
 
@@ -138,12 +142,13 @@ class BasePreviewable(dd.Model):
138
142
  def get_preview_length(self):
139
143
  return settings.SITE.plugins.memo.short_preview_length
140
144
 
145
+ # def after_ui_save(self, ar, watcher):
141
146
  def save(self, *args, **kwargs):
142
147
  """Updates the preview fields and the list of mentioned objects."""
143
- pf = self.previewable_field
144
148
  mentions = set()
149
+ pf = self.previewable_field
145
150
  txt = self.get_previewable_text(settings.SITE.DEFAULT_LANGUAGE)
146
- short, full = self.parse_previews(txt, None, mentions)
151
+ short, full = self.parse_previews(txt, None, mentions, True)
147
152
  # if "choose one or the other" in short:
148
153
  # raise Exception("20230928 {} {}".format(len(short), short))
149
154
  # print("20231023 b", short)
@@ -154,23 +159,30 @@ class BasePreviewable(dd.Model):
154
159
  src = self.get_previewable_text(lng)
155
160
  # src = getattr(self, pf + lng.suffix)
156
161
  with translation.override(lng.django_code):
157
- short, full = self.parse_previews(src, None, mentions)
162
+ short, full = self.parse_previews(src, None, mentions, True)
158
163
  setattr(self, pf + "_short_preview" + lng.suffix, short)
159
164
  setattr(self, pf + "_full_preview" + lng.suffix, full)
165
+
166
+ # self.save() # yes this causes a second save()
160
167
  super().save(*args, **kwargs)
168
+ # super().after_ui_save(ar, watcher)
161
169
  self.synchronize_mentions(mentions)
162
170
 
163
171
  def get_previewable_text(self, lng):
164
172
  return getattr(self, self.previewable_field + lng.suffix)
165
173
 
166
- def parse_previews(self, source, ar=None, mentions=None, **context):
174
+ def parse_previews(
175
+ self, source, ar=None, mentions=None, save=False, **context):
167
176
  context.update(self=self)
168
177
  full = settings.SITE.plugins.memo.parser.parse(
169
- source, ar=ar, context=context, mentions=mentions
170
- )
171
- short = truncate_comment(full, self.get_preview_length())
172
- if not full.startswith("<"):
173
- if settings.SITE.plugins.memo.use_markup:
178
+ source, ar=ar, mentions=mentions, context=context)
179
+ short = truncate_comment(
180
+ full, self.get_preview_length(),
181
+ ar=ar, save=save, mentions=mentions)
182
+ if len(chunks := full.split(MORE_MARKER, 1)) == 2:
183
+ full = " ".join(chunks)
184
+ if settings.SITE.plugins.memo.use_markup:
185
+ if not full.startswith("<"):
174
186
  full = markdown.markdown(full, **MARKDOWNCFG)
175
187
  return (short, full)
176
188
 
@@ -201,7 +213,7 @@ class BasePreviewable(dd.Model):
201
213
  for e in lxml.html.fragments_fromstring(self.body_short_preview):
202
214
  yield e
203
215
  except Exception as e:
204
- yield "{} [{}]".format(self.body_short_preview, e)
216
+ yield f"{self.body_short_preview} [{e}]"
205
217
 
206
218
 
207
219
  class Previewable(BasePreviewable):
@@ -218,20 +230,21 @@ class Previewable(BasePreviewable):
218
230
 
219
231
  def get_body_parsed(self, ar, short=False):
220
232
  if ar.renderer is settings.SITE.kernel.editing_front_end.renderer:
221
- return self.body_short_preview if short else self.body_full_preview
233
+ return mark_safe(
234
+ self.body_short_preview if short else self.body_full_preview)
222
235
  # raise Exception("{} is not {}".format(
223
236
  # ar.renderer, settings.SITE.kernel.editing_front_end.renderer))
224
237
  src = self.body
225
- s, f = self.parse_previews(src, ar, set())
226
- return s if short else f
238
+ s, f = self.parse_previews(src, ar, None, False)
239
+ return mark_safe(s if short else f)
227
240
 
228
241
  def as_paragraph(self, ar):
229
242
  s = super().as_paragraph(ar)
230
243
  # s = format_html("<b>{}</b> : {}", .format(ar.add_detail_link(self, str(self)))
231
244
  # s = ar.obj2htmls(self)
232
245
  s = format_html(
233
- "<b>{}</b> : {}", s, mark_safe(self.body_short_preview) or _("(no preview)")
234
- )
246
+ "<b>{}</b> : {}",
247
+ s, mark_safe(self.body_short_preview) or _("(no preview)"))
235
248
  return s
236
249
 
237
250
 
@@ -267,13 +280,16 @@ class PreviewableChecker(Checker):
267
280
  pf = obj.previewable_field
268
281
  # src = getattr(obj, pf+suffix)
269
282
  expected_mentions = set()
270
- short, full = obj.parse_previews(src, None, expected_mentions)
283
+ short, full = obj.parse_previews(src, None, expected_mentions, False)
271
284
  is_broken = False
272
- if (
273
- getattr(obj, pf + "_short_preview" + lng.suffix) != short
274
- or getattr(obj, pf + "_full_preview" + lng.suffix) != full
275
- ):
285
+ stored_short = getattr(obj, pf + "_short_preview" + lng.suffix)
286
+ stored_full = getattr(obj, pf + "_full_preview" + lng.suffix)
287
+ if stored_short != short or stored_full != full:
276
288
  yield (True, _("Preview differs from source."))
289
+ # print(f"20250908 found_full is {stored_full}, to expected: {full}")
290
+ # # print("20250908 found_full to expected_full:")
291
+ # sys.stdout.writelines(difflib.unified_diff(
292
+ # stored_full.splitlines(), full.splitlines()))
277
293
  is_broken = True
278
294
  found_mentions = set([obj.target for obj in obj.get_saved_mentions()])
279
295
  if expected_mentions != found_mentions:
@@ -284,6 +300,7 @@ class PreviewableChecker(Checker):
284
300
  # setattr(obj, pf+'_full_preview'+suffix, full)
285
301
  obj.full_clean()
286
302
  obj.save()
303
+ # obj.after_ui_save(ar, None)
287
304
  # self.synchronize_mentions(mentions)
288
305
 
289
306
  def get_checkdata_problems(self, ar, obj, fix=False):
@@ -23,7 +23,8 @@ target_label = _("Target")
23
23
 
24
24
 
25
25
  class Mention(Controllable):
26
- class Meta(object):
26
+
27
+ class Meta:
27
28
  app_label = "memo"
28
29
  abstract = dd.is_abstract_model(__name__, "Mention")
29
30
  verbose_name = _("Mention")
@@ -85,12 +86,14 @@ class Mentions(dd.Table):
85
86
  # id comment owner created
86
87
  # """
87
88
 
88
- # Not used because when you are on the owner, you can see the mentions in the memo text
89
- # class MentionsByOwner(Mentions):
90
- # label = _("Mentions")
91
- # master_key = "owner"
92
- # column_names = "target *"
93
- # default_display_modes = {None: constants.DISPLAY_MODE_SUMMARY}
89
+
90
+ class MentionsByOwner(Mentions):
91
+ # Not much used because when you are on the owner, you can see the mentions
92
+ # in the memo text
93
+ label = _("Mentions")
94
+ master_key = "owner"
95
+ column_names = "target *"
96
+ default_display_modes = {None: constants.DISPLAY_MODE_SUMMARY}
94
97
 
95
98
 
96
99
  class MentionsByTarget(Mentions):
@@ -19,7 +19,7 @@ from django.conf import settings
19
19
  from lino import logger
20
20
 
21
21
  import re
22
- import inspect
22
+ import traceback
23
23
  from typing import Callable, Any
24
24
 
25
25
  from bs4 import BeautifulSoup, MarkupResemblesLocatorWarning
@@ -313,6 +313,8 @@ All remaining arguments are used as the text of the link.
313
313
  mo.end(),
314
314
  )
315
315
  # logger.debug(msg)
316
+ # print(msg, ":")
317
+ # traceback.print_exc()
316
318
  return msg
317
319
 
318
320
  def parse_suggestions(self, src):
@@ -519,13 +519,10 @@ if remove_after:
519
519
  # "You do not have a working installation of the service_identity module: .* Many valid certificate/hostname mappings may be rejected.",
520
520
  # UserWarning)
521
521
 
522
+ if dd.get_plugin_setting("linod", "use_channels", False):
522
523
 
523
- @dd.receiver(dd.post_ui_save)
524
- def notify_panels(sender, instance, ar=None, **kwargs):
525
- if (
526
- not dd.get_plugin_setting("linod", "use_channels", False)
527
- or not instance.updatable_panels
528
- ):
529
- return
530
- data = get_updatables(instance, ar)
531
- send_panel_update(data)
524
+ @dd.receiver(dd.post_ui_save)
525
+ def notify_panels(sender, instance, ar=None, **kwargs):
526
+ if instance.updatable_panels:
527
+ data = get_updatables(instance, ar)
528
+ send_panel_update(data)
@@ -10,7 +10,7 @@ class Plugin(Plugin):
10
10
  "lino.modlib.system", # 'lino.modlib.memo',
11
11
  "lino.modlib.linod",
12
12
  "lino.modlib.jinja",
13
- "lino.modlib.bootstrap5",
13
+ "lino.modlib.bootstrap5"
14
14
  ]
15
15
  locations: list[tuple[str, str]] = []
16
16
 
@@ -53,8 +53,17 @@ class Plugin(Plugin):
53
53
  # Only if this is the primary front end:
54
54
  if self.site.kernel.primary_front_end is self:
55
55
  # yield url("^(?P<ref>.*)$", views.Index.as_view())
56
+ Tree = self.site.models.publisher.Tree
57
+ from django.db.utils import OperationalError, ProgrammingError
58
+ # language=self.site.DEFAULT_LANGUAGE.django_code
59
+ try:
60
+ for t in Tree.objects.filter(ref__isnull=False):
61
+ yield url(f"^{t.ref}$", views.Index.as_view(ref=t.ref))
62
+ except (OperationalError, ProgrammingError):
63
+ pass
56
64
  yield url("^$", views.Index.as_view())
57
- # yield url('^login$',views.Login.as_view())
65
+ yield url('^login$',views.Login.as_view())
66
+ yield url('^logout$',views.Logout.as_view())
58
67
 
59
68
  def setup_main_menu(self, site, user_type, m, ar=None):
60
69
  mg = self.get_menu_group()
@@ -65,8 +74,4 @@ class Plugin(Plugin):
65
74
  mg = self.get_menu_group()
66
75
  m = m.add_menu(mg.app_label, mg.verbose_name)
67
76
  m.add_action("publisher.SpecialPages")
68
-
69
- def setup_explorer_menu(self, site, user_type, m, ar=None):
70
- mg = self.get_menu_group()
71
- m = m.add_menu(mg.app_label, mg.verbose_name)
72
- m.add_action("publisher.RootPages")
77
+ m.add_action("publisher.Trees")
@@ -87,65 +87,7 @@ add("20", _("Ready"), "ready", is_public=False)
87
87
  add("30", _("Public"), "published", is_public=True)
88
88
  add("40", _("Removed"), "removed", is_public=False)
89
89
 
90
- # class EntryStates(dd.Workflow):
91
- # # verbose_name_plural = _("Enrolment states")
92
- # required_roles = dd.login_required(dd.SiteAdmin)
93
- # is_public = models.BooleanField(_("Public"), default=False)
94
- #
95
- # @classmethod
96
- # def get_column_names(self, ar):
97
- # return "value name text button_text is_public"
98
- #
99
- # add = EntryStates.add_item
100
- # add('10', _("Draft"), 'draft', is_public=False)
101
- # add('20', _("Ready"), 'ready', is_public=False)
102
- # add('30', _("Public"), 'published', is_public=True)
103
- # add('40', _("Cancelled"), 'cancelled', is_public=False)
104
-
105
-
106
- class PageFiller(Choice):
107
- data_view = None
108
-
109
- def __init__(self, data_view=None, **request_params):
110
- if data_view is not None:
111
- self.data_view = data_view
112
- self.request_params = request_params
113
- super().__init__(str(self.data_view))
114
-
115
- def create_request(self, ar, obj, **kwargs):
116
- kwargs.update(self.request_params, parent=ar)
117
- return self.data_view.create_request(**kwargs)
118
-
119
- def get_dynamic_story(self, ar, obj, **kwargs):
120
- txt = ""
121
- sar = self.create_request(ar, obj, limit=self.data_view.preview_limit)
122
- # print("20231028", dv, list(sar))
123
- # print("20230409", ar.renderer)
124
- # rv += "20230325 [show {}]".format(dv)
125
- for e in sar.renderer.table2story(sar, **kwargs):
126
- txt += tostring(e)
127
- return txt
128
-
129
- def get_dynamic_paragraph(self, ar, obj, **kwargs):
130
- # dv = self.data_view
131
- # sar = dv.create_request(parent=ar, limit=dv.preview_limit)
132
- sar = self.create_request(ar, obj)
133
- return " / ".join([sar.obj2htmls(row) for row in sar])
134
-
135
-
136
- class PageFillers(ChoiceList):
137
- verbose_name = _("Page filler")
138
- verbose_name_plural = _("Page fillers")
139
- item_class = PageFiller
140
- max_length = 50
141
- column_names = "value name text data_view *"
142
-
143
- @dd.virtualfield(models.CharField(_("Data table")))
144
- def data_view(cls, choice, ar):
145
- return choice.data_view
146
-
147
-
148
- # class SpecialPage(PointingChoice):
90
+
149
91
  class SpecialPage(dd.Choice):
150
92
  # pointing_field_name = 'publisher.Page.special_page'
151
93
  # show_values = True
@@ -153,7 +95,8 @@ class SpecialPage(dd.Choice):
153
95
  def __init__(self, name, text=None, parent=None, **kwargs):
154
96
  self.parent_value = parent
155
97
  self._default_values = dict()
156
- for k in ("ref", "title", "filler", "body"):
98
+ # for k in ("ref", "title", "filler", "body"):
99
+ for k in ("ref", "title", "body"):
157
100
  if k in kwargs:
158
101
  self._default_values[k] = kwargs.pop(k)
159
102
  super().__init__(name, text, name, **kwargs)
@@ -167,8 +110,8 @@ class SpecialPage(dd.Choice):
167
110
  def on_page_created(self, obj):
168
111
  for k, v in self._default_values.items():
169
112
  setattr(obj, k, v)
170
- if obj.filler and not obj.title:
171
- obj.title = obj.filler.data_view.get_actor_label()
113
+ # if obj.filler and not obj.title:
114
+ # obj.title = obj.filler.data_view.get_actor_label()
172
115
  if not obj.title:
173
116
  obj.title = self.text or "20250422"
174
117
  if self.parent_value:
@@ -183,7 +126,8 @@ class SpecialPage(dd.Choice):
183
126
  # else:
184
127
  # language = ar.request.LANGUAGE_CODE
185
128
  # return rt.models.publisher.Page.objects.get(ref=self.defaul_values['ref'], language=language)
186
- return rt.models.publisher.Page.objects.get(special_page=self, language=language)
129
+ return rt.models.publisher.Page.objects.get(
130
+ special_page=self, language=language)
187
131
 
188
132
 
189
133
  class SpecialPages(dd.ChoiceList):
@@ -206,7 +150,8 @@ class SpecialPages(dd.ChoiceList):
206
150
  Page = rt.models.publisher.Page
207
151
  for lng in settings.SITE.languages:
208
152
  try:
209
- page = Page.objects.get(special_page=choice, language=lng.django_code)
153
+ page = Page.objects.get(
154
+ special_page=choice, language=lng.django_code)
210
155
  lst.append(ar.obj2html(page, lng.name))
211
156
  except Page.DoesNotExist:
212
157
  page = _("(create)")