OpenOrchestrator 1.1.0__py3-none-any.whl → 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- OpenOrchestrator/common/crypto_util.py +21 -9
- OpenOrchestrator/common/datetime_util.py +1 -1
- OpenOrchestrator/database/db_util.py +167 -131
- OpenOrchestrator/database/queues.py +1 -0
- OpenOrchestrator/database/triggers.py +1 -0
- OpenOrchestrator/database/truncated_string.py +18 -0
- OpenOrchestrator/orchestrator/application.py +18 -1
- OpenOrchestrator/orchestrator/datetime_input.py +16 -2
- OpenOrchestrator/orchestrator/popups/constant_popup.py +8 -7
- OpenOrchestrator/orchestrator/popups/credential_popup.py +8 -7
- OpenOrchestrator/orchestrator/popups/trigger_popup.py +27 -15
- OpenOrchestrator/orchestrator/tabs/constants_tab.py +1 -1
- OpenOrchestrator/orchestrator/tabs/logging_tab.py +4 -3
- OpenOrchestrator/orchestrator/tabs/queue_tab.py +19 -11
- OpenOrchestrator/orchestrator/tabs/settings_tab.py +2 -2
- OpenOrchestrator/orchestrator/tabs/trigger_tab.py +4 -7
- OpenOrchestrator/orchestrator_connection/connection.py +11 -9
- OpenOrchestrator/scheduler/application.py +1 -1
- OpenOrchestrator/scheduler/connection_frame.py +1 -1
- OpenOrchestrator/scheduler/run_tab.py +85 -87
- OpenOrchestrator/scheduler/runner.py +34 -23
- {OpenOrchestrator-1.1.0.dist-info → OpenOrchestrator-1.3.0.dist-info}/METADATA +1 -1
- OpenOrchestrator-1.3.0.dist-info/RECORD +39 -0
- {OpenOrchestrator-1.1.0.dist-info → OpenOrchestrator-1.3.0.dist-info}/WHEEL +1 -1
- OpenOrchestrator-1.1.0.dist-info/RECORD +0 -38
- {OpenOrchestrator-1.1.0.dist-info → OpenOrchestrator-1.3.0.dist-info}/LICENSE +0 -0
- {OpenOrchestrator-1.1.0.dist-info → OpenOrchestrator-1.3.0.dist-info}/top_level.txt +0 -0
@@ -1,124 +1,123 @@
|
|
1
1
|
"""This module is responsible for the layout and functionality of the run tab
|
2
2
|
in Scheduler."""
|
3
3
|
|
4
|
+
from __future__ import annotations
|
5
|
+
from typing import TYPE_CHECKING
|
6
|
+
|
4
7
|
import tkinter
|
5
8
|
from tkinter import ttk
|
6
9
|
import sys
|
7
10
|
|
11
|
+
from sqlalchemy import exc as alc_exc
|
12
|
+
|
8
13
|
from OpenOrchestrator.common import crypto_util
|
9
14
|
from OpenOrchestrator.database import db_util
|
10
15
|
from OpenOrchestrator.scheduler import runner
|
11
16
|
|
17
|
+
if TYPE_CHECKING:
|
18
|
+
from OpenOrchestrator.scheduler.application import Application
|
12
19
|
|
13
|
-
def create_tab(parent: ttk.Notebook, app) -> ttk.Frame:
|
14
|
-
"""Create a new Run tab object.
|
15
|
-
|
16
|
-
Args:
|
17
|
-
parent: The ttk.Notebook object that this tab is a child of.
|
18
|
-
app: The Scheduler application object.
|
19
|
-
|
20
|
-
Returns:
|
21
|
-
ttk.Frame: The created tab object as a ttk.Frame.
|
22
|
-
"""
|
23
|
-
tab = ttk.Frame(parent)
|
24
|
-
tab.pack(fill='both', expand=True)
|
25
|
-
|
26
|
-
status_label = ttk.Label(tab, text="State: Paused")
|
27
|
-
status_label.pack()
|
28
|
-
|
29
|
-
ttk.Button(tab, text="Run", command=lambda: run(app, status_label)).pack()
|
30
|
-
ttk.Button(tab, text="Pause", command=lambda: pause(app, status_label)).pack()
|
31
|
-
|
32
|
-
# Text area
|
33
|
-
text_frame = tkinter.Frame(tab)
|
34
|
-
text_frame.pack()
|
35
20
|
|
36
|
-
|
37
|
-
|
21
|
+
# pylint: disable-next=too-many-ancestors
|
22
|
+
class RunTab(ttk.Frame):
|
23
|
+
"""A ttk.frame object containing the functionality of the run tab in Scheduler."""
|
24
|
+
def __init__(self, parent: ttk.Notebook, app: Application):
|
25
|
+
super().__init__(parent)
|
26
|
+
self.pack(fill='both', expand=True)
|
38
27
|
|
39
|
-
|
40
|
-
text_yscroll.pack(side='right', fill='y')
|
41
|
-
text_area.configure(yscrollcommand=text_yscroll.set)
|
28
|
+
self.app = app
|
42
29
|
|
43
|
-
|
44
|
-
|
45
|
-
|
30
|
+
s = ttk.Style()
|
31
|
+
s.configure('my.TButton', font=('Helvetica Bold', 24))
|
32
|
+
self.button = ttk.Button(self, text="Run", command=self.button_click, style='my.TButton')
|
33
|
+
self.button.pack()
|
46
34
|
|
47
|
-
|
35
|
+
# Text area
|
36
|
+
text_frame = tkinter.Frame(self)
|
37
|
+
text_frame.pack()
|
48
38
|
|
49
|
-
|
39
|
+
self.text_area = tkinter.Text(text_frame, state='disabled', wrap='none')
|
50
40
|
|
41
|
+
# Redirect stdout to the text area instead of console
|
42
|
+
sys.stdout.write = self.print_text
|
51
43
|
|
52
|
-
|
53
|
-
|
44
|
+
# Add scroll bars to text area
|
45
|
+
text_yscroll = ttk.Scrollbar(text_frame, orient='vertical', command=self.text_area.yview)
|
46
|
+
text_yscroll.pack(side='right', fill='y')
|
47
|
+
self.text_area.configure(yscrollcommand=text_yscroll.set)
|
54
48
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
"""
|
59
|
-
if db_util.get_conn_string() is None:
|
60
|
-
print("Can't start without a valid connection string. Go to the settings tab to configure the connection string")
|
61
|
-
return
|
62
|
-
if crypto_util.get_key() is None:
|
63
|
-
print("Can't start without a valid encryption key. Go to the settings tab to configure the encryption key")
|
64
|
-
return
|
65
|
-
|
66
|
-
if not app.running:
|
67
|
-
status_label.configure(text='State: Running')
|
68
|
-
print('Running...\n')
|
69
|
-
app.running = True
|
49
|
+
text_xscroll = ttk.Scrollbar(text_frame, orient='horizontal', command=self.text_area.xview)
|
50
|
+
text_xscroll.pack(side='bottom', fill='x')
|
51
|
+
self.text_area.configure(xscrollcommand=text_xscroll.set)
|
70
52
|
|
71
|
-
|
72
|
-
if app.tk.call('after', 'info') == '':
|
73
|
-
app.after(0, loop, app)
|
53
|
+
self.text_area.pack()
|
74
54
|
|
55
|
+
def button_click(self):
|
56
|
+
"""Callback for when the run/pause button is clicked."""
|
57
|
+
if self.app.running:
|
58
|
+
self.pause()
|
59
|
+
else:
|
60
|
+
self.run()
|
75
61
|
|
76
|
-
def pause(
|
77
|
-
|
78
|
-
|
79
|
-
Args:
|
80
|
-
app: The Scheduler application object.
|
81
|
-
status_label: The label showing the current status.
|
82
|
-
"""
|
83
|
-
if app.running:
|
84
|
-
status_label.configure(text="State: Paused")
|
62
|
+
def pause(self):
|
63
|
+
"""Stops the Scheduler and sets the app's status to 'paused'."""
|
64
|
+
self.button.configure(text="Run")
|
85
65
|
print('Paused... Please wait for all processes to stop before closing the application\n')
|
86
|
-
app.running = False
|
66
|
+
self.app.running = False
|
67
|
+
|
68
|
+
def run(self):
|
69
|
+
"""Starts the Scheduler and sets the app's status to 'running'."""
|
70
|
+
if db_util.get_conn_string() is None:
|
71
|
+
print("Can't start without a valid connection string. Go to the settings tab to configure the connection string")
|
72
|
+
return
|
73
|
+
if crypto_util.get_key() is None:
|
74
|
+
print("Can't start without a valid encryption key. Go to the settings tab to configure the encryption key")
|
75
|
+
return
|
76
|
+
|
77
|
+
self.button.configure(text="Pause")
|
78
|
+
print('Running...\n')
|
79
|
+
self.app.running = True
|
87
80
|
|
81
|
+
# Only start a new loop if it's not already running
|
82
|
+
if self.app.tk.call('after', 'info') == '':
|
83
|
+
self.app.after(0, loop, self.app)
|
88
84
|
|
89
|
-
def print_text(
|
90
|
-
|
91
|
-
|
85
|
+
def print_text(self, text: str) -> None:
|
86
|
+
"""Appends text to the text area.
|
87
|
+
Is used to replace the functionality of sys.stdout.write (print).
|
92
88
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
text_widget.insert('end', text)
|
89
|
+
Args:
|
90
|
+
string: The string to append.
|
91
|
+
"""
|
92
|
+
# Insert text at the end
|
93
|
+
self.text_area.configure(state='normal')
|
94
|
+
self.text_area.insert('end', text)
|
100
95
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
96
|
+
# If the number of lines are above 1000 delete 10 lines from the top
|
97
|
+
num_lines = int(self.text_area.index('end').split('.', maxsplit=1)[0])
|
98
|
+
if num_lines > 1000:
|
99
|
+
self.text_area.delete("1.0", "10.0")
|
105
100
|
|
106
|
-
|
107
|
-
|
108
|
-
|
101
|
+
# Scroll to end
|
102
|
+
self.text_area.see('end')
|
103
|
+
self.text_area.configure(state='disabled')
|
109
104
|
|
110
105
|
|
111
|
-
def loop(app) -> None:
|
106
|
+
def loop(app: Application) -> None:
|
112
107
|
"""The main loop function of the Scheduler.
|
113
108
|
Checks heartbeats, check triggers, and schedules the next loop.
|
114
109
|
|
115
110
|
Args:
|
116
111
|
app: The Scheduler Application object.
|
117
112
|
"""
|
118
|
-
|
113
|
+
try:
|
114
|
+
check_heartbeats(app)
|
115
|
+
|
116
|
+
if app.running:
|
117
|
+
check_triggers(app)
|
119
118
|
|
120
|
-
|
121
|
-
|
119
|
+
except alc_exc.OperationalError:
|
120
|
+
print("Couldn't connect to database.")
|
122
121
|
|
123
122
|
if len(app.running_jobs) == 0:
|
124
123
|
print("Doing cleanup...")
|
@@ -132,7 +131,7 @@ def loop(app) -> None:
|
|
132
131
|
print("Scheduler is paused and no more processes are running.")
|
133
132
|
|
134
133
|
|
135
|
-
def check_heartbeats(app) -> None:
|
134
|
+
def check_heartbeats(app: Application) -> None:
|
136
135
|
"""Check if any running jobs are still running, failed or done.
|
137
136
|
|
138
137
|
Args:
|
@@ -141,8 +140,6 @@ def check_heartbeats(app) -> None:
|
|
141
140
|
print('Checking heartbeats...')
|
142
141
|
for job in app.running_jobs:
|
143
142
|
if job.process.poll() is not None:
|
144
|
-
app.running_jobs.remove(job)
|
145
|
-
|
146
143
|
if job.process.returncode == 0:
|
147
144
|
print(f"Process '{job.trigger.process_name}' is done")
|
148
145
|
runner.end_job(job)
|
@@ -150,11 +147,12 @@ def check_heartbeats(app) -> None:
|
|
150
147
|
print(f"Process '{job.trigger.process_name}' failed. Check process log for more info.")
|
151
148
|
runner.fail_job(job)
|
152
149
|
|
150
|
+
app.running_jobs.remove(job)
|
153
151
|
else:
|
154
152
|
print(f"Process '{job.trigger.process_name}' is still running")
|
155
153
|
|
156
154
|
|
157
|
-
def check_triggers(app) -> None:
|
155
|
+
def check_triggers(app: Application) -> None:
|
158
156
|
"""Checks any process is blocking
|
159
157
|
and if not checks if any trigger should be run.
|
160
158
|
|
@@ -16,6 +16,7 @@ class Job():
|
|
16
16
|
"""An object that holds information about a running job."""
|
17
17
|
process: subprocess.Popen
|
18
18
|
trigger: Trigger
|
19
|
+
process_folder: str | None
|
19
20
|
|
20
21
|
|
21
22
|
def poll_triggers(app) -> Job | None:
|
@@ -66,10 +67,7 @@ def run_single_trigger(trigger: SingleTrigger) -> Job | None:
|
|
66
67
|
print('Running trigger: ', trigger.trigger_name)
|
67
68
|
|
68
69
|
if db_util.begin_single_trigger(trigger.id):
|
69
|
-
|
70
|
-
|
71
|
-
if process is not None:
|
72
|
-
return Job(process, trigger)
|
70
|
+
return run_process(trigger)
|
73
71
|
|
74
72
|
return None
|
75
73
|
|
@@ -88,10 +86,7 @@ def run_scheduled_trigger(trigger: ScheduledTrigger) -> Job | None:
|
|
88
86
|
print('Running trigger: ', trigger.trigger_name)
|
89
87
|
|
90
88
|
if db_util.begin_scheduled_trigger(trigger.id):
|
91
|
-
|
92
|
-
|
93
|
-
if process is not None:
|
94
|
-
return Job(process, trigger)
|
89
|
+
return run_process(trigger)
|
95
90
|
|
96
91
|
return None
|
97
92
|
|
@@ -109,10 +104,7 @@ def run_queue_trigger(trigger: QueueTrigger) -> Job | None:
|
|
109
104
|
print('Running trigger: ', trigger.trigger_name)
|
110
105
|
|
111
106
|
if db_util.begin_queue_trigger(trigger.id):
|
112
|
-
|
113
|
-
|
114
|
-
if process is not None:
|
115
|
-
return Job(process, trigger)
|
107
|
+
return run_process(trigger)
|
116
108
|
|
117
109
|
return None
|
118
110
|
|
@@ -142,7 +134,7 @@ def clone_git_repo(repo_url: str) -> str:
|
|
142
134
|
def clear_repo_folder() -> None:
|
143
135
|
"""Completely remove the repos folder."""
|
144
136
|
repo_folder = get_repo_folder_path()
|
145
|
-
|
137
|
+
clear_folder(repo_folder)
|
146
138
|
|
147
139
|
|
148
140
|
def get_repo_folder_path() -> str:
|
@@ -156,6 +148,15 @@ def get_repo_folder_path() -> str:
|
|
156
148
|
return repo_path
|
157
149
|
|
158
150
|
|
151
|
+
def clear_folder(folder_path: str) -> None:
|
152
|
+
"""Clear a folder on the system.
|
153
|
+
|
154
|
+
Args:
|
155
|
+
folder_path: The folder to remove.
|
156
|
+
"""
|
157
|
+
subprocess.run(['rmdir', '/s', '/q', folder_path], check=False, shell=True, capture_output=True)
|
158
|
+
|
159
|
+
|
159
160
|
def find_main_file(folder_path: str) -> str:
|
160
161
|
"""Finds the file in the given folder with the name 'main.py'.
|
161
162
|
The search checks subfolders recursively.
|
@@ -179,7 +180,7 @@ def end_job(job: Job) -> None:
|
|
179
180
|
"""Mark a job as ended in the triggers table
|
180
181
|
in the database.
|
181
182
|
If it's a single trigger it's marked as 'Done'
|
182
|
-
else it's marked as 'Idle'.
|
183
|
+
else it's marked as 'Idle' or 'Paused'.
|
183
184
|
|
184
185
|
Args:
|
185
186
|
job: The job whose trigger to mark as ended.
|
@@ -187,11 +188,15 @@ def end_job(job: Job) -> None:
|
|
187
188
|
if isinstance(job.trigger, SingleTrigger):
|
188
189
|
db_util.set_trigger_status(job.trigger.id, TriggerStatus.DONE)
|
189
190
|
|
190
|
-
elif isinstance(job.trigger, ScheduledTrigger):
|
191
|
-
db_util.
|
191
|
+
elif isinstance(job.trigger, (ScheduledTrigger, QueueTrigger)):
|
192
|
+
current_status = db_util.get_trigger(job.trigger.id).process_status
|
193
|
+
if current_status == TriggerStatus.PAUSING:
|
194
|
+
db_util.set_trigger_status(job.trigger.id, TriggerStatus.PAUSED)
|
195
|
+
elif current_status == TriggerStatus.RUNNING:
|
196
|
+
db_util.set_trigger_status(job.trigger.id, TriggerStatus.IDLE)
|
192
197
|
|
193
|
-
|
194
|
-
|
198
|
+
if job.process_folder:
|
199
|
+
clear_folder(job.process_folder)
|
195
200
|
|
196
201
|
|
197
202
|
def fail_job(job: Job) -> None:
|
@@ -205,8 +210,11 @@ def fail_job(job: Job) -> None:
|
|
205
210
|
error_msg = f"An uncaught error ocurred during the process:\n{error}"
|
206
211
|
db_util.create_log(job.trigger.process_name, LogLevel.ERROR, error_msg)
|
207
212
|
|
213
|
+
if job.process_folder:
|
214
|
+
clear_folder(job.process_folder)
|
208
215
|
|
209
|
-
|
216
|
+
|
217
|
+
def run_process(trigger: Trigger) -> Job | None:
|
210
218
|
"""Runs the process of the given trigger with the necessary inputs:
|
211
219
|
Process name
|
212
220
|
Connection string
|
@@ -224,14 +232,15 @@ def run_process(trigger: Trigger) -> subprocess.Popen | None:
|
|
224
232
|
trigger: The trigger whose process to run.
|
225
233
|
|
226
234
|
Returns:
|
227
|
-
|
235
|
+
Job: A Job object referencing the process if succesful.
|
228
236
|
"""
|
229
237
|
process_path = trigger.process_path
|
238
|
+
folder_path = None
|
230
239
|
|
231
240
|
try:
|
232
241
|
if trigger.is_git_repo:
|
233
|
-
|
234
|
-
process_path = find_main_file(
|
242
|
+
folder_path = clone_git_repo(process_path)
|
243
|
+
process_path = find_main_file(folder_path)
|
235
244
|
|
236
245
|
if not os.path.isfile(process_path):
|
237
246
|
raise ValueError(f"The process path didn't point to a file on the system. Path: '{process_path}'")
|
@@ -244,7 +253,9 @@ def run_process(trigger: Trigger) -> subprocess.Popen | None:
|
|
244
253
|
|
245
254
|
command_args = ['python', process_path, trigger.process_name, conn_string, crypto_key, trigger.process_args]
|
246
255
|
|
247
|
-
|
256
|
+
process = subprocess.Popen(command_args, stderr=subprocess.PIPE, text=True) # pylint: disable=consider-using-with
|
257
|
+
|
258
|
+
return Job(process, trigger, folder_path)
|
248
259
|
|
249
260
|
# We actually want to catch any exception here
|
250
261
|
# pylint: disable=broad-exception-caught
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: OpenOrchestrator
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.3.0
|
4
4
|
Summary: A package containing OpenOrchestrator and OpenOrchestrator Scheduler
|
5
5
|
Author-email: ITK Development <itk-rpa@mkb.aarhus.dk>
|
6
6
|
Project-URL: Homepage, https://github.com/itk-dev-rpa/OpenOrchestrator
|
@@ -0,0 +1,39 @@
|
|
1
|
+
OpenOrchestrator/__init__.py,sha256=i4Ir68mBu7rrqhlEE6Qh_uyble599jaEWCEMf8g58tI,179
|
2
|
+
OpenOrchestrator/__main__.py,sha256=Oe3SbWqw3zUhpQpspUaS6mMddXxVvvV-pJbuBU_1GgA,518
|
3
|
+
OpenOrchestrator/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
+
OpenOrchestrator/common/connection_frame.py,sha256=NuRwbEZviOExszhspbETvHcMi7pS4cgOnwQBvAqAZc4,2838
|
5
|
+
OpenOrchestrator/common/crypto_util.py,sha256=VJ7fgxyjrW-bGQmsGVKXLUk98pcZGXG4faHtwxCWDDk,2440
|
6
|
+
OpenOrchestrator/common/datetime_util.py,sha256=4I70tz6WZGZ3xdxodJhdHJID14Y9myJTShFArOWCSpA,534
|
7
|
+
OpenOrchestrator/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
+
OpenOrchestrator/database/constants.py,sha256=ik6lY6IR8EOyKEg-N70X-0U654i3nFb3u-XWhqbUbJU,2404
|
9
|
+
OpenOrchestrator/database/db_util.py,sha256=2M2j47LLj6OymS1J3Zw4q6b7xfgUzEhlcoVQbTpFuiE,28768
|
10
|
+
OpenOrchestrator/database/logs.py,sha256=h2BztjmDRhj8TACYN3LK5c9hIqn5xCs9m_LDUdYYHEk,1623
|
11
|
+
OpenOrchestrator/database/queues.py,sha256=GYrTktg-RiHef-nFAXGAR9Ne0MIiRipxkAXv-CGc0_Q,2292
|
12
|
+
OpenOrchestrator/database/triggers.py,sha256=cO3-dq5-Ib4P_F6p5EgU02XgaRaiIgs6CKqsY0SnDBk,4028
|
13
|
+
OpenOrchestrator/database/truncated_string.py,sha256=v5TvMn3Sof9sG3RzHZx5_wRGBZ5IcJTsiyIO20MjehA,521
|
14
|
+
OpenOrchestrator/orchestrator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
|
+
OpenOrchestrator/orchestrator/application.py,sha256=Sb0rMrlFsvwkXuTLvBLqTUNqFSYjvdrAz3keiQYiUvY,3224
|
16
|
+
OpenOrchestrator/orchestrator/datetime_input.py,sha256=GmQ7kVe_QgOsFF7okJJshjaTQ7P-Epe3lxOJ1u21Z0k,3011
|
17
|
+
OpenOrchestrator/orchestrator/popups/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
|
+
OpenOrchestrator/orchestrator/popups/constant_popup.py,sha256=58Yhyz7dW0I_1Vly0U54NEpwWHhEmwLr34z2nUpQAgs,3435
|
19
|
+
OpenOrchestrator/orchestrator/popups/credential_popup.py,sha256=4uY4mhD-EGOnOCu9GN4JPecoCbKj067kdSs1kMutpv8,3909
|
20
|
+
OpenOrchestrator/orchestrator/popups/generic_popups.py,sha256=wV5isJrwFGUBpDhDpuOzzURwU4NTp4l5mzMDg-KebKw,1061
|
21
|
+
OpenOrchestrator/orchestrator/popups/trigger_popup.py,sha256=adCKg-nnUYq_1WWdJK0SI6mZhekYuUD-0VaaQZMgK1E,10063
|
22
|
+
OpenOrchestrator/orchestrator/tabs/constants_tab.py,sha256=dSnfWbZeCndsd8vzVEyRJFEyEUPnP-RAY2YwCCi7Omw,2485
|
23
|
+
OpenOrchestrator/orchestrator/tabs/logging_tab.py,sha256=kLl2QplqGEkvWwmXlr3wfZEFf-XXqctOeQN8hcpMBQw,3589
|
24
|
+
OpenOrchestrator/orchestrator/tabs/queue_tab.py,sha256=ZjN_rWUZ99alunztxEMMI-OYIYvzMlulwmzuMoO2wlU,5820
|
25
|
+
OpenOrchestrator/orchestrator/tabs/settings_tab.py,sha256=9_B5K__GtUVWFxBD4XQ1KiGOx5a7VxiMz4WjJHoWuVE,852
|
26
|
+
OpenOrchestrator/orchestrator/tabs/trigger_tab.py,sha256=bBIyQSbfL6zBEiA8ZlhzVR3u6AdsAOlp-L5MVW4rz08,4035
|
27
|
+
OpenOrchestrator/orchestrator_connection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
28
|
+
OpenOrchestrator/orchestrator_connection/connection.py,sha256=whw3pbCiTwVoy4bmgdkaxBjPOpsHhGmpz7dHGlsYZjY,8923
|
29
|
+
OpenOrchestrator/scheduler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
30
|
+
OpenOrchestrator/scheduler/application.py,sha256=vjDzW8x0MwS9giFI6UOlhtFqUPHKbsRnrb6-HY8jWOI,1620
|
31
|
+
OpenOrchestrator/scheduler/connection_frame.py,sha256=Ufltek3jyX0Fm20A5JxSGQPuftqtY5BvodfLFOkmm8U,3378
|
32
|
+
OpenOrchestrator/scheduler/run_tab.py,sha256=QP-hoZEJAI5A-T7kV1lFCftpTm_e_R3T8I2Fg9BHxnA,5779
|
33
|
+
OpenOrchestrator/scheduler/runner.py,sha256=5F9eGlo8AsUx8WgeGxCe4k33NBPUzpsqTnVRS7_NaGQ,8348
|
34
|
+
OpenOrchestrator/scheduler/settings_tab.py,sha256=AQxt5HxPn4sLfj-6GwyAQ8ffJ35D0PHLBVoi8W3tu2A,613
|
35
|
+
OpenOrchestrator-1.3.0.dist-info/LICENSE,sha256=4-Kjm-gkbiOLCBYMzsVJZEepdsm2vk8QesNOASvi9mg,1068
|
36
|
+
OpenOrchestrator-1.3.0.dist-info/METADATA,sha256=esgDD3fPQSnTXFRZMfDlg1kq18WpFr5ihCJtjVG-bhY,1938
|
37
|
+
OpenOrchestrator-1.3.0.dist-info/WHEEL,sha256=cpQTJ5IWu9CdaPViMhC9YzF8gZuS5-vlfoFihTBC86A,91
|
38
|
+
OpenOrchestrator-1.3.0.dist-info/top_level.txt,sha256=2btKMQESHuRC_ICbCjHTHH_-us2G7CyeskeaSTTL07Y,17
|
39
|
+
OpenOrchestrator-1.3.0.dist-info/RECORD,,
|
@@ -1,38 +0,0 @@
|
|
1
|
-
OpenOrchestrator/__init__.py,sha256=i4Ir68mBu7rrqhlEE6Qh_uyble599jaEWCEMf8g58tI,179
|
2
|
-
OpenOrchestrator/__main__.py,sha256=Oe3SbWqw3zUhpQpspUaS6mMddXxVvvV-pJbuBU_1GgA,518
|
3
|
-
OpenOrchestrator/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
OpenOrchestrator/common/connection_frame.py,sha256=NuRwbEZviOExszhspbETvHcMi7pS4cgOnwQBvAqAZc4,2838
|
5
|
-
OpenOrchestrator/common/crypto_util.py,sha256=Yo3WvIJnWtBJvlbvkDRu-HaReUUdaW747PcamCJUHzw,2029
|
6
|
-
OpenOrchestrator/common/datetime_util.py,sha256=xNf_LORb67ohR3KfWE_owY15RqAOLJ8DfDPQlMBfsGc,527
|
7
|
-
OpenOrchestrator/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
-
OpenOrchestrator/database/constants.py,sha256=ik6lY6IR8EOyKEg-N70X-0U654i3nFb3u-XWhqbUbJU,2404
|
9
|
-
OpenOrchestrator/database/db_util.py,sha256=wqIK01ODOnmG5dfz5doPLDTVJTKTMuaWibk87fGr7T4,27599
|
10
|
-
OpenOrchestrator/database/logs.py,sha256=h2BztjmDRhj8TACYN3LK5c9hIqn5xCs9m_LDUdYYHEk,1623
|
11
|
-
OpenOrchestrator/database/queues.py,sha256=BFCbUUbo_OOCPNCzRRxDcgoxos_LI__Ypg7t9e3qdUk,2264
|
12
|
-
OpenOrchestrator/database/triggers.py,sha256=Qq1lsSNrOYBKXnKhaD5s71YVmviaTxiD8j8kMBc76sg,4004
|
13
|
-
OpenOrchestrator/orchestrator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
|
-
OpenOrchestrator/orchestrator/application.py,sha256=RgAyc-O79AtrgqOgUoKA5dcusBtIVBxjGpf-jCqAkdE,2804
|
15
|
-
OpenOrchestrator/orchestrator/datetime_input.py,sha256=1EEkmKxYOQSIE6e-anbjACgbo7SL4wyuhqerdiBIg5w,2571
|
16
|
-
OpenOrchestrator/orchestrator/popups/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
|
-
OpenOrchestrator/orchestrator/popups/constant_popup.py,sha256=B6-xfEYRNNkf4dwbPgjGRuDqfKDL5pa6wUoZJ-A2l4g,3367
|
18
|
-
OpenOrchestrator/orchestrator/popups/credential_popup.py,sha256=dIDro77ogBCZEZ8jUXMkenpSBANIfYX-PqVgKvVVbvU,3839
|
19
|
-
OpenOrchestrator/orchestrator/popups/generic_popups.py,sha256=wV5isJrwFGUBpDhDpuOzzURwU4NTp4l5mzMDg-KebKw,1061
|
20
|
-
OpenOrchestrator/orchestrator/popups/trigger_popup.py,sha256=Ir8Hx-DHtvCu3qm5BkG0uSRTObM9G4fpk-VOfeajelA,9684
|
21
|
-
OpenOrchestrator/orchestrator/tabs/constants_tab.py,sha256=JcRIyntrzZBh5Ugkb0QrkBrjI-g9xl2VpbeKhdT6bFM,2478
|
22
|
-
OpenOrchestrator/orchestrator/tabs/logging_tab.py,sha256=7HdXAnAMDHGC6Au8FaQ58M8i88oalBBtBAvGvdiRD_0,3527
|
23
|
-
OpenOrchestrator/orchestrator/tabs/queue_tab.py,sha256=Yl_THeka0ykM-IlbsRpktxiGxZwhKGx0T-XC4S50aQI,5169
|
24
|
-
OpenOrchestrator/orchestrator/tabs/settings_tab.py,sha256=xBMBdgrTxehmbuAk-H3QfEP_zdILzJ3sIgMCii7qlQg,845
|
25
|
-
OpenOrchestrator/orchestrator/tabs/trigger_tab.py,sha256=qIEI3BEuKaknuV7EcH1fNTbGULVR4zAtHdADx5W-26c,4047
|
26
|
-
OpenOrchestrator/orchestrator_connection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
|
-
OpenOrchestrator/orchestrator_connection/connection.py,sha256=DU552EigOu2xzM3SjY4766BXrDEnDC2jC4Jjy0-9OrU,8706
|
28
|
-
OpenOrchestrator/scheduler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
29
|
-
OpenOrchestrator/scheduler/application.py,sha256=W2nkI6q6BCkgzmIMp3P_OHY-uZN5clACCa9rLtZg5-U,1624
|
30
|
-
OpenOrchestrator/scheduler/connection_frame.py,sha256=I1Qooso_iqkNhvztQvFgjlC89Lvfqx0s5B6olATqa98,3369
|
31
|
-
OpenOrchestrator/scheduler/run_tab.py,sha256=huwx5pQ5DhPCXgpDtK7b49BwyxuDdfZ9Dwh_P5kfWBY,5456
|
32
|
-
OpenOrchestrator/scheduler/runner.py,sha256=2oC-WvfFcdyCWnbLCYh-jybA4t6cnayN__mSii7bW3U,7980
|
33
|
-
OpenOrchestrator/scheduler/settings_tab.py,sha256=AQxt5HxPn4sLfj-6GwyAQ8ffJ35D0PHLBVoi8W3tu2A,613
|
34
|
-
OpenOrchestrator-1.1.0.dist-info/LICENSE,sha256=4-Kjm-gkbiOLCBYMzsVJZEepdsm2vk8QesNOASvi9mg,1068
|
35
|
-
OpenOrchestrator-1.1.0.dist-info/METADATA,sha256=6COV_ps1Vx9CEOvt-Nj5D7fCGv7lyf943QPTaRRGQbk,1938
|
36
|
-
OpenOrchestrator-1.1.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
37
|
-
OpenOrchestrator-1.1.0.dist-info/top_level.txt,sha256=2btKMQESHuRC_ICbCjHTHH_-us2G7CyeskeaSTTL07Y,17
|
38
|
-
OpenOrchestrator-1.1.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|