lino 24.11.1__py3-none-any.whl → 25.1.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.
Files changed (60) hide show
  1. lino/__init__.py +1 -1
  2. lino/core/actors.py +33 -12
  3. lino/core/dbtables.py +0 -4
  4. lino/core/fields.py +26 -18
  5. lino/core/kernel.py +4 -6
  6. lino/core/model.py +5 -16
  7. lino/core/renderer.py +1 -7
  8. lino/core/requests.py +70 -47
  9. lino/core/site.py +1 -1
  10. lino/core/tables.py +0 -16
  11. lino/help_texts.py +4 -4
  12. lino/locale/bn/LC_MESSAGES/django.po +58 -45
  13. lino/locale/de/LC_MESSAGES/django.mo +0 -0
  14. lino/locale/de/LC_MESSAGES/django.po +79 -108
  15. lino/locale/django.pot +55 -44
  16. lino/locale/es/LC_MESSAGES/django.po +56 -44
  17. lino/locale/et/LC_MESSAGES/django.po +58 -45
  18. lino/locale/fr/LC_MESSAGES/django.mo +0 -0
  19. lino/locale/fr/LC_MESSAGES/django.po +60 -48
  20. lino/locale/nl/LC_MESSAGES/django.po +59 -45
  21. lino/locale/pt_BR/LC_MESSAGES/django.po +55 -44
  22. lino/locale/zh_Hant/LC_MESSAGES/django.po +55 -44
  23. lino/mixins/dupable.py +8 -7
  24. lino/mixins/periods.py +4 -4
  25. lino/modlib/checkdata/__init__.py +1 -1
  26. lino/modlib/comments/mixins.py +45 -44
  27. lino/modlib/comments/models.py +2 -2
  28. lino/modlib/comments/ui.py +9 -3
  29. lino/modlib/dupable/models.py +10 -14
  30. lino/modlib/gfks/mixins.py +8 -1
  31. lino/modlib/jinja/choicelists.py +3 -3
  32. lino/modlib/jinja/renderer.py +2 -0
  33. lino/modlib/languages/fixtures/all_languages.py +4 -6
  34. lino/modlib/memo/mixins.py +7 -7
  35. lino/modlib/memo/models.py +41 -12
  36. lino/modlib/memo/parser.py +7 -3
  37. lino/modlib/notify/mixins.py +8 -8
  38. lino/modlib/periods/choicelists.py +46 -0
  39. lino/modlib/periods/mixins.py +26 -0
  40. lino/modlib/periods/models.py +17 -45
  41. lino/modlib/publisher/choicelists.py +1 -4
  42. lino/modlib/system/__init__.py +0 -3
  43. lino/modlib/system/choicelists.py +0 -13
  44. lino/modlib/system/mixins.py +1 -0
  45. lino/modlib/system/models.py +0 -18
  46. lino/modlib/uploads/mixins.py +37 -37
  47. lino/modlib/uploads/models.py +68 -18
  48. lino/modlib/uploads/utils.py +6 -0
  49. lino/modlib/users/mixins.py +9 -6
  50. lino/modlib/users/models.py +0 -2
  51. lino/modlib/users/ui.py +1 -1
  52. lino/modlib/weasyprint/choicelists.py +17 -7
  53. lino/utils/choosers.py +21 -8
  54. lino/utils/instantiator.py +9 -0
  55. lino/utils/soup.py +5 -5
  56. {lino-24.11.1.dist-info → lino-25.1.1.dist-info}/METADATA +4 -2
  57. {lino-24.11.1.dist-info → lino-25.1.1.dist-info}/RECORD +60 -59
  58. {lino-24.11.1.dist-info → lino-25.1.1.dist-info}/WHEEL +1 -1
  59. {lino-24.11.1.dist-info → lino-25.1.1.dist-info}/licenses/AUTHORS.rst +0 -0
  60. {lino-24.11.1.dist-info → lino-25.1.1.dist-info}/licenses/COPYING +0 -0
@@ -7,7 +7,7 @@ msgid ""
7
7
  msgstr ""
8
8
  "Project-Id-Version: lino 24.7.0\n"
9
9
  "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
10
- "POT-Creation-Date: 2024-11-15 13:05+0200\n"
10
+ "POT-Creation-Date: 2024-11-16 21:41+0200\n"
11
11
  "PO-Revision-Date: 2024-07-20 19:57+0300\n"
12
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
13
  "Language: zh_Hant\n"
@@ -3539,8 +3539,8 @@ msgstr ""
3539
3539
  #: lino/modlib/importfilters/models.py:100 lino/modlib/notify/actions.py:14
3540
3540
  #: lino/modlib/search/models.py:85 lino/modlib/system/mixins.py:286
3541
3541
  #: lino/modlib/tinymce/models.py:21 lino/modlib/uploads/actions.py:23
3542
- #: lino/modlib/uploads/models.py:49 lino/modlib/uploads/models.py:121
3543
- #: lino/modlib/uploads/models.py:193 lino/modlib/users/ui.py:262
3542
+ #: lino/modlib/uploads/models.py:53 lino/modlib/uploads/models.py:125
3543
+ #: lino/modlib/uploads/models.py:189 lino/modlib/users/ui.py:262
3544
3544
  msgid "Description"
3545
3545
  msgstr ""
3546
3546
 
@@ -3613,7 +3613,7 @@ msgstr ""
3613
3613
  msgid "Select a %s..."
3614
3614
  msgstr ""
3615
3615
 
3616
- #: lino/core/elems.py:1618 lino/modlib/uploads/models.py:377
3616
+ #: lino/core/elems.py:1618 lino/modlib/uploads/models.py:380
3617
3617
  msgid "show"
3618
3618
  msgstr ""
3619
3619
 
@@ -4936,12 +4936,12 @@ msgid "Controlled by"
4936
4936
  msgstr ""
4937
4937
 
4938
4938
  #: lino/modlib/gfks/mixins.py:31 lino/modlib/gfks/mixins.py:53
4939
- #: lino/modlib/memo/models.py:36
4939
+ #: lino/modlib/memo/models.py:37
4940
4940
  msgid "(type)"
4941
4941
  msgstr ""
4942
4942
 
4943
4943
  #: lino/modlib/gfks/mixins.py:39 lino/modlib/gfks/mixins.py:49
4944
- #: lino/modlib/memo/models.py:44
4944
+ #: lino/modlib/memo/models.py:45
4945
4945
  msgid "(object)"
4946
4946
  msgstr ""
4947
4947
 
@@ -5256,19 +5256,26 @@ msgstr ""
5256
5256
  msgid "Mentions differ from expected mentions."
5257
5257
  msgstr ""
5258
5258
 
5259
- #: lino/modlib/memo/models.py:20 lino/modlib/uploads/models.py:250
5260
- #: lino/modlib/uploads/models.py:264
5261
- msgid "Source"
5259
+ #: lino/modlib/memo/models.py:21
5260
+ msgid "Target"
5262
5261
  msgstr ""
5263
5262
 
5264
- #: lino/modlib/memo/models.py:27
5263
+ #: lino/modlib/memo/models.py:28
5265
5264
  msgid "Mention"
5266
5265
  msgstr ""
5267
5266
 
5268
- #: lino/modlib/memo/models.py:28
5267
+ #: lino/modlib/memo/models.py:29
5269
5268
  msgid "Mentions"
5270
5269
  msgstr ""
5271
5270
 
5271
+ #: lino/modlib/memo/models.py:62
5272
+ msgid "Referrer"
5273
+ msgstr ""
5274
+
5275
+ #: lino/modlib/memo/models.py:81
5276
+ msgid "Mentioned by"
5277
+ msgstr ""
5278
+
5272
5279
  #: lino/modlib/notify/__init__.py:16
5273
5280
  msgid "Messages"
5274
5281
  msgstr ""
@@ -5711,7 +5718,7 @@ msgstr ""
5711
5718
  msgid "You have a dangling edit lock on"
5712
5719
  msgstr ""
5713
5720
 
5714
- #: lino/modlib/system/actions.py:17 lino/modlib/uploads/models.py:389
5721
+ #: lino/modlib/system/actions.py:17 lino/modlib/uploads/models.py:392
5715
5722
  msgid "Edit"
5716
5723
  msgstr ""
5717
5724
 
@@ -6144,116 +6151,120 @@ msgstr ""
6144
6151
  msgid "File size"
6145
6152
  msgstr ""
6146
6153
 
6147
- #: lino/modlib/uploads/models.py:42
6154
+ #: lino/modlib/uploads/models.py:46
6148
6155
  msgid "Library volume"
6149
6156
  msgstr ""
6150
6157
 
6151
- #: lino/modlib/uploads/models.py:43
6158
+ #: lino/modlib/uploads/models.py:47
6152
6159
  msgid "Library volumes"
6153
6160
  msgstr ""
6154
6161
 
6155
- #: lino/modlib/uploads/models.py:47
6162
+ #: lino/modlib/uploads/models.py:51
6156
6163
  msgid "Root directory"
6157
6164
  msgstr ""
6158
6165
 
6159
- #: lino/modlib/uploads/models.py:80
6166
+ #: lino/modlib/uploads/models.py:84
6160
6167
  msgid "Upload type"
6161
6168
  msgstr ""
6162
6169
 
6163
- #: lino/modlib/uploads/models.py:81
6170
+ #: lino/modlib/uploads/models.py:85
6164
6171
  msgid "Upload types"
6165
6172
  msgstr ""
6166
6173
 
6167
- #: lino/modlib/uploads/models.py:86
6174
+ #: lino/modlib/uploads/models.py:90
6168
6175
  msgid "Max. number"
6169
6176
  msgstr ""
6170
6177
 
6171
- #: lino/modlib/uploads/models.py:94
6178
+ #: lino/modlib/uploads/models.py:98
6172
6179
  msgid "No need to upload more uploads than N of this type."
6173
6180
  msgstr ""
6174
6181
 
6175
- #: lino/modlib/uploads/models.py:95
6182
+ #: lino/modlib/uploads/models.py:99
6176
6183
  msgid "-1 means no limit."
6177
6184
  msgstr ""
6178
6185
 
6179
- #: lino/modlib/uploads/models.py:99
6186
+ #: lino/modlib/uploads/models.py:103
6180
6187
  msgid "Wanted"
6181
6188
  msgstr ""
6182
6189
 
6183
- #: lino/modlib/uploads/models.py:101
6190
+ #: lino/modlib/uploads/models.py:105
6184
6191
  msgid "Add a (+) button when there is no upload of this type."
6185
6192
  msgstr ""
6186
6193
 
6187
- #: lino/modlib/uploads/models.py:112
6194
+ #: lino/modlib/uploads/models.py:116
6188
6195
  msgid "Upload file"
6189
6196
  msgstr ""
6190
6197
 
6191
- #: lino/modlib/uploads/models.py:113
6198
+ #: lino/modlib/uploads/models.py:117
6192
6199
  msgid "Upload files"
6193
6200
  msgstr ""
6194
6201
 
6195
- #: lino/modlib/uploads/models.py:120
6202
+ #: lino/modlib/uploads/models.py:124
6196
6203
  msgid "Library file"
6197
6204
  msgstr ""
6198
6205
 
6199
- #: lino/modlib/uploads/models.py:155
6206
+ #: lino/modlib/uploads/models.py:160
6200
6207
  msgid "Uploaded an {obj}."
6201
6208
  msgstr ""
6202
6209
 
6203
- #: lino/modlib/uploads/models.py:230
6210
+ #: lino/modlib/uploads/models.py:233
6204
6211
  msgid "No preview available"
6205
6212
  msgstr ""
6206
6213
 
6207
- #: lino/modlib/uploads/models.py:234
6214
+ #: lino/modlib/uploads/models.py:237
6208
6215
  msgid "Thumbnail"
6209
6216
  msgstr ""
6210
6217
 
6211
- #: lino/modlib/uploads/models.py:273
6218
+ #: lino/modlib/uploads/models.py:253 lino/modlib/uploads/models.py:267
6219
+ msgid "Source"
6220
+ msgstr ""
6221
+
6222
+ #: lino/modlib/uploads/models.py:276
6212
6223
  msgid "Uploaded by"
6213
6224
  msgstr ""
6214
6225
 
6215
- #: lino/modlib/uploads/models.py:274
6226
+ #: lino/modlib/uploads/models.py:277
6216
6227
  msgid "Attached to"
6217
6228
  msgstr ""
6218
6229
 
6219
- #: lino/modlib/uploads/models.py:278
6230
+ #: lino/modlib/uploads/models.py:281
6220
6231
  msgid "Check metadata of upload files"
6221
6232
  msgstr ""
6222
6233
 
6223
- #: lino/modlib/uploads/models.py:286
6234
+ #: lino/modlib/uploads/models.py:289
6224
6235
  msgid "Upload entry {} has no file"
6225
6236
  msgstr ""
6226
6237
 
6227
- #: lino/modlib/uploads/models.py:303
6238
+ #: lino/modlib/uploads/models.py:306
6228
6239
  msgid "Find orphaned files in uploads folder"
6229
6240
  msgstr ""
6230
6241
 
6231
- #: lino/modlib/uploads/models.py:319
6242
+ #: lino/modlib/uploads/models.py:322
6232
6243
  msgid "File {} has no upload entry."
6233
6244
  msgstr ""
6234
6245
 
6235
- #: lino/modlib/uploads/models.py:365
6246
+ #: lino/modlib/uploads/models.py:368
6236
6247
  msgid "Upload"
6237
6248
  msgstr ""
6238
6249
 
6239
- #: lino/modlib/uploads/models.py:367
6250
+ #: lino/modlib/uploads/models.py:370
6240
6251
  msgid "Upload a file from your PC to the server."
6241
6252
  msgstr ""
6242
6253
 
6243
- #: lino/modlib/uploads/models.py:381
6254
+ #: lino/modlib/uploads/models.py:384
6244
6255
  msgid "Open the uploaded file in a new browser window"
6245
6256
  msgstr ""
6246
6257
 
6247
- #: lino/modlib/uploads/models.py:391 lino/modlib/uploads/ui.py:204
6258
+ #: lino/modlib/uploads/models.py:394 lino/modlib/uploads/ui.py:204
6248
6259
  msgid "Edit metadata of the uploaded file."
6249
6260
  msgstr ""
6250
6261
 
6251
- #: lino/modlib/uploads/models.py:396
6262
+ #: lino/modlib/uploads/models.py:399
6252
6263
  msgctxt "uploaded file"
6253
6264
  msgid "Last"
6254
6265
  msgstr ""
6255
6266
 
6256
- #: lino/modlib/uploads/models.py:402
6267
+ #: lino/modlib/uploads/models.py:405
6257
6268
  msgid "All {0} files"
6258
6269
  msgstr ""
6259
6270
 
@@ -6261,19 +6272,19 @@ msgstr ""
6261
6272
  msgid "Open the file in a new browser window"
6262
6273
  msgstr ""
6263
6274
 
6264
- #: lino/modlib/uploads/utils.py:37
6275
+ #: lino/modlib/uploads/utils.py:43
6265
6276
  msgid "PDF file"
6266
6277
  msgstr ""
6267
6278
 
6268
- #: lino/modlib/uploads/utils.py:39
6279
+ #: lino/modlib/uploads/utils.py:45
6269
6280
  msgid "picture"
6270
6281
  msgstr ""
6271
6282
 
6272
- #: lino/modlib/uploads/utils.py:40
6283
+ #: lino/modlib/uploads/utils.py:46
6273
6284
  msgid "media file"
6274
6285
  msgstr ""
6275
6286
 
6276
- #: lino/modlib/uploads/utils.py:83
6287
+ #: lino/modlib/uploads/utils.py:89
6277
6288
  msgid "Must build thumbnail for {}"
6278
6289
  msgstr ""
6279
6290
 
lino/mixins/dupable.py CHANGED
@@ -9,7 +9,7 @@ Don't mix up this module with :mod:`lino.mixins.duplicable`. Models
9
9
  are "duplicable" if users may *want* to duplicate some instance
10
10
  thereof, while "dupable" implies that the duplicates are *unwanted*.
11
11
  To dupe *somebody* means "to make a dupe of; deceive; delude; trick."
12
- (`reference.com <http://dictionary.reference.com/browse/dupe>`_), and
12
+ (`reference.com <https://dictionary.reference.com/browse/dupe>`_), and
13
13
  to dupe *something* means to duplicate it (eventually in order to
14
14
  cheat somebody e.g. by making a cheap copy of a valuable object).
15
15
 
@@ -31,9 +31,6 @@ in Python
31
31
  by Frank Hofmann (2018-02-12)
32
32
  """
33
33
 
34
- import six
35
- from builtins import map
36
-
37
34
  from django.conf import settings
38
35
  from django.db import models
39
36
 
@@ -76,6 +73,10 @@ class CheckedSubmitInsert(SubmitInsert):
76
73
  else:
77
74
  ok(ar)
78
75
 
76
+ # TODO: remove duplicate code. PhoneticWordBase.reduce_word() is exactly the
77
+ # same code as lino.modlib.dupable.models.PhoneticWord.reduce_word(). One of
78
+ # them is used in welfare, the other in avanti.
79
+
79
80
 
80
81
  class PhoneticWordBase(dd.Model):
81
82
  """Base class for the table of phonetic words of a given dupable
@@ -88,7 +89,7 @@ class PhoneticWordBase(dd.Model):
88
89
 
89
90
  """
90
91
 
91
- class Meta(object):
92
+ class Meta:
92
93
  abstract = True
93
94
 
94
95
  allow_cascaded_delete = ["owner"]
@@ -118,7 +119,7 @@ class PhoneticWordBase(dd.Model):
118
119
  dms = dm[0] or dm[1]
119
120
  if dms is None:
120
121
  return ""
121
- if isinstance(dms, six.binary_type):
122
+ if isinstance(dms, bytes):
122
123
  dms = dms.decode("utf8")
123
124
  return dms
124
125
 
@@ -141,7 +142,7 @@ class Dupable(dd.Model):
141
142
  :mod:`lino_welfare.modlib.dupable_clients`
142
143
  """
143
144
 
144
- class Meta(object):
145
+ class Meta:
145
146
  abstract = True
146
147
 
147
148
  submit_insert = CheckedSubmitInsert()
lino/mixins/periods.py CHANGED
@@ -7,10 +7,10 @@ Defines classes related to date ranges.
7
7
 
8
8
  import datetime
9
9
 
10
- try:
11
- import pytz
12
- except ImportError:
13
- pytz = None
10
+ # try:
11
+ # import pytz
12
+ # except ImportError:
13
+ # pytz = None
14
14
 
15
15
  from django.db import models
16
16
  from django.conf import settings
@@ -64,7 +64,7 @@ class Plugin(ad.Plugin):
64
64
 
65
65
  """
66
66
  super().on_plugins_loaded(site)
67
- if site.is_demo_site:
67
+ if site.is_demo_site and self.responsible_user is None:
68
68
  self.configure(responsible_user="robin")
69
69
 
70
70
  def post_site_startup(self, site):
@@ -43,49 +43,50 @@ class MyEmotionField(dd.VirtualField):
43
43
  def value_from_object(self, obj, ar=None):
44
44
  return obj.get_my_emotion(ar)
45
45
 
46
-
47
- class AddCommentField(dd.VirtualField):
48
- """
49
- An editable virtual field to add a comment about that database object.
50
-
51
- """
52
-
53
- editable = True
54
- # simple_elem = True
55
-
56
- def __init__(self, slave_table):
57
- t = models.TextField(_("Add comment"), blank=True)
58
- super().__init__(t, None)
59
- self.slave_table = slave_table
60
-
61
- def set_value_in_object(self, ar, obj, value):
62
- actor = rt.models.resolve(self.slave_table)
63
- # 20240913: The following line fixes a variant of #5715
64
- # (ObjectDoesNotExist: Invalid primary key 114 for
65
- # storage.FillersByPartner). When programmatically creating an action
66
- # request, we must not pass the incoming http request because that would
67
- # ask Lino to re-parse the URL parameters, including (in this case) sr
68
- # (the ids of selected rows).
69
- sar = actor.request(master_instance=obj, parent=ar)
70
- # sar = actor.request(
71
- # master_instance=obj, request=ar.request, renderer=ar.renderer
72
- # )
73
- obj = sar.create_instance(body=value)
74
- obj.full_clean()
75
- obj.save_new_instance(sar)
76
-
77
- # The refresh_delayed_value response below is theoretically NOT needed
78
- # because CommentsByRFC.live_panel_update does the update for delayed
79
- # value already. But live_panel_update doesn't work when linod is not
80
- # running or linod.use_channels is `False`.
81
- ar.set_response(refresh_delayed_value=str(actor))
82
-
83
- # if anybody complains that the refresh doesn't work in ExtJS, we would
84
- # need to reactivate the following line:
85
- # ar.set_response(refresh=True)
86
-
87
- def value_from_object(self, obj, ar=None):
88
- return None
46
+ # Removed because it requires much hacking and doesn't improve user experience
47
+ # dramatically:
48
+ # class AddCommentField(dd.VirtualField):
49
+ # """
50
+ # An editable virtual field to add a comment about that database object.
51
+ #
52
+ # """
53
+ #
54
+ # editable = True
55
+ # # simple_elem = True
56
+ #
57
+ # def __init__(self, slave_table):
58
+ # t = models.TextField(_("Add comment"), blank=True)
59
+ # super().__init__(t, None)
60
+ # self.slave_table = slave_table
61
+ #
62
+ # def set_value_in_object(self, ar, obj, value):
63
+ # actor = rt.models.resolve(self.slave_table)
64
+ # # 20240913: The following line fixes a variant of #5715
65
+ # # (ObjectDoesNotExist: Invalid primary key 114 for
66
+ # # storage.FillersByPartner). When programmatically creating an action
67
+ # # request, we must not pass the incoming http request because that would
68
+ # # ask Lino to re-parse the URL parameters, including (in this case) sr
69
+ # # (the ids of selected rows).
70
+ # sar = actor.request(master_instance=obj, parent=ar)
71
+ # # sar = actor.request(
72
+ # # master_instance=obj, request=ar.request, renderer=ar.renderer
73
+ # # )
74
+ # obj = sar.create_instance(body=value)
75
+ # obj.full_clean()
76
+ # obj.save_new_instance(sar)
77
+ #
78
+ # # The refresh_delayed_value response below is theoretically NOT needed
79
+ # # because CommentsByRFC.live_panel_update does the update for delayed
80
+ # # value already. But live_panel_update doesn't work when linod is not
81
+ # # running or linod.use_channels is `False`.
82
+ # ar.set_response(refresh_delayed_value=str(actor))
83
+ #
84
+ # # if anybody complains that the refresh doesn't work in ExtJS, we would
85
+ # # need to reactivate the following line:
86
+ # # ar.set_response(refresh=True)
87
+ #
88
+ # def value_from_object(self, obj, ar=None):
89
+ # return None
89
90
 
90
91
 
91
92
  class Commentable(MemoReferrable):
@@ -121,7 +122,7 @@ class Commentable(MemoReferrable):
121
122
  def get_create_comment_text(self, ar):
122
123
  return _("Created new {model} {obj}.").format(
123
124
  model=self.__class__._meta.verbose_name, obj=self)
124
-
125
+
125
126
  @classmethod
126
127
  def add_comments_filter(cls, qs, ar):
127
128
  return qs
@@ -24,7 +24,7 @@ from lino.modlib.gfks.mixins import Controllable
24
24
  from lino.modlib.memo.mixins import Previewable, MemoReferrable
25
25
  from lino.modlib.publisher.mixins import Publishable
26
26
  from .choicelists import CommentEvents, Emotions
27
- from .mixins import Commentable, MyEmotionField, AddCommentField
27
+ from .mixins import Commentable, MyEmotionField
28
28
  from .roles import CommentsReader, CommentsStaff
29
29
  # from .choicelists import PublishAllComments, PublishComment
30
30
 
@@ -127,7 +127,7 @@ class Comment(
127
127
 
128
128
  my_emotion = MyEmotionField()
129
129
 
130
- reply = AddCommentField("comments.RepliesByComment")
130
+ # reply = AddCommentField("comments.RepliesByComment")
131
131
 
132
132
  def is_public(self):
133
133
  return not self.private
@@ -55,9 +55,14 @@ class CommentDetail(dd.DetailLayout):
55
55
  body #body_full_preview
56
56
  """
57
57
  general2 = """
58
- reply
59
58
  RepliesByComment
59
+ # reply
60
60
  """
61
+ # I moved the reply field to the bottom, and later removed it altogether,
62
+ # because i stopped using it after repeated cases where my editing got lost
63
+ # because there was a traceback after hitting submit, leaving me unable to
64
+ # even copy the text I just typed in order to re-create my comment after
65
+ # reloading the page. And these tracebacks are difficult to reproduce.
61
66
 
62
67
  more = dd.Panel(
63
68
  """
@@ -120,7 +125,8 @@ class Comments(dd.Table):
120
125
 
121
126
  @classmethod
122
127
  def comments_created(cls, user, sd, ed):
123
- pv = dict(start_date=sd, end_date=ed, observed_event=CommentEvents.created)
128
+ pv = dict(user=user, start_date=sd, end_date=ed, observed_event=CommentEvents.created)
129
+ # pv = dict(start_date=sd, end_date=ed, observed_event=CommentEvents.created)
124
130
  return cls.request(user=user, param_values=pv)
125
131
 
126
132
  # @classmethod
@@ -268,7 +274,7 @@ class CommentsByMentioned(CommentsByX):
268
274
  Mention = rt.models.memo.Mention
269
275
  assert not cls.model._meta.abstract
270
276
  ct = ContentType.objects.get_for_model(cls.model)
271
- mkw = gfk2lookup(Mention.source, mi, owner_type=ct)
277
+ mkw = gfk2lookup(Mention.target, mi, owner_type=ct)
272
278
  mentions = Mention.objects.filter(**mkw).values_list("owner_id", flat=True)
273
279
  # mentions = [o.comment_id for o in Mention.objects.filter(**mkw)]
274
280
  # print(mkw, mentions)
@@ -8,7 +8,7 @@ Don't mix up this module with :mod:`lino.mixins.duplicable`. Models
8
8
  are "duplicable" if users may *want* to duplicate some instance
9
9
  thereof, while "dupable" implies that the duplicates are *unwanted*.
10
10
  To dupe *somebody* means "to make a dupe of; deceive; delude; trick."
11
- (`reference.com <http://dictionary.reference.com/browse/dupe>`_), and
11
+ (`reference.com <https://dictionary.reference.com/browse/dupe>`_), and
12
12
  to dupe *something* means to duplicate it (eventually in order to
13
13
  cheat somebody e.g. by making a cheap copy of a valuable object).
14
14
 
@@ -23,15 +23,11 @@ and the `Double Metaphone
23
23
  <https://en.wikipedia.org/wiki/Metaphone#Double_Metaphone>`_
24
24
  algorithm. Read also Doug Hellmann about `Using Fuzzy Matching to
25
25
  Search by Sound with Python
26
- <http://www.informit.com/articles/article.aspx?p=1848528>`_
26
+ <https://www.informit.com/articles/article.aspx?p=1848528>`_
27
27
  (2012-03-22).
28
28
 
29
29
  """
30
30
 
31
- from __future__ import unicode_literals
32
- import six
33
- from builtins import object
34
-
35
31
  from django.db import models
36
32
 
37
33
  from lino.api import dd, _
@@ -54,7 +50,7 @@ class PhoneticWord(Controllable):
54
50
 
55
51
  """
56
52
 
57
- class Meta(object):
53
+ class Meta:
58
54
  verbose_name = _("Phonetic word")
59
55
  verbose_name_plural = _("Phonetic words")
60
56
 
@@ -86,16 +82,16 @@ class PhoneticWord(Controllable):
86
82
  dms = dm[0] or dm[1]
87
83
  if dms is None:
88
84
  return ""
89
- if isinstance(dms, six.binary_type):
85
+ if isinstance(dms, bytes):
90
86
  dms = dms.decode("utf8")
91
87
  return dms
92
88
 
93
- @classmethod
94
- def get_simple_parameters(cls):
95
- for p in super(PhoneticWord, cls).get_simple_parameters():
96
- yield p
97
- yield "owner_id"
98
- yield "owner_type"
89
+ # @classmethod
90
+ # def get_simple_parameters(cls):
91
+ # for p in super(PhoneticWord, cls).get_simple_parameters():
92
+ # yield p
93
+ # yield "owner_id"
94
+ # yield "owner_type"
99
95
 
100
96
 
101
97
  class PhoneticWords(dd.Table):
@@ -56,7 +56,7 @@ class Controllable(dd.Model):
56
56
  def update_owned_instance(self, controllable):
57
57
  if self.owner:
58
58
  self.owner.update_owned_instance(controllable)
59
- super(Controllable, self).update_owned_instance(controllable)
59
+ super().update_owned_instance(controllable)
60
60
 
61
61
  def save(self, *args, **kw):
62
62
  if settings.SITE.loading_from_dump:
@@ -72,3 +72,10 @@ class Controllable(dd.Model):
72
72
  gfk = self._meta.get_field("owner")
73
73
  kwargs = gfk2lookup(gfk, self, **kwargs)
74
74
  return model.objects.filter(**kwargs)
75
+
76
+ @classmethod
77
+ def get_simple_parameters(cls):
78
+ for p in super().get_simple_parameters():
79
+ yield p
80
+ yield "owner_type"
81
+ yield "owner_id"
@@ -37,8 +37,8 @@ class JinjaBuildMethod(DjangoBuildMethod):
37
37
  )
38
38
  context = elem.get_printable_context(ar)
39
39
  html = tpl.render(context)
40
- self.html2file(html, filename)
40
+ self.html2file(html, filename, context)
41
41
  return os.path.getmtime(filename)
42
42
 
43
- def html2file(self, html, filename):
44
- raise NotImplementedError()
43
+ def html2file(self, html, filename, context):
44
+ open(filename, "w").write(html)
@@ -128,6 +128,8 @@ class JinjaRenderer(HtmlRenderer):
128
128
  iif=iif,
129
129
  str=str,
130
130
  len=len,
131
+ int=int,
132
+ round=round,
131
133
  E=E,
132
134
  tostring=tostring,
133
135
  isinstance=isinstance,
@@ -1,5 +1,5 @@
1
1
  # -*- coding: UTF-8 -*-
2
- # Copyright 2011-2020 Rumma & Ko Ltd
2
+ # Copyright 2011-2025 Rumma & Ko Ltd
3
3
  # License: GNU Affero General Public License v3 (see file COPYING for details)
4
4
  """
5
5
  Adds all languages of the world to your database.
@@ -22,8 +22,6 @@ import codecs
22
22
 
23
23
  from django.conf import settings
24
24
 
25
- # from lino.utils import dblogger as logger
26
-
27
25
  from lino.api import dd
28
26
  from lino.modlib.languages.models import Language
29
27
 
@@ -752,7 +750,7 @@ def objects():
752
750
  if ln:
753
751
  ln = ln.strip()
754
752
  if not ln[-4:-3].isspace():
755
- logger.warning("german %d: syntax", n)
753
+ dd.logger.warning("german %d: syntax", n)
756
754
  else:
757
755
  code = ln[-3:]
758
756
  name = ln[:-4]
@@ -772,7 +770,7 @@ def objects():
772
770
  ln = ln.strip()
773
771
  rec = ln.split("\t")
774
772
  if len(rec) < 6:
775
- logger.warning("Ignored french:%d:%s (len(rec) is %d)", n, ln, len(rec))
773
+ dd.logger.warning("Ignored french:%d:%s (len(rec) is %d)", n, ln, len(rec))
776
774
  code = rec[1]
777
775
  if len(code) == 7:
778
776
  if code[3:4] == "/":
@@ -794,7 +792,7 @@ def objects():
794
792
  kw.update(iso2=iso2)
795
793
  yield Language(id=code, **kw)
796
794
  else:
797
- logger.debug(
795
+ dd.logger.debug(
798
796
  "%r : no name for default site language %s",
799
797
  code,
800
798
  settings.SITE.DEFAULT_LANGUAGE.django_code,