-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathprogram.py
More file actions
executable file
·169 lines (151 loc) · 4.06 KB
/
program.py
File metadata and controls
executable file
·169 lines (151 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import logging.config, datetime, pytz, time
from threading import Thread
import operation
logger = logging.getLogger(__name__)
####
class Log(object):
def __init__(self):
self.__logs = []
def add(self, val):
self.__logs.append((datetime.datetime.now(pytz.timezone('Asia/Tokyo')), val,))
def getAll(self):
return self.__logs
def getFormatted(self):
res = ''
for (dt, val) in self.__logs:
res += dt.isoformat() + ' ' + val + '\n'
return res
class Runner(Thread):
def __init__(self, sequence):
super(Runner, self).__init__()
self.__started = None
self.__stopping = None
self.__stopped = None
self.__aborted = None
self.__finished = None
self.__log = Log()
self.__sequence = sequence
def run(self):
self.__ensureNotStarted()
self.__started = datetime.datetime.now(pytz.timezone('Asia/Tokyo'))
self.__log.add('program started')
for op in self.__sequence:
if self.__stopping is not None:
self.__stop()
return
results = []
t = Thread(target = op.run, args = (self.__log, results,))
t.daemon = True
t.start()
t.join()
if len(results) == 0 or not results[0]:
self.__abort()
return
self.__finish()
def stop(self):
self.__ensureRunning()
self.__stopping = datetime.datetime.now(pytz.timezone('Asia/Tokyo'))
self.__log.add('stop requested')
def __stop(self):
self.__ensureRunning()
self.__stopped = datetime.datetime.now(pytz.timezone('Asia/Tokyo'))
self.__log.add('program stopped')
def __abort(self):
self.__ensureRunning()
self.__aborted = datetime.datetime.now(pytz.timezone('Asia/Tokyo'))
self.__log.add('program aborted')
def __finish(self):
self.__ensureRunning()
self.__finished = datetime.datetime.now(pytz.timezone('Asia/Tokyo'))
self.__log.add('program finished')
def isRunning(self):
return self.__started is not None and self.__stopped is None and self.__aborted is None and self.__finished is None
def getLog(self):
return self.__log.getFormatted()
def eraseLog(self):
self.__log = Log()
return True
def __ensureNotStarted(self):
if self.__started is not None:
raise RuntimeError('Runner already started at ' + self.__started.isoformat())
def __ensureRunning(self):
if self.__started is None:
raise RuntimeError('Runner not started')
elif self.__stopped is not None:
raise RuntimeError('Runner already stopped at ' + self.__stopped.isoformat())
elif self.__aborted is not None:
raise RuntimeError('Runner already aborted at ' + self.__aborted.isoformat())
elif self.__finished is not None:
raise RuntimeError('Runner already finished at ' + self.__finished.isoformat())
####
__runner = None
def start():
if not isRunning():
time.sleep(1)
global __runner
__runner = Runner(__sequence)
__runner.start()
return True
def isRunning():
return __runner is not None and __runner.isRunning()
def stop():
__runner.stop()
return True
def getLog():
if __runner is not None:
return __runner.getLog()
else:
return ''
def eraseLog():
if __runner is not None:
return __runner.eraseLog()
else:
return True
####
__sequence = []
def getSequence():
return __sequence
def addOperation(val):
__sequence.append(val);
def operationById(val):
for op in __sequence:
if op.getId() == val:
return op
raise RuntimeError('no operation found by id : ' + val)
def moveOperationById(val, upDown):
op = operationById(val)
idx = __sequence.index(op)
if upDown == 'up':
if 0 < idx:
__sequence.remove(op)
__sequence.insert(idx - 1, op)
return True
else:
return False
elif upDown == 'down':
if idx < len(__sequence) - 1:
__sequence.remove(op)
__sequence.insert(idx + 1, op)
return True
else:
return False
raise RuntimeError('unknown upDown value : ' + upDown)
def removeOperationById(val):
op = operationById(val)
__sequence.remove(op)
return op
####
def dump():
seq = []
for op in __sequence:
seq.append(op.dump())
return {'sequence' : seq}
def restore(data):
result = []
for aData in data.get('sequence'):
type_ = aData.get('type')
op = operation.createByType(type_)
op.save(aData)
result.append(op)
global __sequence
__sequence = result