endi.utils package

Submodules

endi.utils.avatar module

endi.utils.colanderalchemy module

endi.utils.colanderalchemy.get_colanderalchemy_column_info(column: object, info: str) str

Return the colanderalchemy specified “info” data for the given model’s column

Paramètres:
  • column (obj) – An SqlAlchemy model’s column object

  • info (str) – The info we want from the column (« title », « section », …)

Renvoie:

The value of the info (string)

endi.utils.colanderalchemy.get_colanderalchemy_model_sections(model: object, exclude_columns: list = ['id']) list

Return all colanderalchemy’s sections of given model

Paramètres:
  • model (obj) – An SqlAlchemy model object

  • exclude_columns (list) – List of columns names we don’t want to get section from

Renvoie:

A list of sections (string)

endi.utils.colanderalchemy.get_model_columns_by_colanderalchemy_section(model: object, section_name: str, exclude_columns: list = ['id']) list

Return sqlalchemy columns of a model with specific section

Paramètres:
  • model (obj) – An SqlAlchemy model object

  • section_name (str) – The section we want the column

  • exclude_columns (list) – List of columns names we don’t want to return

Renvoie:

A list of column objects

endi.utils.colanderalchemy.get_model_columns_list(model: object, exclude: list = ['id']) list

Return the list of the columns of given model

Paramètres:
  • model (obj) – An SqlAlchemy model object

  • exclude (list) – List of columns names we don’t want to return

Renvoie:

A list of column objects

endi.utils.colanderalchemy.patched_objectify(self, dict_, context=None)

endi.utils.colors module

Color utilities

endi.utils.colors.get_color()

return a random color

endi.utils.colors.rgb_to_hex(rgb)

return an hexadecimal version of the rgb tuple for css rendering

endi.utils.controller module

class endi.utils.controller.BaseAddEditController(request, edit=False)

Bases : object

Base class for building an add edit controller

field_serializer_factory

alias de ModelSerializeManager

related_manager_factory

alias de RelatedAttrManager

to_json(instance) dict
class endi.utils.controller.ModelSerializeManager(request)

Bases : object

serialize(item, item_dict: dict, fields: List[str])
class endi.utils.controller.RelatedAttrManager(request)

Bases : object

endi.utils.datetimes module

class endi.utils.datetimes.DateTools

Bases : object

age(birth_date: date) int
format_date(date: Union[datetime, date, str, int], long_format: bool = False, force_no_time: bool = False) str

Returns formatted string date from various date entry

Paramètres:

date ([datetime.datetime, datetime.date, str, int]) – The date we want to format, can be :

  • datetime.datetime object

  • datetime.date object

  • timestamp as int

  • string formated as “YYYY-MM-DD”, “YYYYMMDD”, or “DD/MM/YYYY”

Paramètres:
  • long_format (bool) – “1 janvier 2023” if True, else “01/01/2023”

  • force_no_time (bool) – no time in returned string if True, even with datetime or timestamp

month_end(year: Optional[int] = None, month: Optional[int] = None) date
month_start(year: Optional[int] = None, month: Optional[int] = None) date
previous_month_end(year: Optional[int] = None, month: Optional[int] = None) date
previous_month_start(year: Optional[int] = None, month: Optional[int] = None) date
previous_year_end(year: Optional[int] = None) date
previous_year_start(year: Optional[int] = None) date
today()
year_end(year: Optional[int] = None) date
year_start(year: Optional[int] = None) date
endi.utils.datetimes.date_to_datetime(date: date) datetime

Generate a datetime (0h00) from a date

endi.utils.datetimes.format_date(date, short=True)

return a pretty print version of the date object

endi.utils.datetimes.format_datetime(datetime_object, timeonly=False)

format a datetime object

endi.utils.datetimes.format_duration(duration, short=True)

return a pretty print version of a duration.

Paramètres:
  • duration ((int,int)) – hours,minutes tuple to convert.

  • short (bool) – if True, hide minutes part when it equals zero.

endi.utils.datetimes.format_long_date(date: date, include_dayname: bool = True) str

Convert a date to a localized string

>>> import datetime
>>> d = datetime.date.today()
>>> format_long_date(d, include_name=True)
Jeudi 22 juin 2023
endi.utils.datetimes.format_long_datetime(datetime_object: date, include_dayname: bool = True) str

Convert a datetime to a localized string

>>> import datetime
>>> d = datetime.datetime.now()
>>> format_long_datetime(d, include_dayname=True)
Jeudi 22 juin 2023 à 10h22
endi.utils.datetimes.format_short_date(date)

return a short printable version of the date obj

endi.utils.datetimes.get_current_year()
endi.utils.datetimes.get_strftime_from_date(date_obj, template_str)

Return the result of date.strftime(template_str) handling exceptions

endi.utils.datetimes.parse_date(value, default=None, format_='%Y-%m-%d')

Get a date object from a string

Paramètres:
  • value (str) – The string to parse

  • default (str) – The default value to return

  • format (str) – The format of the str date

Renvoie:

a datetime.date object

endi.utils.datetimes.parse_datetime(str_datetime: str, default=None, format_: str = '%Y-%m-%d %H:%M:%S') datetime

Transform a date string to a date object

Paramètres:
  • str_date (str) – The date string

  • formats (tuple) – List of date format to try when parsing

Renvoie:

A datetime object

Type renvoyé:

datetime.date

endi.utils.datetimes.str_to_date(str_date, formats=('%d/%m/%Y', '%d-%m-%Y', '%d/%m/%y', '%Y-%m-%d', '%Y%m%d'))

Transform a date string to a date object

Paramètres:
  • str_date (str) – The date string

  • formats (tuple) – List of date format to try when parsing

Renvoie:

A datetime object

Type renvoyé:

datetime.datetime

endi.utils.datetimes.utcnow(delay=0)

Add Timezone info to the “now” datetime object Usefull for delaying celery calls

endi.utils.filedepot module

Configuration de filedepot

endi.utils.filedepot.configure_filedepot(settings)

Setup filedepot storage(s)

endi.utils.files module

Filesystem abstraction

class endi.utils.files.Base(path, parent, **args)

Bases : dict

Base resource object for directory representation

get_keyname()
get_path()
class endi.utils.files.Directory(path, parent=None, **args)

Bases : Base

Directory resource object

add_child(name, element)

Add a child element

build_children()

Populate the resource’s dict

isdir()
class endi.utils.files.File(path, parent, **args)

Bases : Base

File resource object

get_mod_date()

return a datetime object for the atime of the file

get_size()

Return a pretty printing value of the file

isdir()
endi.utils.files.decode_path(path)

decode a filepath

endi.utils.files.encode_path(path)

=format a filepath as a dict key

Paramètres:

path (str) – The path to encode

Renvoie:

The formatted path

Type renvoyé:

str

endi.utils.files.filesizeformat(value, precision=2)

Returns a humanized string for a given amount of bytes

endi.utils.files.get_timestamped_filename(root_name, extension)

Build a filename with timestamp info

Paramètres:
  • root_name (str) – The filename prefix

  • extension (str) – The extension of the destination file

Renvoie:

a filename with a timestamp

Type renvoyé:

str

endi.utils.files.issubdir(root_path, path)

Return True if path is a subdirectory of root_path

endi.utils.fileupload module

Fileupload temp store store the file and the main information used to handle it Usefull for preview_urls

class endi.utils.fileupload.FileTempStore(session, path, url, default_filename=None, filters=None)

Bases : dict

Temporary stores files at a given location implements deform.interfaces.FileUploadTempStore

default_filenameif provided, name used to store and access the

uploaded file

session : pyramid session path : the path to store (retrieve) the file from url : the base url used to access the file filters : list of callables that take a file object as parameter Example :

to upload a file to /tmp/logo/ and access it through /assets/logo FileTempStore(session, « /tmp/logo », « /assets/logo/ ») if you want to force the logo file to be called logo.png FileTempStore(session, « /tmp/logo », « /assets/logo/ », « logo.png ») if you want to pass the logo file through a resize function FileTempStore(session, « /tmp/logo », « /assets/logo/ », [resize])

filter_data(fbuf)

Pass file datas through filters

get(uid, default=None)

Tries to get a element given by name, or default when it doesn’t exists

get_filepath(filename)

Return the destination file path

preview_url(uid, filename=None)

Returns the url for the preview

session_key = 'deform_uploads'
write_file(fpath, fdata)

Writes file datas to a file

endi.utils.fileupload.pop_absolute_urls(filepath)

pop all directories informations included in a filename used to avoid problems with IE who’s sending absolute filepaths

endi.utils.formatters module

endi.utils.formatters.format_civilite(civilite_str)

Shorten the civilite string

Paramètres:

civilite_str (str) – Monsieur/Madame

Renvoie:

Mr/Mme

Type renvoyé:

str

endi.utils.html module

endi.utils.html.clean_html(text)

Return a sanitized version of an html code keeping essential html tags and allowing only a few attributes

endi.utils.html.clean_style_attribute(tagname: str, attribute: str, value: str) str

Remove unwanted css styles from the style attribute

endi.utils.html.remove_tag(text, tag)

Remove the tag from the beginning of the given text

Paramètres:
  • text (str) – The text with the tag

  • tag (str) – The tag to remove

Type renvoyé:

str

endi.utils.html.split_rich_text_in_blocks(html_text: str)

Split the html text around the first level occurences of tagname

>>> split_by_first_level_tag("<p>text <p>Texte</p></p><p>Texte2</p>texte en dehors"
['<p>text <p>Texte</p></p>', '<p>Texte2</p>', 'text en dehors]
endi.utils.html.strip_html(value)

Strip html void lines

endi.utils.html.strip_html_tags(text: str) str

Remove Html tags from text

endi.utils.html.strip_linebreaks(value)

Strip linebreaks

Paramètres:

value (str) – The value to clean

Type renvoyé:

str

endi.utils.html.strip_void_lines(value)

RStrip value ending with void html tags

Paramètres:

value (str) – The value to clean

Type renvoyé:

str

endi.utils.html.strip_whitespace(value)

Strip whitespace and tabs at the beginning/end of a string

Paramètres:

value (str) – The value to clean

Type renvoyé:

str

endi.utils.image module

utilities for image handling

class endi.utils.image.ImageRatio(width, height, color=(255, 255, 255))

Bases : object

Ensure images respect the given proportions by adding white spaces

r = ImageRatio(height_proportion, width_proportion, default_color) resized_image_buffer = r.complete(image_buffer)

resized_image_buffer will respect the given proportions and will be filed with the given color

height

The destination height used to compile the dest ratio

width

The destination width used to compile the dest ratio

color

The RGB tuple describing the filling color to use

complete(img_buf)

Complete the image to get at last my proportions, not more

get_white_layer(width, height)

Returns a white layer that will be our image background

class endi.utils.image.ImageResizer(width, height)

Bases : object

Ensure image fit inside the given box

if the image’s width or height are larger than the provided one, the image is resized accordingly

complete(img_buf)
endi.utils.image.build_header(text, size=(1000, 250))

Build a header image containing text

Paramètres:

text (str) – The text to write

Renvoie:

The header image

Type renvoyé:

BytesIO instance populated with the image datas in PNG Format

endi.utils.image.ensure_rgb(image)

Ensure the image is in RGB format

endi.utils.iteration module

endi.utils.iteration.groupby(elements: Iterable, attrname: str) Tuple[Any, Iterable]

Specialized version of itertools.groupby grouping on attribute

Note that for this to work, elements should be already ordered to allow grouping ; see itertools.groupby doc.

endi.utils.menu module

class endi.utils.menu.AppMenu(**kw)

Bases : BaseAppMenuContainer

build(request, context=None, **params)
class endi.utils.menu.AppMenuDropDown(**kw)

Bases : AppMenu

build(request, context=None, **params)
class endi.utils.menu.AppMenuItem(**kw)

Bases : BaseMenuElement

label icon route_name id_key (one of user_id/company_id) route_prefixes route prefix that will enable the item permission not_permission

build(request, context=None, **params)

Build a menuitem for the final rendering 1- bind 2- build

Type renvoyé:

dict

selected(request, href)
class endi.utils.menu.AttrMenuDropdown(*args, **kw)

Bases : MenuDropdown

enabled(context, request)
visible(context, request)
class endi.utils.menu.AttrMenuItem(*args, **kw)

Bases : MenuItem

A menu item that is condionnaly active regarding a model’s attribute

hidden_attribute

The context’s attribute used to check if the menu should be shown or not (not shown if the attribute is None)

disable_attribute

The context’s attribute used to check if the menu should be disabled (disabled if attribute is None)

perm_context_attribute

The current context’s attribute used as context for the permission check

E.g: if the context is a User and perm_context_attribute is « userdatas », we will chek the menu permission regarding the related UserDatas instance

enabled(context, request)
has_permission(context, request, **bind_params)
visible(context, request)
class endi.utils.menu.BaseAppMenuContainer(**kw)

Bases : BaseMenuElement

add(item, parent_node=None)

Add an item in the menu registry

find(name)
property items
pop(index)
remove(item)
class endi.utils.menu.BaseMenuElement(*args, **kw)

Bases : object

Base Class for menu items

Allows properties to be deferred (computed on each request)

Permissions :

attr permission:

The permission required to get this item displayed

or a callable that will be called to get the responses :attr not_permission: The permission the user should not have to get this item displayed

allowed(request, context=None)

Test if the end user should have access to this item

Paramètres:
  • request (obj) – The pyramid request object

  • context (obj) – The alternative context on which we check the

permission

bind(**kw)
class endi.utils.menu.HtmlAppMenuItem(**kw)

Bases : BaseMenuElement

A static html item that’s used to carry html generated code {“html”: the html code}

build(*args, **kwargs)
class endi.utils.menu.Menu(name, **kw)

Bases : BaseMenuElement

add(item)
add_after(name, new_item)

Add an item after the item named name

add_before(name, new_item)

Add an item before the item named name

remove(name)
set_current(current)
class endi.utils.menu.MenuDropdown(name, icon, label, title=None, default_route=None, perm=None)

Bases : object

Dropdown menu icon

An icon

label

A label (will be used as title on smaller viewports

title

The title shown on hovering the menu entry

default_route

If the menu is disabled, a link to that route will be provided instead

add_item(name, route_name, icon, label, title=None, perm=None, other_route_name=None)
enabled(context, request)
get_label(**params)
has_permission(context, request, **bind_params)
selected(context, request)
url(context, request)
class endi.utils.menu.MenuItem(name, route_name, icon, label, title=None, perm=None, other_route_name=None, anchor='', **kw)

Bases : BaseMenuElement

enabled(context, request)
get_label(**params)
get_title(**params)
has_permission(context, request, **bind_params)
selected(context, request)
url(context, request)
visible(context, request)
endi.utils.menu.add_admin_menu(config, **params)
endi.utils.menu.add_company_menu(config, **params)
endi.utils.menu.add_help_menu(config, **params)
endi.utils.menu.add_menu_item_directive(config)

config.add_menu(item, “admin”, “accompagnement”

endi.utils.menu.add_user_menu(config, **params)
endi.utils.menu.build_admin_menu_registry()

Build the manager menu structure that will be filled by the different modules

endi.utils.menu.build_company_menu_registry()

Build the menu structure for the Company menu. This Structure will be filled in the different modules

Renvoie:

A AppMenu instance

endi.utils.menu.build_user_menu_registry()

Build a AppMenu that will be attached to the global registry Can then be used to add menu entries, module after module

endi.utils.menu.includeme(config)

endi.utils.modules module

enDI modules management

endi.utils.modules.add_module(config, name)

Load an endi module (with include) and add it to the « modules » registry

endi.utils.modules.add_plugin(config, name)

Load an endi module (with include) and add it to the « modules » registry

endi.utils.modules.has_module(request, module_name)

Check if a module has been enabled

Paramètres:
  • request (obj) – The current pyramid request

  • module_name (str) – The name of the module to check

Renvoie:

True if the module exists

Type renvoyé:

bool

endi.utils.modules.has_plugin(request, plugin_name)

Check if a plugin has been enabled

This tool should be used as less as possible to keep code-separated logic

Paramètres:
  • request (obj) – The current pyramid request

  • plugin_name (str) – The name of the plugin to check

Renvoie:

True if the plugin exists

Type renvoyé:

bool

endi.utils.modules.includeme(config)
endi.utils.modules.route_exists(request, route_name)

Check if a route exists in the current registry

Paramètres:
  • request (obj) – The current pyramid request

  • route_name (str) – The name of the route to check

Renvoie:

True if the route exists

Type renvoyé:

bool

endi.utils.navigation module

class endi.utils.navigation.NavigationHandler(request, keyword)

Bases : object

Class used to manage the navigation history of a user

request

Current pyramid request

keyword

The history keyword e.g: project

Usage 1 : remember the current page

>>> nav_handler = NavigationHandler(request, "project")
>>> nav_handler.remember()

Usage 2 : retrieve the last visited page

>>> nav_handler = NavigationHandler(request, "project")
>>> nav_handler.last()
last()
remember()

endi.utils.pdf module

Tools for rendering and handling pdf files

write_pdf(request, filename, html) buffer_pdf(html)

In case of using headers and/or footers, more manipulation is necessary

Use overlays and the HTMLWithHeadersAndFooters tool

see task pdf rendering tools

class endi.utils.pdf.HTMLWithHeadersAndFooters(request, main_html, header_overlay=None, footer_overlay=None, extra_vertical_margin=0, **kwargs)

Bases : HTML

Generate a PDF out of a rendered template, with the possibility to integrate nicely a header and a footer if provided.

Notes:

render(stylesheets=None, enable_hinting=False, presentational_hints=False, font_config=None, **kw)

Render all content with the header and footer

Renvoie:

A weasyprint Document instance

class endi.utils.pdf.Overlay(template_path=None, panel_name=None, context_dict=None, type_='footer')

Bases : object

Stores datas used to manipulate an overlay (footer, header …)

An overlay can be template based or panel based (panels allows to provide more computation on python side, with better testing ability)

Paramètres:
  • template_path (str) – The path to the template to render

  • panel_name (str) – The name of the pyramid_layout panel to use

  • context_dict (dict) – The context dict to pass to the template/panel

  • type (str) – type of overlay footer/header/main the type is used for

margin computation

render(request, extra_context_dict)
class endi.utils.pdf.OverlayRenderer(request, overlay, weasyprint_args)

Bases : object

OVERLAY_LAYOUT = '@page {size: A4 portrait; margin: 0;}'
get_body(extra_context_dict, render_args)

Compile the body “Box” of the given overlay

Type renvoyé:

Box instance

get_height(render_args)

Compute the overlay’s height

endi.utils.pdf.fetch_resource(uri, rel=None)

Callback used by pisa to locally retrieve ressources giving the uri if the uri starts with /files : we’re looking for a db file else we’re looking for a static resource

endi.utils.pdf.get_db_file_resource(fileobj)

Return a resource string usable by the pdf renderer for dynamically db loaded resources

Paramètres:

fileobj (obj) – a file object with a mimetype attr and a get_value

method

Renvoie:

a resource string (default : with a void png)

endi.utils.pdf.get_element(boxes, element)

Given a set of boxes representing the elements of a PDF page in a DOM-like way, find the box which is named element.

Look at the notes of the class for more details on Weasyprint insides.

endi.utils.pdf.html_to_pdf_buffer(html)

Convert the given html string to a pdf buffer

Paramètres:

html (str) – The html string

Type renvoyé:

instance of io.BytesIO

endi.utils.pdf.render_html(request, template, datas)

Compile the current template with the given datas

endi.utils.pdf.weasyprint_pdf_css()

Return the weasyprint CSS resource object for pdf.css

endi.utils.pdf.write_html_as_pdf_response(request, filename, html)

Convert the given html string to pdf and attach it as a file response object to the request

Paramètres:
  • request (obj) – The Pyramid Request

  • filename (str) – The pdf filename

  • html (str) – An html string

endi.utils.predicates module

class endi.utils.predicates.SettingHasValuePredicate(val, config)

Bases : object

Custom view predicate allowing to declare views only if a setting is set

phash()
text()

endi.utils.renderer module

MultiRenderer tools to allow multiple renderers to be used with deform

class endi.utils.renderer.CustomRenderer(search_path, auto_reload=True, debug=False, encoding='utf-8', translator=None)

Bases : ZPTRendererFactory

Custom renderer needed to ensure our buttons (see utils/widgets.py) can be added in the form actions list It adds the current request object to the rendering context

endi.utils.renderer.configure_export()

Customize sqla_inspect tools

endi.utils.renderer.customize_renderers(config)

Customize the different renderers

endi.utils.renderer.get_json_dict_repr(obj, request)

Call the json renderer on the object and convert it back to a dict to simulate the rest_api workflow

endi.utils.renderer.get_search_path()

Add enDI’s deform custom templates to the loader

endi.utils.renderer.render_template(template: str, data: dict, request) str

Render a template including the api tools in the template context

endi.utils.renderer.set_close_popup_response(request, message=None, error=None, refresh=True, force_reload=False)

Write directly js code inside the request reponse’s body to call popup close

Paramètres:
  • request (obj) – The Pyramid request object

  • message (str) – The information message we want to return

  • error (str) – The optionnal error messahe to send

  • refresh (bool) – Should a refresh link be included

  • force_reload (bool) – Shoud we reload the parent window automatically ?

endi.utils.renderer.set_custom_form_renderer(config)

Uses an extended renderer that ensures the request object is on our form rendering context Code largely inspired from pyramid_deform/__init__.py

endi.utils.renderer.set_export_blacklist()

Globally set an export blacklist

endi.utils.renderer.set_export_formatters()

Globally set export formatters in the sqla_inspect registry

endi.utils.renderer.set_json_renderer(config)

Customize json renderer to allow datetime rendering

endi.utils.renderer.set_xls_formats()

Globally set the xls formats by datatype

endi.utils.rest module

Rest related utilities

class endi.utils.rest.Apiv1Error(request, datas=None, messages=None)

Bases : Apiv1Resp

Error response

class endi.utils.rest.Apiv1Resp(request, datas={}, status='success')

Bases : dict

v1 api Response object

Returns a dict that should be sent as a json object

request

The pyramid request object

datas

The datas to be sent in the data key of the result

status

The status of the response (one of [“success”, “error”])

The response contains :

id

The id of the request if one is provided by passing the js client Check for the “_” key as jquery handles it ex:

$.ajax({…, cache:false, …});

api

The version of the api

status

the status of the request

datas

The datas sent through the request In case of errors, the datas are of the form:

datas: {“messages”: [list of messages]}

class endi.utils.rest.ApivJsonRpc2Resp(request)

Bases : dict

A response corresponding to the jsonrpc v2 protocol

base_dict(request)
class endi.utils.rest.LoadOptions(filters: Union[dict, NoneType] = None, fields: Union[list, NoneType] = None, related: Union[list, NoneType] = None, page_options: Union[endi.utils.rest.PaginationOptions, NoneType] = None)

Bases : object

fields: Optional[list] = None
filters: Optional[dict] = None
classmethod from_request(request)
page_options: Optional[PaginationOptions] = None
related: Optional[list] = None
class endi.utils.rest.PaginationOptions(page: Union[int, NoneType] = None, per_page: Union[int, NoneType] = None)

Bases : object

classmethod from_request(request)
page: Optional[int] = None
per_page: Optional[int] = None
exception endi.utils.rest.RestError(errors, code=400)

Bases : HTTPError

Rest error, allows to raise errors from rest apis like we would do with common http exceptions

class endi.utils.rest.RestJsonRepr(model, bind_params=None)

Bases : object

BaseJson model wrapper Allows to enhance the __json__ method of an sqlalchemy model by formatting its output with a colander schema for UI representation purpose. Takes the json dict and update it with the output of the serialize method of the given schema

Attr schema:

colander schema used to preformat datas for ui rendering

Paramètres:
  • model – the model instance we have to format

  • bind_params – parameters used to bind the schema.

By default the json renderer passes the request when calling the __json__ method of our object, so we use request as default bind_param

appstruct(request)

Return the appstruct associated to the current schema Should be overriden if the model has some relationships

get_schema(request)

Return the binded schema

postformat(appstruct)

allows to postformat the data we want to provide as json

preformat(appstruct, request)

Pass the values through the form schema to preformat some datas for ui representation (e.g: amounts are represented as floats while they are integers in the db)

schema = None
endi.utils.rest.add_rest_service(config, factory, route_name=None, edit_rights='edit', add_rights='view', view_rights='view', delete_rights='edit', collection_route_name=None, collection_view_rights=None, context=None, collection_context=None, **add_view_kwargs)

Add a rest service

Paramètres:
  • route_name (str) – The single item route name

  • factory (cls) – Class View grouping the methods for Rest views

  • edit_rights (str) – The permission needed to execute the edit actions

  • add_rights (str) – The permission needed to execute the add actions

  • view_rights (str) – The permission needed to get datas

  • delete_rights (str) – The permission needed to execute the delete

actions :param str collection_route_name: Specific route name for collection related views (default is route_name +”s”) :param str collection_view_rights: Specific rights for collection view :param context: context param passed to the item add_view :param collection_context: context param passed to the collection add_view :param **add_view_kwargs: passed as-is to all config.add_view() calls

Add a rest iface associating the factory’s methods to the different request methods of the routes based on route_name :

route_name : route name of a single item (items/{id}) route_name + « s » : route name of the items model (items)

del - > route_name, DELETE put - > route_name, PUT get - > route_name, GET post - > route_name+ »s », POST

endi.utils.rest.allowed_methods(*allowed)

Custom predict checking if the HTTP method in the allowed set. It also changes the request.method according to « _method » form parameter and « X-HTTP-Method-Override » header

endi.utils.rest.make_redirect_view(route_name, with_id=True)

Returns a redirect function that redirects to route_name :@param with_id: the route expects and id

endi.utils.security module

endi.utils.session module

Custom beaker session handling allowing to use a remember me cookie that allows long time connections

Entrypoint to delete a session from a cookie value. Handles both beaker and redis session factories.

endi.utils.session.get_session_factory(settings)

Entry point to get the session factory. Handles both beaker and redis session factories

endi.utils.session.get_session_id(request)

Entrypoint to get the session id. Handles both beaker and redis session factories

endi.utils.sqlalchemy_fix module

Module providing a custom tween that cleans the scoped_session on each request

The problem :

pyramid_tm commits/rollback/closes the current sqlalchemy session

But inside a same thread, scoped_session returns the same session object which keeps some state related informations

See :

endi.utils.sqlalchemy_fix.includeme(config)
endi.utils.sqlalchemy_fix.tm_cleanup_tween_factory(handler, registry)

endi.utils.status_rendering module

Document statuses presentation

Centralize in a place (here) css classes (which handle colors) and icons to use for document statuses.

endi.utils.strings module

Common translation strings

endi.utils.strings.add_trailing_zeros(amount)

Ensure an amount has sufficient trailing zeros

endi.utils.strings.cancelinvoice_get_major_status(cinvoice)

Return the most significant status for the given task

endi.utils.strings.compile_template_str(template_string, template_context)

Compile the template string and merge the context

Paramètres:
  • template_string (str) – The string to templatize

  • template (dict) – templating context

Type renvoyé:

str

endi.utils.strings.estimation_get_major_status(estimation)

Return the most significant status for the given task

endi.utils.strings.expense_get_major_status(expense)
endi.utils.strings.format_account(account, reverse=True, upper=True)

return {firstname} {lastname}

endi.utils.strings.format_activity_status(activity)

Return a formatted status string for the given activity

endi.utils.strings.format_amount(amount, trim=True, grouping=True, precision=2, display_precision=None, html=True, currency=False)

return a pretty printable amount

Paramètres:
  • amount (int) – The amount to display

  • trim (bool) – Should the amount be trimmed

  • grouping (bool) – Should the amount be grouped (grouping form depends

on locales) :param int precision: The decimal precision to convert the amount to (Decimal amounts are stored as BigInteger in the database to avoid float precision conflicts and facilitate computation, here precision indicates with which 10**precision the conversion is made) :param int display_precision: The precision used to display the amount (trimming strategy)

endi.utils.strings.format_cancelinvoice_status(cinvoice, full=True)

Return a string representing the state of this cancelinvoice

Paramètres:

cinvoice (obj) – A CancelInvoice instance

endi.utils.strings.format_civilite(civilite_str)

Shorten the civilite string

Paramètres:

civilite_str (str) – Monsieur/Madame

Renvoie:

Mr/Mme

Type renvoyé:

str

endi.utils.strings.format_estimation_status(estimation, full=True)

Return a formatted string for estimation specific status

endi.utils.strings.format_expense_status(expense, full=True)
endi.utils.strings.format_expense_status_sentence(expense)
endi.utils.strings.format_float(value, precision=None, grouping=True, html=True, wrap_decimals=False)
Format a float value :
  • Localized version with grouped values

  • trim datas to precision if asked for

Paramètres:
  • value (float) – The value to format

  • precision (int) – If set, the value will be trimmed to that precision

  • grouping (bool) – Should the datas be grouped (by thousands)

  • html (bool) – Should the resulting string be html-friendly (using

&nbsp;) :returns: A formatted string that can be used in html outputs :rtype: str

endi.utils.strings.format_indicator_main_status(indicator) str

Returns the main status of the given status

endi.utils.strings.format_indicator_status(status: str) str

Return a formatted status string for the given indicator

endi.utils.strings.format_invoice_status(invoice, full=True)

Return a formatted string for invoice specific status

Paramètres:

invoice (obj) – An invoice instance

endi.utils.strings.format_lower_ascii(original_str)

Generate a lower ascii only string from the original one :param str original_str: The string to modify :returns: A modified string :rtype: str

endi.utils.strings.format_main_status(obj, full=True)

return a formatted status string

endi.utils.strings.format_name(firstname, lastname, reverse=True, upper=True)

format firstname and lastname in a common format

endi.utils.strings.format_paymentmode(paymentmode)

format payment modes for display Since #662 ( Permettre la configuration des modes de paiement ) no formatting is necessary

endi.utils.strings.format_quantity(quantity)

format the quantity

endi.utils.strings.format_status(element, full=True)
endi.utils.strings.format_status_sentence(element)

Same as format status but with a full sentence.

E.g.: « Cette note de dépenses a été validée. »

endi.utils.strings.format_status_string(status: StatusLogEntry, genre='')

Return a label for the given status

Paramètres:
  • code (str) – StatusLogEntry

  • genre (str) – “” or “e”

endi.utils.strings.format_supplier_invoice_status(supplier_invoice, full=True)
endi.utils.strings.format_supplier_order_status(supplier_order, full=True)
endi.utils.strings.format_task_type(task)
endi.utils.strings.format_valid_status_message(request, element)
endi.utils.strings.human_readable_filesize(size)

Return a human readable file size

endi.utils.strings.invoice_get_major_status(invoice)

Return the most significant status for the given task

endi.utils.strings.is_hours(unit) bool

Test if the given unit is in hours

endi.utils.strings.major_status(element)
endi.utils.strings.month_name(index, capitalize=False)

Return the name of the month number « index »

endi.utils.strings.pluralize(collection, plural_mark='s', singular_mark='')

Helps handling the singular/plural forms of a word

>>> 'Simpson' + pluralize(['bart'])
'Simpson'
>>> 'Simpson' + pluralize(['homer', 'bart'])
'Simpsons'
>>> pluralize(['Jolly Jumper'], 'chevaux', 'cheval')
'cheval'
>>> 'chou' + 'pluralize(['rave'], 'x')
'chou'
Paramètres:

collection – list-like object

endi.utils.strings.remove_kms_training_zeros(amount)

Removed unnecessary kms amount training zeros :param amount: :return: amount

endi.utils.strings.remove_newlines(s: str) str

Remove new line character

Replace them by space, in case they were used as a separator

endi.utils.strings.safe_ascii_str(value)

Replace special chars to their ascii counterpart.

This does modify the string (remove accents…) and is only intended for non-human-facing strings.

Paramètres:

value (str) – The value to convert

Type renvoyé:

str

endi.utils.strings.short_month_name(index)

Return the short name of the month number « index »

endi.utils.strings.supplier_invoice_get_major_status(invoice)
endi.utils.strings.supplier_order_get_major_status(order)

endi.utils.widgets module

Widget library

class endi.utils.widgets.ActionMenu(template=None, css=None, icon=None)

Bases : Menu

Represent the ActionMenu

template = 'base/actionmenu.mako'
class endi.utils.widgets.ButtonDropDownMenu(template=None, css=None, icon=None)

Bases : Menu

A standalone dropdown menu from a button

template = 'base/buttondropdownmenu.mako'

Bases : ButtonLink

selected(request)

return True if it’s selected

template = 'base/button.mako'
url(request)

Returns the button’s url

Bases : Widget

onclick()

return the onclick attribute

selected(request)

Return True if the button is active

template = 'base/button.mako'
url(request)

Returns the button’s url

class endi.utils.widgets.Column(label, sort_key=None)

Bases : object

Wraps a column definition

Bases : object

A <a> link, leading to GET request

Mandatory :

url label

title: title de l’ancre js: Code js à lancer onclick icon: nom de l’icône css: class Css disabled: Le bouton est-il actif ? confirm: Libellé à afficher avant de valider le onclick popup: Le lien doit-il être ouvert dans une nouvelle fenêtre

panel_name = 'link'
class endi.utils.widgets.Menu(template=None, css=None, icon=None)

Bases : Widget

add(item)

Add an item to the menu

insert(item, index=0)

Insert an item in the menu

template = None
void()

Return True if the menu is void

class endi.utils.widgets.Navigation

Bases : object

class endi.utils.widgets.POSTButton(*args, **kwargs)

Bases : Link

A <form><button>, leading to POST request

Includes handling of CSRF.

panel_name = 'post_button'
class endi.utils.widgets.PermWidget

Bases : object

widget with permission

perm = None
permitted(context, request)

Return True if the user has the right to access the destination

set_special_perm_func(func)

Allows to insert a specific permission function

class endi.utils.widgets.PopUp(name, title, html)

Bases : object

A popup

open_btn(label=None, factory=<class 'endi.utils.widgets.ButtonJsLink'>, **kw)
class endi.utils.widgets.StaticWidget(html, perm=None)

Bases : PermWidget

Static Html widget with permission management @html : an html string (maybe you can use Webhelpers to build it) @perm: the permission needed to display this element

render(request)

Return the html output

class endi.utils.widgets.Submit(label, value, title=None, request=None, confirm=None, name='submit')

Bases : Widget

Submit Link used to be included in a form It’s componed by : @label : the label of the button @perm : permission needed to display this button @value: value of the button @name : name of the button (the couple name=value is submitted) @title: title used onmouseover @css: css class string @_type: type of the button

css = 'btn btn-primary'
disabled = False
icon = None
js = None
template = 'base/submit.mako'
type_ = 'submit'

Bases : Widget, PermWidget

template = 'base/togglelink.mako'

Bases : Widget, PermWidget

onclick()

return the onclick attribute

selected(request)

Return True if the button is active

template = 'base/button.mako'
url(request)

Returns the button’s url

class endi.utils.widgets.Widget

Bases : object

Base widget

name = None
render(request)

return an html output of the widget

request = None
set_template(template)

Change the template of the menu

template = None
endi.utils.widgets.cmp_urls(url1, url2)

Compare two urls

Paramètres:
  • url1 (str) –

  • url2 (str) –

Result:

True or False

Type renvoyé:

bool

endi.utils.widgets.mako_renderer(tmpl, **kw)

A mako renderer to be used inside deform special widgets

Module contents