1#!/usr/bin/env python3
 2
 3"""Utility functions for CHART algorithms written in Python."""
 4
 5
 6
 7
 8class NotDispatcher(Exception):
 9    """Exception to be raised if init_algorithm() is called but we are not
10    being run run inside the `dispatcher`.
11    """
12
13    def __init__(self, message):
14        super(NotDispatcher, self).__init__()
15        self.message = message
16
17    def __str__(self):
18        return self.message
19
20
21def init_algorithm():
22    """Read in work order file and initialise logging.
23    This function now always returns 3 objects (workorder file, result file, eventraiser)
24    even if the event raiser is None.
25    Previously the function returned either 2 or 3 values depending on whether the function
26    has events defined.
27    """
28    import chart.alg.settings
29    # careful, we don't want to interfere with code that calls "import chart.alg.settings"
30    # by giving them the core settings instead
31    from chart.project import settings as proj_settings
32    from chart.common.log import init_log
33    from chart.common import errors
34    from chart.backend.result import Result
35    from chart.backend.workorder import WorkOrder
36    from chart.backend.eventsfile import EventsFile
37    # from chart import db  # avoid circular dependency
38    # (error running ingestion.py)
39
40    # install global error handler
41    errors.init_handler()
42
43    # logging.debug('Looking for ' + chart.alg.settings.WORKORDER_FILENAME + ' in ' + Path.cwd())
44    if not chart.alg.settings.WORKORDER_FILENAME.exists():
45        raise NotDispatcher('This tool is not being run from inside the dispatcher tool. '
46                            'Set $CHART_DISPATCHER or run via "chart dispatcher" to avoid '
47                            'this error'.format(ENV_PREFIX=proj_settings.ENV_PREFIX))
48
49    # start up logging (either to console or single file)
50    init_log()
51
52    wo = WorkOrder(mode='r')
53    resultfile = Result(filename=chart.alg.settings.RESULT_FILENAME,
54                        mode='w',
55                        activity=wo.activity)
56
57    if len(wo.activity.eventnames) > 0:
58        # !!! TDB: events file validity element must to converted to allow
59        # for multiple separate validity periods !!!
60        return wo, resultfile, EventsFile(wo)
61
62    else:
63        return wo, resultfile, None
64
65init_algorithm.NotDispatcher = NotDispatcher
66
67from chart.backend.job import JobStatus