Completed
Push — master ( a4f2fd...4fbdfd )
by Vincent
01:14
created

ActionStatus.display()   B

Complexity

Conditions 5

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 18
rs 8.5454
cc 5
1
#!/usr/bin/env python3
2
3
import datetime
4
import sys
5
import time
6
7
from ActionTree import Action, execute, Hooks
8
9
10
UNKNOWN = (0, "unwknown since")
11
PENDING = (1, "pending since")
12
READY = (2, "ready since")
13
STARTED = (3, "running since")
14
SUCCESSFUL = (4, "succeeded at")
15
FAILED = (5, "FAILED at")
16
CANCELED = (6, "canceled at")
17
18
19
class DemoHooks(Hooks):
20
    class ActionStatus:
21
        num_lines = {
22
            UNKNOWN: 0,
23
            PENDING: 0,
24
            READY: 0,
25
            STARTED: 5,
26
            SUCCESSFUL: 2,
27
            FAILED: 10,
28
            CANCELED: 0,
29
        }
30
31
        def __init__(self, label, time, status):
32
            self.label = label
33
            self.status = status
34
            self.time = time
35
            self.lines = []
36
37
        def set(self, time, status):
38
            self.time = time
39
            self.status = status
40
41
        def display(self):
42
            num_lines = self.num_lines[self.status]
43
            title = "\"{}\" ({} t={:.2f}s)".format(self.label, self.status[1], self.time.total_seconds())
44
            print()
45
            print(title)
46
            print("-" * len(title))
47
            if num_lines > 1:
48
                if len(self.lines) > num_lines:
49
                    print("[... {} lines not displayed ...]".format(len(self.lines) - num_lines))
50
                    lines_to_display = self.lines[1 - num_lines:]
51
                    padding = 0
52
                else:
53
                    lines_to_display = self.lines
54
                    padding = num_lines - len(self.lines)
55
                for line in lines_to_display:
56
                    print(">", line)
57
                for i in range(padding):
58
                    print()
59
60
    def __init__(self, action):
61
        self.start_time = datetime.datetime.now()
62
        actions = action.get_possible_execution_order()
63
        self.action_statuses = [self.ActionStatus(a.label, datetime.timedelta(), UNKNOWN) for a in actions]
64
        self.action_indexes = {action: i for (i, action) in enumerate(actions)}
65
        self.display()
66
67
    def display(self):
68
        print("\x1b[2J\x1b[H")
69
        title = "ActionTree demo (t={:.2f}s)".format((datetime.datetime.now() - self.start_time).total_seconds())
70
        print(title)
71
        print("=" * len(title))
72
        for action_status in self.action_statuses:
73
            action_status.display()
74
75
    def set(self, action, time, status):
76
        self.action_statuses[self.action_indexes[action]].set(time - self.start_time, status)
77
        self.display()
78
79
    def action_pending(self, time, action):
80
        self.set(action, time, PENDING)
81
82
    def action_ready(self, time, action):
83
        self.set(action, time, READY)
84
85
    def action_canceled(self, time, action):
86
        self.set(action, time, CANCELED)
87
88
    def action_started(self, time, action):
89
        self.set(action, time, STARTED)
90
91
    def action_printed(self, time, action, text):
92
        self.action_statuses[self.action_indexes[action]].lines += [line.rstrip() for line in text.splitlines()]
93
        self.display()
94
95
    def action_successful(self, time, action):
96
        self.set(action, time, SUCCESSFUL)
97
98
    def action_failed(self, time, action):
99
        self.set(action, time, FAILED)
100
101
102
class DemoAction(Action):
103
    def __init__(self, label, interval, iterations, exception=None):
104
        super(DemoAction, self).__init__("action {}".format(label))
105
        self.interval = interval
106
        self.iterations = iterations
107
        self.exception = exception
108
109
    def do_execute(self):
110
        print(self.label, "iteration 0 /", self.iterations)
111
        for i in range(self.iterations):
112
            time.sleep(self.interval)
113
            print(self.label, "iteration", (i + 1), "/", self.iterations)
114
        if self.exception:
115
            print(self.label, "failing")
116
            raise self.exception
117
118
119
a = DemoAction("a", 1., 5)
120
a.add_dependency(DemoAction("a1", 0.9, 7))
121
a.add_dependency(DemoAction("a2", 0.5, 12))
122
a.add_dependency(DemoAction("a3", 0.8, 10))
123
124
b = DemoAction("b", 1., 5)
125
b.add_dependency(DemoAction("b1", 0.5, 14, exception=Exception()))
126
b.add_dependency(DemoAction("b2", 0.3, 25))
127
b.add_dependency(DemoAction("b3", 1.7, 5))
128
129
z = DemoAction("z", 1., 5)
130
z.add_dependency(a)
131
z.add_dependency(b)
132
133
execute(z, jobs=4, hooks=DemoHooks(z), do_raise=False, keep_going=True)
134