Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More

2024

This is the 2024 change log for Lino. Learn how to read and maintain this document in Documenting changes.

2024-12-08

New methods lino.core.model.Model.as_str() and lino.core.model.Model.get_str_words() for #5809 (Optimize as_summary_item()).

2024-11-16

Advancing with #4381 (Uploading photos or other media files via email (postfix/inbox plugin)). When processing an inbox message, Lino no longer creates one comment for each attached file + one comment for the body text. It creates maximum one comment per incoming message. Fixed multiple issues with rendering uploads in comments. The Upload model now has two memo commands: [upload] and [file]. [upload] inserts a link to the detail page in the web front end while [file] inserts a tag representing the media file (for example an <img> or a <video> tag).

Change in database schema: in the lino.modlib.memo.Mention model, source was renamed to target. Done #4702 (There are no comments.Mention in amici though there are memo references in comments)

2024-11-15

More optimization for #5585: The Previewers choicelist is replaced by a single lino.modlib.uploads.previewer object and a class UploadMediaFile. The create_comment_template attribute is replaced by a method lino.modlib.comments.Commentable.get_create_comment_text().

Fixed #4851 (Bleach is no longer being maintained). Lino no longer requires the bleach package, it now relies on beautifulsoup4. See Bleaching.

Fixed a “TypeError: BaseRequest.setup() got an unexpected keyword argument ‘quick_search’” occurring in lino.modlib.search.SiteSearch. Removed the Actor.list_layout attribute, which is no longer used.

2024-11-12

The lino.modlib.uploads plugin can now build “thumbnails” of images and PDF files. For this purpose the plugin defines a new choicelist lino.modlib.uploads.Previewers.

The following tickets are now done (or almost): #5585 (The albums plugin should manage thumbnails), #5299 (Lino should write a comment when somebody uploads a screenshot) and #4381 (Uploading photos or other media files via email (postfix/inbox plugin)).

2024-11-03

The lino_xl.lib.working plugin has a new database model Contract, a report ActiveContracts, and a new system task procedure send_weekly_report().

2024-11-02

Moved the DEMO_DATA constant from lino.utils to lino_book.

2024-11-01

New attribute lino.core.actors.Actor.row_template, which is a kind of a context-sensitive template for __str__() . An avalanche of internal changes. The lino.core.actors.Actor.group_by attribute is back. If specified, it must be a callable, and it currently only for the display mode “list” and only in the React front end. Details in my blog.

2024-10-21

Add support for customized period types and shifted years. New choicelist lino.modlib.periods.PeriodTypes and several plugin settings in lino.modlib.periods.

2024-10-18

Add a new method lino.core.actors.Actor.table_as_html(). Move the DisplayColors choicelist from lino_xl.lib.cal to lino.modlib.system. Optimize gen_insert_button. Fix a minor bug in BaseRequest.setup.

2024-10-09

New plugin lino.modlib.periods to make the concept of “years” and “periods” stored as database rows available outside of the lino_xl.lib.accounting plugin (which will be used by Lino Prima). Requires database migration for site that use the accounting plugin: The model “accounting.AccountingPeriod” was renamed to “periods.StoredPeriod” and model “accounting.FiscalYear” was renamed to “periods.StoredYear”. New function lino.core.utils.overlap_range_filter(). DateStoreField no longer raises a Warning when invalid date is given.

2024-10-04

Fixed #5768 (WorkedHours detail is broken), which was caused by #5759 (Anonymous can GET private comments), which was caused by #5751 (ObjectDoesNotExist: Invalid primary key 4968 for avanti.Clients) Fixing this ticket caused me to merge TableRequest into ActionRequest, which caused multiple internal optimizations but also may have introduced some regression. One of the optimizations is that GridElement.showDetail() in the React front end now passes the parameter values (URL_PARAM_PARAM_VALUES) in the GET when asking for a detail view. The original problem (#5751) was because the React front end didn’t do this. The problem did not occur in the ExtJS front end, which did it. For example when the user manually removes the default filter and then switches to detail view of a row that would be hidden under the default filter, Lino must not look up the pk in model.objects.all() instead of ar.get_request_queryset() because that would bypass user permissions. More details in #5751 ObjectDoesNotExist: Invalid primary key 4968 for avanti.Clients.

2024-10-02

Removed the Commentable.add_comment field because its implementation was quirky and caused confusion when a user had no write permission for a ticket.

Release to PyPI

2024-10-01

Fixed #5759 (Anonymous can GET private comments). Optimized the developer API for specifying the default display mode to use in a slave panel. Rather than specifying a tuple of 2-tuples called display_mode, we now specify a dict called default_display_modes, which maps available_width to display_mode. New attribute extra_display_modes on Model and Actor. Adapted the documentation More about display modes. The RecentComments table in the dashboard is now being rendered in display mode story instead of list. lino.core.renderer.HtmlRenderer.table2story() now supports display mode “story”. Internals: renamed Store.list_fields to Store.grid_fields, Actor.get_list_layout to Actor.get_grid_layout and TableHandle.list_layout to TableHandle.grid_layout. Removed DISPLAY_MODE_TABLE from lino.core.constants and changed all usages of it to DISPLAY_MODE_GRID.

In the lino_react, changed the icon for the “Expand this panel to own window” button from external-link (external link) to eject (pi-eject button).

2024-09-22

Optimized error reporting. Fixed #5755 (Remove AjaxExceptionResponse middleware). Added an lino.core.model.Model.as_paragraph() method to lino_xl.lib.cal.Guest.

2024-09-20

Fixed #5751 (ObjectDoesNotExist: Invalid primary key 4968 for avanti.Clients). Disable the [py] memo command. Optimize AJAX exception reporting.

2024-09-13

Fixed a variant of #5715 (ObjectDoesNotExist: Invalid primary key 114 for storage.FillersByPartner). The reason was lino.modlib.comments.AddCommentField.set_value_in_object(), which passed ar.request to the sub-request, which caused Lino to apply the selected pks of the master table to the slave table.

2024-09-11

The lino package has migrated from setup.py to pyproject.toml.

We probably fixed a series of issues with invalid ObjectDoesNotExist error messages when saving a ticket or a client.

Sites with the notify plugin but with notify.use_push_api set to False still caused the browser to send /WS/ requests every few seconds (each of which caused an error message in the JS console).

2024-09-08

The lino_xl.lib.inbox plugin got some optimizations, is now documented and being used again in Lino Noi, Lino Amici, Lino CMS. Lino CMS now also uses lino.modlib.groups. The cms1 demo project is the first to test this, it has a mailbox with a few demo emails that get processed during pm prep. New admin command pm procmail.

The lino.modlib.notify plugin has a new database field Message.reply_to and a new method ChangeNotifier.get_notify_options().

The lino.modlib.uploads plugin no longer uses the lino.core.Site attribute upload_to_tpl (Upload.file now build Django’s FieldField.upload_to from constants UPLOADS_ROOT and lino.utils.DATE_TO_DIR_TPL). The plugin now manages two top-level subdirectories of the media_root: uploads and volumes. It no longer creates the media directory if it doesn’t exist (anyway the initdb command removes it again). The Volume model no longer has a field base_url (the URL of a volume is made from its ref). New slave table UploadsByVolume is visible in the detail of a Volume.

Changing the lino.modlib.users.Assignable.assigned_to field now emits a customized notification message when changed. This behavious was previously defined in Lino Noi but is not generalized.

Fixed #5728 (Status report in dashboard is rendered as html tags).

2024-09-07

In Lino Avanti we have a new database field can_excuse on a course. When this checkbox is checked, users can select an additional presence state “excused”. See Calendar functions in Lino Avanti for details.

2024-08-26

Fixed #5719 (Check for password quality in ChangePassword). A default Lino site now uses the four basic password validators that are included with Django. See Password validation.

2024-08-05

Fixed #5704 (The MovementsByFiller panel in FillersByPartner detail doesn’t work). New class method Actor.cast_master_instance() is more intuitive to use and explain than Actor.get_master_instance() for use cases like storage.MovementsByFiller. Side effect is a new (internal) rule: when a master type mt is specified, it now has precedence over the Actor.master. Until now, mt was ignored unless Actor.master was ContentType.

2024-08-03

#5666 (Some optimizations in Noi): Display all tickets in list mode by default and add workflow buttons to tickets.Ticket.as_paragraph().

Fixed #5705 (Time credit provisions must not differentiate extra and regular). In lino_xl.lib.working we have a new database model ReportingRule, which is now used instead of the ReportingTypes choicelist to decide which product to use when invoicing a session. And ReportingTypes consequently no longer uses lino.core.choicelists.PointingChoice. Side effects: the lino_xl.lib.tickets.Site model, the lino_xl.lib.tickets.SiteStates choicelist, the lino_xl.lib.working.ServiceReport model and the lino.core.model.Model.get_typed_instance() method have been removed because they weren’t used by anybody.

2024-07-28

Continued #5666 (Some optimizations in Noi): General reorganization of the detail layout of ticket. New field Ticket.urgent. Lino Noi no longer uses the AssignToMe action because the Ticket.quick_assign_to field is more convenient.

2024-07-12

#5685 (Review the API for get_table_summary(). Most but not all customized Actor.get_table_summary() methods have been converted to Actor.table_as_summary(). Minor optimizations as side effects: lino.utils.AttrDict now supports setting an attribute. The overview field didn’t yet support getting a safe html string from get_overview_elems(). For more details, see Luc’s developer blog

2024-07-10

First steps for #5670 (Support e-invoices (PEPPOL)): When printing a sales invoice to a customer who has a VAT number, Lino now generates an XML file containing the electronic invoice in PEPPOL format. The pdf invoice then contains a text “e-invoice: /media/beppol/SLS/112.xml”. See Lino and eInvoicing (PEPPOL).

lino_xl.lib.vat.VatItemBase.get_peppol_vat_category() lino_xl.lib.vat.VatDocument()

2024-06-30

lino.utils.xml.validate_xml() now acts differently depending on whether the given xsdfile ends with .xsd or with .sch. When it ends with .xsd, the generated xmlfile file is validated using lxml.etree.XMLSchema (as it was until now). When it ends with .sch, the generated xmlfile file is validated using lxml.isoschematron.Schematron.

2024-06-17

#5660 (logger.debug() notification messages). The msg_func argument to lino.modlib.notify.Message.emit_notification() is no longer called with two arguments (user, mail_mode) but without arguments.

2024-06-14

BaseRequest.is_obvious_field() no longer fails when called on an actorless request.

The obj2href() and as_summary_row() methods of Model were merged into a single method named as_summary_item.

2024-06-02

Lino Noi has now two major options with_accounting and with_cms.

lino.modlib.publisher.Page.child_node_depth now defaults to 1, and child pages are now also shown when memo.use_markup is True.

2024-05-31

The format of a textfield must now be specified using the format attribute. An attribute named textfield_format no longer exists on the RichTextField object. Until now the attribute was named textfield_format, but an format was accepted as a keyword and stored as textfield_format. (The textfield_format attribute of the Site class remains unchanged.)

The use_markup setting has been moved from publisher to memo.

2024-05-30

Merged lino_xl.lib.pages in to lino.modlib.publisher. New choicelist publisher.SpecialPages. The pages.use_markup setting is now publisher.use_markup.

2024-05-28

A first step towards #5623 (Replace memo parser by markdown?): added a new plugin setting pages.use_markup. Side effect: moved PageFillers from lino_xl.lib.pages to lino.modlib.publisher.

Done #5632 (We can always talk about a ticket).

2024-05-24

The master_key of a slave table is no longer automatically added as a simple parameter field. For example lino.modlib.dashboard.WidgetsByUser.

2024-05-21

The functionality for verifying the email address of a user is now available also when allow_online_registration is False.

2024-05-18

The as_paragraph of contacts.Partner did not always return a safe string. Such a stupid bug should not have slipped through our test suite! So lino_react.react.views now uses lino.utils.html.assert_safe() and the lino.api.doctest.walk_menu_items() function now also calls every table with display_mode set to 'list'. This detected two more models whose as_paragraph doesn’t yet return a safe string (working.Session and contacts.Role).

The lino.core.site.Site.remote_user_header is no longer being used. #5618 (Stop supporting HTTP authentication (Site.remote_user_header))

2024-05-16

Lino no longer sets a default time when inserting a calendar entry. New function show_change_watchers for usage in tested documents.

2024-05-13

New plugin lino_xl.lib.agenda. Visible in Lino Amici where calendar entries have a new tab “Agend” in their detail view and when you print an entry. Lino will also list the agenda items.

2024-05-11

Rename plugin: ledger (lino_xl.lib.ledger) to accounting (lino_xl.lib.accounting).

2024-05-11

A series of internal optimizations: Fixed a bug in lino.modlib.jinja : the config directory of the site_dir was searched last when looking for a template, but it should get searched first. The polls and polls2 demo sites were probably the only victims of that bug. show_menu no longer requires a username. ar.action_link. The docutils.conf of the Developer Guide no longer sets smart_quotes to False; this might cause a series of help texts to get marked as needing work in the .po files. #5600 (react plugin no longer needs lino.modlib.system).

2024-05-10

Work in progress for ##5596 (Better names for obj2href() and obj2html()): Model.as_summary_row() and Model.as_paragraph() now call Model.obj2href() instead of ar.obj2html(). Some more internal optimizations: The lino.utils.html.tostring() function is now a copy of etgen.html.tostring() and it now escapes the value when it is an unsafe str.

2024-05-08

Fixing #5576 (My teams should show description in only one language) was trivial but caused an avalanche of internal optimizations. The default implementation of detail_link now uses lino.core.model.Model.as_paragraph() as default text instead of ar.obj2htmls(). #5353 (Use mark_safe instead of ElementTree). New feature: #5589 (Simple parameters should be considered obvious fields). Optimization: #5590 (Render href in tested docs more consistently). To avoid making etgen depend on Django, I created a new module lino.utils.html with a function tostring that wraps Django’s safestring tools around etgen.html.tostring(). All Lino code now imports tostring() from this new lino.utils.html module. I started a topic guide Generating HTML.

2024-04-30

New feature Job providers with multiple workplaces for Lino Welfare Châtelet (#5567). New database fields jobs.Job.workplace and contacts.Company.job_provider. New slave table WorkplacesByProvider in the detail view of a job provider.

2024-04-25

Internal optimizations: the lino_xl.lib.contacts.Partner model now inherits from Commentable. This fixes #5578 (Amici says ‘Household’ object has no attribute ‘is_comment_private’). Optimized Plugin.__repr__().

2024-04-24

Fixed several bugs that caused the background task runner to get stuck. pm linod now also starts a log server when linod.use_channels is False.

Database needs migration because lino.modlib.linod.SystemTask and lino_xl.lib.invoicing.Task have a new field name.

2024-04-22

Done #5565 (Replace “Project” by “Topics” in Noi). Fixed a database design bug in lino_xl.lib.topics: New model lino_xl.lib.topics.Tag, and lino_xl.lib.topics.Interest no longer has an owner field. InterestsByController has become TagsByOwner, InterestsByPartner has become TagsByTopic. Topic is no longer a BabelNamed. The Interesting mixin has been renamed to Taggable. The topics.partner_model can now be None, which means that there is no Interest model, use cases are Lino Tera and Lino CMS.

2024-04-15

Fixed #5553 (Invalid panel spec. start_invoicing_1 POST null). The lino_xl.lib.invoicing plugin now creates a single menu command “My invoicing plan” instead of creating one command per invoicing task.

Started documentation about Single-row tables.

2024-04-08

Lino now supports the new Estonian VAT rate. (Not already since Januar because there is no production site yet in Estonia). Changes are visible in eevat : Estonian VAT declarations. Side effect: lino.mixins.periods.DateRange.get_period_text() is now more generally available as lino.mixins.periods.rangetext() and used by lino_xl.lib.vat.

2024-04-07

New actions reset_password and verify_user. The “Verify” action on lino.modlib.users.User is now named verify_me. New database field lino.modlib.users.User.verification_password. Interesting to note how lino.modlib.users.User.verify_me inherits from lino.modlib.about.About.verify_user and how they do almost the same in different situations.

The react.UserSettings view no longer sets require_verification and code_expiry.

2024-04-05

Renamed model linod.BackgroundTask to linod.SystemTask. Requires database migration.

2024-04-02

Optimize background tasks: add possibility to have multiple task classes (django models); run separate task classes in separate coroutines.

2024-03-30

The ChangesByMaster and ChangesByObject tables are now available on every watched model as toolbar button (). For this to work, applications must call lino.modlib.changes.watch_changes() from setup_actions rather than from do_site_startup. Side effects: Renamed Plugin.on_site_startup to Plugin.pre_site_startup. The watch_all_changes() feature has been removed because it was not used. Moved lino.utils.watch to lino.modlib.changes.utils. Updated documentation pages: When Lino starts up, changes: Keep track of changes in the database, watch – Watching database changes and More about plugins.

2024-03-27

I renamed Site.get_installed_apps() to Site.get_installed_plugins() and Site.get_apps_modifiers() to Site.get_plugin_modifiers(). A technically simple change to improve readability for newcomers. But it will require local settings.py files to get updated. Lino raises an ChangedAPI exception if you forget to do it.

2024-03-26

New field User.nickname and users.with_nickname. The CreateAccount action is now presented in the admin_main.html, and its dialog no longer shows the third-party auth providers because we have them in the SignIn action.

2024-03-25

Renamed lino_xl.lib.sales to lino_xl.lib.trading because it can be used for any trade type, not only for sales. Requires database migration.

2024-03-24

Fixed #5520 (Recent comments shows comments to tickets that the user cannot see). In lino.modlib.comments.Commentable, get_comments_filter() has been changed to add_comments_filter. New database field lino_xl.lib.groups.Group.private. The ar argument to lino.core.actors.Actor.get_request_summary and lino.core.model.Model.get_request_summary can now be a BaseRequest.

Noi no longer adds a group owner to (database field Group.user has been removed). And the view parameter subscriber has been removed.

2024-03-17

Some subtle optimizations in Lino core: Default value for lino.core.actors.Actor.summary_sep changed from "<br/>" to ", ". New keyword argument max_width for TableRequest.show(). React renderer still used mjames icons for renderering actions even when a PrimeIcon icon exists. Clickable links sometimes had no style="text-decoration:none".

2024-03-14

New method lino.core.site.Site.get_config_value() for #5497 (SITE.site_config is sometimes None on asgi server).

2024-03-10

Resurrection of the commondata package. They had been sleeping for many years because the original idea assumed that people who know the data would site down and write Python code. A first example is commondata.countries. Because commondata was a namespace package and no longer is, you need to manually uninstall the old commondata packages by removing commondata*-nspkg.pth from your site-packages directory.

2024-03-08

A developer in Uruguay started an internship, so we added Uruguayan demo data in cosi4 : a Lino Così for Uruguay.

2024-02-26

Added the new plugin :mod:’lino_xl.lib.sources’ (#5214).

2024-02-14

Automatically run invoicing plans as background tasks (#5399). Replace InvoicingAreas by lino_xl.lib.invoicing.Task

2024-01-24

rename StorageState to ProvisionState

2024-01-23

New field lino_xl.lib.products.Product.pieces_per_unit

2024-01-14

Add the lino_xl.lib.nicknames plugin.

2024-01-11

Review socket file of log server ():ticket:5379).