lino 25.3.1__py3-none-any.whl → 25.3.2__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 (44) hide show
  1. lino/__init__.py +6 -7
  2. lino/api/dd.py +1 -0
  3. lino/api/doctest.py +3 -68
  4. lino/api/rt.py +2 -4
  5. lino/core/actors.py +22 -16
  6. lino/core/boundaction.py +17 -7
  7. lino/core/dashboard.py +5 -4
  8. lino/core/dbtables.py +15 -16
  9. lino/core/fields.py +3 -3
  10. lino/core/menus.py +1 -1
  11. lino/core/model.py +1 -1
  12. lino/core/renderer.py +10 -11
  13. lino/core/requests.py +11 -7
  14. lino/core/tables.py +2 -2
  15. lino/core/utils.py +3 -3
  16. lino/core/views.py +3 -3
  17. lino/help_texts.py +1 -0
  18. lino/management/commands/buildsite.py +57 -0
  19. lino/management/commands/initdb.py +12 -14
  20. lino/mixins/sequenced.py +1 -1
  21. lino/modlib/comments/models.py +1 -1
  22. lino/modlib/comments/ui.py +2 -2
  23. lino/modlib/extjs/ext_renderer.py +2 -2
  24. lino/modlib/extjs/views.py +50 -48
  25. lino/modlib/help/config/makehelp/model.tpl.rst +1 -1
  26. lino/modlib/help/management/commands/makehelp.py +6 -5
  27. lino/modlib/jinja/renderer.py +2 -2
  28. lino/modlib/linod/management/commands/linod.py +5 -2
  29. lino/modlib/memo/__init__.py +1 -1
  30. lino/modlib/publisher/choicelists.py +3 -3
  31. lino/modlib/publisher/views.py +2 -2
  32. lino/modlib/search/models.py +5 -5
  33. lino/modlib/system/choicelists.py +6 -3
  34. lino/modlib/tinymce/views.py +1 -1
  35. lino/modlib/uploads/models.py +1 -1
  36. lino/modlib/users/ui.py +2 -3
  37. lino/utils/__init__.py +4 -1
  38. lino/utils/diag.py +1 -1
  39. lino/utils/fieldutils.py +79 -0
  40. {lino-25.3.1.dist-info → lino-25.3.2.dist-info}/METADATA +1 -1
  41. {lino-25.3.1.dist-info → lino-25.3.2.dist-info}/RECORD +44 -42
  42. {lino-25.3.1.dist-info → lino-25.3.2.dist-info}/WHEEL +0 -0
  43. {lino-25.3.1.dist-info → lino-25.3.2.dist-info}/licenses/AUTHORS.rst +0 -0
  44. {lino-25.3.1.dist-info → lino-25.3.2.dist-info}/licenses/COPYING +0 -0
lino/help_texts.py CHANGED
@@ -139,6 +139,7 @@ help_texts = {
139
139
  'lino.modlib.extjs.ext_renderer.ExtRenderer.goto_instance' : _("""See JsRenderer.goto_instance(), but when this is called while the detail window is already open (only on another record), then we don’t want to redirect to another page because that would take more time."""),
140
140
  'lino.modlib.extjs.views.AdminIndex' : _("""Similar to PlainIndex"""),
141
141
  'lino.modlib.extjs.views.Restful' : _("""Used to collaborate with a restful Ext.data.Store."""),
142
+ 'lino.modlib.extjs.views.ApiElement' : _("""The view that responds to r'api/(?P<app_label>\w+)/(?P<actor>\w+)/(?P<pk>[^/]+)$'."""),
142
143
  'lino.modlib.gfks.Plugin' : _("""Base class for this plugin."""),
143
144
  'lino.modlib.importfilters.Plugin' : _("""See /dev/plugins."""),
144
145
  'lino.modlib.jinja.Plugin' : _("""See /dev/plugins."""),
@@ -0,0 +1,57 @@
1
+ # -*- coding: UTF-8 -*-
2
+ # Copyright 2009-2023 Rumma & Ko Ltd.
3
+ # License: GNU Affero General Public License v3 (see file COPYING for details)
4
+
5
+ from click import confirm
6
+ from django.core.management.base import BaseCommand, CommandError
7
+ from django.core.management import call_command
8
+ from django.conf import settings
9
+ from lino import logger
10
+
11
+
12
+ class Command(BaseCommand):
13
+ """Run install, buildcache, collectstatic and makehelp after pull."""
14
+
15
+ def add_arguments(self, parser):
16
+ super().add_arguments(parser)
17
+ parser.add_argument(
18
+ "--noinput",
19
+ action="store_false",
20
+ dest="interactive",
21
+ default=True,
22
+ help="Do not prompt for input of any kind.",
23
+ ),
24
+
25
+ def handle(self, *args, **options):
26
+ interactive = options.get("interactive")
27
+ verbosity = options.get("verbosity")
28
+ project_dir = settings.SITE.project_dir
29
+
30
+ if interactive:
31
+ msg = "Build everything for ({})".format(project_dir)
32
+ msg += ".\nAre you sure?"
33
+ if not confirm(msg, default=True):
34
+ raise CommandError("User abort.")
35
+
36
+ # the following log message was useful on Travis 20150104
37
+ if verbosity > 0:
38
+ logger.info("`buildsite` started on %s.", project_dir)
39
+
40
+ pth = project_dir / "settings.py"
41
+ if pth.exists():
42
+ pth.touch()
43
+
44
+ options = dict(interactive=False, verbosity=verbosity)
45
+
46
+ call_command("install", **options)
47
+ call_command("collectstatic", **options)
48
+ call_command("buildcache", verbosity=verbosity)
49
+ if settings.SITE.is_installed("help"):
50
+ call_command("makehelp", verbosity=verbosity)
51
+
52
+ # for p in settings.SITE.installed_plugins:
53
+ # p.on_buildsite(settings.SITE, verbosity=verbosity)
54
+
55
+ settings.SITE.clear_site_config()
56
+
57
+ logger.info("`buildsite` finished on %s.", project_dir)
@@ -1,7 +1,16 @@
1
1
  # -*- coding: UTF-8 -*-
2
- # Copyright 2009-2023 Rumma & Ko Ltd.
2
+ # Copyright 2009-2025 Rumma & Ko Ltd.
3
3
  # License: GNU Affero General Public License v3 (see file COPYING for details)
4
4
 
5
+ from click import confirm
6
+ from lino.api import dd
7
+ from django.db import models
8
+ from django.db import connections, transaction, DEFAULT_DB_ALIAS
9
+ from django.core.management.color import no_style
10
+ from django.db.utils import IntegrityError, OperationalError
11
+ from django.core.management.base import BaseCommand, CommandError
12
+ from django.core.management import call_command
13
+ from django.conf import settings
5
14
  import os
6
15
  import shutil
7
16
  from pathlib import Path
@@ -22,20 +31,9 @@ warnings.filterwarnings(
22
31
  "django.core.management.commands.loaddata",
23
32
  )
24
33
 
25
- from django.conf import settings
26
- from django.core.management import call_command
27
- from django.core.management.base import BaseCommand, CommandError
28
- from django.db.utils import IntegrityError, OperationalError
29
- from django.db.migrations.exceptions import CircularDependencyError
30
- from django.core.management.color import no_style
31
34
 
32
35
  # ~ from django.core.management.sql import sql_reset
33
- from django.db import connections, transaction, DEFAULT_DB_ALIAS
34
- from django.db import models
35
-
36
- from lino.api import dd
37
36
 
38
- from rstgen.utils import confirm
39
37
 
40
38
  USE_SQLDELETE = True
41
39
 
@@ -198,8 +196,8 @@ class Command(BaseCommand):
198
196
  msg = "We are going to flush your database ({})".format(dbname)
199
197
  if removemedia:
200
198
  msg += "\nAND REMOVE ALL FILES BELOW {}".format(mroot)
201
- msg += ".\nAre you sure (y/n) ?"
202
- if not confirm(msg):
199
+ msg += ".\nAre you sure?"
200
+ if not confirm(msg, default=True):
203
201
  raise CommandError("User abort.")
204
202
 
205
203
  # mroot = Path(settings.MEDIA_ROOT)
lino/mixins/sequenced.py CHANGED
@@ -524,7 +524,7 @@ class Hierarchical(Duplicable):
524
524
  et.append(ar.goto_pk(c.id, get_text(c)))
525
525
  i -= 1
526
526
  if child == self:
527
- sar = ar.actor.request(
527
+ sar = ar.actor.create_request(
528
528
  parent=ar, master_instance=self, is_on_main_actor=False
529
529
  )
530
530
  # sar = ar.spawn_request(master_instance=self, is_on_main_actor=False)
@@ -257,7 +257,7 @@ class Comment(
257
257
  return format_html("<p>{}</p>", s)
258
258
 
259
259
  htmls = storypar(self.as_paragraph(ar))
260
- for child in RepliesByComment.request(master_instance=self, parent=ar):
260
+ for child in RepliesByComment.create_request(master_instance=self, parent=ar):
261
261
  htmls += storypar(child.as_story_item(ar, indent=indent + 1))
262
262
  # if self.replies_to_this.count():
263
263
  # # s += "<p>{}</p>".format("Replies:")
@@ -129,7 +129,7 @@ class Comments(dd.Table):
129
129
  pv = dict(user=user, start_date=sd, end_date=ed,
130
130
  observed_event=CommentEvents.created)
131
131
  # pv = dict(start_date=sd, end_date=ed, observed_event=CommentEvents.created)
132
- return cls.request(user=user, param_values=pv)
132
+ return cls.create_request(user=user, param_values=pv)
133
133
 
134
134
  # @classmethod
135
135
  # def get_card_title(cls, ar, obj):
@@ -302,7 +302,7 @@ class RepliesByComment(CommentsByX):
302
302
 
303
303
 
304
304
  def comments_by_owner(obj):
305
- return CommentsByRFC.request(master_instance=obj)
305
+ return CommentsByRFC.create_request(master_instance=obj)
306
306
 
307
307
 
308
308
  class Reactions(dd.Table):
@@ -136,7 +136,7 @@ class ExtRenderer(JsCacheRenderer):
136
136
  return self.handler_item(v, js, None)
137
137
  elif v.bound_action is not None:
138
138
  if v.params:
139
- ar = v.bound_action.request(**v.params)
139
+ ar = v.bound_action.create_request(**v.params)
140
140
  js = self.request_handler(ar)
141
141
  # print("20230513", js)
142
142
  else:
@@ -265,7 +265,7 @@ class ExtRenderer(JsCacheRenderer):
265
265
 
266
266
  """
267
267
  if ar is None:
268
- sar = ba.request(**request_kwargs)
268
+ sar = ba.create_request(**request_kwargs)
269
269
  else:
270
270
  sar = ar.spawn(ba, **request_kwargs)
271
271
  return self.ar2js(sar, obj, **status)
@@ -24,14 +24,11 @@ Summary from <http://en.wikipedia.org/wiki/Restful>:
24
24
  import json
25
25
  import os
26
26
 
27
- from pathlib import Path
28
-
29
27
  from django import http
30
- from django.contrib.messages import success
31
28
  from django.db import models
32
29
  from django.conf import settings
33
30
  from django.core.cache import cache
34
- from django.core.exceptions import PermissionDenied, ObjectDoesNotExist
31
+ from django.core.exceptions import PermissionDenied
35
32
  from django.views.generic import View
36
33
  from django.views.generic.base import TemplateView
37
34
  from django.views.decorators.cache import never_cache
@@ -40,27 +37,24 @@ from django.views.decorators.csrf import ensure_csrf_cookie, csrf_protect
40
37
  from django.utils.translation import gettext as _
41
38
  from django.utils.encoding import force_str
42
39
  from django.utils.html import mark_safe
43
- from lino.core import auth
44
40
 
45
41
  from lino.core.signals import pre_ui_delete
46
42
  from lino.core.utils import obj2unicode
47
43
 
48
44
  # from etgen import html as xghtml
49
- from lino.utils.html import E, tostring
45
+ from lino.utils.html import E, tostring, escape
50
46
  from etgen.html import Document
51
47
 
52
48
  from lino.utils import ucsv
53
49
  from lino import logger
54
50
  # from lino.utils import dblogger
55
51
  from lino.core import constants
56
- from lino.core import actions
57
- from lino.core import fields
58
52
  from lino.core.fields import choices_for_field
59
53
  from lino.core.views import requested_actor, action_request
60
- from lino.core.views import json_response, json_response_kw
54
+ from lino.core.views import json_response
61
55
  from lino.core.views import choices_response
62
56
  from lino.core.requests import BaseRequest
63
- from lino.core.utils import PhantomRow, is_devserver
57
+ from lino.core.utils import is_devserver
64
58
 
65
59
  MAX_ROW_COUNT = 300
66
60
 
@@ -207,7 +201,7 @@ class ActionParamChoices(View):
207
201
  raise Exception("Unknown action %r for %s" % (an, actor))
208
202
  field = ba.action.get_param_elem(field)
209
203
  qs, row2dict = choices_for_field(
210
- ba.request(request=request), ba.action, field)
204
+ ba.create_request(request=request), ba.action, field)
211
205
  if field.blank:
212
206
  emptyValue = "<br/>"
213
207
  else:
@@ -229,7 +223,7 @@ class Choices(View):
229
223
  rpt = requested_actor(app_label, rptname)
230
224
  emptyValue = None
231
225
  if fldname is None:
232
- ar = rpt.request(request=request)
226
+ ar = rpt.create_request(request=request)
233
227
  qs = ar.data_iterator
234
228
 
235
229
  def row2dict(obj, d):
@@ -247,7 +241,7 @@ class Choices(View):
247
241
  if field.blank:
248
242
  # logger.info("views.Choices: %r is blank",field)
249
243
  emptyValue = "<br/>"
250
- ar = rpt.request(request=request)
244
+ ar = rpt.create_request(request=request)
251
245
  # if str(rpt) == 'comments.CommentsByRFC':
252
246
  # print("20230426", ar.master_instance)
253
247
  qs, row2dict = choices_for_field(ar, rpt, field)
@@ -263,7 +257,7 @@ class Restful(View):
263
257
  @method_decorator(csrf_protect)
264
258
  def post(self, request, app_label=None, actor=None, pk=None):
265
259
  rpt = requested_actor(app_label, actor)
266
- ar = rpt.request(request=request)
260
+ ar = rpt.create_request(request=request)
267
261
 
268
262
  instance = ar.create_instance()
269
263
  # store uploaded files.
@@ -284,14 +278,14 @@ class Restful(View):
284
278
  @method_decorator(csrf_protect)
285
279
  def delete(self, request, app_label=None, actor=None, pk=None):
286
280
  rpt = requested_actor(app_label, actor)
287
- ar = rpt.request(request=request)
281
+ ar = rpt.create_request(request=request)
288
282
  ar.set_selected_pks(pk)
289
283
  return delete_element(ar, ar.selected_rows[0])
290
284
 
291
285
  def get(self, request, app_label=None, actor=None, pk=None):
292
286
  rpt = requested_actor(app_label, actor)
293
287
  assert pk is None, 20120814
294
- ar = rpt.request(request=request)
288
+ ar = rpt.create_request(request=request)
295
289
  rh = ar.ah
296
290
  rows = [
297
291
  rh.store.row2dict(ar, row, rh.store.grid_fields)
@@ -304,7 +298,7 @@ class Restful(View):
304
298
  @method_decorator(csrf_protect)
305
299
  def put(self, request, app_label=None, actor=None, pk=None):
306
300
  rpt = requested_actor(app_label, actor)
307
- ar = rpt.request(request=request)
301
+ ar = rpt.create_request(request=request)
308
302
  ar.set_selected_pks(pk)
309
303
  elem = ar.selected_rows[0]
310
304
  rh = ar.ah
@@ -313,7 +307,7 @@ class Restful(View):
313
307
  data = json.loads(data)
314
308
  # 20240404 a = rpt.get_url_action(rpt.default_list_action_name)
315
309
  a = rpt.default_action
316
- ar = rpt.request(request=request, action=a)
310
+ ar = rpt.create_request(request=request, action=a)
317
311
  ar.renderer = settings.SITE.kernel.extjs_renderer
318
312
  ar.form2obj_and_save(data, elem, False)
319
313
  # Ext.ensible needs grid_fields, not detail_fields
@@ -326,6 +320,10 @@ NOT_FOUND = "%s has no row with primary key %r"
326
320
 
327
321
 
328
322
  class ApiElement(View):
323
+ """
324
+ The view that responds to
325
+ ``r'api/(?P<app_label>\w+)/(?P<actor>\w+)/(?P<pk>[^/]+)$'``.
326
+ """
329
327
 
330
328
  @method_decorator(ensure_csrf_cookie)
331
329
  def get(self, request, app_label=None, actor=None, pk=None):
@@ -353,48 +351,53 @@ class ApiElement(View):
353
351
  ba.action.default_format)
354
352
 
355
353
  try:
354
+ ar = ba.create_request(
355
+ request=request, renderer=settings.SITE.kernel.default_renderer)
356
356
  if pk and pk != "-99999" and pk != "-99998":
357
- sr = [pk]
358
357
  if issubclass(rpt.model, models.Model):
359
358
  try:
360
- ar = ba.request(request=request, selected_pks=sr)
361
- # except ObjectDoesNotExist as e: # 20250212
359
+ ar.set_selected_pks(pk)
362
360
  except rpt.model.DoesNotExist:
363
361
  if fmt == constants.URL_FORMAT_JSON:
364
- # rescue_ar: without sr and even request, to render a table request (grid view action) on breadcrumb
365
- rescue_ar = rpt.request(
362
+ # rescue_ar: without sr and even request, to render
363
+ # a table request (grid view action) on breadcrumb
364
+ safe_kw = dict(
365
+ user=request.user,
366
366
  renderer=settings.SITE.kernel.default_renderer)
367
- default_table = rpt.model.get_default_table()
368
-
367
+ rescue_ar = rpt.create_request(**safe_kw)
369
368
  title = tostring(rescue_ar.href_to_request(
370
369
  rescue_ar, icon_name=None))
371
-
372
- def get_response():
373
- msg = mark_safe(
374
- f'Record (pk={pk}) is no longer available on current table.')
375
- datarec = dict(
376
- success=False, message=msg, title=title)
377
- datarec.update(**vm)
378
- return datarec
379
-
370
+ datarec = dict(alert=False, success=False,
371
+ title=title, **vm)
372
+ msg = _("Row {pk} is not visible here.").format(pk=pk)
373
+ default_table = rpt.model.get_default_table()
374
+ if default_table is rpt:
375
+ datarec.update(message=mark_safe(msg))
376
+ return json_response(datarec)
377
+ ar = default_table.detail_action.create_request(parent=ar)
380
378
  try:
381
379
  # take default table and try to show the row
382
- ar = default_table.detail_action.request(
383
- request=request, selected_pks=sr)
380
+ ar.set_selected_pks(pk)
384
381
  except default_table.model.DoesNotExist:
385
- return json_response(get_response())
386
-
387
- url = ar.obj2url(ar.selected_rows[0])
388
- datarec = get_response()
389
- datarec['message'] += mark_safe(
390
- f' Reload in <a href="{url}">{default_table}</a>.')
382
+ msg += " " + _("Neither is it visible in {table}.").format(
383
+ table=ar.get_title())
384
+ datarec.update(message=mark_safe(msg))
385
+ return json_response(datarec)
386
+
387
+ lnk = ar.obj2htmls(ar.selected_rows[0], ar.get_title())
388
+ s = escape(_("But you can see it in {}.")).format(lnk)
389
+ msg += "<br>" + s
390
+ # msg = format_html("{}<br>{}", )
391
+ # msg = format_html("{}<br>{}", _("But you can see it in {link}"))
392
+ # url = ar.obj2url(dtar.selected_rows[0])
393
+ # msg += "<br>" + _('But you can see it in <a href="{url}">{table}</a>.').format(
394
+ # url=url, table=ar.get_title())
395
+ datarec.update(message=mark_safe(msg))
391
396
  return json_response(datarec)
392
- # print("20240911", e)
393
- raise http.Http404(
394
- f"Object {sr} does not exist on {rpt}")
397
+ raise http.Http404(f"Row {pk} does not exist on {rpt}")
395
398
  else:
396
- ar = ba.request(request=request, selected_pks=sr)
397
- # ar = ba.request(request=request, selected_pks=sr)
399
+ ar.set_selected_pks(pk)
400
+ # ar = ba.create_request(request=request, selected_pks=sr)
398
401
  elem = ar.selected_rows[0]
399
402
  # print(
400
403
  # "20170116 views.ApiElement.get", ba,
@@ -405,7 +408,6 @@ class ApiElement(View):
405
408
  # raise http.Http404(
406
409
  # "No permission to see {} {}.".format(rpt, action_name))
407
410
  else:
408
- ar = ba.request(request=request)
409
411
  elem = None
410
412
  except Exception as e:
411
413
 
@@ -8,4 +8,4 @@
8
8
 
9
9
  {{header(2, str(_("Database fields")))}}
10
10
 
11
- {{doctest.fields_help(model, all=True)}}
11
+ {{dd.fields_help(model, all=True)}}
@@ -41,7 +41,7 @@ from lino.core.model import Model
41
41
  from lino.core.utils import model_class_path
42
42
  from lino.modlib.help.utils import HelpTextsLoader, simplify_name
43
43
  from lino.modlib.gfks.fields import GenericForeignKey
44
- from lino.api.dd import full_model_name
44
+ from lino.api import dd
45
45
 
46
46
  # removed import doctest because it caused "pytest not installed" during
47
47
  # makehelp on LF:
@@ -91,7 +91,7 @@ def runcmd(cmd, **kw):
91
91
 
92
92
  def field_ref(f):
93
93
  if isinstance(f.model, Model):
94
- return ":ref:`{}.{}`".format(full_model_name(f.model), f.name)
94
+ return ":ref:`{}.{}`".format(dd.full_model_name(f.model), f.name)
95
95
  # parameter field
96
96
  return ":ref:`{}.{}`".format(str(f.model), f.name)
97
97
 
@@ -136,7 +136,7 @@ def model_referenced_from(model):
136
136
  def ddhfmt(ddh):
137
137
  return ", ".join(
138
138
  [
139
- "{}.{}".format(full_model_name(model), fk.name)
139
+ "{}.{}".format(dd.full_model_name(model), fk.name)
140
140
  for model, fk in ddh.fklist
141
141
  ]
142
142
  )
@@ -265,7 +265,8 @@ class Command(GeneratingCommand):
265
265
  # ~ py2rst=rstgen.py2rst,
266
266
  languages=[lng.django_code for lng in settings.SITE.languages],
267
267
  get_models=apps.get_models,
268
- full_model_name=full_model_name,
268
+ full_model_name=dd.full_model_name,
269
+ dd=dd,
269
270
  model_overview=self.model_overview,
270
271
  actor2par=self.actor2par,
271
272
  actors2table=self.actors2table,
@@ -324,7 +325,7 @@ class Command(GeneratingCommand):
324
325
  elif issubclass(x, models.Model):
325
326
  if text is None:
326
327
  text = x.__name__
327
- return ":doc:`" + text + " <" + full_model_name(x) + ">`"
328
+ return ":doc:`" + text + " <" + dd.full_model_name(x) + ">`"
328
329
  if isinstance(x, BoundAction):
329
330
  if text is None:
330
331
  text = x.action_name
@@ -82,7 +82,7 @@ class JinjaRenderer(HtmlRenderer):
82
82
 
83
83
  def as_table(action_spec):
84
84
  a = settings.SITE.models.resolve(action_spec)
85
- ar = a.request(user=settings.SITE.get_anonymous_user())
85
+ ar = a.create_request(user=settings.SITE.get_anonymous_user())
86
86
  return self.as_table(ar)
87
87
 
88
88
  def as_table2(ar):
@@ -99,7 +99,7 @@ class JinjaRenderer(HtmlRenderer):
99
99
 
100
100
  def as_ul(action_spec):
101
101
  a = settings.SITE.models.resolve(action_spec)
102
- ar = a.request(user=settings.SITE.get_anonymous_user())
102
+ ar = a.create_request(user=settings.SITE.get_anonymous_user())
103
103
  # 20150810
104
104
  ar.renderer = self
105
105
  # return tostring(E.ul(*[obj.as_paragraph(ar) for obj in ar]))
@@ -51,8 +51,11 @@ class Command(BaseCommand):
51
51
  # print("20240424 Run Lino daemon without channels")
52
52
 
53
53
  async def main():
54
- u = await settings.SITE.user_model.objects.aget(
55
- username=settings.SITE.plugins.linod.daemon_user)
54
+ try:
55
+ u = await settings.SITE.user_model.objects.aget(
56
+ username=settings.SITE.plugins.linod.daemon_user)
57
+ except settings.SITE.user_model.DoesNotExist:
58
+ u = None
56
59
  ar = BaseRequest(user=u)
57
60
  # ar = rt.login(dd.plugins.linod.daemon_user)
58
61
  await asyncio.gather(start_log_server(), start_task_runner(ar))
@@ -93,7 +93,7 @@ class Plugin(ad.Plugin):
93
93
  # kwargs = dict(header_level=3) #, nosummary=True)
94
94
  kwargs = dict() # , nosummary=True)
95
95
  dv = self.site.models.resolve(s)
96
- sar = dv.request(parent=ar, limit=dv.preview_limit)
96
+ sar = dv.create_request(parent=ar, limit=dv.preview_limit)
97
97
  rv = ""
98
98
  # rv += "20230325 [show {}]".format(dv)
99
99
  for e in sar.renderer.table2story(sar, **kwargs):
@@ -149,7 +149,7 @@ class PageFiller(Choice):
149
149
  def get_dynamic_story(self, ar, obj, **kwargs):
150
150
  txt = ""
151
151
  dv = self.data_view
152
- sar = dv.request(parent=ar, limit=dv.preview_limit)
152
+ sar = dv.create_request(parent=ar, limit=dv.preview_limit)
153
153
  # print("20231028", dv, list(sar))
154
154
  # print("20230409", ar.renderer)
155
155
  # rv += "20230325 [show {}]".format(dv)
@@ -159,8 +159,8 @@ class PageFiller(Choice):
159
159
 
160
160
  def get_dynamic_paragraph(self, ar, obj, **kwargs):
161
161
  dv = self.data_view
162
- # sar = dv.request(parent=ar, limit=dv.preview_limit)
163
- sar = dv.request(parent=ar)
162
+ # sar = dv.create_request(parent=ar, limit=dv.preview_limit)
163
+ sar = dv.create_request(parent=ar)
164
164
  return " / ".join([sar.obj2htmls(row) for row in sar])
165
165
 
166
166
 
@@ -37,7 +37,7 @@ class Element(View):
37
37
  kw.update(selected_pks=[pk])
38
38
 
39
39
  try:
40
- ar = self.table_class.request(request=request, **kw)
40
+ ar = self.table_class.create_request(request=request, **kw)
41
41
  except ObjectDoesNotExist as e:
42
42
  # print("20240911", e)
43
43
  return http.HttpResponseNotFound(f"No row #{pk} in {self.table_class} ({e})")
@@ -54,5 +54,5 @@ class Index(View):
54
54
  dv = settings.SITE.models.publisher.Pages
55
55
  index_node = dv.model.objects.get(ref="index", language=request.LANGUAGE_CODE)
56
56
  # print("20231025", index_node)
57
- ar = dv.request(request=request, renderer=rnd, selected_rows=[index_node])
57
+ ar = dv.create_request(request=request, renderer=rnd, selected_rows=[index_node])
58
58
  return index_node.get_publisher_response(ar)
@@ -52,7 +52,7 @@ class SiteSearchBase(dd.VirtualTable):
52
52
  if t is None:
53
53
  return
54
54
  t = cls.get_table_for_role(t, ar.get_user().user_type.role)
55
- sar = t.request(parent=ar)
55
+ sar = t.create_request(parent=ar)
56
56
  return obj.as_search_item(sar)
57
57
 
58
58
  @classmethod
@@ -68,7 +68,7 @@ class SiteSearchBase(dd.VirtualTable):
68
68
  if t is None:
69
69
  return
70
70
  t = cls.get_table_for_role(t, ar.get_user().user_type.role)
71
- sar = t.request(parent=ar)
71
+ sar = t.create_request(parent=ar)
72
72
  return t.get_card_title(sar, obj)
73
73
 
74
74
  @classmethod
@@ -158,7 +158,7 @@ class SiteSearch(SiteSearchBase):
158
158
  t = cls.get_table_for_role(t, user_type.role)
159
159
  if not t.get_view_permission(user_type):
160
160
  continue
161
- sar = t.request(parent=ar, quick_search=ar.quick_search)
161
+ sar = t.create_request(parent=ar, quick_search=ar.quick_search)
162
162
  try:
163
163
  for obj in sar:
164
164
  if obj.show_in_site_search: # don't show calview.HeaderRow
@@ -197,7 +197,7 @@ if settings.SITE.use_elasticsearch and has_elasticsearch:
197
197
  user_type = ar.get_user().user_type
198
198
  query = MultiMatch(query=ar.quick_search)
199
199
  s = search.query(query)
200
- s = s[ar.offset : ar.offset + ar.limit]
200
+ s = s[ar.offset: ar.offset + ar.limit]
201
201
  sq = execute_search(s, save=False)
202
202
  return sq
203
203
  return []
@@ -210,7 +210,7 @@ if settings.SITE.use_solr and has_haystack:
210
210
  class SolrSiteSearch(SiteSearchBase):
211
211
  @classmethod
212
212
  def get_rows_from_search_query(cls, sqs, ar):
213
- results = sqs[ar.offset : ar.offset + ar.limit]
213
+ results = sqs[ar.offset: ar.offset + ar.limit]
214
214
  for result in results:
215
215
  yield result.model.objects.get(pk=result.pk)
216
216
 
@@ -222,9 +222,9 @@ add("P", _("per weekday"), "per_weekday") # deprecated
222
222
  add("E", _("Relative to Easter"), "easter")
223
223
 
224
224
 
225
-
226
225
  class DisplayColor(Choice):
227
226
  font_color = None
227
+
228
228
  def __init__(self, value, text, names, font_color="white"):
229
229
  super().__init__(value, text, names)
230
230
  self.font_color = font_color
@@ -247,12 +247,14 @@ class DisplayColors(ChoiceList):
247
247
  # text = escape(bc.text)
248
248
  # txt = f"""<span style="background-color:{bc.name};color:{bc.font_color}">{text}</span>"""
249
249
  # txt = mark_safe(txt)
250
- sample = f"""<span style="padding:3pt;background-color:{bc.name};color:{bc.font_color}">(sample)</span>"""
250
+ sample = f"""<span style="padding:3pt;background-color:{
251
+ bc.name};color:{bc.font_color}">(sample)</span>"""
251
252
  sample = mark_safe(sample)
252
253
  txt = format_html("{} {}", bc.text, sample)
253
254
  # raise Exception(f"20250118 {txt.__class__}")
254
255
  return txt
255
256
 
257
+
256
258
  add = DisplayColors.add_item
257
259
  # cssColors = 'White Silver Gray Black Red Maroon Yellow Olive Lime Green Aqua Teal Blue Navy Fuchsia Purple'
258
260
  # cssColors = 'white silver gray black red maroon yellow olive lime green aqua teal blue navy fuchsia purple'
@@ -275,7 +277,7 @@ add("220", _("Orange"), "orange", "white")
275
277
  add("230", _("Yellow"), "yellow", "black")
276
278
  add("240", _("Green"), "green", "white")
277
279
  add("250", _("Blue"), "blue", "white")
278
- add("260", _("Magenta"), "magenta","white")
280
+ add("260", _("Magenta"), "magenta", "white")
279
281
  add("270", _("Violet"), "violet", "white")
280
282
 
281
283
  # Other colors
@@ -291,6 +293,7 @@ add("342", _("DarkGreen"), "darkgreen", "white")
291
293
  add("343", _("PaleGreen"), "palegreen", "black")
292
294
  add("344", _("Chartreuse"), "chartreuse", "black")
293
295
  add("345", _("Lime"), "lime", "black")
296
+ add("346", _("Teal"), "teal", "white")
294
297
  add("350", _("Fuchsia"), "fuchsia", "white")
295
298
  add("351", _("Cyan"), "cyan", "black")
296
299
  add("361", _("Purple"), "purple", "white")
@@ -29,7 +29,7 @@ class Templates(View):
29
29
  ):
30
30
  if request.method == "GET":
31
31
  rpt = requested_actor(app_label, actor)
32
- ar = rpt.request(request=request)
32
+ ar = rpt.create_request(request=request)
33
33
  elem = rpt.get_row_by_pk(ar, pk)
34
34
  if elem is None:
35
35
  raise http.Http404("%s %s does not exist." % (rpt, pk))
@@ -485,7 +485,7 @@ def on_sanitize(soup, save=False, ar=None):
485
485
  if (src := tag.get('src')) and src.startswith("data:image"):
486
486
  file = base64_to_image(src)
487
487
  upload = rt.models.uploads.Upload(file=file, user=ar.get_user())
488
- sar = upload.get_default_table().request(parent=ar)
488
+ sar = upload.get_default_table().create_request(parent=ar)
489
489
  upload.save_new_instance(sar)
490
490
  tag.replace_with(f'[file {upload.pk}]')
491
491