support.report – Reporting Manager¶
This module defines functions and classes which implement a flexible reporting manager for applications and libraries.
Public Classes¶
This module is built around two main parts: the first one is the reporting manager; the second one is a collection of handlers which manages the way by which the report is going to be published.
The reporting manager has only on public class.
To date, the module includes a number of handlers listed below in
alphabetical order. A handler is a derived class from the BaseHandler
class.
Using the module¶
The first step is to create a report and at least a handler, then you fill the report with some sections and then publish it. The creating step may done either in programmatic way or using a configuration file.
Using the module with its API¶
Creating a report needs at least the following steps.
Create a
Reportclass instance.Set the template report with the
Report.set_templatemethod.Create at least a handler class instance (see
FileHandlerfor a file handler).Set the handler options (see
FileHandler.set_filenamefor the file handler).Add the created handler to the report with the
Report.add_handlermethod.
A report mainly consist in four parts: a header, a table of contents, a list
of sections and a tail. The header and the tail may have some optional
variables which has set with the Report.set_attributes method. The
table of contents is automatically generated from the list of sections.
Theses are added to the report with the Report.add_section method.
Then, the report is ready to be published by calling the Report.publish which
is going to use the registered handlers.
- Examples
content_attributes = { "name": "Dummy Product", "editor": "Dummy Company, SA", "description": "Dummy product is a amazing tool to do nothing", "version": "0.1.0+dummy", "url": "http://dummy.exemple.com/installer.exe", "installer": "./store/installer_0.1.0+dummy.exe", "release_note": "http://dummy.exemple.com/release_note.html", "published": "2016-02-18", "file_size": 12345689 } a_report = report.Report() a_report.set_template() a_report.set_attributes(report_attributes) a_handler = report.FileHandler() a_handler.set_filename("report.html") a_report.add_handler(a_handler) a_report.add_section(content_attributes) a_report.publish()
Using the module with a configuration file¶
The creation step may be described in a configuration file (see
Example of configuration file for an example) which is going to load by the
Report.load_config method.
a_report = report.Report()
filename = os.path.join(os.path.dirname(__file__), "report.example.ini")
a_report.load_config(_load_config(filename), False)
a_report.set_attributes(report_attributes)
a_report.add_section(content_attributes)
a_report.publish()
Objects reference¶
This section details the objects defined in this module.
- class support.report.Report¶
Bases:
objectMake and publish report with the registered handlers.
The report is based on a template using named keyword argument and composed of named sections. The module use the HTML Default template by default. The use of the named keyword argument is based on the
Format String Syntaxof thestringmodule.Each section starts with a HTML comment and it ends with the start of next section or with the end of the file. The comment must have the following format and must be on one line:
<!-- $lau:<name>$ -->
where
nameMUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-] and MUST NOT be empty.If a named section is not declared in
Report.names, its contents is added to the current section (i.e. no section is created).- Configuration
Example of configuration file details the configuration options the
Report.- Public Methods
This class has a number of public methods listed below in alphabetical order.
- Using Report…
The section “Using the module” provides a simple use case of the class.
- _clear_template()¶
Clear the template.
- _load_default()¶
Configure the report module with its default value.
- _parse_template(template)¶
Parse the template to extract the report sections.
- Parameters
template (str) – The full path name of the template file.
- add_handler(handler)¶
Add a handler to publish the report.
- Parameters
handler (BaseHandler) – The handler to add, It’s a class instance derived from the
BaseHandlerbase class.
- add_section(attributes)¶
Add a section to the report.
- Parameters
attributes (dict) – The product attributes (typically the one returned by the
cots.core.BaseProduct.dumpmethod).
- load_config(config, append=True)¶
Configure the report module from a dictionary.
- Parameters
config (dict) – The configuration as described in the
report.example.ini.append (bool) – (optional)
Falseto indicate if the configuration specified by the config parameter will overwrite the current configuration.Trueto indicate if the configuration specified by the config parameter will append to the current configuration.
- publish()¶
Publish the report with the registered handler
- set_attributes(attributes=None)¶
Set the attributes of the report.
Theses attributes are used in the header and tail sections of the report (see
Title,BodyStart,BodyEnd,Tailsections in the template)- Parameters
attributes (dict) – The attributes.
- set_template(template='/home/docs/checkouts/readthedocs.org/user_builds/lapptrack/checkouts/develop/lapptrack/support/report_template.html', separator='')¶
Set the report template.
- Parameters
template (str) – (optional) is the full path name of the template file. The format of the template file is described in the Report class introduction. The HTML Default template is used by default.
separator (str) – (optional) The separator added at the end of each added section in the report.
- class support.report.BaseHandler¶
Bases:
objectBase class for all publishing handlers.
- Public Methods
This class has a number of public methods listed below in alphabetical order.
- Methods to Override
This class is a abstract class, so all the methods must be overridden. They are listed below in alphabetical order.
- Using BaseHandler…
This class is the abstract class for publishing handler used by
Reportand this one only use the public methods.
- _load_default()¶
Configure the handler with its default value.
- load_config(config)¶
Configure the handler from a dictionary.
- Parameters
config (dict) – The configuration as described in the
report.example.ini.
- publish(report, subtype, charset=None)¶
Publish the report
- class support.report.MailHandler¶
Bases:
support.report.BaseHandlerMail publishing handler.
This concrete class implements the publishing mechanism by sending the report by mail. So most of information are in the
BaseHandlerclass documentation. The information below focuses on the added value of this class.- Public Methods
This class has a number of public methods listed below in alphabetical order.
- Overridden Methods
This class is a concrete class, so the overridden methods are listed below in alphabetical order.
- Using MailHandler…
The “Using the module” section provides a simple use case of a publishing handler concrete class (a file handler in the example). The handler classes differ by the options to set.
For this handler, only the mail host and the mail recipient must be set with the
set_hostandset_to_addressesmethods as shown in the following example. All other options have default values.- Examples
a_handler = report.MailHandler() a_handler.set_host("smtp.example.com") a_handler.set_to_addresses("sysadmin@example.com")
The above steps, except the first one, may be described in a dictionary which is going to load by the
MailHandler.load_configmethod. TheReport.load_configmethod use this one to set options for each declared handler (see “Configuration file” section).
- _load_default()¶
Configure the handler with its default value.
For the mail handler, there is no default value
- _subject2filename()¶
Convert a mail subject in a file name.
The method replace special characters in string using the %xx escape using the
urllib.parse.quotefunction.The method use only the first 20 characters of the subject to avoid long file name. The file name has a suffix based on current date time to guarantee to have a unique value.
- Returns
unique string for the filename.
- Return type
- load_config(config)¶
Configure the handler from a dictionary.
- Parameters
config (dict) – The configuration as described in the
report.example.ini.
- publish(report, subtype, charset=None)¶
Publish the report
- set_credentials(credentials)¶
Set the recipients mail addresses.
- Parameters
credentials (list) – The username and the password to connect to the SMTP server.
- set_from_address(address='')¶
Set the sender mail address.
- Parameters
address (str) – (optional) The mail addresses of the sender. If not specified, the address is set to the local hostname. (see
smtplib.SMTP)
- set_host(hostname, port_number=25)¶
Set the SMTP host.
- set_pending_mail_folder(path='')¶
Set the pending mail special folder.
- Parameters
path (str) – (optional) The full path name of the folder where a copy of the mail will be written until it is sent. It avoid to lost mail if the mail server configuration is erroneous or if the mail server doesn’t answer. An empty string does nothing.
- set_sent_mail_folder(path)¶
Set the mail sent special folder.
- Parameters
path (str) – The full path name of the folder where a copy of the mail will be written. If the folder doesn’t exit, it will be create. An empty string does nothing.
- class support.report.FileHandler¶
Bases:
support.report.BaseHandlerFile publishing handler.
This concrete class implements the publishing mechanism by writing the report in a regular file. So most of information are in the
BaseHandlerclass documentation. The information below focuses on the added value of this class.- Public Methods
This class has a number of public methods listed below in alphabetical order.
- Overridden Methods
This class is a concrete class, so the overridden methods are listed below in alphabetical order.
- Using MailHandler…
The “Using the module” section provides a simple use case of a publishing handler concrete class (precisely a file handler in the example). The handler classes differ by the options to set.
For this handler, only filename must be set with the
set_filenameas shown in the following example. All other options have default values.With the default settings, the file is open in overwriting mode (i.e (“w”
openmode). Theset_modesets the opening mode of the file (practically the “w” or “a” mode, the others mode aren’t useful in this context).- Examples
a_handler = report.FileHandler() a_handler.set_filename("report.html")
The above steps, except the first one, may be described in a dictionary which is going to load by the
FileHandler.load_configmethod. TheReport.load_configmethod use this one to set options for each declared handler (see “Configuration file” section).
- _load_default()¶
Configure the handler with its default value.
For the file handler, there is no default value
- load_config(config)¶
Configure the handler from a dictionary.
- Parameters
config (dict) – The configuration as described in report.ini.
- publish(report, subtype, charset=None)¶
Publish the report
- class support.report.StreamHandler¶
Bases:
support.report.BaseHandlerStream publishing handler.
This concrete class implements the publishing mechanism by writing the report in a stream. So most of information are in the
BaseHandlerclass documentation. The information below focuses on the added value of this class.- Public Methods
This class has a number of public methods listed below in alphabetical order.
- Overridden Methods
This class is a concrete class, so the overridden methods are listed below in alphabetical order.
- Using MailHandler…
The “Using the module” section provides a simple use case of a publishing handler concrete class (a file handler in the example). The handler classes differ by the options to set.
For this handler, there is no mandatory option to set, the only option is the stream, and its default value is the standard output (see
sys.stdout).- Examples
a_handler = report.StreamHandler()
The above steps, except the first one, may be described in a dictionary which is going to load by the
StreamHandler.load_configmethod. TheReport.load_configmethod use this one to set options for each declared handler (see “Configuration file” section).
- _load_default()¶
Configure the handler with its default value.
For the file handler, there is no default value
- load_config(config)¶
Configure the handler from a dictionary.
- Parameters
config (dict) – The configuration as described in the
report.example.ini.
- publish(report, subtype, charset=None)¶
Publish the report
- set_stream(stream=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>)¶
Set the stream in which the report will be written.
- Parameters
stream (io.TextIOWrapper) – The standard stream on which report will be written. If it is not present,
sys.stdoutis going to be used.
Configuration file¶
# -----------------------------------------------------------------------------
# This ini file contains the configuration details of the report module.
# Only one report and its ways of publication have to define in this file. If
# you need of several report, you must define several configurations file and
# call `Report.load_config()` method for each of them.
# -----------------------------------------------------------------------------
#
# Core section contains configuration items for the report processor.
# handlers (mandatory): is the list of handlers to publish the report. Each
# handler has to have a corresponding section for its own configuration.
# template (optional): is the full path name of the template file. The Report
# class introduction described the format of the template file. The default
# value is 'summary_tmpl.html'.
[core]
handlers = mailhandler,filehandler
;template = summary_tmpl.html
# Attributes section contains named keyword used in the template report (see
# `template` item in the above section. Theses attributes are used in the header
# and tail sections of the report (see `Title`, `BodyStart`, `BodyEnd`, `Tail`
# sections in the template). The 'summary_tmpl.html' doesn't use any additional
# attribute, so this section is empty if you use the default template.
;[attributes]
;about = "Short text to summarize the report content"
# Handlers section contains configuration details for handlers declared in the
# `core`section (see `handlers`item).
# The following sections give an example for each handler supported by the
# `report` module (send a mail, write in a file, write in a stream). Each
# handler section has to define a `class` item.
# Warning: name section must be lowercase, since the section name is a key in
# core section.
#
# Mail handler.
# class: indicates the handler’s class (as determined in the report module).
# By default, the name of the section is used as the class name.
# host (mandatory): is a string containing the full qualified name of the SMTP
# server host, or a 2-tuple containing the full qualified name of the SMTP
# server and the port number to use.
# credentials (optional): is a 2-tuple containing the username and the password
# to connect to the SMTP server.
# from_address(optional): is a string containing the mail addresses of the
# sender. If not specified, the address is set to the local hostname. (see
# smtplib.SMTP())
# mail_sent (optional): is the full path name of the folder where a copy of the
# mail will be written. An empty string does nothing.
# pending_mail (optional): is the full path name of the folder where a copy of
# the mail will be written until it is sent. It avoid to lost mail if the mail
# server configuration is erroneous or if the mail server doesn't answer. An
# empty string does nothing.
# to_addresses (mandatory): is a string or a list containing the mail addresses
# of the recipient.
# subject (optional): is a string containing the mail subject. An empty string
# does nothing.
[mailhandler]
class = MailHandler
host = smtp.example.com
;host = smtp.example.com, 25
;credentials= username, password
;from_address = lappupdate@example.com
;mail_sent = ./mailstore/sent
;pending_mail = ./mailstore/pending
to_addresses = sysadmin@example.com
;to_addresses = sysadmin@example.com, helpdesk@example.com
;subject = lAppUpdate: New Update(s) Alert
# File handler.
# class: indicates the handler’s class (as determined in the report module).
# By default, the name of the section is used as the class name.
# filename (mandatory): is a string containing the full path name of the
# destination file.
# mode (optional): is a string specifying the mode in which the file is opened.
# (see [`open()`](https://docs.python.org/3/library/functions.html#open)
[filehandler]
class = FileHandler
filename = ./tempstore/report.html
;mode = w
# Stream handler.
# class: indicates the handler’s class (as determined in the report module).
# By default, the name of the section is used as the class name.
# stream (optional): is a string specifying the [standard stream](https://docs.
# python.org/3/library/sys.html#sys.stdout) on which report will be written. By
# default, sys.stdout will be used.
[streamhandler]
class = StreamHandler
;stream = sys.stderr
Report Templates¶
<html lang=en-GB>
<!-- $lau:HeaderStart$ -->
<head>
<meta http-equiv=Content-Type content="text/html; charset=UTF-8">
<style>
<!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.body, li.body, div.body
{margin-top:10.0pt;
margin-right:0cm;
margin-bottom:10.0pt;
margin-left:0cm;
line-height:115%;
font-size:11.0pt;
font-family:"Calibri","sans-serif";}
h1
{margin-top:10.0pt;
margin-right:0cm;
margin-bottom:0cm;
margin-left:0cm;
margin-bottom:.0001pt;
line-height:115%;
background:#4F81BD;
border:none;
padding:0cm;
font-size:12.0pt;
font-family:"Calibri","sans-serif";
color:white;
text-transform:uppercase;
letter-spacing:.75pt;
font-weight:bold;}
h2
{margin-top:10.0pt;
margin-right:0cm;
margin-bottom:0cm;
margin-left:0cm;
margin-bottom:.0001pt;
line-height:115%;
background:#DBE5F1;
border:none;
padding:0cm;
font-size:10.0pt;
font-family:"Calibri","sans-serif";
text-transform:uppercase;
letter-spacing:.75pt;
font-weight:normal;}
a:link, span.link
{color:blue;
text-decoration:underline;}
a:visited, span.visited
{color:purple;
text-decoration:underline;}
em
{color:#243F60;
text-transform:uppercase;
letter-spacing:.25pt;
font-style:normal;}
p
{margin-right:0cm;
margin-left:0cm;
font-size:12.0pt;
font-family:"Times New Roman","serif";}
p.list_body, li.list_body, div.list_body
{margin-top:3.0pt;
margin-right:0cm;
margin-bottom:3.0pt;
margin-left:0cm;
line-height:100%;
font-size:11.0pt;
font-family:"Calibri","sans-serif";}
@page WordSection1
{size:595.3pt 841.9pt;
margin:70.85pt 70.85pt 70.85pt 70.85pt;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
ol
{margin-bottom:0cm;}
ul
{margin-bottom:0cm;}
-->
</style>
<!-- $lau:Title$ -->
<!-- reserved for <title></title> tag in a HTML document published on a web server -->
<!-- $lau:HeaderEnd$ -->
</head>
<!-- $lau:BodyStart$ -->
<body link=blue vlink=purple>
<div class=WordSection1>
<p class=body>On {date}, the following products have available updates.</p>
<!-- $lau:TOCStart$ -->
<ul>
<!-- $lau:TOCEntry$ -->
<li class=list_body><a href="#{id}">{name} ({version})</a></li>
<!-- $lau:TOCEnd$ -->
</ul>
<p class=body></p>
<!-- $lau:SummaryStart$ -->
<!-- $lau:SummaryEntry$ -->
<div style='border:solid #4F81BD 3.0pt;padding:0cm 0cm 0cm 0cm;background:#4F81BD'>
<h1 style='margin-top:0cm;line-height:normal;background:#4F81BD'>
<a name="{id}">{name}</a></h1>
</div>
<p class=body>
<a href="{location}">{name} ({version})</a> has been released on {published}. It will be
fetched on the next step.
</p>
<p class=body>
file size: {file_size}<br>
hash: {secure_hash}
</p>
<div style='border:solid #DBE5F1 3.0pt;padding:0cm 0cm 0cm 0cm;background:#DBE5F1'>
<h2 style='margin-top:0cm;line-height:normal;background:#DBE5F1'>
Release note
</h2>
</div>
<p class=body>See the <a href="{release_note}">detailed change history</a>.</p>
<div style='border:solid #DBE5F1 3.0pt;padding:0cm 0cm 0cm 0cm;background:#DBE5F1'>
<h2 style='margin-top:0cm;line-height:normal;background:#DBE5F1'>
Product information
</h2>
</div>
<p class=body style='margin-bottom:0cm;margin-bottom:.0001pt;line-height:normal'>
Published by {editor}, {description}
</p>
<p class=body style='margin-bottom:0cm;margin-bottom:.0001pt;line-height:normal'>
</p>
<!-- $lau:SummaryEnd$ -->
<!-- $lau:BodyEnd$ -->
</div>
</body>
<!-- $lau:Tail$ -->
</html>
<!-- $lau:BodyStart$ -->
On {date}, products below have available updates.
--------------------------------------------------------------------------------
<!-- $lau:SummaryStart$ -->
<!-- $lau:SummaryEntry$ -->
{name} {version} released on {published}
================================================================================
location: {location}
installer: {installer}
file size: {file_size}
Release note since ...
------------------------
See the detailed change history at {release_note}
{release_note}
Product information
------------------------
Published by {editor}, {description}
<!-- $lau:SummaryEnd$ -->
<!-- $lau:BodyEnd$ -->