kytos.core.helpers   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 145
Duplicated Lines 0 %

Test Coverage

Coverage 73.08%

Importance

Changes 0
Metric Value
eloc 28
dl 0
loc 145
ccs 19
cts 26
cp 0.7308
rs 10
c 0
b 0
f 0
wmc 6

4 Functions

Rating   Name   Duplication   Size   Complexity  
A get_time() 0 30 3
A run_on_thread() 0 21 1
A listen_to() 0 66 1
A now() 0 11 1
1
"""Utilities functions used in Kytos."""
2 1
from datetime import datetime, timezone
3 1
from threading import Thread
4
5 1
__all__ = ['listen_to', 'now', 'run_on_thread', 'get_time']
6
7
8
# APP_MSG = "[App %s] %s | ID: %02d | R: %02d | P: %02d | F: %s"
9
10
11 1
def listen_to(event, *events):
12
    """Decorate Event Listener methods.
13
14
    This decorator was built to be used on NAPPs methods to define which
15
    type of event the method will handle. With this, we will be able to
16
    'schedule' the app/method to receive an event when a new event is
17
    registered on the controller buffers.
18
    By using the run_on_thread decorator, we also guarantee that the method
19
    (handler) will be called from inside a new thread, avoiding this method to
20
    block its caller.
21
22
    The decorator will add an attribute to the method called 'events', that
23
    will be a list of the events that the method will handle.
24
25
    The event that will be listened to is always a string, but it can represent
26
    a regular expression to match against multiple Event Types. All listened
27
    events are documented in :doc:`/developer/listened_events` section.
28
29
    Example of usage:
30
31
    .. code-block:: python3
32
33
        class MyAppClass(KytosApp):
34
            @listen_to('kytos/of_core.messages.in')
35
            def my_handler_of_message_in(self, event):
36
                # Do stuff here...
37
38
            @listen_to('kytos/of_core.messages.out')
39
            def my_handler_of_message_out(self, event):
40
                # Do stuff here...
41
42
            @listen_to('kytos/of_core.messages.in.ofpt_hello',
43
                       'kytos/of_core.messages.out.ofpt_hello')
44
            def my_handler_of_hello_messages(self, event):
45
                # Do stuff here...
46
47
            @listen_to('kytos/of_core.message.*.hello')
48
            def my_other_handler_of_hello_messages(self, event):
49
                # Do stuff here...
50
51
            @listen_to('kytos/of_core.message.*.hello')
52
            def my_handler_of_hello_messages(self, event):
53
                # Do stuff here...
54
55
            @listen_to('kytos/of_core.message.*')
56
            def my_stats_handler_of_any_message(self, event):
57
                # Do stuff here...
58
    """
59
    def decorator(handler):
60
        """Decorate the handler method.
61
62
        Returns:
63
            A method with an `events` attribute (list of events to be listened)
64
            and also decorated to run on a new thread.
65
66
        """
67
        @run_on_thread
68
        def threaded_handler(*args):
69
            """Decorate the handler to run from a new thread."""
70
            handler(*args)
71
72
        threaded_handler.events = [event]
73
        threaded_handler.events.extend(events)
74
        return threaded_handler
75
76
    return decorator
77
78
79 1
def now(tzone=timezone.utc):
80
    """Return the current datetime (default to UTC).
81
82
    Args:
83
        tzone (datetime.timezone): Specific time zone used in datetime.
84
85
    Returns:
86
        datetime.datetime.now: Date time with specific time zone.
87
88
    """
89 1
    return datetime.now(tzone)
90
91
92 1
def run_on_thread(method):
93
    """Decorate to run the decorated method inside a new thread.
94
95
    Args:
96
        method (function): function used to run as a new thread.
97
98
    Returns:
99
        Decorated method that will run inside a new thread.
100
        When the decorated method is called, it will not return the created
101
        thread to the caller.
102
103
    """
104 1
    def threaded_method(*args):
105
        """Ensure the handler method runs inside a new thread."""
106 1
        thread = Thread(target=method, args=args)
107
108
        # Set daemon mode so that we don't have to wait for these threads
109
        # to finish when exiting Kytos
110 1
        thread.daemon = True
111 1
        thread.start()
112 1
    return threaded_method
113
114
115 1
def get_time(data=None):
116
    """Receive a dictionary or a string and return a datatime instance.
117
118
    data = {"year": 2006,
119
            "month": 11,
120
            "day": 21,
121
            "hour": 16,
122
            "minute": 30 ,
123
            "second": 00}
124
125
    or
126
127
    data = "21/11/06 16:30:00"
128
129
    2018-04-17T17:13:50Z
130
131
    Args:
132
        data (str, dict): python dict or string to be converted to datetime
133
134
    Returns:
135
        datetime: datetime instance.
136
137
    """
138 1
    if isinstance(data, str):
139 1
        date = datetime.strptime(data, "%Y-%m-%dT%H:%M:%S")
140 1
    elif isinstance(data, dict):
141 1
        date = datetime(**data)
142
    else:
143 1
        return None
144
    return date.replace(tzinfo=timezone.utc)
145