lino 25.7.1__py3-none-any.whl → 25.7.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 +1 -1
- lino/api/doctest.py +13 -10
- lino/core/__init__.py +0 -2
- lino/core/actions.py +5 -7
- lino/core/actors.py +2 -162
- lino/core/elems.py +1 -1
- lino/core/fields.py +3 -0
- lino/core/kernel.py +6 -0
- lino/core/layouts.py +5 -7
- lino/core/model.py +1 -0
- lino/core/plugin.py +1 -1
- lino/core/renderer.py +1 -1
- lino/core/requests.py +3 -4
- lino/core/site.py +1 -1
- lino/core/utils.py +6 -4
- lino/help_texts.py +2 -1
- lino/mixins/registrable.py +4 -2
- lino/modlib/extjs/views.py +7 -0
- lino/modlib/linod/__init__.py +1 -1
- lino/modlib/memo/__init__.py +1 -2
- lino/modlib/office/roles.py +0 -1
- lino/modlib/printing/actions.py +2 -6
- lino/modlib/printing/choicelists.py +6 -6
- lino/modlib/printing/mixins.py +2 -2
- lino/modlib/publisher/__init__.py +21 -30
- lino/modlib/publisher/models.py +3 -1
- lino/modlib/publisher/views.py +4 -11
- lino/modlib/weasyprint/__init__.py +9 -0
- lino/modlib/weasyprint/choicelists.py +14 -9
- lino/modlib/weasyprint/config/weasyprint/base.weasy.html +15 -13
- {lino-25.7.1.dist-info → lino-25.7.2.dist-info}/METADATA +1 -1
- {lino-25.7.1.dist-info → lino-25.7.2.dist-info}/RECORD +35 -39
- lino/modlib/forms/__init__.py +0 -51
- lino/modlib/forms/models.py +0 -0
- lino/modlib/forms/renderer.py +0 -74
- lino/modlib/forms/views.py +0 -311
- {lino-25.7.1.dist-info → lino-25.7.2.dist-info}/WHEEL +0 -0
- {lino-25.7.1.dist-info → lino-25.7.2.dist-info}/licenses/AUTHORS.rst +0 -0
- {lino-25.7.1.dist-info → lino-25.7.2.dist-info}/licenses/COPYING +0 -0
lino/modlib/forms/views.py
DELETED
@@ -1,311 +0,0 @@
|
|
1
|
-
# -*- coding: UTF-8 -*-
|
2
|
-
# Copyright 2009-2017 Rumma & Ko Ltd
|
3
|
-
# License: GNU Affero General Public License v3 (see file COPYING for details)
|
4
|
-
"""Views for `lino.modlib.bootstrap3`.
|
5
|
-
|
6
|
-
"""
|
7
|
-
from __future__ import division
|
8
|
-
from past.utils import old_div
|
9
|
-
|
10
|
-
from lino import logger
|
11
|
-
|
12
|
-
from django import http
|
13
|
-
from django.conf import settings
|
14
|
-
from django.views.generic import View
|
15
|
-
from django.core import exceptions
|
16
|
-
from django.utils.translation import gettext as _
|
17
|
-
from django.utils.translation import get_language
|
18
|
-
|
19
|
-
# from django.contrib import auth
|
20
|
-
from lino.core import auth
|
21
|
-
|
22
|
-
# from lino.api import dd
|
23
|
-
from lino.core import constants
|
24
|
-
|
25
|
-
# from lino.core import auth
|
26
|
-
from lino.core.requests import BaseRequest
|
27
|
-
from lino.core.tables import AbstractTable
|
28
|
-
from lino.core.views import action_request
|
29
|
-
from lino.core.utils import navinfo
|
30
|
-
from lino.utils.html import E, tostring
|
31
|
-
from etgen import html as xghtml
|
32
|
-
|
33
|
-
PLAIN_PAGE_LENGTH = 15
|
34
|
-
|
35
|
-
MENUS = dict()
|
36
|
-
|
37
|
-
|
38
|
-
def http_response(ar, tplname, context):
|
39
|
-
"Deserves a docstring"
|
40
|
-
u = ar.get_user()
|
41
|
-
lang = get_language()
|
42
|
-
k = (u.user_type, lang)
|
43
|
-
menu = MENUS.get(k, None)
|
44
|
-
if menu is None:
|
45
|
-
menu = settings.SITE.get_site_menu(u.user_type)
|
46
|
-
bs3 = settings.SITE.plugins.bootstrap3
|
47
|
-
if False: # 20150803 home button now in base.html
|
48
|
-
assert bs3.renderer is not None
|
49
|
-
url = bs3.build_plain_url()
|
50
|
-
menu.add_url_button(url, label=_("Home"))
|
51
|
-
e = bs3.renderer.show_menu(ar, menu)
|
52
|
-
menu = tostring(e)
|
53
|
-
MENUS[k] = menu
|
54
|
-
context.update(menu=menu)
|
55
|
-
context = ar.get_printable_context(**context)
|
56
|
-
context["ar"] = ar
|
57
|
-
context["memo"] = ar.parse_memo # MEMO_PARSER.parse
|
58
|
-
env = settings.SITE.plugins.jinja.renderer.jinja_env
|
59
|
-
template = env.get_template(tplname)
|
60
|
-
|
61
|
-
response = http.HttpResponse(
|
62
|
-
template.render(**context), content_type='text/html;charset="utf-8"'
|
63
|
-
)
|
64
|
-
|
65
|
-
return response
|
66
|
-
|
67
|
-
|
68
|
-
def buttons2pager(buttons, title=None):
|
69
|
-
items = []
|
70
|
-
if title:
|
71
|
-
items.append(E.li(E.span(title)))
|
72
|
-
for symbol, label, url in buttons:
|
73
|
-
if url is None:
|
74
|
-
items.append(E.li(E.span(symbol), **{"class": "disabled"}))
|
75
|
-
else:
|
76
|
-
items.append(E.li(E.a(symbol, href=url)))
|
77
|
-
# Bootstrap version 2.x
|
78
|
-
# return E.div(E.ul(*items), class_='pagination')
|
79
|
-
return E.ul(*items, **{"class": "pagination pagination-sm"})
|
80
|
-
|
81
|
-
|
82
|
-
def table2html(ar, as_main=True):
|
83
|
-
"""Represent the given table request as an HTML table.
|
84
|
-
|
85
|
-
`ar` is the request to be rendered, an instance of
|
86
|
-
:class:`lino.core.requests.ActionRequest`.
|
87
|
-
|
88
|
-
The returned HTML enclosed in a ``<div>`` tag and generated using
|
89
|
-
:mod:`etgen.html`.
|
90
|
-
|
91
|
-
If `as_main` is True, include additional elements such as a paging
|
92
|
-
toolbar. (This argument is currently being ignored.)
|
93
|
-
|
94
|
-
"""
|
95
|
-
as_main = True
|
96
|
-
t = xghtml.Table()
|
97
|
-
t.set("class", "table table-striped table-hover")
|
98
|
-
if ar.limit is None:
|
99
|
-
ar.limit = PLAIN_PAGE_LENGTH
|
100
|
-
pglen = ar.limit
|
101
|
-
if ar.offset is None:
|
102
|
-
page = 1
|
103
|
-
else:
|
104
|
-
"""
|
105
|
-
(assuming pglen is 5)
|
106
|
-
offset page
|
107
|
-
0 1
|
108
|
-
5 2
|
109
|
-
"""
|
110
|
-
page = int(old_div(ar.offset, pglen)) + 1
|
111
|
-
|
112
|
-
ar.dump2html(t, ar.sliced_data_iterator, header_links=as_main)
|
113
|
-
if not as_main:
|
114
|
-
url = ar.get_request_url() # open in own window
|
115
|
-
return E.div(E.a(ar.get_title(), href=url), t.as_element())
|
116
|
-
|
117
|
-
buttons = []
|
118
|
-
kw = dict()
|
119
|
-
kw = {}
|
120
|
-
if pglen != PLAIN_PAGE_LENGTH:
|
121
|
-
kw[constants.URL_PARAM_LIMIT] = pglen
|
122
|
-
|
123
|
-
if page > 1:
|
124
|
-
kw[constants.URL_PARAM_START] = pglen * (page - 2)
|
125
|
-
prev_url = ar.get_request_url(**kw)
|
126
|
-
kw[constants.URL_PARAM_START] = 0
|
127
|
-
first_url = ar.get_request_url(**kw)
|
128
|
-
else:
|
129
|
-
prev_url = None
|
130
|
-
first_url = None
|
131
|
-
buttons.append(("<<", _("First page"), first_url))
|
132
|
-
buttons.append(("<", _("Previous page"), prev_url))
|
133
|
-
|
134
|
-
next_start = pglen * page
|
135
|
-
if next_start < ar.get_total_count():
|
136
|
-
kw[constants.URL_PARAM_START] = next_start
|
137
|
-
next_url = ar.get_request_url(**kw)
|
138
|
-
last_page = int(old_div((ar.get_total_count() - 1), pglen))
|
139
|
-
kw[constants.URL_PARAM_START] = pglen * last_page
|
140
|
-
last_url = ar.get_request_url(**kw)
|
141
|
-
else:
|
142
|
-
next_url = None
|
143
|
-
last_url = None
|
144
|
-
buttons.append((">", _("Next page"), next_url))
|
145
|
-
buttons.append((">>", _("Last page"), last_url))
|
146
|
-
|
147
|
-
return E.div(buttons2pager(buttons), t.as_element())
|
148
|
-
|
149
|
-
|
150
|
-
def layout2html(ar, elem):
|
151
|
-
wl = ar.bound_action.get_window_layout()
|
152
|
-
# ~ print 20120901, wl.main
|
153
|
-
lh = wl.get_layout_handle()
|
154
|
-
|
155
|
-
items = list(lh.main.as_plain_html(ar, elem))
|
156
|
-
# if navigator:
|
157
|
-
# items.insert(0, navigator)
|
158
|
-
# ~ print tostring(E.div())
|
159
|
-
# ~ if len(items) == 0: return ""
|
160
|
-
return E.form(*items)
|
161
|
-
# ~ print 20120901, lh.main.__html__(ar)
|
162
|
-
|
163
|
-
|
164
|
-
class List(View):
|
165
|
-
"""Render a list of records."""
|
166
|
-
|
167
|
-
def get(self, request, app_label=None, actor=None):
|
168
|
-
ar = action_request(app_label, actor, request, request.GET, True)
|
169
|
-
ar.renderer = settings.SITE.plugins.bootstrap3.renderer
|
170
|
-
|
171
|
-
context = dict(
|
172
|
-
title=ar.get_title(),
|
173
|
-
heading=ar.get_title(),
|
174
|
-
)
|
175
|
-
|
176
|
-
if ar.actor is not None and issubclass(ar.actor, AbstractTable):
|
177
|
-
context.update(main=table2html(ar))
|
178
|
-
else:
|
179
|
-
context.update(main=layout2html(ar, None))
|
180
|
-
|
181
|
-
context.update(ar=ar)
|
182
|
-
return http_response(ar, ar.actor.list_html_template, context)
|
183
|
-
|
184
|
-
|
185
|
-
class Element(View):
|
186
|
-
"""Render a single record."""
|
187
|
-
|
188
|
-
def get(self, request, app_label=None, actor=None, pk=None):
|
189
|
-
ar = action_request(app_label, actor, request, request.GET, False)
|
190
|
-
ar.renderer = settings.SITE.plugins.bootstrap3.renderer
|
191
|
-
|
192
|
-
navigator = None
|
193
|
-
if pk and pk != "-99999" and pk != "-99998":
|
194
|
-
elem = ar.get_row_by_pk(pk)
|
195
|
-
if elem is None:
|
196
|
-
raise http.Http404("%s has no row with primary key %r" % (ar.actor, pk))
|
197
|
-
# ~ raise Exception("20120327 %s.get_row_by_pk(%r)" % (rpt,pk))
|
198
|
-
if ar.actor.show_detail_navigator:
|
199
|
-
ni = navinfo(ar.data_iterator, elem)
|
200
|
-
if ni:
|
201
|
-
# m = elem.__class__
|
202
|
-
buttons = []
|
203
|
-
# ~ buttons.append( ('*',_("Home"), '/' ))
|
204
|
-
|
205
|
-
buttons.append(("<<", _("First page"), ar.pk2url(ni["first"])))
|
206
|
-
buttons.append(("<", _("Previous page"), ar.pk2url(ni["prev"])))
|
207
|
-
buttons.append((">", _("Next page"), ar.pk2url(ni["next"])))
|
208
|
-
buttons.append((">>", _("Last page"), ar.pk2url(ni["last"])))
|
209
|
-
|
210
|
-
navigator = buttons2pager(buttons)
|
211
|
-
else:
|
212
|
-
navigator = E.p("No navinfo")
|
213
|
-
else:
|
214
|
-
elem = None
|
215
|
-
|
216
|
-
main = layout2html(ar, elem)
|
217
|
-
|
218
|
-
# The `method="html"` argument isn't available in Python 2.6,
|
219
|
-
# only 2.7. It is useful to avoid side effects in case of
|
220
|
-
# empty elements: the default method (xml) writes an empty
|
221
|
-
# E.div() as "<div/>" while in HTML5 it must be "<div></div>"
|
222
|
-
# (and the ending / is ignored).
|
223
|
-
|
224
|
-
# ~ return tostring(main, method="html")
|
225
|
-
# ~ return tostring(main)
|
226
|
-
# return main
|
227
|
-
|
228
|
-
context = dict(
|
229
|
-
title=ar.get_action_title(),
|
230
|
-
obj=elem,
|
231
|
-
form=main,
|
232
|
-
navigator=navigator,
|
233
|
-
)
|
234
|
-
# ~ template = web.jinja_env.get_template('detail.html')
|
235
|
-
context.update(ar=ar)
|
236
|
-
return http_response(ar, ar.actor.detail_html_template, context)
|
237
|
-
|
238
|
-
|
239
|
-
class Authenticate(View):
|
240
|
-
def get(self, request, *args, **kw):
|
241
|
-
action_name = request.GET.get(constants.URL_PARAM_ACTION_NAME)
|
242
|
-
if action_name == "logout":
|
243
|
-
username = request.session.pop("username", None)
|
244
|
-
auth.logout(request)
|
245
|
-
# request.user = settings.SITE.user_model.get_anonymous_user()
|
246
|
-
# request.session.pop('password', None)
|
247
|
-
# ~ username = request.session['username']
|
248
|
-
# ~ del request.session['password']
|
249
|
-
target = "/"
|
250
|
-
return http.HttpResponseRedirect(target)
|
251
|
-
|
252
|
-
# ar = BaseRequest(request)
|
253
|
-
# ar.success("User %r logged out." % username)
|
254
|
-
# return ar.renderer.render_action_response(ar)
|
255
|
-
raise http.Http404()
|
256
|
-
|
257
|
-
def post(self, request, *args, **kw):
|
258
|
-
username = request.POST.get("username")
|
259
|
-
password = request.POST.get("password")
|
260
|
-
user = auth.authenticate(request, username=username, password=password)
|
261
|
-
auth.login(request, user)
|
262
|
-
target = "/"
|
263
|
-
return http.HttpResponseRedirect(target)
|
264
|
-
# ar = BaseRequest(request)
|
265
|
-
# mw = auth.get_auth_middleware()
|
266
|
-
# msg = mw.authenticate(username, password, request)
|
267
|
-
# if msg:
|
268
|
-
# request.session.pop('username', None)
|
269
|
-
# ar.error(msg)
|
270
|
-
# else:
|
271
|
-
# request.session['username'] = username
|
272
|
-
# # request.session['password'] = password
|
273
|
-
# # ar.user = request....
|
274
|
-
# ar.success(("Now logged in as %r" % username))
|
275
|
-
# # print "20150428 Now logged in as %r (%s)" % (username, user)
|
276
|
-
# return ar.renderer.render_action_response(ar)
|
277
|
-
|
278
|
-
|
279
|
-
class Index(View):
|
280
|
-
"""
|
281
|
-
Render the main page.
|
282
|
-
"""
|
283
|
-
|
284
|
-
def get(self, request, *args, **kw):
|
285
|
-
# raise Exception("20171122 {} {}".format(
|
286
|
-
# get_language(), settings.MIDDLEWARE_CLASSES))
|
287
|
-
ui = settings.SITE.plugins.bootstrap3
|
288
|
-
# print("20170607", request.user)
|
289
|
-
# assert ui.renderer is not None
|
290
|
-
ar = BaseRequest(
|
291
|
-
# user=user,
|
292
|
-
request=request,
|
293
|
-
renderer=ui.renderer,
|
294
|
-
)
|
295
|
-
return index_response(ar)
|
296
|
-
|
297
|
-
|
298
|
-
def index_response(ar):
|
299
|
-
ui = settings.SITE.plugins.bootstrap3
|
300
|
-
main = settings.SITE.get_main_html(ar, front_end=ui)
|
301
|
-
main = ui.renderer.html_text(main)
|
302
|
-
context = dict(
|
303
|
-
title=settings.SITE.title,
|
304
|
-
main=main,
|
305
|
-
)
|
306
|
-
# if settings.SITE.user_model is None:
|
307
|
-
# user = auth.AnonymousUser.instance()
|
308
|
-
# else:
|
309
|
-
# user = request.subst_user or request.user
|
310
|
-
# context.update(ar=ar)
|
311
|
-
return http_response(ar, "bootstrap3/index.html", context)
|
File without changes
|
File without changes
|
File without changes
|