|
1
|
|
|
"""Data structures that combine all program data.""" |
|
2
|
|
|
|
|
3
|
1 |
|
import crayons |
|
4
|
|
|
import log |
|
5
|
1 |
|
import yorm |
|
6
|
|
|
|
|
7
|
1 |
|
from .config import ProgramConfig |
|
8
|
1 |
|
from .status import ProgramStatus |
|
9
|
|
|
|
|
10
|
|
|
|
|
11
|
1 |
|
@yorm.attr(config=ProgramConfig) |
|
12
|
|
|
@yorm.attr(status=ProgramStatus) |
|
13
|
|
|
class Data: |
|
14
|
1 |
|
"""Primary wrapper for all settings.""" |
|
15
|
1 |
|
|
|
16
|
|
|
def __init__(self): |
|
17
|
|
|
self.config = ProgramConfig() |
|
18
|
|
|
self.status = ProgramStatus() |
|
19
|
1 |
|
self._last_counter = self.status.counter |
|
20
|
1 |
|
|
|
21
|
1 |
|
def __repr__(self): |
|
22
|
1 |
|
return "settings" |
|
23
|
|
|
|
|
24
|
1 |
|
@property |
|
25
|
1 |
|
def modified(self): |
|
26
|
|
|
changed = self.status.counter != self._last_counter |
|
27
|
1 |
|
self._last_counter = self.status.counter |
|
28
|
|
|
return changed |
|
29
|
1 |
|
|
|
30
|
1 |
|
@staticmethod |
|
31
|
1 |
|
def prune_status(config, status): |
|
32
|
|
|
"""Remove undefined applications and computers.""" |
|
33
|
1 |
|
log.info("Cleaning up applications and computers...") |
|
34
|
|
|
for appstatus in status.applications.copy(): |
|
35
|
|
|
if not config.applications.find(appstatus.application): |
|
36
|
1 |
|
status.applications.remove(appstatus) |
|
37
|
1 |
|
log.info("Removed application: %s", appstatus) |
|
38
|
1 |
|
else: |
|
39
|
|
|
for computerstate in appstatus.computers.copy(): |
|
40
|
|
|
if not config.computers.find(computerstate.computer): |
|
41
|
|
|
appstatus.computers.remove(computerstate) |
|
42
|
1 |
|
log.info("Removed computer: %s", computerstate) |
|
43
|
1 |
|
|
|
44
|
|
|
@staticmethod |
|
45
|
|
|
def queue_all_applications(config, status, computer): |
|
46
|
|
|
"""Queue applications for launch.""" |
|
47
|
1 |
|
log.info("Queuing applications for launch...") |
|
48
|
|
|
for application in config.applications: |
|
49
|
|
|
if application.auto_queue: |
|
50
|
|
|
log.debug("Queuing %s on %s...", application, computer) |
|
51
|
|
|
status.queue(application, computer) |
|
52
|
|
|
|
|
53
|
|
|
@staticmethod |
|
54
|
|
|
def launch_queued_applications(config, status, computer, manager): |
|
55
|
|
|
"""Launch applications that have been queued.""" |
|
56
|
1 |
|
log.info("Launching queued applications...") |
|
57
|
|
|
for app_status in status.applications: |
|
58
|
|
|
if app_status.next: |
|
59
|
1 |
|
application = config.applications.get(app_status.application) |
|
60
|
1 |
|
print(crayons.yellow(f"{application} is queued for {app_status.next}")) |
|
61
|
1 |
|
if app_status.next == computer: |
|
62
|
|
|
latest = status.get_latest(application) |
|
63
|
|
|
if latest in (computer, None) or application.no_wait: |
|
64
|
|
|
if not manager.is_running(application): |
|
65
|
|
|
manager.start(application) |
|
66
|
|
|
app_status.next = None |
|
67
|
|
|
else: |
|
68
|
|
|
print( |
|
69
|
|
|
crayons.yellow( |
|
70
|
|
|
f"{application} is still running on {latest}" |
|
71
|
|
|
) |
|
72
|
|
|
) |
|
73
|
|
|
elif manager.is_running(application): |
|
74
|
|
|
manager.stop(application) |
|
75
|
1 |
|
|
|
76
|
|
|
@staticmethod |
|
77
|
|
|
def close_all_applications(config, manager): |
|
78
|
|
|
"""Close all applications running on this computer.""" |
|
79
|
|
|
log.info("Closing all applications on this computer...") |
|
80
|
|
|
for application in config.applications: |
|
81
|
|
|
manager.stop(application) |
|
82
|
1 |
|
|
|
83
|
|
|
@staticmethod |
|
84
|
|
|
def update_status(config, status, computer, manager): |
|
85
|
1 |
|
"""Update each application's status.""" |
|
86
|
1 |
|
log.info("Recording application status...") |
|
87
|
1 |
|
for application in config.applications: |
|
88
|
1 |
|
latest = status.get_latest(application) |
|
89
|
1 |
|
if manager.is_running(application): |
|
90
|
1 |
|
if computer != latest: |
|
91
|
|
|
if status.is_running(application, computer): |
|
92
|
1 |
|
# case 1: application just launched remotely |
|
93
|
1 |
|
manager.stop(application) |
|
94
|
1 |
|
status.stop(application, computer) |
|
95
|
1 |
|
print( |
|
96
|
|
|
crayons.green(f"{application} is now running on {latest}") |
|
97
|
|
|
) |
|
98
|
1 |
|
print( |
|
99
|
1 |
|
crayons.red(f"{application} is now stopped on {computer}") |
|
100
|
|
|
) |
|
101
|
|
|
else: |
|
102
|
1 |
|
# case 2: application just launched locally |
|
103
|
|
|
status.start(application, computer) |
|
104
|
1 |
|
print( |
|
105
|
|
|
crayons.green(f"{application} is now running on {computer}") |
|
106
|
1 |
|
) |
|
107
|
1 |
|
else: |
|
108
|
|
|
# case 3: application already running locally |
|
109
|
|
|
print(crayons.cyan(f"{application} is running on {computer}")) |
|
110
|
1 |
|
else: |
|
111
|
|
|
if status.is_running(application, computer): |
|
112
|
|
|
# case 4: application just closed locally |
|
113
|
1 |
|
status.stop(application, computer) |
|
114
|
|
|
print(crayons.red(f"{application} is now stopped on {computer}")) |
|
115
|
|
|
elif latest: |
|
116
|
|
|
# case 5: application already closed locally |
|
117
|
|
|
print(crayons.magenta(f"{application} is running on {latest}")) |
|
118
|
1 |
|
else: |
|
119
|
|
|
# case 6: application is not running |
|
120
|
|
|
print(crayons.white(f"{application} is not running")) |
|
121
|
|
|
|