lino 25.3.2__py3-none-any.whl → 25.3.3__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 CHANGED
@@ -31,7 +31,7 @@ from django import VERSION
31
31
  from django.apps import AppConfig
32
32
  from django.conf import settings
33
33
  import warnings
34
- __version__ = '25.3.2'
34
+ __version__ = '25.3.3'
35
35
 
36
36
  # import setuptools # avoid UserWarning "Distutils was imported before Setuptools"?
37
37
 
lino/api/doctest.py CHANGED
@@ -22,6 +22,7 @@ from django.db.models import Model
22
22
  from lino.core.actions import ShowTable
23
23
  from lino.core.menus import Menu
24
24
  from lino.utils.html import html2text
25
+ from lino.utils import dbhash
25
26
  from lino.core.utils import full_model_name, get_models
26
27
  from lino.utils.diag import visible_for
27
28
  from lino.sphinxcontrib.actordoc import menuselection_text
lino/core/site.py CHANGED
@@ -3,14 +3,12 @@
3
3
  # License: GNU Affero General Public License v3 (see file COPYING for details)
4
4
  # doctest lino/core/site.py
5
5
 
6
- import json
7
6
  from lino.core.exceptions import ChangedAPI
8
- from lino.core.utils import get_models, is_logserver
7
+ from django.apps import apps
9
8
  from lino.utils.html import E, tostring
10
9
  from lino import assert_django_code, DJANGO_DEFAULT_LANGUAGE
11
10
  # from lino.core import constants
12
11
  from lino.core.plugin import Plugin
13
- from lino.core.utils import full_model_name as fmn
14
12
  from rstgen.confparser import ConfigParser
15
13
  from django.utils import translation
16
14
  from django.utils.html import mark_safe
@@ -657,7 +655,6 @@ class Site(object):
657
655
  log_file_path = logdir / self.logger_filename
658
656
  # print("20231019 logging", file_level, "to", log_file_path)
659
657
  self.log_sock_path = logdir / (self.logger_filename + ".sock")
660
- # if is_logserver() or not self.log_sock_path.exists():
661
658
  if self.log_sock_path.exists():
662
659
  # print("20231019 log via socket server")
663
660
  handlers["file"] = {
@@ -1348,10 +1345,8 @@ class Site(object):
1348
1345
  setattr(obj, name, resolve_model(spec, strict=msg))
1349
1346
 
1350
1347
  def on_each_app(self, methname, *args):
1351
- from django.apps import apps
1352
-
1353
- apps = [a.models_module for a in apps.get_app_configs()]
1354
- for mod in apps:
1348
+ modules = [a.models_module for a in apps.get_app_configs()]
1349
+ for mod in modules:
1355
1350
  meth = getattr(mod, methname, None)
1356
1351
  if meth is not None:
1357
1352
  if False: # 20150925 once we will do it for good...
@@ -1470,7 +1465,7 @@ class Site(object):
1470
1465
  def setup_actions(self):
1471
1466
  from lino.core.merge import MergeAction
1472
1467
 
1473
- for m in get_models():
1468
+ for m in apps.get_models():
1474
1469
  if m.allow_merge_action:
1475
1470
  m.define_action(merge_row=MergeAction(m))
1476
1471
 
@@ -1794,61 +1789,6 @@ class Site(object):
1794
1789
  # ~ return v
1795
1790
  # ~ return getattr(obj,attrname,*args)
1796
1791
 
1797
- def mark_virgin(self):
1798
- """
1799
- Mark the database as virgin. This is called by :manage:`prep`.
1800
- """
1801
- dbhash = self.get_dbhash()
1802
- fn = self.site_dir / "dbhash.json"
1803
- with fn.open("w") as fp:
1804
- json.dump(dbhash, fp)
1805
- # self.site.logger.info("Wrote %s", fn)
1806
-
1807
- def check_virgin(self):
1808
- """
1809
- Verify whether the database is virgin. Print the differences if there
1810
- are any.
1811
- """
1812
- new = self.get_dbhash()
1813
- db = self.site_dir
1814
- fn = db / "dbhash.json"
1815
- if not fn.exists():
1816
- raise Exception(
1817
- f"No `dbhash.json` in {db} (did you run `django-admin prep`?)")
1818
- with fn.open("r") as fp:
1819
- old = json.load(fp)
1820
-
1821
- # noi1r has noi1e as master_site, but the react front end removes the
1822
- # tinymce plugin, i.e. noi1r doesn't care about
1823
- # tinymce.TextFieldTemplate model.
1824
-
1825
- ok = True
1826
- for k, v in new.items():
1827
- v = set(v)
1828
- oldv = set(old.get(k, None))
1829
- if oldv != v:
1830
- if ok:
1831
- print(f"Database {db} isn't virgin:")
1832
- ok = False
1833
- diffs = []
1834
- if (added := len(oldv-v)):
1835
- diffs.append(f"{added} rows added")
1836
- if (removed := len(v-oldv)):
1837
- diffs.append(f"{removed} rows removed")
1838
- print(f"- {k}: {', '.join(diffs)}")
1839
-
1840
- def get_dbhash(self):
1841
- """
1842
- Return a dictionary with a hash value of the current database content.
1843
- """
1844
- rv = dict()
1845
- for m in get_models(include_auto_created=True):
1846
- k = fmn(m)
1847
- if k != "sessions.Session":
1848
- # rv[k] = m.objects.count()
1849
- rv[k] = list(m.objects.values_list('pk', flat=True))
1850
- return rv
1851
-
1852
1792
  def diagnostic_report_rst(self, *args):
1853
1793
  """Returns a string with a diagnostic report about this
1854
1794
  site. :manage:`diag` is a command-line shortcut to this.
@@ -1998,18 +1938,9 @@ class Site(object):
1998
1938
  return self._sorted_plugins
1999
1939
 
2000
1940
  def setup_menu(self, user_type, main, ar=None):
2001
- # from django.apps import apps
2002
- # apps = [a.models_module for a in apps.get_app_configs()]
2003
-
2004
1941
  for k, label in self.top_level_menus:
2005
1942
  methname = "setup_{0}_menu".format(k)
2006
1943
 
2007
- # for mod in apps:
2008
- # if hasattr(mod, methname):
2009
- # msg = "{0} still has a function {1}(). \
2010
- # Please convert to Plugin method".format(mod, methname)
2011
- # raise ChangedAPI(msg)
2012
-
2013
1944
  if label is None:
2014
1945
  menu = main
2015
1946
  else:
@@ -2074,6 +2005,9 @@ class Site(object):
2074
2005
  return mark_safe(s)
2075
2006
 
2076
2007
  def build_site_cache(self, force=False, later=False, verbosity=1):
2008
+ from lino.modlib.users.utils import with_user_profile
2009
+ from lino.modlib.users.choicelists import UserTypes
2010
+ # from django.utils import translation
2077
2011
  # if not self.is_prepared:
2078
2012
  # self.prepare_layouts()
2079
2013
  # self.is_prepared = True
@@ -2108,9 +2042,8 @@ class Site(object):
2108
2042
 
2109
2043
  self.makedirs_if_missing(self.media_root / "webdav")
2110
2044
 
2111
- from lino.modlib.users.utils import with_user_profile
2112
- from lino.modlib.users.choicelists import UserTypes
2113
- # from django.utils import translation
2045
+ if verbosity > 0:
2046
+ self.logger.info("Build site cache in %s.", self.media_root)
2114
2047
 
2115
2048
  started = time.time()
2116
2049
  count = 0
@@ -10,22 +10,32 @@ from lino import logger
10
10
 
11
11
 
12
12
  class Command(BaseCommand):
13
- """Run install, buildcache, collectstatic and makehelp after pull."""
13
+ """Build the site cache files and optionally run collectstatic for this Lino site."""
14
14
 
15
15
  def add_arguments(self, parser):
16
16
  super().add_arguments(parser)
17
17
  parser.add_argument(
18
- "--noinput",
18
+ "-b", "--batch", "--noinput",
19
19
  action="store_false",
20
20
  dest="interactive",
21
21
  default=True,
22
22
  help="Do not prompt for input of any kind.",
23
23
  ),
24
+ parser.add_argument(
25
+ "-c", "--collectstatic",
26
+ action="store_true",
27
+ dest="collectstatic",
28
+ default=False,
29
+ help="Also run collectstatic.",
30
+ ),
24
31
 
25
32
  def handle(self, *args, **options):
26
33
  interactive = options.get("interactive")
27
34
  verbosity = options.get("verbosity")
28
35
  project_dir = settings.SITE.project_dir
36
+ collectstatic = options.get("collectstatic")
37
+
38
+ options = dict(interactive=False, verbosity=verbosity)
29
39
 
30
40
  if interactive:
31
41
  msg = "Build everything for ({})".format(project_dir)
@@ -37,21 +47,21 @@ class Command(BaseCommand):
37
47
  if verbosity > 0:
38
48
  logger.info("`buildsite` started on %s.", project_dir)
39
49
 
40
- pth = project_dir / "settings.py"
41
- if pth.exists():
42
- pth.touch()
50
+ # pth = project_dir / "settings.py"
51
+ # if pth.exists():
52
+ # pth.touch()
43
53
 
44
- options = dict(interactive=False, verbosity=verbosity)
54
+ if collectstatic:
55
+ call_command("collectstatic", **options)
56
+
57
+ settings.SITE.build_site_cache(force=True, verbosity=verbosity)
45
58
 
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)
59
+ # if settings.SITE.is_installed("help"):
60
+ # call_command("makehelp", verbosity=verbosity)
51
61
 
52
62
  # for p in settings.SITE.installed_plugins:
53
63
  # p.on_buildsite(settings.SITE, verbosity=verbosity)
54
64
 
55
- settings.SITE.clear_site_config()
65
+ # settings.SITE.clear_site_config()
56
66
 
57
67
  logger.info("`buildsite` finished on %s.", project_dir)
@@ -2,6 +2,10 @@
2
2
  # Copyright 2013-2023 by Rumma & Ko Ltd.
3
3
  # License: GNU Affero General Public License v3 (see file COPYING for details)
4
4
 
5
+ from lino.utils.mldbc.fields import BabelCharField, BabelTextField
6
+ from lino.core.choicelists import ChoiceListField
7
+ from lino.core.utils import sorted_models_list, full_model_name
8
+ from lino.utils import puts
5
9
  from io import open
6
10
  from lino import logger
7
11
 
@@ -20,12 +24,6 @@ from datetime import timezone
20
24
 
21
25
  utc = timezone.utc
22
26
 
23
- from lino.utils import puts
24
- from lino.core.utils import sorted_models_list, full_model_name
25
- from lino.core.choicelists import ChoiceListField
26
-
27
- from lino.utils.mldbc.fields import BabelCharField, BabelTextField
28
-
29
27
 
30
28
  def is_pointer_to_contenttype(f):
31
29
  if not settings.SITE.is_installed("contenttypes"):
@@ -402,7 +400,7 @@ def main(args):
402
400
  if __name__ == '__main__':
403
401
  import argparse
404
402
  parser = argparse.ArgumentParser(description='Restore the data.')
405
- parser.add_argument('--noinput', dest='interactive',
403
+ parser.add_argument('-b', '--noinput', '--batch', dest='interactive',
406
404
  action='store_false', default=True,
407
405
  help="Don't ask for confirmation before flushing the database.")
408
406
  parser.add_argument('--quick', dest='quick',
@@ -4,7 +4,7 @@
4
4
 
5
5
  import sys
6
6
  import subprocess
7
- from rstgen.utils import confirm
7
+ from click import confirm
8
8
  from django.core.management.base import BaseCommand
9
9
  from django.conf import settings
10
10
 
@@ -54,5 +54,5 @@ class Command(BaseCommand):
54
54
  return
55
55
  # cmd = "pip install --upgrade --trusted-host svn.forge.pallavi.be {}".format(' '.join(reqs))
56
56
  cmd = sys.executable + " -m pip install --upgrade pip {}".format(" ".join(reqs))
57
- if not options["interactive"] or confirm("{} (y/n) ?".format(cmd)):
57
+ if not options["interactive"] or confirm("{} ?".format(cmd), default=True):
58
58
  runcmd(cmd)
@@ -1,15 +1,11 @@
1
1
  # -*- coding: UTF-8 -*-
2
- # Copyright 2013-2023 Rumma & Ko Ltd
2
+ # Copyright 2013-2025 Rumma & Ko Ltd
3
3
  # License: GNU Affero General Public License v3 (see file COPYING for details)
4
4
 
5
- from pathlib import Path
6
5
  from django.core.management import call_command
7
6
  from django.core.management.base import BaseCommand, CommandError
8
7
  from django.conf import settings
9
- from django.db import DEFAULT_DB_ALIAS
10
- from rstgen.utils import confirm
11
- # from lino.management.commands.initdb import Command as BaseCommand
12
- # from lino.management.commands.initdb import CommandError
8
+ from lino.utils import dbhash
13
9
 
14
10
 
15
11
  class Command(BaseCommand):
@@ -66,4 +62,4 @@ class Command(BaseCommand):
66
62
  kwargs["removemedia"] = True
67
63
  call_command("initdb", *args, **kwargs)
68
64
 
69
- settings.SITE.mark_virgin()
65
+ dbhash.mark_virgin()
lino/utils/__init__.py CHANGED
@@ -18,6 +18,7 @@ function for general use. It has also many subpackages and submodules.
18
18
  dataserializer
19
19
  dbfreader
20
20
  dblogger
21
+ dbhash
21
22
  diag
22
23
  djangotest
23
24
  dpy
lino/utils/dbhash.py ADDED
@@ -0,0 +1,112 @@
1
+ # -*- coding: UTF-8 -*-
2
+ # Copyright 2009-2025 Rumma & Ko Ltd
3
+ # License: GNU Affero General Public License v3 (see file COPYING for details)
4
+
5
+ """
6
+ Utilities around a "database hash".
7
+ See :doc:`/utils/dbhash`.
8
+ """
9
+
10
+ import json
11
+ from importlib import import_module
12
+ from pathlib import Path
13
+ from django.conf import settings
14
+ from django.apps import apps
15
+ from django.db.models.deletion import ProtectedError
16
+
17
+ mod = import_module(settings.SETTINGS_MODULE)
18
+ HASH_FILE = Path(mod.__file__).parent / "dbhash.json"
19
+
20
+
21
+ def fmn(m):
22
+ return f"{m._meta.app_label}.{m._meta.object_name}"
23
+
24
+
25
+ def compute_dbhash():
26
+ """
27
+ Return a dictionary with a hash value of the current database content.
28
+ """
29
+ rv = dict()
30
+ for m in apps.get_models(include_auto_created=True):
31
+ k = fmn(m)
32
+ if k != "sessions.Session":
33
+ # rv[k] = m.objects.count()
34
+ rv[k] = list(m.objects.values_list('pk', flat=True))
35
+ return rv
36
+
37
+
38
+ def mark_virgin():
39
+ """
40
+ Mark the database as virgin. This is called by :manage:`prep`.
41
+ """
42
+ dbhash = compute_dbhash()
43
+ with HASH_FILE.open("w") as fp:
44
+ json.dump(dbhash, fp)
45
+
46
+
47
+ def load_dbhash():
48
+ """
49
+ Load the dbhash that was saved in :xfile:`dbhash.json`
50
+ """
51
+ if not HASH_FILE.exists():
52
+ raise Exception(
53
+ f"No file {HASH_FILE} (did you run `django-admin prep`?)")
54
+ with HASH_FILE.open("r") as fp:
55
+ return json.load(fp)
56
+
57
+
58
+ def check_virgin(restore=True, verbose=True):
59
+ """
60
+ Verify whether the database is virgin. Print the differences if there
61
+ are any.
62
+ """
63
+ new = compute_dbhash()
64
+ old = load_dbhash()
65
+
66
+ first_diff = True
67
+ can_restore = True
68
+ must_delete = {}
69
+ for k, v in new.items():
70
+ v = set(v)
71
+ oldv = set(old.get(k, None))
72
+ if oldv != v:
73
+ if first_diff:
74
+ if verbose:
75
+ print(f"Database {HASH_FILE.parent} isn't virgin:")
76
+ first_diff = False
77
+ diffs = []
78
+ added = v - oldv
79
+ if len(added):
80
+ diffs.append(f"{len(added)} rows added")
81
+ must_delete[apps.get_model(k)] = added
82
+ # for pk in added:
83
+ # must_delete.append(m.objects.get(pk=pk))
84
+ if (removed := len(oldv-v)):
85
+ diffs.append(f"{removed} rows deleted")
86
+ can_restore = False
87
+ if verbose:
88
+ print(f"- {k}: {', '.join(diffs)}")
89
+ if len(must_delete) == 0 or not restore:
90
+ return
91
+ if not can_restore:
92
+ raise Exception(
93
+ "Cannot restore database because some rows have been deleted")
94
+ # print(f"Tidy up {len(must_delete)} rows from database")
95
+ # It can happen that some rows refer to each other with a protected fk
96
+ # We call bulk delete() to avoid Lino deleting the items of an invoice
97
+ must_delete = list(must_delete.items())
98
+ while len(must_delete):
99
+ todo = []
100
+ hope = False
101
+ for m, added in must_delete:
102
+ try:
103
+ m.objects.filter(pk__in=added).delete()
104
+ # obj.delete()
105
+ hope = True
106
+ except Exception:
107
+ todo.append((m, added))
108
+ if not hope:
109
+ raise Exception(f"Failed to delete {todo}")
110
+ must_delete = todo
111
+ if verbose:
112
+ print("Database has been restored.")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lino
3
- Version: 25.3.2
3
+ Version: 25.3.3
4
4
  Summary: A framework for writing desktop-like web applications using Django and ExtJS or React
5
5
  Project-URL: Homepage, https://www.lino-framework.org
6
6
  Project-URL: Repository, https://gitlab.com/lino-framework/lino
@@ -1,6 +1,6 @@
1
1
  lino/.cvsignore,sha256=1vrrWoP-WD8hPfCszHHIiJEi8KUMRCt5WvoKB9TSB1k,28
2
2
  lino/SciTEDirectory.properties,sha256=rCYi_e-6h8Yx5DwXhAa6MBPlVINcl6Vv9BQDYZV2_go,28
3
- lino/__init__.py,sha256=JSaZWfVR4OayYdVzI4qaWfe-r8BIhXc8Fyo0p9o8B-4,5915
3
+ lino/__init__.py,sha256=yyhUdRFDF6YNOft_vdDCiieTETtc-ISKZtJ1-AvJR8c,5915
4
4
  lino/ad.py,sha256=AQ-vJ4scac1mx3xegXezxnxyOQpV-a0q3VFMJSDbj2s,142
5
5
  lino/apps.py,sha256=ECq-dPARDkuhngwNrcipse3b4Irj70HxJs44uWEZFc4,27
6
6
  lino/hello.py,sha256=7-PJg7PnEiznyETqGjOwXcKh8rda0qLetpbS2gvRYy0,532
@@ -8,7 +8,7 @@ lino/help_texts.py,sha256=RMFC74eOV6v5TO7dv-1jM9FFham2AyuuuzDTJgOIKfU,91231
8
8
  lino/api/__init__.py,sha256=WmzHU-rHdZ68se_nI0SmepQTGE8-cd9tPpovHRH9aag,512
9
9
  lino/api/ad.py,sha256=F6SrcKPRRalHKOZ7QLwsRWGq9hhykQIeo0b85cEk9NQ,314
10
10
  lino/api/dd.py,sha256=R0Hx5McdTz86Veba9SttWSOIn2lTDXdpTQEEK10XEsw,7426
11
- lino/api/doctest.py,sha256=vxC79ZFJXV6vmezbJ4f2pykWI6Rte1-mlBaJAeo7Pzw,23998
11
+ lino/api/doctest.py,sha256=87j1_xGpomQlEmUUh8CprBFbbqKuQe1OWr5iIXABWag,24028
12
12
  lino/api/rt.py,sha256=OCYWhrWnMcL988MdvBLBEP8qKQJEGXQhVoam_X0sotU,1376
13
13
  lino/api/selenium.py,sha256=bOu8UaNz3Q7lGVvxjmvrtYtSWn1xfI1f5MN5sVcdYr8,9383
14
14
  lino/api/shell.py,sha256=epyjwEZ396TiJ0AHqhVIvzX8TBIXU8xR4UHJlYOrRhc,536
@@ -59,7 +59,7 @@ lino/core/renderer.py,sha256=auQn2v9bBp6jLIH3hXRQXbrjFrTmsO1o0DwaoXBn1eE,47310
59
59
  lino/core/requests.py,sha256=67335dTFqcwfF1PvWFmWwDKmVyJvDW9dMRQJF_X_Q9I,95093
60
60
  lino/core/roles.py,sha256=PXwk436xUupxdbJcygRSYFu7ixfKjAJPQRUQ8sy0lB0,4425
61
61
  lino/core/signals.py,sha256=0JT89mkjSbRm57QZcSI9DoThoKUGkyi-egNhuLUKEds,948
62
- lino/core/site.py,sha256=JhAj4eBmgEv0aJIiHIW2HNPlRIDvC4gCZneDtBmpTLA,84998
62
+ lino/core/site.py,sha256=SOwcz3MZNRq0HFpRUwEMhnrqX4bGAWMPBYi0sS9eIaw,82631
63
63
  lino/core/store.py,sha256=6pd4J5Y-U7Muz4mKFSL6K9KEZpJUbpM-I7RQTWyCo-8,51483
64
64
  lino/core/tables.py,sha256=rMMDmDKMcWJ39fD9Q_EFV7qdcXMktwO40G4ATyKuRGg,24427
65
65
  lino/core/urls.py,sha256=06QlmN1vpxjmb5snO3SPpP6lX1pMdE60bTiBiC77_vQ,2677
@@ -97,20 +97,20 @@ lino/locale/zh_Hant/LC_MESSAGES/django.po,sha256=JeP8cSTQ5bjX12Nr3EcCVhIaR-1pBYl
97
97
  lino/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
98
98
  lino/management/commands/__init__.py,sha256=raVDRiXns3SegyXEhaLZMcxfEDs7ggy2nFUN5D0f5F0,47
99
99
  lino/management/commands/buildcache.py,sha256=QjhvKKdp1mX6rl8Y5rcS6kUK2LVOBVAd6wrUKLYSGF8,448
100
- lino/management/commands/buildsite.py,sha256=DF3IJAGo62fkv_iGlu_jHj-ytNd5x31YgPPxLvtGVIw,1938
100
+ lino/management/commands/buildsite.py,sha256=BsXoKjQEA8sT57nD-_8Fd5ji9lARQ4ymkNMdhgyiXj0,2256
101
101
  lino/management/commands/demotest.py,sha256=yvxpl1G0Clt-iu7lY0DK9HVhaWyl_tQhYx0YUpddTWM,5041
102
102
  lino/management/commands/diag.py,sha256=vt-NlZUx5gf7T4EpbM-gle3tAwMuwfPQY8lUgxjFaUw,478
103
- lino/management/commands/dump2py.py,sha256=DyvhXYPJY7-Tt_xyw4_U5WjVeobcOU5AhWRZB6l4esI,20329
103
+ lino/management/commands/dump2py.py,sha256=X2u6OVkSb4MVQucF6jOKDDwRc8TCBNakW3UX_9S-n-U,20344
104
104
  lino/management/commands/dump_settings.py,sha256=tGOR4h_ueVe2DOk84ILFvzvndt0doshvaxRkybB-rnY,2009
105
105
  lino/management/commands/initdb.py,sha256=j_cWTlugP2-UP_qnHpXmz_pzPGRK1oORymjxphhcdEg,11398
106
- lino/management/commands/install.py,sha256=PljQJecr9s8rk5caR4rW0Fg1mL3S9JJHp6NqgB8bWTs,1888
106
+ lino/management/commands/install.py,sha256=k7lCJznVLS6swR4ayKNulj5TPpJ3qf99Fha87TZAaUk,1889
107
107
  lino/management/commands/makemigdump.py,sha256=TvNnFFjD6XRMFLbX8IEMSNDKTMPLTBCi8i5SRNcpYD8,1279
108
108
  lino/management/commands/makescreenshots.py,sha256=fJF7ATZz7_s1IWkkYMEHVTLB5r5C1ny-kJp253BeoKM,8667
109
109
  lino/management/commands/makeui.py,sha256=qYz68fnUKNXicZfGy3GXdjIZubhg1KyQnqjMblFN_LY,4813
110
110
  lino/management/commands/mergedata.py,sha256=-dPvBtyc-AqKpQeL4TUd2IKHGe8EaaW8Citcsp_hwEU,2527
111
111
  lino/management/commands/monitor.py,sha256=-axtsW-uzk87ESR6-GSfUL0Y2ylB5BwHC6Xlx3fPxo4,5113
112
112
  lino/management/commands/passwd.py,sha256=S-7qyUWOaBnqRo_quwWewJjzwonqK4PBP2j8fuBGy3c,3012
113
- lino/management/commands/prep.py,sha256=pCRRbuv5V2PYyIAdpFPmsQVl0LBge-M-jW2ENYW4-rw,2309
113
+ lino/management/commands/prep.py,sha256=V5pEHmw5ldav9flgJNfW96Z5TI5Z1rz5gMN5l0e32mg,2107
114
114
  lino/management/commands/qtclient.py,sha256=ltZyz-SmIevotRmv26TmPiW8VTXKK37DUwdwwMUzrHI,4715
115
115
  lino/management/commands/resetsequences.py,sha256=v7MdzJCw-rBXljttCsgoMIi-cgubCPptXDlcNO0pCjw,978
116
116
  lino/management/commands/run.py,sha256=MiK53KIACYKDTKF6knJGwU-uzEApGnDxByi-3_nrTjQ,1115
@@ -4579,7 +4579,7 @@ lino/templates_old/404.html,sha256=9O5EJgULwLws0X1LjNig3xT4l9Hw04MBIGswD-EAlnw,2
4579
4579
  lino/templates_old/500.html,sha256=inOR744w4FGJM_fCSQcnlk-OIYQpaBTxUQWgXQozon4,496
4580
4580
  lino/templates_old/base.html,sha256=qYqj5-u1UPtpatrFkqBr3MnwS0oFUXCyQRcuNZczDfk,1641
4581
4581
  lino/templates_old/base_site.html,sha256=NcLEk0kBT1b-SrhoGpDPUej7NExqJ9-dP1kbrvwBzrs,255
4582
- lino/utils/__init__.py,sha256=G8usc5_91WE_cqojsq9sNSRcSla7oqT5509zcAmbtRU,18380
4582
+ lino/utils/__init__.py,sha256=MFwWwBqgr6pPomfpfB9DvsXiB16EVBpWSSNanmI7Vqw,18391
4583
4583
  lino/utils/addressable.py,sha256=o7bmLbyvrmOoAT478s7XqjWKvnZ7zSXj4k7Xf0ccqf8,2213
4584
4584
  lino/utils/ajax.py,sha256=npCS0WumhTQlBzXxQPKnp2sYCRcPsYcbFqzE2ykVc4Q,3254
4585
4585
  lino/utils/choosers.py,sha256=9jjeLz-QcWVBfR8_GdY4PNYoqIYM63OI3OvOL2l1ZaU,17604
@@ -4590,6 +4590,7 @@ lino/utils/daemoncommand.py,sha256=NjGShiz09fddIV0WU0jK2nzO_CwPj1MfdmgwAOYZi4M,1
4590
4590
  lino/utils/dataserializer.py,sha256=-_xHXaGwDSO6-sYEHEa2BtEmKS8bW6gsYx4dV-GbvDs,3779
4591
4591
  lino/utils/dates.py,sha256=eWF5WxA5uJf51Y9PKvDVBWD8yIf6yBF6oO6TeU3ujzw,1030
4592
4592
  lino/utils/dbfreader.py,sha256=4sXOGBKX6DFQCEPkCMfnJAVneHMyDzJQB5tsYAq90vQ,12205
4593
+ lino/utils/dbhash.py,sha256=9qZS64tri2A88fX7iKRQVx0Xks7ow2r9oo020paYmSg,3368
4593
4594
  lino/utils/dblogger.py,sha256=kr0YxQY6veymvNg5A4tsvkqW8haRWdwqL0C-_9_QTg0,721
4594
4595
  lino/utils/diag.py,sha256=8BGsPrLd1_Fympy3PKiTpX1MdMWGApXr6IBoVOkWRxE,18314
4595
4596
  lino/utils/djangotest.py,sha256=Phz1qNp0wDonZRja5dxbCk0Xl3a73gZNiKK8v9tAgZg,8334
@@ -4633,8 +4634,8 @@ lino/utils/xml.py,sha256=EGDnO1UaREst9fS7KTESdbHnrrVCwKbRQdvut6B6GmQ,1612
4633
4634
  lino/utils/mldbc/__init__.py,sha256=QqWRlzeXaOmFfbCk-vTY3SZMn1-FCf67XnpZdd_Nim0,1134
4634
4635
  lino/utils/mldbc/fields.py,sha256=tAX8G5UKigr9c6g0F3ARIjZZtg406mdaZ--PWSbiH9E,2873
4635
4636
  lino/utils/mldbc/mixins.py,sha256=CkYe5jDa7xp9fJq_V8zcZf8ocxgIjUgHc9KZccvA_Yw,1945
4636
- lino-25.3.2.dist-info/METADATA,sha256=aV-5LIwoIcuTOc1o_4p5-YNOFn2_9xNKSKIrq-498f4,42534
4637
- lino-25.3.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
4638
- lino-25.3.2.dist-info/licenses/AUTHORS.rst,sha256=8VEm_G4HOmYEa4oi1nVoKKsdo4JanekEJCefWd2E8vk,981
4639
- lino-25.3.2.dist-info/licenses/COPYING,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
4640
- lino-25.3.2.dist-info/RECORD,,
4637
+ lino-25.3.3.dist-info/METADATA,sha256=Y4RzsZ45wfffloOg3bOkXYPu6vWSMGL2KB4_LzpDusE,42534
4638
+ lino-25.3.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
4639
+ lino-25.3.3.dist-info/licenses/AUTHORS.rst,sha256=8VEm_G4HOmYEa4oi1nVoKKsdo4JanekEJCefWd2E8vk,981
4640
+ lino-25.3.3.dist-info/licenses/COPYING,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
4641
+ lino-25.3.3.dist-info/RECORD,,
File without changes