lino 24.10.2__py3-none-any.whl → 24.10.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
@@ -26,7 +26,7 @@ defines no models, some template files, a series of :term:`django-admin commands
26
26
 
27
27
  """
28
28
 
29
- __version__ = '24.10.2'
29
+ __version__ = '24.10.3'
30
30
 
31
31
  # import setuptools # avoid UserWarning "Distutils was imported before Setuptools"?
32
32
 
lino/api/dd.py CHANGED
@@ -25,6 +25,7 @@ from lino.core.utils import obj2str
25
25
  from lino.core.utils import obj2unicode
26
26
  from lino.core.utils import range_filter
27
27
  from lino.core.utils import inrange_filter
28
+ from lino.core.utils import overlap_range_filter
28
29
  from lino.core.utils import full_model_name
29
30
 
30
31
  from lino.core.model import Model
lino/core/store.py CHANGED
@@ -821,7 +821,10 @@ class DateStoreField(StoreField):
821
821
  try:
822
822
  return datetime.date(*settings.SITE.parse_date(v))
823
823
  except Exception as e:
824
- raise Warning("Invalid date '{}'' : {}".format(v, e))
824
+ # The front end is responsible for validating before submitting.
825
+ # Here it's too late to complain.
826
+ return None
827
+ # raise Warning("Invalid date '{}'' : {}".format(v, e))
825
828
 
826
829
  def format_value(self, ar, v):
827
830
  """Return a plain textual representation of this value as a unicode
lino/core/utils.py CHANGED
@@ -23,6 +23,7 @@ from django.core import exceptions
23
23
  from django.http import QueryDict
24
24
 
25
25
  from lino.utils.html import E, assert_safe, tostring
26
+ from lino.utils.ranges import isrange
26
27
 
27
28
  from django.core.validators import validate_email, ValidationError, URLValidator
28
29
 
@@ -309,21 +310,41 @@ def range_filter(value, f1, f2):
309
310
  q2 = Q(**{f2 + "__isnull": True}) | Q(**{f2 + "__gte": value})
310
311
  return Q(q1, q2)
311
312
 
312
-
313
313
  def inrange_filter(fld, rng, **kw):
314
314
  """Assuming a database model with a field named `fld`, return a Q
315
- object to select those rows whose `fld` value is not null and
316
- within the given range `rng`. `rng` must be a tuple or list with
317
- two items.
318
-
315
+ object to select the rows having value for `fld` within the given range `rng`.
316
+ `rng` must be a tuple or list with two items.
319
317
  """
320
- assert rng[0] <= rng[1]
318
+
319
+ # assert rng[0] <= rng[1]
321
320
  kw[fld + "__isnull"] = False
322
- kw[fld + "__gte"] = rng[0]
323
- kw[fld + "__lte"] = rng[1]
321
+ if rng[0] is not None:
322
+ kw[fld + "__gte"] = rng[0]
323
+ if rng[1] is not None:
324
+ kw[fld + "__lte"] = rng[1]
324
325
  return Q(**kw)
325
326
 
326
327
 
328
+ def overlap_range_filter(sv, ev, f1, f2, **kw):
329
+ """
330
+
331
+ Return a Q object to select all objects having fields `f1` and `f2` define a
332
+ range that overlaps with the range specified by `sv` (start value) and `ev`
333
+ (end value).
334
+
335
+ For example, when I specify filter parameters `Date from` 2024-02-21 and
336
+ `until` 2024-03-12 in a :class:`lino.modlib.periods.StoredPeriods` table, I
337
+ want both February and March. Tested examples see
338
+ :ref:`dg.plugins.periods.period_filter`.
339
+
340
+ """
341
+ # if not isrange(rng[0], rng[1]):
342
+ # raise ValueError(f"{rng} is not a valid range")
343
+ if not ev:
344
+ ev = sv
345
+ return Q(**{f1+"__lte" : ev, f2+"__gte" : sv})
346
+
347
+
327
348
  def babelkw(*args, **kw):
328
349
  return settings.SITE.babelkw(*args, **kw)
329
350
 
@@ -679,7 +700,7 @@ class ParameterPanel(object):
679
700
 
680
701
  Subclassed e.g. by
681
702
  :class:`lino.mixins.periods.ObservedDateRange`.
682
- :class:`lino_xl.lib.accounting.AccountingPeriodRange`.
703
+ :class:`lino_xl.lib.accounting.PeriodRangeParameters`.
683
704
  """
684
705
 
685
706
  def __init__(self, **kw):
lino/help_texts.py CHANGED
@@ -376,6 +376,15 @@ help_texts = {
376
376
  'lino.modlib.linod.SystemTask.log_level' : _("""The logging level to apply when running this task."""),
377
377
  'lino.modlib.linod.SystemTask.run' : _("""Performs a routine job."""),
378
378
  'lino.modlib.linod.SystemTasks' : _("""The default actor for the SystemTask model."""),
379
+ 'lino.modlib.periods.StoredPeriod' : _("""An accounting period is the smallest time slice to be declared in accounting reports. Usually it corresponds to one month. But there are except for some small companies which declare per quarter."""),
380
+ 'lino.modlib.periods.StoredYears' : _("""The fiscal years available in this database."""),
381
+ 'lino.modlib.periods.PeriodRange' : _("""Model mixin for objects that cover a range of accounting periods."""),
382
+ 'lino.modlib.periods.PeriodRange.start_period' : _("""The first period of the range to cover."""),
383
+ 'lino.modlib.periods.PeriodRange.end_period' : _("""The last period of the range to cover."""),
384
+ 'lino.modlib.periods.PeriodRangeObservable' : _("""Model mixin for objects that can be filtered by a range of accounting periods. This adds two parameter fields start_period and end_period to every table on this model."""),
385
+ 'lino.modlib.periods.StoredPeriodRange' : _("""A parameter panel with two fields:"""),
386
+ 'lino.modlib.periods.StoredPeriodRange.start_period' : _("""Start of observed period range."""),
387
+ 'lino.modlib.periods.StoredPeriodRange.end_period' : _("""Optional end of observed period range. Leave empty to consider only the Start period."""),
379
388
  'lino.modlib.publisher.Page' : _("""The Django model that represents a content page."""),
380
389
  'lino.modlib.publisher.PublisherBuildMethod' : _("""This deserves better documentation."""),
381
390
  'lino.modlib.publisher.Publishable' : _("""Model mixin to add to models that are potentially publishable."""),
lino/mixins/periods.py CHANGED
@@ -372,4 +372,4 @@ class Today(ParameterPanel):
372
372
  help_text=_("Date of observation"),
373
373
  ),
374
374
  )
375
- super(Today, self).__init__(**kw)
375
+ super().__init__(**kw)
@@ -27,7 +27,7 @@ from lino import ad, _
27
27
  class Plugin(ad.Plugin):
28
28
  "See :doc:`/dev/plugins`."
29
29
 
30
- verbose_name = _("Boards")
30
+ verbose_name = _("Languages")
31
31
 
32
32
  def setup_config_menu(self, site, user_type, m, ar=None):
33
33
  p = self.get_menu_group()
@@ -1,5 +1,5 @@
1
1
  # -*- coding: UTF-8 -*-
2
- # Copyright 2008-2017 Luc Saffre
2
+ # Copyright 2008-2017 Rumma & Ko Ltd
3
3
  # License: GNU Affero General Public License v3 (see file COPYING for details)
4
4
  """Defines the :class:`Language` model.
5
5
 
@@ -0,0 +1,20 @@
1
+ # Copyright 2008-2024 Rumma & Ko Ltd
2
+ # License: GNU Affero General Public License v3 (see file COPYING for details)
3
+ from lino import ad, _
4
+
5
+
6
+ class Plugin(ad.Plugin):
7
+
8
+ verbose_name = _("Stored periods")
9
+ period_name = _("Accounting period")
10
+ period_name_plural = _("Accounting periods")
11
+ year_name = _("Fiscal year")
12
+ year_name_plural = _("Fiscal years")
13
+ fix_y2k = False
14
+ start_year = 2012
15
+
16
+ def setup_config_menu(self, site, user_type, m, ar=None):
17
+ p = self.get_menu_group()
18
+ m = m.add_menu(p.app_label, p.verbose_name)
19
+ m.add_action("periods.StoredYears")
20
+ m.add_action("periods.StoredPeriods")
@@ -0,0 +1,22 @@
1
+ # -*- coding: UTF-8 -*-
2
+ # Copyright 2012-2024 Rumma & Ko Ltd
3
+ # License: GNU Affero General Public License v3 (see file COPYING for details)
4
+
5
+ import datetime
6
+ from django.conf import settings
7
+ from lino.api import dd, rt, _
8
+
9
+ start_year = dd.get_plugin_setting("periods", "start_year", None)
10
+
11
+ def objects():
12
+ StoredYear = rt.models.periods.StoredYear
13
+
14
+ cfg = dd.plugins.periods
15
+ site = settings.SITE
16
+ if site.the_demo_date is not None:
17
+ if start_year > site.the_demo_date.year:
18
+ raise Exception("plugins.periods.start_year is after the_demo_date")
19
+ today = site.the_demo_date or datetime.date.today()
20
+ for y in range(start_year, today.year + 6):
21
+ yield StoredYear.create_from_year(y)
22
+ # StoredYears.add_item(StoredYear.year2value(y), str(y))
@@ -0,0 +1,126 @@
1
+ # -*- coding: UTF-8 -*-
2
+ # Copyright 2008-2024 Rumma & Ko Ltd
3
+ # License: GNU Affero General Public License v3 (see file COPYING for details)
4
+
5
+ from django.db import models
6
+ from django.utils.translation import gettext_lazy as _
7
+
8
+ from lino.api import dd, rt
9
+ from lino import mixins
10
+ from lino.mixins.periods import DateRange
11
+ from lino.mixins import Referrable
12
+
13
+ from lino.modlib.office.roles import OfficeStaff
14
+
15
+
16
+ class PeriodRange(dd.Model):
17
+
18
+ class Meta:
19
+ abstract = True
20
+
21
+ start_period = dd.ForeignKey(
22
+ 'periods.StoredPeriod',
23
+ blank=True,
24
+ verbose_name=_("Start period"),
25
+ related_name="%(app_label)s_%(class)s_set_by_start_period")
26
+
27
+ end_period = dd.ForeignKey(
28
+ 'periods.StoredPeriod',
29
+ blank=True,
30
+ null=True,
31
+ verbose_name=_("End period"),
32
+ related_name="%(app_label)s_%(class)s_set_by_end_period")
33
+
34
+ def get_period_filter(self, fieldname, **kwargs):
35
+ return rt.models.periods.StoredPeriod.get_period_filter(
36
+ fieldname, self.start_period, self.end_period, **kwargs)
37
+
38
+
39
+ class PeriodRangeObservable(dd.Model):
40
+
41
+ class Meta:
42
+ abstract = True
43
+
44
+ observable_period_prefix = ''
45
+
46
+ @classmethod
47
+ def setup_parameters(cls, fields):
48
+ fields.update(start_period=dd.ForeignKey(
49
+ 'periods.StoredPeriod',
50
+ blank=True,
51
+ null=True,
52
+ help_text=_("Start of observed period range."),
53
+ verbose_name=_("Period from")))
54
+ fields.update(end_period=dd.ForeignKey(
55
+ 'periods.StoredPeriod',
56
+ blank=True,
57
+ null=True,
58
+ help_text=_("Optional end of observed period range. "
59
+ "Leave empty to observe only the start period."),
60
+ verbose_name=_("Period until")))
61
+ super().setup_parameters(fields)
62
+
63
+ @classmethod
64
+ def get_request_queryset(cls, ar, **kwargs):
65
+ qs = super().get_request_queryset(ar, **kwargs)
66
+ if (pv := ar.param_values) is None: return qs
67
+ if pv.start_period is not None:
68
+ fkw = dict()
69
+ fkw[cls.observable_period_prefix + "journal__preliminary"] = False
70
+ flt = rt.models.periods.StoredPeriod.get_period_filter(
71
+ cls.observable_period_prefix + "accounting_period",
72
+ pv.start_period, pv.end_period, **fkw)
73
+ qs = qs.filter(**flt)
74
+ return qs
75
+
76
+ @classmethod
77
+ def get_title_tags(cls, ar):
78
+ for t in super().get_title_tags(ar):
79
+ yield t
80
+ pv = ar.param_values
81
+ if pv.start_period is not None:
82
+ if pv.end_period is None:
83
+ yield str(pv.start_period)
84
+ else:
85
+ yield "{}..{}".format(pv.start_period, pv.end_period)
86
+
87
+
88
+ class PeriodRangeParameters(dd.ParameterPanel):
89
+
90
+ def __init__(self,
91
+ verbose_name_start=_("Period from"),
92
+ verbose_name_end=_("until"),
93
+ **kwargs):
94
+ kwargs.update(
95
+ start_period=dd.ForeignKey(
96
+ 'periods.StoredPeriod',
97
+ blank=True,
98
+ null=True,
99
+ help_text=_("Start of observed period range"),
100
+ verbose_name=verbose_name_start),
101
+ end_period=dd.ForeignKey(
102
+ 'periods.StoredPeriod',
103
+ blank=True,
104
+ null=True,
105
+ help_text=_("Optional end of observed period range. "
106
+ "Leave empty to consider only the Start period."),
107
+ verbose_name=verbose_name_end))
108
+ super().__init__(**kwargs)
109
+
110
+ def check_values(self, pv):
111
+ if not pv.start_period:
112
+ raise Warning(_("Select at least a start period"))
113
+ if pv.end_period:
114
+ if str(pv.start_period) > str(pv.end_period):
115
+ raise Warning(_("End period must be after start period"))
116
+
117
+ def get_title_tags(self, ar):
118
+ pv = ar.param_values
119
+ if pv.start_period:
120
+ if pv.end_period:
121
+ yield _("Periods {}...{}").format(pv.start_period,
122
+ pv.end_period)
123
+ else:
124
+ yield _("Period {}").format(pv.start_period)
125
+ else:
126
+ yield str(_("All periods"))
@@ -0,0 +1,242 @@
1
+ # -*- coding: UTF-8 -*-
2
+ # Copyright 2008-2024 Rumma & Ko Ltd
3
+ # License: GNU Affero General Public License v3 (see file COPYING for details)
4
+
5
+ import datetime
6
+ from django.db import models
7
+ from django.utils.translation import gettext_lazy as _
8
+
9
+ from lino.api import dd
10
+ from lino import mixins
11
+ from lino.utils import last_day_of_month
12
+ from lino.mixins.periods import DateRange
13
+ from lino.mixins import Referrable
14
+
15
+ from lino.modlib.office.roles import OfficeStaff
16
+
17
+
18
+ class PeriodStates(dd.Workflow):
19
+ pass
20
+
21
+ add = PeriodStates.add_item
22
+ add('10', _("Open"), 'open')
23
+ add('20', _("Closed"), 'closed')
24
+
25
+
26
+ class StoredYear(DateRange, Referrable):
27
+
28
+ class Meta:
29
+ app_label = 'periods'
30
+ verbose_name = _("Fiscal year")
31
+ verbose_name_plural = _("Fiscal years")
32
+ ordering = ['ref']
33
+
34
+ preferred_foreignkey_width = 10
35
+
36
+ state = PeriodStates.field(default='open')
37
+
38
+ @classmethod
39
+ def get_simple_parameters(cls):
40
+ yield super().get_simple_parameters()
41
+ yield "state"
42
+
43
+ @classmethod
44
+ def year2ref(cls, year):
45
+ if dd.plugins.periods.fix_y2k:
46
+ if year < 2000:
47
+ return str(year)[-2:]
48
+ elif year < 3000:
49
+ return chr(int(str(year)[-3:-1]) + 65) + str(year)[-1]
50
+ else:
51
+ raise Exception("20180827")
52
+ # elif year < 2010:
53
+ # return "A" + str(year)[-1]
54
+ # elif year < 2020:
55
+ # return "B" + str(year)[-1]
56
+ # elif year < 2030:
57
+ # return "C" + str(year)[-1]
58
+ # else:
59
+ # raise Exception(20160304)
60
+ # return str(year)[2:]
61
+ return str(year)
62
+
63
+ @classmethod
64
+ def from_int(cls, year, *args):
65
+ ref = cls.year2ref(year)
66
+ return cls.get_by_ref(ref, *args)
67
+
68
+ @classmethod
69
+ def create_from_year(cls, year):
70
+ ref = cls.year2ref(year)
71
+ return cls(ref=ref,
72
+ start_date=datetime.date(year, 1, 1),
73
+ end_date=datetime.date(year, 12, 31))
74
+ # obj.full_clean()
75
+ # obj.save()
76
+ # return obj
77
+
78
+ @classmethod
79
+ def get_or_create_from_date(cls, date):
80
+ obj = cls.from_int(date.year, None)
81
+ if obj is None:
82
+ obj = cls.create_from_year(date.year)
83
+ obj.full_clean()
84
+ obj.save()
85
+ return obj
86
+
87
+ def __str__(self):
88
+ return self.ref
89
+
90
+
91
+ class StoredPeriod(DateRange, Referrable):
92
+
93
+ class Meta:
94
+ ordering = ['ref']
95
+ app_label = 'periods'
96
+ verbose_name = dd.plugins.periods.period_name
97
+ verbose_name_plural = dd.plugins.periods.period_name_plural
98
+
99
+ preferred_foreignkey_width = 10
100
+
101
+ state = PeriodStates.field(default='open')
102
+ year = dd.ForeignKey('periods.StoredYear', blank=True, null=True)
103
+ remark = models.CharField(_("Remark"), max_length=250, blank=True)
104
+
105
+ @classmethod
106
+ def get_simple_parameters(cls):
107
+ yield super().get_simple_parameters()
108
+ yield "state"
109
+ yield "year"
110
+
111
+ @classmethod
112
+ def get_request_queryset(cls, ar):
113
+ qs = super().get_request_queryset(ar)
114
+ if (pv := ar.param_values) is None: return qs
115
+
116
+ # if pv.start_date is None or pv.end_date is None:
117
+ # period = None
118
+ # else:
119
+ # period = (pv.start_date, pv.end_date)
120
+ # if period is not None:
121
+ # qs = qs.filter(dd.inrange_filter('start_date', period))
122
+ if pv.start_date or pv.end_date:
123
+ qs = qs.filter(dd.overlap_range_filter(
124
+ pv.start_date, pv.end_date, "start_date", "end_date"))
125
+ # if pv.start_date:
126
+ # qs = qs.filter(dd.range_filter(pv.start_date, 'start_date', 'end_date'))
127
+ # # qs = qs.filter(start_date__gte=pv.start_date)
128
+ # if pv.end_date:
129
+ # qs = qs.filter(dd.range_filter(pv.end_date, 'start_date', 'end_date'))
130
+ # qs = qs.filter(end_date__lte=pv.end_date)
131
+ return qs
132
+
133
+ @classmethod
134
+ def get_available_periods(cls, today):
135
+ """Return a queryset of periods available for booking."""
136
+ if today is None: # added 20160531
137
+ today = dd.today()
138
+ fkw = dict(start_date__lte=today, end_date__gte=today)
139
+ return cls.objects.filter(**fkw)
140
+
141
+ @classmethod
142
+ def get_ref_for_date(cls, d):
143
+ """Return a text to be used as :attr:`ref` for a new period.
144
+
145
+ Alternative implementation for usage on a site with movements
146
+ before year 2000::
147
+
148
+ @classmethod
149
+ def get_ref_for_date(cls, d):
150
+ if d.year < 2000:
151
+ y = str(d.year - 1900)
152
+ elif d.year < 2010:
153
+ y = "A" + str(d.year - 2000)
154
+ elif d.year < 2020:
155
+ y = "B" + str(d.year - 2010)
156
+ elif d.year < 2030:
157
+ y = "C" + str(d.year - 2020)
158
+ return y + "{:0>2}".format(d.month)
159
+
160
+ """
161
+ y = StoredYear.year2ref(d.year)
162
+ return "{}-{:0>2}".format(y, d.month)
163
+
164
+ # if dd.plugins.periods.fix_y2k:
165
+ # return rt.models.periods.StoredYear.from_int(d.year).ref \
166
+ # + "{:0>2}".format(d.month)
167
+
168
+ # return "{0.year}-{0.month:0>2}".format(d)
169
+
170
+ # """The template used for building the :attr:`ref` of an
171
+ # :class:`StoredPeriod`.
172
+ #
173
+ # `Format String Syntax
174
+ # <https://docs.python.org/2/library/string.html#formatstrings>`_
175
+ #
176
+ # """
177
+
178
+ @classmethod
179
+ def get_periods_in_range(cls, p1, p2):
180
+ return cls.objects.filter(ref__gte=p1.ref, ref__lte=p2.ref)
181
+
182
+ @classmethod
183
+ def get_period_filter(cls, fieldname, p1, p2, **kwargs):
184
+ if p1 is None:
185
+ return kwargs
186
+
187
+ # ignore preliminary movements if a start_period is given:
188
+ # kwargs[voucher_prefix + "journal__preliminary"] = False
189
+
190
+ # accounting_period = voucher_prefix + "accounting_period"
191
+
192
+ if p2 is None:
193
+ kwargs[fieldname] = p1
194
+ else:
195
+ periods = cls.get_periods_in_range(p1, p2)
196
+ kwargs[fieldname + '__in'] = periods
197
+ return kwargs
198
+
199
+ @classmethod
200
+ def get_default_for_date(cls, d):
201
+ ref = cls.get_ref_for_date(d)
202
+ obj = cls.get_by_ref(ref, None)
203
+ if obj is None:
204
+ values = dict(start_date=d.replace(day=1))
205
+ values.update(end_date=last_day_of_month(d))
206
+ values.update(ref=ref)
207
+ obj = StoredPeriod(**values)
208
+ obj.full_clean()
209
+ obj.save()
210
+ return obj
211
+
212
+ def full_clean(self, *args, **kwargs):
213
+ if self.start_date is None:
214
+ self.start_date = dd.today().replace(day=1)
215
+ if not self.year:
216
+ self.year = StoredYear.get_or_create_from_date(self.start_date)
217
+ super().full_clean(*args, **kwargs)
218
+
219
+ def __str__(self):
220
+ if not self.ref:
221
+ return dd.obj2str(self)
222
+ # "{0} {1} (#{0})".format(self.pk, self.year)
223
+ return self.ref
224
+
225
+
226
+ StoredPeriod.set_widget_options('ref', width=6)
227
+
228
+
229
+ class StoredYears(dd.Table):
230
+ model = 'periods.StoredYear'
231
+ required_roles = dd.login_required(OfficeStaff)
232
+ column_names = "ref start_date end_date state *"
233
+ # detail_layout = """
234
+ # ref id
235
+ # start_date end_date
236
+ # """
237
+
238
+ class StoredPeriods(dd.Table):
239
+ required_roles = dd.login_required(OfficeStaff)
240
+ model = 'periods.StoredPeriod'
241
+ order_by = ["ref", "start_date", "year"]
242
+ column_names = "ref start_date end_date year state remark *"
lino/utils/ranges.py CHANGED
@@ -1,5 +1,5 @@
1
1
  # -*- coding: UTF-8 -*-
2
- # Copyright 2009-2021 Luc Saffre
2
+ # Copyright 2009-2024 Rumma & Ko Ltd
3
3
  # License: GNU Affero General Public License v3 (see file COPYING for details)
4
4
  """The :mod:`lino.utils.ranges` module contains utility methods for
5
5
  working with "ranges".
@@ -76,10 +76,10 @@ def overlap(a1, a2, b1, b2):
76
76
  works with integers or other comparable values. The following
77
77
  examples use integer values to be more readable.
78
78
 
79
- Unlike the test presented at
80
- <http://bytes.com/topic/python/answers/457949-determing-whether-two-ranges-overlap>,
81
- this works also with "open" ranges (the open end being indicated
82
- by a `None` value).
79
+ Unlike the test presented in `Determing whether two ranges overlap
80
+ <https://post.bytes.com/forum/topic/python/398735-determing-whether-two-ranges-overlap?t=457949>`__,
81
+ this works also with "open" ranges (the open end being indicated by a `None`
82
+ value).
83
83
 
84
84
  Types of constellations::
85
85
 
@@ -129,13 +129,3 @@ def overlap(a1, a2, b1, b2):
129
129
  else:
130
130
  return True
131
131
  return True
132
-
133
-
134
- def _test():
135
- import doctest
136
-
137
- doctest.testmod()
138
-
139
-
140
- if __name__ == "__main__":
141
- _test()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: lino
3
- Version: 24.10.2
3
+ Version: 24.10.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,13 +1,13 @@
1
1
  lino/.cvsignore,sha256=1vrrWoP-WD8hPfCszHHIiJEi8KUMRCt5WvoKB9TSB1k,28
2
2
  lino/SciTEDirectory.properties,sha256=rCYi_e-6h8Yx5DwXhAa6MBPlVINcl6Vv9BQDYZV2_go,28
3
- lino/__init__.py,sha256=ISO_sqTgmyY5do7wrEc2SMiswT8DTnaL49JbqPkWny0,5585
3
+ lino/__init__.py,sha256=xXbC44yjPzSBUvfGWf_PgZxIv2O6_VnDETw6O0AHX_4,5585
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
7
- lino/help_texts.py,sha256=gZq8EJfReHB8Z5jKFFOr1pjDRODm7FVkHC8IRA7gq3w,89104
7
+ lino/help_texts.py,sha256=jcABL4QqvwyJrzaTIqCZfSdeOd5LBu7QcV3curn3ArI,90338
8
8
  lino/api/__init__.py,sha256=WmzHU-rHdZ68se_nI0SmepQTGE8-cd9tPpovHRH9aag,512
9
9
  lino/api/ad.py,sha256=F6SrcKPRRalHKOZ7QLwsRWGq9hhykQIeo0b85cEk9NQ,314
10
- lino/api/dd.py,sha256=LHooukTaNuxAbhtSdvDNVbI7nkxeU-QTp5Dfz00bmjk,7764
10
+ lino/api/dd.py,sha256=-mjuoflZilnFM97we-N1H_sEf1TQiNs62JwZ5m4XV1s,7813
11
11
  lino/api/doctest.py,sha256=fJ97w6rOO7AdlZ5DmgSHuIq-2LfOIbLT_mmslCdI2do,25561
12
12
  lino/api/rt.py,sha256=auN4YoIthkXsjSN09OR6YeaNxSNfUO7E5KyTAvQtjh8,1400
13
13
  lino/api/selenium.py,sha256=07BQuC6KW2tBUlIUcPGeCQHIfogz-wuHJqPshSzLDp0,9384
@@ -60,12 +60,12 @@ lino/core/requests.py,sha256=ZLsiyAI2zNt65nWV3ebrnZWaqarTpZSyS31ba7_a_9A,92177
60
60
  lino/core/roles.py,sha256=PXwk436xUupxdbJcygRSYFu7ixfKjAJPQRUQ8sy0lB0,4425
61
61
  lino/core/signals.py,sha256=0JT89mkjSbRm57QZcSI9DoThoKUGkyi-egNhuLUKEds,948
62
62
  lino/core/site.py,sha256=sUuyTNi9IvJ-BwOW1LbAiRKmAE0xOYpHlJqsDH_ID5E,85443
63
- lino/core/store.py,sha256=uMza9XRX3QeIRCWwBOK9w-4pyjruWtJCfSqOV4_kdgA,51338
63
+ lino/core/store.py,sha256=j3Dk2mSYJLKI6R-SSsuomBcF0cb3dnI87hysqBl5PHU,51499
64
64
  lino/core/tables.py,sha256=FfA3KhGshsR1maNB6B11BbJ4m8cxxIaOhV0jvMxTaJA,25468
65
65
  lino/core/urls.py,sha256=06QlmN1vpxjmb5snO3SPpP6lX1pMdE60bTiBiC77_vQ,2677
66
66
  lino/core/user_types.py,sha256=0iSYmzr2M9v2Mn2y6hzAZeqareUT-gD7l3MfIPyG9ZI,867
67
67
  lino/core/userprefs.py,sha256=cmufIS9xJErKDrw05uoWtQTUR6WRWIGkU1KdAqzNr5M,2850
68
- lino/core/utils.py,sha256=3JgByh5KIG-WM_JMkZpFEot-HAh6wV7jR2YfVeDl48o,34540
68
+ lino/core/utils.py,sha256=TW9eKS8Ua6tCGugBzJUS6gXiEAqI7EbB6VAiKwYshw8,35304
69
69
  lino/core/views.py,sha256=b7q9XOjl8nkBV-ZRcR-swFjcC9BGyanRYM2CsB_A5xc,6959
70
70
  lino/core/widgets.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
71
  lino/core/workflows.py,sha256=9O5INnx3nPW73UmeEPWgN146clQSWwna3Jq_w1MThcg,10567
@@ -120,7 +120,7 @@ lino/mixins/__init__.py,sha256=cSFXzy8i0Akp9PmUSJz8E5t3twO3Z2lyCTyTCEqAQSU,8931
120
120
  lino/mixins/dupable.py,sha256=lk1Lgqae1PXRP1Ej6AKg5n3tG1MLYu7Ww1Qy5kb46_E,10092
121
121
  lino/mixins/duplicable.py,sha256=lQ5SEQmxPcOU9vETocgQI41uzgvunvXIy7HAnPeKDUI,4224
122
122
  lino/mixins/human.py,sha256=YDIfIHHAaVmzd3uGsJp_vDvkaBWOp09I7i4AGNy9YsQ,13255
123
- lino/mixins/periods.py,sha256=zEK9OiwTMVZX3vpy-viByRrBDNN6OgQFb4sdQmOxjow,11280
123
+ lino/mixins/periods.py,sha256=VSxYLfO3b7aJm0ZbGYBwhA3sFuft2-OO4Qv2iR2cKVk,11269
124
124
  lino/mixins/polymorphic.py,sha256=jzpfnzdDChvh1Ua16mdCQQOmoG-7Zyz69UOpcdqIiSA,9391
125
125
  lino/mixins/printable.py,sha256=4U8M1lrTjUeuaPwrcWoanCBo53iAxiNpSTsVctI-gI0,199
126
126
  lino/mixins/ref.py,sha256=gMWewqZjydq02LRDYY30t5EDWBbtecCOAoVU5IX1ayc,5249
@@ -3525,8 +3525,8 @@ lino/modlib/jinja/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
3525
3525
  lino/modlib/jinja/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3526
3526
  lino/modlib/jinja/management/commands/showsettings.py,sha256=nM5PNWXzbNdhnyH1b05iB__qwBdtPJ14T-Gt5jqGkww,452
3527
3527
  lino/modlib/jinja/management/commands/status.py,sha256=REApUMUqYgQY_50RwfAFbFBGXmn4UZGtLJMOncmOQHg,609
3528
- lino/modlib/languages/__init__.py,sha256=xKTD2jBZ2Dy5iScnPDH9L035bKmlkixifQ4DOKpl__0,1005
3529
- lino/modlib/languages/models.py,sha256=LiEGV_XNR5xy-eIHYIH-GHVmyFJ4ovK2wz4eCv2KhCY,806
3528
+ lino/modlib/languages/__init__.py,sha256=RUPzAiUVGuJXBWVWSomkbMm-f5OXBagZShfx4UyaUIw,1008
3529
+ lino/modlib/languages/models.py,sha256=tHF14XZKwx1te3DLbdsdogFLeyLuCWz_WExA-OU6VFo,810
3530
3530
  lino/modlib/languages/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3531
3531
  lino/modlib/languages/fixtures/all_languages.py,sha256=L_EmmcLVPKXcFB8uJITN3rWxNJ43CVNTKj5nbSXPK54,20941
3532
3532
  lino/modlib/languages/fixtures/few_languages.py,sha256=nhhfS4bV9x2yvtGlWFX5j7pC40-c31bFInGvlHxmT4Y,846
@@ -3572,6 +3572,10 @@ lino/modlib/odata/views.py,sha256=ssyYYIyGoxXtR3hKnIa-ZBPLb6vxEU5C6XUUQ1L6Z70,72
3572
3572
  lino/modlib/odata/config/odata/csdl.xml,sha256=KFDImzUA4YI6PL-i5AHnm22eBMLTw-K2iljslDJFQH8,296
3573
3573
  lino/modlib/office/__init__.py,sha256=rOKD9zKt-VBvFFqoHBioNp299Igb1Sk2n466iCt6ASQ,287
3574
3574
  lino/modlib/office/roles.py,sha256=oQWTZ-_9_vssc9QW5A0YspMjG_V5gCiHSU0eE0AIH30,356
3575
+ lino/modlib/periods/__init__.py,sha256=Q94txH81IrZR23X00rAbR3BUXDYwfUafnURrWzqEmlg,651
3576
+ lino/modlib/periods/mixins.py,sha256=IEjeeenFJD9HItK2n1wmsz1KTC9apFb1u87Mz-bhlY4,4266
3577
+ lino/modlib/periods/models.py,sha256=tk-CyIqii4s5gj9KBatvU_sAaUseeL6hdRbYDTlItVs,7522
3578
+ lino/modlib/periods/fixtures/std.py,sha256=c7K5xYHgC6AJT59W77MSRM2WS5ut58j55hoO_u9frJ4,788
3575
3579
  lino/modlib/printing/__init__.py,sha256=u1fq44d073-IDH_t8hWs1sQdlAHdsCP85sfEOMSW5L4,689
3576
3580
  lino/modlib/printing/actions.py,sha256=ud56ri8NAK0U8d8vVrhv-GTE8WD8jiUidpdXGrmVPlA,11632
3577
3581
  lino/modlib/printing/choicelists.py,sha256=KzcFD-WjXIXiqLY-gVuuOvE0pueJuV7t5IMgUb4I2P0,9607
@@ -4620,7 +4624,7 @@ lino/utils/pdf.py,sha256=caISmnrrADN1MTK_GIiasfkVUyqhTEuK9mtoMf_S7qU,688
4620
4624
  lino/utils/pythontest.py,sha256=AA9i3CEWgpbJKNTkxc0Gz94sy1R1MBpyinqrlahKKno,4954
4621
4625
  lino/utils/pyuca.py,sha256=YSLpCYEMqKUhx1y0q-ML8Ryu2ARDFO2HyIFxz1DzYEY,4344
4622
4626
  lino/utils/quantities.py,sha256=m_oi647uCTf2NhhQo6ytphZa2jQq1QXIUcts-cLkEJM,7367
4623
- lino/utils/ranges.py,sha256=gXMD3uZBobGnOfn8GXSJ40gtJ7UcxrIOOFWZCk--zXE,3343
4627
+ lino/utils/ranges.py,sha256=wVsZMe3dlaRYWWELXCGSK2DvjBfW4eLbAwpQVYqzj3g,3303
4624
4628
  lino/utils/report.py,sha256=5l1NkZpcZyd1zpg37MB4Doly9dH9KHBEFarp9Q6vh4w,7983
4625
4629
  lino/utils/requests.py,sha256=vXxsC51FK9FgrqmF9dy3MsmUqJINjSQ_4AmvBiQbGEk,1337
4626
4630
  lino/utils/restify.py,sha256=QMVQXrmjDl6PPC7HJJGeDm125pcvrZKvcMpiscaPrsw,14066
@@ -4639,8 +4643,8 @@ lino/utils/xml.py,sha256=4Z44W1e5HvTVrU8erkohgnwqY-5Cr2NHywaAJ5OgRvw,989
4639
4643
  lino/utils/mldbc/__init__.py,sha256=QqWRlzeXaOmFfbCk-vTY3SZMn1-FCf67XnpZdd_Nim0,1134
4640
4644
  lino/utils/mldbc/fields.py,sha256=tAX8G5UKigr9c6g0F3ARIjZZtg406mdaZ--PWSbiH9E,2873
4641
4645
  lino/utils/mldbc/mixins.py,sha256=CkYe5jDa7xp9fJq_V8zcZf8ocxgIjUgHc9KZccvA_Yw,1945
4642
- lino-24.10.2.dist-info/METADATA,sha256=ntU1BmW4OU6iHggi-NZO_PMuJVTb9oUJ6TSEG2NMagU,42535
4643
- lino-24.10.2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
4644
- lino-24.10.2.dist-info/licenses/AUTHORS.rst,sha256=8VEm_G4HOmYEa4oi1nVoKKsdo4JanekEJCefWd2E8vk,981
4645
- lino-24.10.2.dist-info/licenses/COPYING,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
4646
- lino-24.10.2.dist-info/RECORD,,
4646
+ lino-24.10.3.dist-info/METADATA,sha256=OEW_3rFYAWtyG5d4N_-peNOZE4NuzcNH4Tg51ldh6YQ,42535
4647
+ lino-24.10.3.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
4648
+ lino-24.10.3.dist-info/licenses/AUTHORS.rst,sha256=8VEm_G4HOmYEa4oi1nVoKKsdo4JanekEJCefWd2E8vk,981
4649
+ lino-24.10.3.dist-info/licenses/COPYING,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
4650
+ lino-24.10.3.dist-info/RECORD,,
File without changes