lino.utils

lino.utils (the top-level module) contains a few often-used function for general use. It has also many subpackages and submodules.

addressable

Used by lino_xl.lib.appypod.mixins.PrintLabelsAction and lino_xl.lib.contacts.

ajax

This middleware is automatically being installed on every Lino site.

choosers

Extends the possibilities for defining choices for fields of a Django model.

code

Defines some utilities to inspect the running Python code.

config

This defines the ConfigDirCache which Lino instantiates and installs as SITE.confdirs.

dates

Defines classes related to date ranges.

demonames

A collection of tools for generating fictive people and addresses.

daemoncommand

Copyright (c) 2009, Sean Creeley All rights reserved.

dataserializer

YAML serializer.

dbfreader

What's the format of a Clipper .dbf file? http://www.the-oasis.net/clipper-12.html#ss12.4

dblogger

Just a shortcut and encapsulation.

diag

Some diagnostic utilities.

djangotest

Two TestCase classes for writing tests be run using Django's test runner (i.e.

dpy

Defines Lino's Python serializer and deserializer.

html2odf

This module contains mainly a utility function html2odf() which converts an ElementTree object generated using etgen.html to a fragment of ODF.

html2xhtml

Defines the html2xhtml() function which converts HTML to valid XHTML.

mytidylib

This is used only when libtidy is not available.

instantiator

Defines the Instantiator class and some other utilities used for generating database objects in python fixtures.

jinja

This defines the Counter class, a utility used in Jinja templates to generate self-incrementing counters for sections, subsections and any other sequences.

jscompressor

http://code.activestate.com/recipes/496882/ Author: Michael Palmer 13 Jul 2006 a regex-based JavaScript code compression kludge

jsgen

A framework for generating Javascript from Python.

latex

Based on http://www.djangosnippets.org/snippets/102/

log

No longer used since :blogref:`20160712`.

mdbtools

This is for writing fixtures that import data from an MS-Access database (.mdb) into Lino.

media

Defines the MediaFile class.

mldbc

Generic support for Multilingual database content.

mti

A collection of tools around multi-table inheritance.

odsreader

OdsReader uses odfpy to extract data from an .ods document (OpenOffice.org spreadsheet).

pdf

(This module's source code is available here.)

pythontest

An extended TestCase for the plain python tests of a Lino project.

pyuca

Preliminary implementation of the Unicode Collation Algorithm.

quantities

See Quantities.

ranges

The lino.utils.ranges module contains utility methods for working with "ranges".

requests

(This module's source code is available here.)

restify

Just a copy & paste of the docutils.examples module (as instructed there).

screenshots

(This module's source code is available here.)

sendchanges

Send an email to a configurable list of addresses when a configurable database item has been changed.

sqllog

A middleware for sending SQL statements to the Lino logger.

ssin

See ssin : Belgian national identification numbers.

test

Defines the DocTest and DemoTestCase classes.

textfields

This is taken from Helio Perroni Filho's answer at http://stackoverflow.com/questions/328356/extracting-text-from-html-file-using-python/3987802#3987802

ucsv

(This module's source code is available here.)

report

(This module's source code is available here.)

(This module's source code is available here.)

Functions

call_on_bases(cls, name, *args, **kw)

Doesn't work.

call_optional_super(cls, self, name, *args, **kw)

Doesn't work.

camelize(s)

>>> camelize("ABC DEF")

curry(func, *args, **kw)

d2iso(d)

Supports also dates before 1900.

get_class_attr(cl, name)

hex2str(value)

Convert the hexadecimal representation of a string to the original string.

join_words(*words)

Remove any empty item (None or ''), call unicode on each and join the remaining word using a single space.

moneyfmt(value[, places, curr, sep, dp, ...])

Convert Decimal to a money formatted string.

puts(s)

A simplistic replacement for the puts function of clint which has the problem of not supporting unicode strings.

str2hex(s)

Convert a string to its hexadecimal representation.

uncamel(s)

Thanks to nickl in Stackoverflow

unicode_string(x)

When we want unicode strings (e.g.

workdays(start, end)

Return the number of workdays (Monday to Friday) between the given two dates.

Classes

IncompleteDate(year, month, day)

Naive representation of a potentially incomplete gregorian date.

SimpleSingleton

SumCollector()

A dictionary of sums to be collected using an arbitrary key.

lino.utils.join_words(*words)

Remove any empty item (None or ''), call unicode on each and join the remaining word using a single space.

TODO: move this to etgen.html ?

>>> print(join_words('This','is','a','test'))
This is a test
>>> print(join_words('This','is','','another','test'))
This is another test
>>> print(join_words(None, None, None, 'Third', 'test'))
Third test
lino.utils.d2iso(d)

Supports also dates before 1900.

lino.utils.call_optional_super(cls, self, name, *args, **kw)

Doesn't work. See 20110914.

lino.utils.call_on_bases(cls, name, *args, **kw)

Doesn't work. See 20110914. This is necessary because we want to call setup_report on the model and all base classes of the model. We cannot use super() for this because the setup_report method is optional.

lino.utils.str2hex(s)

Convert a string to its hexadecimal representation.

See examples in hex2str().

lino.utils.hex2str(value)

Convert the hexadecimal representation of a string to the original string.

See also str2hex().

>>> str2hex('-L')
'2d4c'
>>> hex2str('2d4c')
'-L'
>>> hex2str('')
''
>>> str2hex('')
''
class lino.utils.IncompleteDate(year, month, day)

Bases: object

Naive representation of a potentially incomplete gregorian date.

For example you can say "Once upon a time in the year 2011":

>>> print(IncompleteDate(2011, 0, 0).strftime("%d.%m.%Y"))
00.00.2011

Unlike datetime.date objects an incomplete date can hold years before 1970.

>>> print(IncompleteDate(1532, 0, 0))
1532-00-00

On June 1st (but we don't say the year):

>>> print(IncompleteDate(0, 6, 1))
0000-06-01

On the first day of the month in 1990:

>>> print(IncompleteDate(1990, 0, 1))
1990-00-01

W.A. Mozart's birth date:

>>> print(IncompleteDate(1756, 1, 27))
1756-01-27

Christ's birth date:

>>> print(IncompleteDate(-7, 12, 25))
-7-12-25
>>> print(IncompleteDate(-7, 12, 25).strftime("%d.%m.%Y"))
25.12.-7

Note that you cannot convert all incomplete dates to real datetime.date objects:

>>> IncompleteDate(-7, 12, 25).as_date()
... 
Traceback (most recent call last):
...
ValueError: year...is out of range
>>> IncompleteDate(1756, 1, 27).as_date()
datetime.date(1756, 1, 27)

An IncompleteDate is allowed to be complete:

>>> d = IncompleteDate.parse('2011-11-19')
>>> print(d)
2011-11-19
>>> d.is_complete()
True
>>> print(repr(d.as_date()))
datetime.date(2011, 11, 19)
>>> d = IncompleteDate.parse('2008-03-24')
>>> d.get_age(i2d(20131224))
5
>>> d.get_age(i2d(20140323))
5
>>> d.get_age(i2d(20140324))
6
>>> d.get_age(i2d(20140325))
6
>>> d.get_age(i2d(20141025))
6

Note that IncompleteDate can store invalid dates:

>>> d = IncompleteDate(2009, 2, 30)
>>> d.get_age(i2d(20160202))
6
>>> IncompleteDate(2009, 2, 32)
IncompleteDate('2009-02-32')
>>> IncompleteDate(2009, 32, 123)
IncompleteDate('2009-32-123')
classmethod parse(s)

Parse the given string and return an IncompleteDate object.

>>> IncompleteDate.parse('2008-03-24')
IncompleteDate('2008-03-24')

Belgian eID cards gave us some special challenges:

>>> IncompleteDate.parse('01.JUN. 1968')
IncompleteDate('1968-06-01')
>>> IncompleteDate.parse('JUN. 1968')
IncompleteDate('1968-06-00')
get_age(today)

Return age in years as integer.

lino.utils.moneyfmt(value, places=2, curr='', sep=', ', dp='.', pos='', neg='-', trailneg='')

Convert Decimal to a money formatted string.

places: required number of places after the decimal point
curr: optional currency symbol before the sign (may be blank)
sep: optional grouping separator (comma, period, space, or blank)
dp: decimal point indicator (comma or period)
only specify as blank when places is zero
pos: optional sign for positive numbers: '+', space or blank
neg: optional sign for negative numbers: '-', '(', space or blank
trailneg: optional trailing minus indicator: '-', ')', space or blank
>>> d = Decimal('-1234567.8901')
>>> print(moneyfmt(d, curr='$'))
-$1,234,567.89
>>> print(moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-'))
1.234.568-
>>> print(moneyfmt(d, curr='$', neg='(', trailneg=')'))
($1,234,567.89)
>>> print(moneyfmt(Decimal(123456789), sep=' '))
123 456 789.00
>>> print(moneyfmt(Decimal('-0.02'), neg='<', trailneg='>'))
<0.02>
lino.utils.unicode_string(x)

When we want unicode strings (e.g. translated exception messages) to appear in an Exception, we must first encode them using a non-strict errorhandler. Because the message of an Exception may not be a unicode string.

lino.utils.workdays(start, end)

Return the number of workdays (Monday to Friday) between the given two dates. Is not aware of holidays.

Both dates start and end are included. For example if you specify a Monday as start and Monday of the following week as end, then you get 6 (not 5).

Examples: >>> examples = [ ... (20121130,20121201,1), ... (20121130,20121224,17), ... (20121130,20121130,1), ... (20121201,20121201,0), ... (20121201,20121202,0), ... (20121201,20121203,1), ... (20121130,20121207,6), ... ] >>> for start,end,expected in examples: ... a = i2d(start) ... b = i2d(end) ... if workdays(a,b) != expected: ... print("Got %d instead of %d for (%s,%s)" % (workdays(a,b),expected,a,b))

lino.utils.camelize(s)
>>> camelize("ABC DEF")
'Abc Def'
>>> camelize("ABC def")
'Abc def'
>>> camelize("eID")
'eID'
lino.utils.uncamel(s)

Thanks to nickl in Stackoverflow

>>> from lino.utils import uncamel
>>> uncamel('EventsByClient')
'events_by_client'
>>> uncamel('Events')
'events'
>>> uncamel('HTTPResponseCodeXYZ')
'http_response_code_xyz'
lino.utils.puts(s)

A simplistic replacement for the puts function of clint which has the problem of not supporting unicode strings.

This method is meant for issuing to the interactive console messages which do not need to be logged because they just give information about what's going on.

Currently this just prints the string to stdout using print. I prefer to use this over a plain print statement because I guess that there will be problems (mainly thinking about the fact that writing to stdout is considered an error in a wsgi application).

class lino.utils.SumCollector

Bases: object

A dictionary of sums to be collected using an arbitrary key.

Usage examples:

>>> sc = SumCollector()
>>> sc.collect("a", 12)
>>> sc.collect("a", None)
>>> sc.collect("a", 5)
>>> sc.a
17
>>> sc = SumCollector()
>>> sc.collect("a", 12)
>>> sc.collect("b", 23)
>>> sc.collect("a", 34)
>>> from future.utils import iteritems
>>> sorted(list(iteritems(sc)))
[('a', 46), ('b', 23)]

This is also included in the default context used by the Jinja renderer (lino.modlib.jinja) when rendering templates, which makes it a more complete solution for a problem asked also elsewhere, e.g. on Stackoverflow.

collect(k, value)

This returns an empty string