diff --git a/python/incendium/__init__.py b/python/incendium/__init__.py
index ed56cb1..80422af 100644
--- a/python/incendium/__init__.py
+++ b/python/incendium/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018
+# Copyright (C) 2019
# Author: Cesar Roman
# Contact: thecesrom@gmail.com
diff --git a/python/incendium/constants.py b/python/incendium/constants.py
index 81c8611..fff6c7f 100644
--- a/python/incendium/constants.py
+++ b/python/incendium/constants.py
@@ -1,13 +1,28 @@
-# Copyright (C) 2018
+# Copyright (C) 2019
# Author: Cesar Roman
# Contact: thecesrom@gmail.com
-"""Incendium Constants module."""
+"""Constants module."""
# Email settings.
SMTP = 'mail.mycompany.com:25'
SENDER = 'no-reply@mycompany.com'
+# Email templates.
+ERROR_REPORT = """
+
+
+ Error Report.
+ Error Message
+ %s
+ Error Details
+ %s
+ System Details
+ *** Please do not reply to this email address.
+
+
+"""
+
# Language settings.
DEFAULT_LANGUAGE = 'en_US'
@@ -37,6 +52,7 @@
PROCEED_WITHOUT_SAVING_CHANGES = ('Would you like to proceed without saving '
'your changes?')
SUCCESS_WINDOW_TITLE = 'Success'
+TABBED_LINE = ' - '
UNEXPECTED_ERROR = 'An unexpected error occurred in %s. \n%s'
UNEXPECTED_ERROR_CAUSED_BY = ('An unexpected error occurred in %s. '
'\n%s\nCaused by: %s')
diff --git a/python/incendium/dataset.py b/python/incendium/dataset.py
index 8272350..d35f774 100644
--- a/python/incendium/dataset.py
+++ b/python/incendium/dataset.py
@@ -1,8 +1,8 @@
-# Copyright (C) 2018
+# Copyright (C) 2019
# Author: Cesar Roman
# Contact: thecesrom@gmail.com
-"""Incendium Dataset module."""
+"""Dataset module."""
__all__ = [
'to_xml'
diff --git a/python/incendium/date.py b/python/incendium/date.py
index 3083e63..6d07d40 100644
--- a/python/incendium/date.py
+++ b/python/incendium/date.py
@@ -1,8 +1,8 @@
-# Copyright (C) 2018
+# Copyright (C) 2019
# Author: Cesar Roman
# Contact: thecesrom@gmail.com
-"""Incendium Date module."""
+"""Date module."""
__all__ = [
'compare'
diff --git a/python/incendium/db.py b/python/incendium/db.py
index 6d714c7..635daff 100644
--- a/python/incendium/db.py
+++ b/python/incendium/db.py
@@ -1,8 +1,8 @@
-# Copyright (C) 2018
+# Copyright (C) 2019
# Author: Cesar Roman
# Contact: thecesrom@gmail.com
-"""Incendium Database module."""
+"""Database module."""
__all__ = [
'check',
@@ -122,13 +122,16 @@ def _execute_sp(stored_procedure, database='', transaction=None,
return _result
-def check(stored_procedure, params=None):
+def check(stored_procedure, database='', params=None):
"""Executes a stored procedure that returns a flag set to TRUE or
FALSE.
Args:
stored_procedure (str): The name of the stored procedure to
execute.
+ database (str): The name of the database connection to execute
+ against. If omitted or "", the project's default database
+ connection will be used. Optional.
params (dict): A Dictionary containing all parameters.
Optional.
@@ -138,12 +141,14 @@ def check(stored_procedure, params=None):
output = {'flag': system.db.BIT}
output_params = get_output_params(stored_procedure,
output=output,
+ database=database,
params=params)
return output_params['flag']
-def execute_non_query(stored_procedure, params=None, transaction=None):
+def execute_non_query(stored_procedure, database='', transaction=None,
+ params=None):
"""Executes a stored procedure against the connection and returns
the number of rows affected.
@@ -152,16 +157,20 @@ def execute_non_query(stored_procedure, params=None, transaction=None):
Args:
stored_procedure (str): The name of the stored procedure to
execute.
- params (dict): A Dictionary containing all parameters.
- Optional.
+ database (str): The name of the database connection to execute
+ against. If omitted or "", the project's default database
+ connection will be used. Optional.
transaction (str): A transaction identifier. If omitted, the
call will be executed in its own transaction. Optional.
+ params (dict): A Dictionary containing all parameters.
+ Optional.
Returns:
int: The number of rows modified by the stored procedure, or
-1 if not applicable.
"""
result = _execute_sp(stored_procedure,
+ database=database,
transaction=transaction,
in_params=params,
get_update_count=True)
@@ -169,12 +178,15 @@ def execute_non_query(stored_procedure, params=None, transaction=None):
return result.update_count
-def get_data(stored_procedure, params=None):
+def get_data(stored_procedure, database='', params=None):
"""Returns data by executing a stored procedure.
Args:
stored_procedure (str): The name of the stored procedure to
execute.
+ database (str): The name of the database connection to execute
+ against. If omitted or "", the project's default database
+ connection will be used. Optional.
params (dict): A Dictionary containing all parameters.
Optional.
@@ -183,28 +195,34 @@ def get_data(stored_procedure, params=None):
procedure call, if any.
"""
result = _execute_sp(stored_procedure,
+ database=database,
in_params=params,
get_result_set=True)
return result.result_set
-def get_output_params(stored_procedure, output, params=None, transaction=None):
+def get_output_params(stored_procedure, output, database='', transaction=None,
+ params=None):
"""Gets the Output parameters from the Stored Procedure.
Args:
stored_procedure (str): The name of the stored procedure to
execute.
output (dict): A Dictionary containing all output parameters.
- params (dict): A Dictionary containing all parameters.
- Optional.
+ database (str): The name of the database connection to execute
+ against. If omitted or "", the project's default database
+ connection will be used. Optional.
transaction (str): A transaction identifier. If omitted, the
call will be executed in its own transaction. Optional.
+ params (dict): A Dictionary containing all parameters.
+ Optional.
Returns:
dict: Result's output_params.
"""
result = _execute_sp(stored_procedure,
+ database=database,
transaction=transaction,
in_params=params,
out_params=output,
@@ -213,23 +231,27 @@ def get_output_params(stored_procedure, output, params=None, transaction=None):
return result.output_params
-def get_return_value(stored_procedure, return_type_code, params=None,
- transaction=None):
+def get_return_value(stored_procedure, return_type_code, database='',
+ transaction=None, params=None):
"""Gets the Return Value from the Stored Procedure.
Args:
stored_procedure (str): The name of the stored procedure to
execute.
return_type_code (int): The Type Code of the Return Value.
- params (dict): A Dictionary containing all parameters.
- Optional.
+ database (str): The name of the database connection to execute
+ against. If omitted or "", the project's default database
+ connection will be used. Optional.
transaction (str): A transaction identifier. If omitted, the
call will be executed in its own transaction. Optional.
+ params (dict): A Dictionary containing all parameters.
+ Optional.
Returns:
int: The return value.
"""
result = _execute_sp(stored_procedure,
+ database=database,
transaction=transaction,
in_params=params,
return_type_code=return_type_code,
diff --git a/python/incendium/exceptions.py b/python/incendium/exceptions.py
index da0a924..8f62f3f 100644
--- a/python/incendium/exceptions.py
+++ b/python/incendium/exceptions.py
@@ -1,8 +1,8 @@
-# Copyright (C) 2018
+# Copyright (C) 2019
# Author: Cesar Roman
# Contact: thecesrom@gmail.com
-"""Incendium Exceptions module."""
+"""Exceptions module."""
__all__ = [
'ApplicationError',
diff --git a/python/incendium/gui.py b/python/incendium/gui.py
index 97c3fa3..b635e2a 100644
--- a/python/incendium/gui.py
+++ b/python/incendium/gui.py
@@ -1,8 +1,8 @@
-# Copyright (C) 2018
+# Copyright (C) 2019
# Author: Cesar Roman
# Contact: thecesrom@gmail.com
-"""Incendium GUI module."""
+"""GUI module."""
__all__ = [
'confirm',
diff --git a/python/incendium/nav.py b/python/incendium/nav.py
index 3c3d7cd..1fee470 100644
--- a/python/incendium/nav.py
+++ b/python/incendium/nav.py
@@ -1,8 +1,8 @@
-# Copyright (C) 2018
+# Copyright (C) 2019
# Authors: Cesar Roman, Kyle Chase.
# Contact: thecesrom@gmail.com
-"""Incendium Navigation module."""
+"""Navigation module."""
__all__ = [
'swap_to',
diff --git a/python/incendium/net.py b/python/incendium/net.py
index 2620426..f6c63b2 100644
--- a/python/incendium/net.py
+++ b/python/incendium/net.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018
+# Copyright (C) 2019
# Author: Cesar Roman
# Contact: thecesrom@gmail.com
@@ -12,6 +12,21 @@
import system.net
from incendium import constants
+HTML_ESCAPE_TABLE = {
+ '&': '&',
+ '"': '"',
+ "'": ''',
+ '>': '>',
+ '<': '<',
+ '\n': '
',
+ '\t': ' ' * 4
+}
+
+
+def _html_escape(text):
+ """Produce entities within text."""
+ return "".join(HTML_ESCAPE_TABLE.get(c, c) for c in text)
+
def _send_email(subject, body, html, to, priority):
"""Sends an email through the given SMTP server.
@@ -24,9 +39,31 @@ def _send_email(subject, body, html, to, priority):
to (list[str]): A list of email addresses to send to.
priority (str): Priority for the message.
"""
- system.net.sendEmail(smtp=constants.SMTP, fromAddr=constants.SENDER,
- subject=subject, body=body, html=html, to=to,
- priority=priority)
+ try:
+ system.net.sendEmail(
+ smtp=constants.SMTP,
+ fromAddr=constants.SENDER,
+ subject=subject,
+ body=body,
+ html=html,
+ to=to,
+ priority=priority
+ )
+ finally:
+ pass
+
+
+def report_error(subject, message, details, to):
+ """Sends an Error Report email message.
+
+ Args:
+ subject (str): The subject line for the email.
+ message (str): The error message.
+ details (str): The error details.
+ to (list[str]): A list of emails addresses to send to.
+ """
+ body = constants.ERROR_REPORT % (message, _html_escape(details))
+ send_high_priority_email(subject, body, to)
def send_high_priority_email(subject, body, to):
@@ -46,9 +83,9 @@ def send_html_email(subject, body, to, priority='3'):
Args:
subject (str): The subject line for the email.
body (str): The body text of the email in HTML format.
- to (list[str]): A List of email addresses to send to.
- priority (str): Priority of the message, from "1" to "5", with
- "1" being highest priority. Defaults to "3" (normal)
+ to (list[str]): A list of email addresses to send to.
+ priority (str): Priority of the message, from "1" to "5",
+ with "1" being highest priority. Defaults to "3" (normal)
priority. Optional.
"""
_send_email(subject, body, True, to, priority)
diff --git a/python/incendium/user.py b/python/incendium/user.py
index 7a32c8f..57b0062 100644
--- a/python/incendium/user.py
+++ b/python/incendium/user.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018
+# Copyright (C) 2019
# Author: Cesar Roman
# Contact: thecesrom@gmail.com
diff --git a/python/incendium/util.py b/python/incendium/util.py
index b19bdde..621b9d1 100644
--- a/python/incendium/util.py
+++ b/python/incendium/util.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018
+# Copyright (C) 2019
# Author: Cesar Roman
# Contact: thecesrom@gmail.com
@@ -87,21 +87,36 @@ def validate_form(strings=None, numbers=None, collections=None):
# Initialize variables.
is_valid = True
error_message = constants.EMPTY_STRING
+ counter = 0
if strings:
- for k, v in strings.iteritems():
- if not v:
- error_message += constants.NEW_TABBED_LINE + k
+ for key, value in strings.iteritems():
+ if not value:
+ counter += 1
+ if counter == 1:
+ error_message += constants.TABBED_LINE + key
+ else:
+ error_message += constants.NEW_TABBED_LINE + key
is_valid = False
if numbers:
- for k, v in numbers.iteritems():
- if v is None or v <= 0:
- error_message += constants.NEW_TABBED_LINE + k
+ for key, value in numbers.iteritems():
+ if value is None or value <= 0:
+ counter += 1
+ if counter == 1:
+ error_message += constants.TABBED_LINE + key
+ else:
+ error_message += constants.NEW_TABBED_LINE + key
is_valid = False
if collections:
- for k, v in collections.iteritems():
- if v is None or v <= 0:
- error_message += constants.NEW_TABBED_LINE + k
+ for key, value in collections.iteritems():
+ if value is None or value <= 0:
+ counter += 1
+ error_message += (constants.TABBED_LINE + key if counter == 1
+ else constants.NEW_TABBED_LINE + key)
+ if counter == 1:
+ error_message += constants.TABBED_LINE + key
+ else:
+ error_message += constants.NEW_TABBED_LINE + key
is_valid = False
return is_valid, error_message