lino 25.3.0__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.
- lino/__init__.py +6 -7
- lino/api/dd.py +1 -0
- lino/api/doctest.py +35 -102
- lino/api/rt.py +2 -4
- lino/core/actors.py +22 -16
- lino/core/boundaction.py +17 -7
- lino/core/dashboard.py +5 -4
- lino/core/dbtables.py +15 -16
- lino/core/fields.py +3 -3
- lino/core/inject.py +7 -6
- lino/core/kernel.py +0 -46
- lino/core/menus.py +1 -1
- lino/core/model.py +18 -16
- lino/core/plugin.py +4 -4
- lino/core/renderer.py +10 -11
- lino/core/requests.py +11 -7
- lino/core/site.py +84 -30
- lino/core/tables.py +2 -2
- lino/core/utils.py +3 -3
- lino/core/views.py +3 -3
- lino/help_texts.py +1 -0
- lino/management/commands/buildsite.py +57 -0
- lino/management/commands/initdb.py +12 -14
- lino/management/commands/prep.py +1 -1
- lino/mixins/sequenced.py +1 -1
- lino/modlib/comments/models.py +1 -1
- lino/modlib/comments/ui.py +2 -2
- lino/modlib/extjs/ext_renderer.py +2 -2
- lino/modlib/extjs/views.py +50 -48
- lino/modlib/help/config/makehelp/model.tpl.rst +1 -1
- lino/modlib/help/management/commands/makehelp.py +11 -7
- lino/modlib/jinja/mixins.py +2 -2
- lino/modlib/jinja/renderer.py +2 -2
- lino/modlib/linod/management/commands/linod.py +5 -2
- lino/modlib/linod/mixins.py +3 -0
- lino/modlib/memo/__init__.py +1 -1
- lino/modlib/printing/mixins.py +3 -0
- lino/modlib/publisher/choicelists.py +3 -3
- lino/modlib/publisher/views.py +2 -2
- lino/modlib/search/models.py +5 -5
- lino/modlib/system/choicelists.py +6 -3
- lino/modlib/tinymce/views.py +1 -1
- lino/modlib/uploads/models.py +7 -6
- lino/modlib/users/ui.py +2 -3
- lino/utils/__init__.py +4 -1
- lino/utils/diag.py +1 -1
- lino/utils/fieldutils.py +79 -0
- {lino-25.3.0.dist-info → lino-25.3.2.dist-info}/METADATA +1 -1
- {lino-25.3.0.dist-info → lino-25.3.2.dist-info}/RECORD +52 -71
- lino/sandbox/bcss/PerformInvestigation.py +0 -2260
- lino/sandbox/bcss/SSDNReply.py +0 -3924
- lino/sandbox/bcss/SSDNRequest.py +0 -3723
- lino/sandbox/bcss/__init__.py +0 -0
- lino/sandbox/bcss/readme.txt +0 -1
- lino/sandbox/bcss/test.py +0 -92
- lino/sandbox/bcss/test2.py +0 -128
- lino/sandbox/bcss/test3.py +0 -161
- lino/sandbox/bcss/test4.py +0 -167
- lino/sandbox/contacts/__init__.py +0 -0
- lino/sandbox/contacts/fixtures/__init__.py +0 -0
- lino/sandbox/contacts/fixtures/demo.py +0 -365
- lino/sandbox/contacts/manage.py +0 -10
- lino/sandbox/contacts/models.py +0 -395
- lino/sandbox/contacts/settings.py +0 -67
- lino/sandbox/tx25/XSD/RetrieveTIGroupsV3.wsdl +0 -65
- lino/sandbox/tx25/XSD/RetrieveTIGroupsV3.xsd +0 -286
- lino/sandbox/tx25/XSD/rn25_Release201104.xsd +0 -2855
- lino/sandbox/tx25/xsd2py1.py +0 -68
- lino/sandbox/tx25/xsd2py2.py +0 -62
- lino/sandbox/tx25/xsd2py3.py +0 -56
- {lino-25.3.0.dist-info → lino-25.3.2.dist-info}/WHEEL +0 -0
- {lino-25.3.0.dist-info → lino-25.3.2.dist-info}/licenses/AUTHORS.rst +0 -0
- {lino-25.3.0.dist-info → lino-25.3.2.dist-info}/licenses/COPYING +0 -0
lino/modlib/extjs/views.py
CHANGED
@@ -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
|
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
|
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
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|
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
|
365
|
-
|
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
|
-
|
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
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
datarec
|
378
|
-
|
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
|
383
|
-
request=request, selected_pks=sr)
|
380
|
+
ar.set_selected_pks(pk)
|
384
381
|
except default_table.model.DoesNotExist:
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
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
|
-
|
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
|
397
|
-
# ar = ba.
|
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
|
|
@@ -41,8 +41,11 @@ 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
|
45
|
-
|
44
|
+
from lino.api import dd
|
45
|
+
|
46
|
+
# removed import doctest because it caused "pytest not installed" during
|
47
|
+
# makehelp on LF:
|
48
|
+
# from lino.api import doctest
|
46
49
|
|
47
50
|
use_dirhtml = False
|
48
51
|
|
@@ -88,7 +91,7 @@ def runcmd(cmd, **kw):
|
|
88
91
|
|
89
92
|
def field_ref(f):
|
90
93
|
if isinstance(f.model, Model):
|
91
|
-
return ":ref:`{}.{}`".format(full_model_name(f.model), f.name)
|
94
|
+
return ":ref:`{}.{}`".format(dd.full_model_name(f.model), f.name)
|
92
95
|
# parameter field
|
93
96
|
return ":ref:`{}.{}`".format(str(f.model), f.name)
|
94
97
|
|
@@ -133,7 +136,7 @@ def model_referenced_from(model):
|
|
133
136
|
def ddhfmt(ddh):
|
134
137
|
return ", ".join(
|
135
138
|
[
|
136
|
-
"{}.{}".format(full_model_name(model), fk.name)
|
139
|
+
"{}.{}".format(dd.full_model_name(model), fk.name)
|
137
140
|
for model, fk in ddh.fklist
|
138
141
|
]
|
139
142
|
)
|
@@ -255,14 +258,15 @@ class Command(GeneratingCommand):
|
|
255
258
|
settings=settings,
|
256
259
|
actors=actors,
|
257
260
|
# actors_list=[a for a in actors.actors_list if not a.abstract],
|
258
|
-
doctest=doctest,
|
261
|
+
# doctest=doctest,
|
259
262
|
translation=translation,
|
260
263
|
use_dirhtml=use_dirhtml,
|
261
264
|
include_useless=include_useless,
|
262
265
|
# ~ py2rst=rstgen.py2rst,
|
263
266
|
languages=[lng.django_code for lng in settings.SITE.languages],
|
264
267
|
get_models=apps.get_models,
|
265
|
-
full_model_name=full_model_name,
|
268
|
+
full_model_name=dd.full_model_name,
|
269
|
+
dd=dd,
|
266
270
|
model_overview=self.model_overview,
|
267
271
|
actor2par=self.actor2par,
|
268
272
|
actors2table=self.actors2table,
|
@@ -321,7 +325,7 @@ class Command(GeneratingCommand):
|
|
321
325
|
elif issubclass(x, models.Model):
|
322
326
|
if text is None:
|
323
327
|
text = x.__name__
|
324
|
-
return ":doc:`" + text + " <" + full_model_name(x) + ">`"
|
328
|
+
return ":doc:`" + text + " <" + dd.full_model_name(x) + ">`"
|
325
329
|
if isinstance(x, BoundAction):
|
326
330
|
if text is None:
|
327
331
|
text = x.action_name
|
lino/modlib/jinja/mixins.py
CHANGED
@@ -55,8 +55,8 @@ class XMLMaker(dd.Model):
|
|
55
55
|
if self.xml_validator_file:
|
56
56
|
# print("20250218 {xml[:100]}")
|
57
57
|
# doc = etree.fromstring(xml.encode("utf-8"))
|
58
|
-
ar.logger.info("Validate %s against %s ...",
|
59
|
-
|
58
|
+
# ar.logger.info("Validate %s against %s ...",
|
59
|
+
# xmlfile.path.name, self.xml_validator_file)
|
60
60
|
if True:
|
61
61
|
validate_xml(xmlfile.path, self.xml_validator_file)
|
62
62
|
else:
|
lino/modlib/jinja/renderer.py
CHANGED
@@ -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.
|
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.
|
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
|
-
|
55
|
-
|
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))
|
lino/modlib/linod/mixins.py
CHANGED
@@ -132,6 +132,9 @@ class Runnable(Sequenced, RecurrenceSet):
|
|
132
132
|
await ar.adebug("Successfully terminated %s", self)
|
133
133
|
# ar.info("Successfully terminated %s", astr(self))
|
134
134
|
self.message = out.getvalue()
|
135
|
+
except Warning as e:
|
136
|
+
await ar.adebug("Terminated %s with warning %s", self, str(e))
|
137
|
+
self.message = out.getvalue()
|
135
138
|
except Exception as e:
|
136
139
|
self.message = out.getvalue()
|
137
140
|
self.message += "\n" + "".join(traceback.format_exception(e))
|
lino/modlib/memo/__init__.py
CHANGED
@@ -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.
|
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):
|
lino/modlib/printing/mixins.py
CHANGED
@@ -183,6 +183,9 @@ class CachedPrintable(Duplicable, Printable):
|
|
183
183
|
def get_target_url(self):
|
184
184
|
return self.build_method.get_target_url(self.do_print, self)
|
185
185
|
|
186
|
+
def get_target_file(self):
|
187
|
+
return self.build_method.get_target_file(self.do_print, self)
|
188
|
+
|
186
189
|
def get_cache_mtime(self):
|
187
190
|
"""Return the modification time (a `datetime`) of the generated cache
|
188
191
|
file, or `None` if no such file exists.
|
@@ -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.
|
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.
|
163
|
-
sar = dv.
|
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
|
|
lino/modlib/publisher/views.py
CHANGED
@@ -37,7 +37,7 @@ class Element(View):
|
|
37
37
|
kw.update(selected_pks=[pk])
|
38
38
|
|
39
39
|
try:
|
40
|
-
ar = self.table_class.
|
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.
|
57
|
+
ar = dv.create_request(request=request, renderer=rnd, selected_rows=[index_node])
|
58
58
|
return index_node.get_publisher_response(ar)
|
lino/modlib/search/models.py
CHANGED
@@ -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.
|
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.
|
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.
|
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
|
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
|
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:{
|
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")
|
lino/modlib/tinymce/views.py
CHANGED
@@ -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.
|
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))
|
lino/modlib/uploads/models.py
CHANGED
@@ -481,12 +481,13 @@ def on_sanitize(soup, save=False, ar=None):
|
|
481
481
|
# raise Exception(f"20250301")
|
482
482
|
for tag in soup.find_all():
|
483
483
|
tag_name = tag.name.lower()
|
484
|
-
if tag_name == "img" and
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
484
|
+
if tag_name == "img" and ar is not None and save:
|
485
|
+
if (src := tag.get('src')) and src.startswith("data:image"):
|
486
|
+
file = base64_to_image(src)
|
487
|
+
upload = rt.models.uploads.Upload(file=file, user=ar.get_user())
|
488
|
+
sar = upload.get_default_table().create_request(parent=ar)
|
489
|
+
upload.save_new_instance(sar)
|
490
|
+
tag.replace_with(f'[file {upload.pk}]')
|
490
491
|
|
491
492
|
|
492
493
|
register_sanitizer(on_sanitize)
|
lino/modlib/users/ui.py
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
# License: GNU Affero General Public License v3 (see file COPYING for details)
|
4
4
|
# Documentation: :doc:`/specs/users` and :doc:`/dev/users`
|
5
5
|
|
6
|
+
from lino.core.site import has_socialauth
|
6
7
|
from datetime import datetime
|
7
8
|
from textwrap import wrap
|
8
9
|
from importlib import import_module
|
@@ -134,7 +135,7 @@ class UsersOverview(Users):
|
|
134
135
|
pv.update(password=dd.plugins.users.demo_password)
|
135
136
|
btn = rt.models.about.About.get_action_by_name("sign_in")
|
136
137
|
# print btn.get_row_permission(ar, None, None)
|
137
|
-
btn = btn.
|
138
|
+
btn = btn.create_request(
|
138
139
|
action_param_values=pv, renderer=settings.SITE.kernel.default_renderer
|
139
140
|
)
|
140
141
|
btn = btn.ar2button(label=self.username)
|
@@ -212,8 +213,6 @@ class AuthoritiesTaken(Authorities):
|
|
212
213
|
auto_fit_column_widths = True
|
213
214
|
|
214
215
|
|
215
|
-
from lino.core.site import has_socialauth
|
216
|
-
|
217
216
|
if has_socialauth and dd.get_plugin_setting("users", "third_party_authentication"):
|
218
217
|
import social_django
|
219
218
|
|
lino/utils/__init__.py
CHANGED
@@ -21,6 +21,7 @@ function for general use. It has also many subpackages and submodules.
|
|
21
21
|
diag
|
22
22
|
djangotest
|
23
23
|
dpy
|
24
|
+
fieldutils
|
24
25
|
html
|
25
26
|
html2odf
|
26
27
|
html2xhtml
|
@@ -78,6 +79,7 @@ from rstgen.utils import confirm, i2d, i2t
|
|
78
79
|
|
79
80
|
DATE_TO_DIR_TPL = "%Y/%m"
|
80
81
|
|
82
|
+
|
81
83
|
def read_exception(excinfo):
|
82
84
|
# TODO: why not use traceback.format_exc(excinfo) intead of this?
|
83
85
|
f = StringIO()
|
@@ -353,7 +355,7 @@ def hex2str(value):
|
|
353
355
|
raise Exception("hex2str got value %r" % value)
|
354
356
|
r = ""
|
355
357
|
for i in range(old_div(len(value), 2)):
|
356
|
-
s = value[i * 2
|
358
|
+
s = value[i * 2: i * 2 + 2]
|
357
359
|
h = int(s, 16)
|
358
360
|
r += chr(h)
|
359
361
|
return r
|
@@ -364,6 +366,7 @@ curry = lambda func, *args, **kw: lambda *p, **n: func(
|
|
364
366
|
*args + p, **dict(list(kw.items()) + list(n.items()))
|
365
367
|
)
|
366
368
|
|
369
|
+
|
367
370
|
def capture_output(func, *args, **kwargs):
|
368
371
|
s = StringIO()
|
369
372
|
with redirect_stdout(s):
|
lino/utils/diag.py
CHANGED
@@ -443,7 +443,7 @@ def py2rst(self, doctestfmt=False, fmt=None):
|
|
443
443
|
from lino.core.store import get_atomizer
|
444
444
|
|
445
445
|
if isinstance(self, models.Model) and fmt is None:
|
446
|
-
ar = self.get_default_table().
|
446
|
+
ar = self.get_default_table().create_request()
|
447
447
|
|
448
448
|
def fmt(e):
|
449
449
|
s = elem_label(e)
|