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
|
|
|
|