lino 24.11.0__py3-none-any.whl → 24.11.1__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.
- lino/__init__.py +1 -1
- lino/core/actions.py +2 -4
- lino/core/actors.py +2 -2
- lino/core/dbtables.py +12 -12
- lino/core/fields.py +1 -0
- lino/core/inject.py +9 -2
- lino/core/kernel.py +7 -6
- lino/core/model.py +24 -27
- lino/core/renderer.py +2 -2
- lino/core/requests.py +21 -45
- lino/core/site.py +4 -45
- lino/core/store.py +4 -4
- lino/core/utils.py +5 -2
- lino/help_texts.py +4 -3
- lino/locale/bn/LC_MESSAGES/django.po +1210 -907
- lino/locale/de/LC_MESSAGES/django.po +1760 -1375
- lino/locale/django.pot +1136 -906
- lino/locale/es/LC_MESSAGES/django.po +1709 -1347
- lino/locale/et/LC_MESSAGES/django.po +1206 -906
- lino/locale/fr/LC_MESSAGES/django.mo +0 -0
- lino/locale/fr/LC_MESSAGES/django.po +1193 -923
- lino/locale/nl/LC_MESSAGES/django.po +1247 -942
- lino/locale/pt_BR/LC_MESSAGES/django.po +1190 -903
- lino/locale/zh_Hant/LC_MESSAGES/django.po +1190 -903
- lino/mixins/periods.py +6 -4
- lino/modlib/comments/choicelists.py +1 -1
- lino/modlib/comments/fixtures/demo2.py +4 -1
- lino/modlib/comments/mixins.py +9 -10
- lino/modlib/comments/models.py +4 -4
- lino/modlib/comments/ui.py +5 -0
- lino/modlib/linod/mixins.py +3 -2
- lino/modlib/memo/mixins.py +10 -208
- lino/modlib/notify/mixins.py +33 -32
- lino/modlib/periods/mixins.py +0 -1
- lino/modlib/printing/choicelists.py +3 -3
- lino/modlib/search/models.py +17 -11
- lino/modlib/system/fixtures/__init__.py +0 -0
- lino/modlib/system/fixtures/std.py +5 -0
- lino/modlib/system/models.py +3 -2
- lino/modlib/uploads/__init__.py +10 -1
- lino/modlib/uploads/choicelists.py +3 -3
- lino/modlib/uploads/mixins.py +30 -32
- lino/modlib/uploads/models.py +89 -56
- lino/modlib/uploads/ui.py +12 -6
- lino/modlib/uploads/utils.py +107 -0
- lino/utils/__init__.py +6 -0
- lino/utils/html.py +1 -1
- lino/utils/media.py +2 -3
- lino/utils/soup.py +311 -0
- {lino-24.11.0.dist-info → lino-24.11.1.dist-info}/METADATA +1 -3
- {lino-24.11.0.dist-info → lino-24.11.1.dist-info}/RECORD +54 -50
- {lino-24.11.0.dist-info → lino-24.11.1.dist-info}/WHEEL +1 -1
- {lino-24.11.0.dist-info → lino-24.11.1.dist-info}/licenses/AUTHORS.rst +0 -0
- {lino-24.11.0.dist-info → lino-24.11.1.dist-info}/licenses/COPYING +0 -0
lino/__init__.py
CHANGED
lino/core/actions.py
CHANGED
@@ -87,7 +87,7 @@ def install_layout(cls, k, layout_class, **options):
|
|
87
87
|
- `cls` is the actor (a class object)
|
88
88
|
|
89
89
|
- `k` is one of 'grid_layout', 'detail_layout', 'insert_layout',
|
90
|
-
'params_layout', 'card_layout'
|
90
|
+
'params_layout', 'card_layout'
|
91
91
|
|
92
92
|
- `layout_class`
|
93
93
|
|
@@ -575,7 +575,7 @@ class Action(Parametrizable, Permittable):
|
|
575
575
|
|
576
576
|
def is_window_action(self):
|
577
577
|
"""Return `True` if this is a "window action" (i.e. which opens a GUI
|
578
|
-
window on the client before
|
578
|
+
window on the client before executing).
|
579
579
|
|
580
580
|
"""
|
581
581
|
return self.opens_a_window or (self.parameters and not self.no_params_window)
|
@@ -805,9 +805,7 @@ class ShowTable(TableAction):
|
|
805
805
|
return self.label or self.defining_actor.label
|
806
806
|
|
807
807
|
def get_window_layout(self, actor):
|
808
|
-
# ~ return self.actor.list_layout
|
809
808
|
return None
|
810
|
-
# return actor.card_layout or actor.list_layout # 20210910
|
811
809
|
|
812
810
|
def get_window_size(self, actor):
|
813
811
|
return actor.window_size
|
lino/core/actors.py
CHANGED
@@ -439,7 +439,7 @@ class Actor(actions.Parametrizable, Permittable, metaclass=ActorMetaClass):
|
|
439
439
|
detail_layout = None
|
440
440
|
insert_layout = None
|
441
441
|
card_layout = None
|
442
|
-
list_layout = None
|
442
|
+
list_layout = None # no longer used
|
443
443
|
|
444
444
|
detail_template = None # deprecated: use insert_layout instead
|
445
445
|
insert_template = None # deprecated: use detail_layout instead
|
@@ -836,7 +836,7 @@ class Actor(actions.Parametrizable, Permittable, metaclass=ActorMetaClass):
|
|
836
836
|
window_size=(cls.insert_layout_width, "auto"),
|
837
837
|
)
|
838
838
|
actions.install_layout(cls, "card_layout", layouts.DetailLayout)
|
839
|
-
actions.install_layout(cls, "list_layout", layouts.DetailLayout)
|
839
|
+
# actions.install_layout(cls, "list_layout", layouts.DetailLayout)
|
840
840
|
|
841
841
|
cls.extra_layouts = dict()
|
842
842
|
for name, main in cls.get_extra_layouts():
|
lino/core/dbtables.py
CHANGED
@@ -209,18 +209,18 @@ class Table(AbstractTable):
|
|
209
209
|
"""If True will position the quick search input to the bottom of the header and have it full width.
|
210
210
|
Default: False"""
|
211
211
|
|
212
|
-
@classmethod
|
213
|
-
def init_layouts(cls):
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
212
|
+
# @classmethod
|
213
|
+
# def init_layouts(cls):
|
214
|
+
# if cls.model is not None and issubclass(cls.model, Model):
|
215
|
+
# if not cls.abstract:
|
216
|
+
# for tbl in cls.__mro__:
|
217
|
+
# # print("20210629", tbl)
|
218
|
+
# if "list_layout" in tbl.__dict__:
|
219
|
+
# break
|
220
|
+
# if issubclass(tbl, actors.Actor):
|
221
|
+
# cls.list_layout = "list_item"
|
222
|
+
# break
|
223
|
+
# super().init_layouts()
|
224
224
|
|
225
225
|
@classmethod
|
226
226
|
def add_quick_search_filter(cls, qs, search_text):
|
lino/core/fields.py
CHANGED
@@ -1375,6 +1375,7 @@ class TableRow(object):
|
|
1375
1375
|
return ar.obj2html(self, text, **kwargs)
|
1376
1376
|
|
1377
1377
|
def as_paragraph(self, ar, **kwargs):
|
1378
|
+
# must return a safe html string
|
1378
1379
|
if ar is None:
|
1379
1380
|
return escape(str(self))
|
1380
1381
|
return tostring(self.as_summary_item(ar, **kwargs))
|
lino/core/inject.py
CHANGED
@@ -111,15 +111,22 @@ def check_pending_injects(sender, models_list=None, **kw):
|
|
111
111
|
# raise Exception(20150304)
|
112
112
|
# called from kernel.analyze_models()
|
113
113
|
# ~ logger.info("20130212 check_pending_injects()...")
|
114
|
+
# if PENDING_INJECTS:
|
115
|
+
# for spec, todos in PENDING_INJECTS.items():
|
116
|
+
# model = resolve_model(spec, strict=True)
|
117
|
+
# if todos is not None:
|
118
|
+
# for func, caller in todos:
|
119
|
+
# func(model)
|
120
|
+
|
114
121
|
if PENDING_INJECTS:
|
115
122
|
msg = ""
|
116
|
-
for spec, funcs in
|
123
|
+
for spec, funcs in PENDING_INJECTS.items():
|
117
124
|
msg += spec + ": "
|
118
125
|
msg += ", ".join([fmt(f) for f in funcs])
|
119
126
|
# ~ msg += '\n'.join([str(dir(func)) for func in funcs])
|
120
127
|
# ~ msg += '\n'.join([str(func.func_code.co_consts) for func in funcs])
|
121
128
|
# ~ msg += str(funcs)
|
122
|
-
raise Exception("Oops, there are pending injects:
|
129
|
+
raise Exception(f"Oops, there are pending injects: {msg}")
|
123
130
|
# ~ logger.warning("pending injects: %s", msg)
|
124
131
|
|
125
132
|
# ~ logger.info("20131110 no pending injects")
|
lino/core/kernel.py
CHANGED
@@ -298,8 +298,11 @@ class Kernel(object):
|
|
298
298
|
# if f.__class__ is models.CharField and f.null:
|
299
299
|
# msg = "Nullable CharField %s in %s" % (f.name, model)
|
300
300
|
# raise Exception(msg)
|
301
|
+
|
301
302
|
if isinstance(f, models.ForeignKey):
|
303
|
+
# f.remote_field.model = resolve_model(f.remote_field.model)
|
302
304
|
if isinstance(f.remote_field.model, str):
|
305
|
+
# models_list = [f"{m}({m._meta.abstract})".format(m) for m in models_list]
|
303
306
|
raise Exception(
|
304
307
|
"Could not resolve target %r of "
|
305
308
|
"ForeignKey '%s' in %s "
|
@@ -308,12 +311,10 @@ class Kernel(object):
|
|
308
311
|
)
|
309
312
|
|
310
313
|
set_default_verbose_name(f)
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
to a Company as well.
|
316
|
-
"""
|
314
|
+
# If JobProvider is an MTI child of Company,
|
315
|
+
# then mti.delete_child(JobProvider) must not fail on a
|
316
|
+
# JobProvider being referred only by objects that can refer
|
317
|
+
# to a Company as well.
|
317
318
|
if not hasattr(f.remote_field.model, "_lino_ddh"):
|
318
319
|
msg = "20150824 {1} (needed by {0}) " "has no _lino_ddh"
|
319
320
|
raise Exception(
|
lino/core/model.py
CHANGED
@@ -20,6 +20,7 @@ from django.db.models.signals import pre_delete
|
|
20
20
|
from django.utils.text import format_lazy
|
21
21
|
|
22
22
|
from lino.utils.html import E, forcetext, tostring, join_elems
|
23
|
+
from lino.utils.soup import sanitize
|
23
24
|
|
24
25
|
from lino.core import fields
|
25
26
|
from lino.core import signals
|
@@ -36,10 +37,10 @@ from .workflows import ChangeStateAction
|
|
36
37
|
from .requests import ActionRequest, sliced_data_iterator
|
37
38
|
from .tables import AbstractTable
|
38
39
|
|
39
|
-
try:
|
40
|
-
|
41
|
-
except ImportError:
|
42
|
-
|
40
|
+
# try:
|
41
|
+
# import bleach
|
42
|
+
# except ImportError:
|
43
|
+
# bleach = None
|
43
44
|
|
44
45
|
|
45
46
|
class Model(models.Model, fields.TableRow):
|
@@ -308,8 +309,7 @@ class Model(models.Model, fields.TableRow):
|
|
308
309
|
if isinstance(f, RichTextField):
|
309
310
|
if f.editable and (
|
310
311
|
f.bleached is True
|
311
|
-
or f.bleached is None
|
312
|
-
and settings.SITE.textfield_bleached
|
312
|
+
or f.bleached is None and settings.SITE.textfield_bleached
|
313
313
|
):
|
314
314
|
bleached_fields.append(f)
|
315
315
|
cls._bleached_fields = tuple(bleached_fields)
|
@@ -428,27 +428,24 @@ class Model(models.Model, fields.TableRow):
|
|
428
428
|
setattr(self, f.name, new)
|
429
429
|
|
430
430
|
def fields_to_bleach(self):
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
if old != new:
|
450
|
-
logger.debug("Bleaching %s from %r to %r", f.name, old, new)
|
451
|
-
yield f, old, new
|
431
|
+
for f in self._bleached_fields:
|
432
|
+
old = getattr(self, f.name)
|
433
|
+
if old is None:
|
434
|
+
continue
|
435
|
+
new = sanitize(old)
|
436
|
+
# try:
|
437
|
+
# new = bleach.clean(
|
438
|
+
# new,
|
439
|
+
# tags=settings.SITE.bleach_allowed_tags,
|
440
|
+
# attributes=settings.SITE.bleach_allowed_attributes,
|
441
|
+
# strip=True,
|
442
|
+
# )
|
443
|
+
# except TypeError as e:
|
444
|
+
# logger.warning("Could not bleach %r : %s (%s)", old, e, self)
|
445
|
+
# continue
|
446
|
+
if old != new:
|
447
|
+
logger.debug("Bleaching %s from %r to %r", f.name, old, new)
|
448
|
+
yield f, old, new
|
452
449
|
|
453
450
|
updatable_panels = None
|
454
451
|
|
lino/core/renderer.py
CHANGED
@@ -197,7 +197,7 @@ class HtmlRenderer(Renderer):
|
|
197
197
|
import rstgen
|
198
198
|
|
199
199
|
if display_mode == constants.DISPLAY_MODE_CARDS:
|
200
|
-
layout = ar.actor.card_layout or ar.actor.list_layout
|
200
|
+
layout = ar.actor.card_layout # or ar.actor.list_layout
|
201
201
|
lh = layout.get_layout_handle()
|
202
202
|
else:
|
203
203
|
lh = ar.bound_action.get_layout_handel()
|
@@ -1264,7 +1264,7 @@ class JsCacheRenderer(JsRenderer):
|
|
1264
1264
|
# if res.parameters is not None:
|
1265
1265
|
add(res, self.param_panels, res.params_layout, "%s.ParamsPanel" % res)
|
1266
1266
|
add(res, self.other_panels, res.card_layout, "%s.CardsPanel" % res)
|
1267
|
-
add(res, self.other_panels, res.list_layout, "%s.ItemsPanel" % res)
|
1267
|
+
# add(res, self.other_panels, res.list_layout, "%s.ItemsPanel" % res)
|
1268
1268
|
|
1269
1269
|
for ba in res.get_actions():
|
1270
1270
|
if ba.action.parameters:
|
lino/core/requests.py
CHANGED
@@ -317,6 +317,11 @@ class BaseRequest:
|
|
317
317
|
master_instance = None
|
318
318
|
request = None
|
319
319
|
selected_rows = []
|
320
|
+
order_by = None
|
321
|
+
filter = None
|
322
|
+
gridfilters = None,
|
323
|
+
quick_search = None
|
324
|
+
extra = None
|
320
325
|
content_type = "application/json"
|
321
326
|
requesting_panel = None
|
322
327
|
xcallback_answers = {}
|
@@ -411,10 +416,20 @@ class BaseRequest:
|
|
411
416
|
xcallback_answers=None,
|
412
417
|
known_values={},
|
413
418
|
show_urls=None,
|
419
|
+
quick_search=None,
|
420
|
+
order_by=None,
|
421
|
+
filter=None,
|
422
|
+
gridfilters=None,
|
423
|
+
extra=None,
|
414
424
|
):
|
415
425
|
if logger is not None:
|
416
426
|
self.logger = logger
|
417
427
|
self.requesting_panel = requesting_panel
|
428
|
+
self.quick_search = quick_search
|
429
|
+
self.order_by = order_by
|
430
|
+
self.filter = filter
|
431
|
+
self.gridfilters = gridfilters
|
432
|
+
self.extra = extra
|
418
433
|
if user is None:
|
419
434
|
self.user = settings.SITE.get_anonymous_user()
|
420
435
|
else:
|
@@ -532,36 +547,11 @@ class BaseRequest:
|
|
532
547
|
master_key=rqdata.get(constants.URL_PARAM_MASTER_PK, None),
|
533
548
|
)
|
534
549
|
|
535
|
-
# if settings.SITE.use_filterRow:
|
536
|
-
# exclude = dict()
|
537
|
-
# for f in self.ah.store.fields:
|
538
|
-
# if f.field:
|
539
|
-
# filterOption = rqdata.get(
|
540
|
-
# 'filter[%s_filterOption]' % f.field.name)
|
541
|
-
# if filterOption == 'empty':
|
542
|
-
# kw[f.field.name + "__isnull"] = True
|
543
|
-
# elif filterOption == 'notempty':
|
544
|
-
# kw[f.field.name + "__isnull"] = False
|
545
|
-
# else:
|
546
|
-
# filterValue = rqdata.get('filter[%s]' % f.field.name)
|
547
|
-
# if filterValue:
|
548
|
-
# if not filterOption:
|
549
|
-
# filterOption = 'contains'
|
550
|
-
# if filterOption == 'contains':
|
551
|
-
# kw[f.field.name + "__icontains"] = filterValue
|
552
|
-
# elif filterOption == 'doesnotcontain':
|
553
|
-
# exclude[f.field.name +
|
554
|
-
# "__icontains"] = filterValue
|
555
|
-
# else:
|
556
|
-
# print("unknown filterOption %r" % filterOption)
|
557
|
-
# if len(exclude):
|
558
|
-
# kw.update(exclude=exclude)
|
559
|
-
|
560
550
|
if settings.SITE.use_gridfilters:
|
561
|
-
|
562
|
-
if
|
563
|
-
|
564
|
-
kw["gridfilters"] = [constants.dict2kw(flt) for flt in
|
551
|
+
v = rqdata.get(constants.URL_PARAM_GRIDFILTER, None)
|
552
|
+
if v is not None:
|
553
|
+
v = json.loads(v)
|
554
|
+
kw["gridfilters"] = [constants.dict2kw(flt) for flt in v]
|
565
555
|
|
566
556
|
# kw = ActionRequest.parse_req(self, request, rqdata, **kw)
|
567
557
|
if settings.SITE.user_model:
|
@@ -962,6 +952,8 @@ class BaseRequest:
|
|
962
952
|
)
|
963
953
|
return
|
964
954
|
|
955
|
+
self.logger.info("Send email '%s' from %s to %s", subject, sender, recipients)
|
956
|
+
|
965
957
|
recipients = [a for a in recipients if "@example.com" not in a]
|
966
958
|
if not len(recipients):
|
967
959
|
self.logger.info(
|
@@ -970,8 +962,6 @@ class BaseRequest:
|
|
970
962
|
# self.logger.info("Email body would have been %s", body)
|
971
963
|
return
|
972
964
|
|
973
|
-
self.logger.info("Send email '%s' from %s to %s", subject, sender, recipients)
|
974
|
-
|
975
965
|
kw = {}
|
976
966
|
if body.startswith("<"):
|
977
967
|
kw["html_message"] = body
|
@@ -1666,11 +1656,8 @@ class ActionRequest(BaseRequest):
|
|
1666
1656
|
renderer = None
|
1667
1657
|
offset = None
|
1668
1658
|
limit = None
|
1669
|
-
order_by = None
|
1670
1659
|
master = None
|
1671
|
-
extra = None
|
1672
1660
|
title = None
|
1673
|
-
filter = None
|
1674
1661
|
limit = None
|
1675
1662
|
offset = None
|
1676
1663
|
|
@@ -1706,25 +1693,14 @@ class ActionRequest(BaseRequest):
|
|
1706
1693
|
known_values=None,
|
1707
1694
|
param_values=None,
|
1708
1695
|
action_param_values={},
|
1709
|
-
quick_search=None,
|
1710
|
-
order_by=None,
|
1711
1696
|
offset=None,
|
1712
1697
|
limit=None,
|
1713
1698
|
title=None,
|
1714
|
-
filter=None,
|
1715
|
-
gridfilters=None,
|
1716
1699
|
exclude=None,
|
1717
1700
|
selected_pks=None,
|
1718
1701
|
selected_rows=None,
|
1719
|
-
extra=None,
|
1720
1702
|
**kw
|
1721
1703
|
):
|
1722
|
-
self.quick_search = quick_search
|
1723
|
-
self.order_by = order_by
|
1724
|
-
self.filter = filter
|
1725
|
-
self.gridfilters = gridfilters
|
1726
|
-
self.extra = extra
|
1727
|
-
|
1728
1704
|
if title is not None:
|
1729
1705
|
self.title = title
|
1730
1706
|
if offset is not None:
|
lino/core/site.py
CHANGED
@@ -18,11 +18,6 @@ from pprint import pprint
|
|
18
18
|
from logging.handlers import SocketHandler
|
19
19
|
import time
|
20
20
|
|
21
|
-
try:
|
22
|
-
from bleach.sanitizer import ALLOWED_ATTRIBUTES
|
23
|
-
except ImportError:
|
24
|
-
ALLOWED_ATTRIBUTES = dict()
|
25
|
-
|
26
21
|
NO_REMOTE_AUTH = True
|
27
22
|
# 20240518 We have only one production site still using remote http
|
28
23
|
# authentication, and they will migrate to sessions-based auth with their next
|
@@ -359,44 +354,6 @@ class Site(object):
|
|
359
354
|
|
360
355
|
detail_main_name = "main"
|
361
356
|
|
362
|
-
bleach_allowed_tags = [
|
363
|
-
"a",
|
364
|
-
"b",
|
365
|
-
"i",
|
366
|
-
"em",
|
367
|
-
"ul",
|
368
|
-
"ol",
|
369
|
-
"li",
|
370
|
-
"strong",
|
371
|
-
"p",
|
372
|
-
"br",
|
373
|
-
"span",
|
374
|
-
"pre",
|
375
|
-
"def",
|
376
|
-
"div",
|
377
|
-
"img",
|
378
|
-
"table",
|
379
|
-
"th",
|
380
|
-
"tr",
|
381
|
-
"td",
|
382
|
-
"thead",
|
383
|
-
"tfoot",
|
384
|
-
"tbody",
|
385
|
-
]
|
386
|
-
|
387
|
-
ALLOWED_ATTRIBUTES["span"] = [
|
388
|
-
"class",
|
389
|
-
"data-index",
|
390
|
-
"data-denotation-char",
|
391
|
-
"data-link",
|
392
|
-
"data-title",
|
393
|
-
"data-value",
|
394
|
-
"contenteditable",
|
395
|
-
]
|
396
|
-
ALLOWED_ATTRIBUTES["p"] = ["href", "title", "align"]
|
397
|
-
|
398
|
-
bleach_allowed_attributes = ALLOWED_ATTRIBUTES
|
399
|
-
|
400
357
|
textfield_bleached = True
|
401
358
|
textfield_format = "plain"
|
402
359
|
verbose_client_info_message = False
|
@@ -627,6 +584,8 @@ class Site(object):
|
|
627
584
|
for k in ("DATABASES", "SECRET_KEY"):
|
628
585
|
self.django_settings[k] = self.master_site.django_settings[k]
|
629
586
|
|
587
|
+
self.update_settings(
|
588
|
+
EMAIL_SUBJECT_PREFIX=f'[{self.project_name}] ')
|
630
589
|
self.update_settings(
|
631
590
|
SERIALIZATION_MODULES={
|
632
591
|
"py": "lino.utils.dpy",
|
@@ -896,7 +855,7 @@ class Site(object):
|
|
896
855
|
# the default_ui.
|
897
856
|
return
|
898
857
|
raise Exception(
|
899
|
-
"Tried to install {}
|
858
|
+
"Tried to install {}, but {} is already installed.".format(
|
900
859
|
app_name, other
|
901
860
|
)
|
902
861
|
)
|
@@ -1009,7 +968,7 @@ class Site(object):
|
|
1009
968
|
for r in p.get_requirements(self):
|
1010
969
|
reqs.add(r)
|
1011
970
|
if self.textfield_bleached:
|
1012
|
-
reqs.add("
|
971
|
+
reqs.add("beautifulsoup4")
|
1013
972
|
return sorted(reqs)
|
1014
973
|
|
1015
974
|
def setup_plugins(self):
|
lino/core/store.py
CHANGED
@@ -1227,10 +1227,10 @@ class Store(BaseStore):
|
|
1227
1227
|
dh = form.get_layout_handle()
|
1228
1228
|
self.collect_fields(self.card_fields, dh)
|
1229
1229
|
|
1230
|
-
form = rh.actor.list_layout
|
1231
|
-
if form:
|
1232
|
-
|
1233
|
-
|
1230
|
+
# form = rh.actor.list_layout
|
1231
|
+
# if form:
|
1232
|
+
# dh = form.get_layout_handle()
|
1233
|
+
# self.collect_fields(self.item_fields, dh)
|
1234
1234
|
|
1235
1235
|
if self.pk is not None:
|
1236
1236
|
self.pk_index = 0
|
lino/core/utils.py
CHANGED
@@ -379,7 +379,7 @@ class UnresolvedModel(object):
|
|
379
379
|
# ~ print(self)
|
380
380
|
|
381
381
|
def __repr__(self):
|
382
|
-
return self.__class__.__name__ + "(%s
|
382
|
+
return self.__class__.__name__ + "(%r, %s)" % (self.model_spec, self.app_label)
|
383
383
|
|
384
384
|
# ~ def __getattr__(self,name):
|
385
385
|
# ~ raise AttributeError("%s has no attribute %r" % (self,name))
|
@@ -421,6 +421,9 @@ def resolve_model(model_spec, app_label=None, strict=False):
|
|
421
421
|
# settings.SITE.logger.info("20181230 resolve %s --> %r, %r",
|
422
422
|
# model_spec, app, model)
|
423
423
|
else:
|
424
|
+
# 20241112 Helped to explore #5797 (Could not resolve target
|
425
|
+
# 'uploads.UploadType' of ForeignKey 'type' in <class
|
426
|
+
# 'lino.modlib.uploads.models.Upload'>)
|
424
427
|
from django.apps import apps
|
425
428
|
|
426
429
|
try:
|
@@ -1113,7 +1116,7 @@ class PhantomRow(VirtualRow):
|
|
1113
1116
|
|
1114
1117
|
|
1115
1118
|
def login(username=None, **kwargs):
|
1116
|
-
"""Return a basic :term:`action request` with the specified user signed in.
|
1119
|
+
"""Return a basic :term:`action request` with the specified user signed in.
|
1117
1120
|
"""
|
1118
1121
|
from lino.core.requests import BaseRequest # avoid circular import
|
1119
1122
|
# settings.SITE.startup()
|
lino/help_texts.py
CHANGED
@@ -56,8 +56,8 @@ help_texts = {
|
|
56
56
|
'lino.mixins.periods.Started.save' : _("""Fills default value “today” to start_date"""),
|
57
57
|
'lino.mixins.periods.Ended' : _("""Mixin for models with two fields end_date and end_time."""),
|
58
58
|
'lino.mixins.periods.Ended.get_duration' : _("""Return the duration in hours."""),
|
59
|
-
'lino.mixins.periods.DateRange' : _("""
|
60
|
-
'lino.mixins.periods.ObservedDateRange' : _("""lino.core.param_panel.ParameterPanel with two fields start_date and end_date
|
59
|
+
'lino.mixins.periods.DateRange' : _("""A model mixin that adds two fields start_date and end_date. DateRangeObservable"""),
|
60
|
+
'lino.mixins.periods.ObservedDateRange' : _("""lino.core.param_panel.ParameterPanel with two fields start_date and end_date."""),
|
61
61
|
'lino.mixins.periods.Yearly' : _("""An ObservedDateRange for which start_date defaults to Jan 1st and end_date to Dec 31 of the current year."""),
|
62
62
|
'lino.mixins.periods.Monthly' : _("""An ObservedDateRange which defaults to the current month."""),
|
63
63
|
'lino.mixins.periods.Weekly' : _("""An ObservedDateRange which defaults to the current week."""),
|
@@ -174,6 +174,7 @@ help_texts = {
|
|
174
174
|
'lino.modlib.tinymce.Plugin.media_name' : _("""Lino currently includes three versions of TinyMCE, but for production sites we still use the eldest version 3.4.8."""),
|
175
175
|
'lino.modlib.uploads.Plugin' : _("""See /dev/plugins."""),
|
176
176
|
'lino.modlib.uploads.Plugin.remove_orphaned_files' : _("""Whether checkdata –fix should automatically delete orphaned files in the uploads folder."""),
|
177
|
+
'lino.modlib.uploads.Plugin.with_thumbnails' : _("""Whether to use PIL, the Python Imaging Library."""),
|
177
178
|
'lino.modlib.weasyprint.Plugin' : _("""See /dev/plugins."""),
|
178
179
|
'lino.modlib.weasyprint.Plugin.header_height' : _("""Height of header in mm. Set to None if you want no header."""),
|
179
180
|
'lino.modlib.weasyprint.Plugin.footer_height' : _("""Height of footer in mm. Set to None if you want no header."""),
|
@@ -515,7 +516,6 @@ help_texts = {
|
|
515
516
|
'lino.modlib.comments.Commentable.add_comments_filter' : _("""Add filters to the given queryset of comments, requested by the given user."""),
|
516
517
|
'lino.modlib.comments.Commentable.get_rfc_description' : _("""Return a HTML formatted string with the description of this Commentable as it should be displayed by the slave summary of CommentsByOwner."""),
|
517
518
|
'lino.modlib.comments.Commentable.on_commented' : _("""This is automatically called when a comment has been created or modified."""),
|
518
|
-
'lino.modlib.comments.Commentable.get_comment_group' : _("""(Currently not used)"""),
|
519
519
|
'lino.modlib.files.Volume' : _("""The Django model representing a file volume."""),
|
520
520
|
'lino.modlib.files.Volume.id' : _("""The primary key used to point to this volume from a database object."""),
|
521
521
|
'lino.modlib.files.Volume.ref' : _("""The full path of the root folder."""),
|
@@ -689,6 +689,7 @@ help_texts = {
|
|
689
689
|
'lino.modlib.uploads.UploadController.show_uploads' : _("""Opens a data window with the uploaded files associated to this database object."""),
|
690
690
|
'lino.modlib.uploads.UploadsByController' : _("""Shows the uploaded files associated to this database object."""),
|
691
691
|
'lino.modlib.uploads.Shortcuts' : _("""The list of available upload shortcut fields in this application."""),
|
692
|
+
'lino.modlib.uploads.Previewers' : _("""An abstract choicelist of the previewers that are available on this site."""),
|
692
693
|
'lino.modlib.uploads.UploadsFolderChecker' : _("""Find orphaned files in uploads folder."""),
|
693
694
|
'lino.modlib.weasyprint.WeasyBuildMethod' : _("""The base class for both build methods."""),
|
694
695
|
'lino.modlib.weasyprint.WeasyHtmlBuildMethod' : _("""Renders the input template and returns the unmodified output as plain HTML."""),
|