zrb 0.16.0__py3-none-any.whl → 0.17.1__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.
- zrb/__init__.py +2 -0
- zrb/action/runner.py +6 -1
- zrb/builtin/_helper/reccuring_action.py +0 -23
- zrb/builtin/devtool/install/helix/helix.py +1 -4
- zrb/builtin/schedule.py +0 -2
- zrb/builtin/watch_changes.py +0 -2
- zrb/helper/callable.py +4 -1
- zrb/task/any_task.py +1 -0
- zrb/task/base_task/base_task.py +4 -0
- zrb/task/checker.py +3 -3
- zrb/task/cmd_task.py +10 -1
- zrb/task/http_checker.py +10 -1
- zrb/task/looper.py +43 -0
- zrb/task/path_checker.py +10 -1
- zrb/task/path_watcher.py +61 -41
- zrb/task/port_checker.py +10 -1
- zrb/task/resource_maker.py +10 -1
- zrb/task/server.py +8 -9
- zrb/task/time_watcher.py +46 -18
- zrb/task/watcher.py +100 -0
- {zrb-0.16.0.dist-info → zrb-0.17.1.dist-info}/METADATA +1 -1
- {zrb-0.16.0.dist-info → zrb-0.17.1.dist-info}/RECORD +25 -23
- {zrb-0.16.0.dist-info → zrb-0.17.1.dist-info}/LICENSE +0 -0
- {zrb-0.16.0.dist-info → zrb-0.17.1.dist-info}/WHEEL +0 -0
- {zrb-0.16.0.dist-info → zrb-0.17.1.dist-info}/entry_points.txt +0 -0
zrb/__init__.py
CHANGED
@@ -35,6 +35,7 @@ from zrb.task.rsync_task import RsyncTask
|
|
35
35
|
from zrb.task.server import Controller, Server
|
36
36
|
from zrb.task.task import Task
|
37
37
|
from zrb.task.time_watcher import TimeWatcher
|
38
|
+
from zrb.task.watcher import Watcher
|
38
39
|
from zrb.task.wiki_task import create_wiki_tasks
|
39
40
|
from zrb.task_env.env import Env
|
40
41
|
from zrb.task_env.env_file import EnvFile
|
@@ -77,6 +78,7 @@ assert PathChecker
|
|
77
78
|
assert PathWatcher
|
78
79
|
assert Controller
|
79
80
|
assert Server
|
81
|
+
assert Watcher
|
80
82
|
assert TimeWatcher
|
81
83
|
assert ResourceMaker
|
82
84
|
assert FlowTask
|
zrb/action/runner.py
CHANGED
@@ -110,7 +110,12 @@ class Runner:
|
|
110
110
|
|
111
111
|
def __get_wrapped_task_function(self, task: AnyTask) -> Callable[..., Any]:
|
112
112
|
def wrapped_function(*args: Any, **kwargs: Any) -> Any:
|
113
|
-
function = task.to_function(
|
113
|
+
function = task.to_function(
|
114
|
+
env_prefix=self.__env_prefix,
|
115
|
+
raise_error=True,
|
116
|
+
should_clear_xcom=True,
|
117
|
+
should_stop_looper=True,
|
118
|
+
)
|
114
119
|
try:
|
115
120
|
function(*args, **kwargs)
|
116
121
|
except Exception:
|
@@ -1,6 +1,4 @@
|
|
1
|
-
from zrb.helper.typing import Any
|
2
1
|
from zrb.task.cmd_task import CmdTask
|
3
|
-
from zrb.task.decorator import python_task
|
4
2
|
from zrb.task.notifier import Notifier
|
5
3
|
from zrb.task.task import Task
|
6
4
|
from zrb.task_input.str_input import StrInput
|
@@ -8,8 +6,6 @@ from zrb.task_input.str_input import StrInput
|
|
8
6
|
|
9
7
|
def create_recurring_action(
|
10
8
|
notif_title: str,
|
11
|
-
trigger_caption: str,
|
12
|
-
trigger_xcom_key: str,
|
13
9
|
default_message: str = "👋",
|
14
10
|
) -> Task:
|
15
11
|
# define inputs
|
@@ -23,16 +19,11 @@ def create_recurring_action(
|
|
23
19
|
default="",
|
24
20
|
prompt="Command to be executed",
|
25
21
|
)
|
26
|
-
# define tasks
|
27
|
-
show_trigger_info = _create_show_trigger_info(
|
28
|
-
trigger_caption=trigger_caption, trigger_xcom_key=trigger_xcom_key
|
29
|
-
)
|
30
22
|
run_command = CmdTask(
|
31
23
|
name="run-command",
|
32
24
|
icon="⚙️",
|
33
25
|
color="blue",
|
34
26
|
inputs=[command_input],
|
35
|
-
upstreams=[show_trigger_info],
|
36
27
|
should_execute='{{ input.command != "" }}',
|
37
28
|
cmd="{{ input.command }}",
|
38
29
|
)
|
@@ -43,7 +34,6 @@ def create_recurring_action(
|
|
43
34
|
inputs=[message_input],
|
44
35
|
title=notif_title,
|
45
36
|
message="{{ input.message }}",
|
46
|
-
upstreams=[show_trigger_info],
|
47
37
|
should_execute='{{ input.message != "" }}',
|
48
38
|
)
|
49
39
|
# return aggregator task
|
@@ -53,16 +43,3 @@ def create_recurring_action(
|
|
53
43
|
upstreams=[run_command, notify],
|
54
44
|
retry=0,
|
55
45
|
)
|
56
|
-
|
57
|
-
|
58
|
-
def _create_show_trigger_info(trigger_caption: str, trigger_xcom_key: str) -> Task:
|
59
|
-
@python_task(
|
60
|
-
name="show-trigger-info",
|
61
|
-
icon="🔍",
|
62
|
-
color="magenta",
|
63
|
-
)
|
64
|
-
def show_trigger_info(*args: Any, **kwargs: Any):
|
65
|
-
task: Task = kwargs.get("_task")
|
66
|
-
task.print_out(f"{trigger_caption}: {task.get_xcom(trigger_xcom_key)}")
|
67
|
-
|
68
|
-
return show_trigger_info
|
@@ -29,7 +29,6 @@ install_helix = FlowTask(
|
|
29
29
|
run=write_config(
|
30
30
|
template_file=os.path.join(
|
31
31
|
_CURRENT_DIR,
|
32
|
-
"helix",
|
33
32
|
"resource",
|
34
33
|
"themes",
|
35
34
|
"gruvbox_transparent.toml", # noqa
|
@@ -41,9 +40,7 @@ install_helix = FlowTask(
|
|
41
40
|
Task(
|
42
41
|
name="configure-helix",
|
43
42
|
run=write_config(
|
44
|
-
template_file=os.path.join(
|
45
|
-
_CURRENT_DIR, "helix", "resource", "config.toml"
|
46
|
-
),
|
43
|
+
template_file=os.path.join(_CURRENT_DIR, "resource", "config.toml"),
|
47
44
|
config_file="~/.config/helix/config.toml",
|
48
45
|
remove_old_config=True,
|
49
46
|
),
|
zrb/builtin/schedule.py
CHANGED
zrb/builtin/watch_changes.py
CHANGED
zrb/helper/callable.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import asyncio
|
1
2
|
import inspect
|
2
3
|
from typing import Any, Callable
|
3
4
|
|
@@ -10,4 +11,6 @@ logger.debug(colored("Loading zrb.helper.callable", attrs=["dark"]))
|
|
10
11
|
async def run_async(fn: Callable, *args: Any, **kwargs: Any) -> Any:
|
11
12
|
if inspect.iscoroutinefunction(fn):
|
12
13
|
return await fn(*args, **kwargs)
|
13
|
-
|
14
|
+
coro = asyncio.to_thread(fn, *args, **kwargs)
|
15
|
+
task = asyncio.create_task(coro)
|
16
|
+
return await task
|
zrb/task/any_task.py
CHANGED
zrb/task/base_task/base_task.py
CHANGED
@@ -26,6 +26,7 @@ from zrb.task.any_task_event_handler import (
|
|
26
26
|
from zrb.task.base_task.component.base_task_model import BaseTaskModel
|
27
27
|
from zrb.task.base_task.component.renderer import Renderer
|
28
28
|
from zrb.task.base_task.component.trackers import AttemptTracker, FinishTracker
|
29
|
+
from zrb.task.looper import looper
|
29
30
|
from zrb.task.parallel import AnyParallel
|
30
31
|
from zrb.task_env.env import Env, PrivateEnv
|
31
32
|
from zrb.task_env.env_file import EnvFile
|
@@ -164,6 +165,7 @@ class BaseTask(FinishTracker, AttemptTracker, Renderer, BaseTaskModel, AnyTask):
|
|
164
165
|
is_async: bool = False,
|
165
166
|
show_done_info: bool = True,
|
166
167
|
should_clear_xcom: bool = False,
|
168
|
+
should_stop_looper: bool = False,
|
167
169
|
) -> Callable[..., Any]:
|
168
170
|
async def function(*args: Any, **kwargs: Any) -> Any:
|
169
171
|
self.log_info("Copy task")
|
@@ -175,6 +177,8 @@ class BaseTask(FinishTracker, AttemptTracker, Renderer, BaseTaskModel, AnyTask):
|
|
175
177
|
kwargs=kwargs,
|
176
178
|
show_done_info=show_done_info,
|
177
179
|
)
|
180
|
+
if should_stop_looper:
|
181
|
+
looper.stop()
|
178
182
|
if should_clear_xcom:
|
179
183
|
self_cp.clear_xcom()
|
180
184
|
return result
|
zrb/task/checker.py
CHANGED
@@ -83,15 +83,15 @@ class Checker(BaseTask):
|
|
83
83
|
while True:
|
84
84
|
self._should_show_progress = wait_time >= self._progress_interval
|
85
85
|
inspect_result = await self.inspect(*args, **kwargs)
|
86
|
-
if inspect_result == self._expected_result:
|
86
|
+
if inspect_result is not None and inspect_result == self._expected_result:
|
87
87
|
return True
|
88
88
|
if wait_time >= self._progress_interval:
|
89
89
|
wait_time = 0
|
90
90
|
await asyncio.sleep(self._checking_interval)
|
91
91
|
wait_time += self._checking_interval
|
92
92
|
|
93
|
-
async def inspect(self, *args: Any, **kwargs: Any) -> bool:
|
94
|
-
return
|
93
|
+
async def inspect(self, *args: Any, **kwargs: Any) -> Optional[bool]:
|
94
|
+
return None
|
95
95
|
|
96
96
|
def show_progress(self, message: str):
|
97
97
|
if self._should_show_progress:
|
zrb/task/cmd_task.py
CHANGED
@@ -199,8 +199,17 @@ class CmdTask(BaseTask):
|
|
199
199
|
raise_error: bool = True,
|
200
200
|
is_async: bool = False,
|
201
201
|
show_done_info: bool = True,
|
202
|
+
should_clear_xcom: bool = False,
|
203
|
+
should_stop_looper: bool = False,
|
202
204
|
) -> Callable[..., CmdResult]:
|
203
|
-
return super().to_function(
|
205
|
+
return super().to_function(
|
206
|
+
env_prefix=env_prefix,
|
207
|
+
raise_error=raise_error,
|
208
|
+
is_async=is_async,
|
209
|
+
show_done_info=show_done_info,
|
210
|
+
should_clear_xcom=should_clear_xcom,
|
211
|
+
should_stop_looper=should_stop_looper,
|
212
|
+
)
|
204
213
|
|
205
214
|
def print_result(self, result: CmdResult):
|
206
215
|
if not self._should_print_cmd_result or result.output == "":
|
zrb/task/http_checker.py
CHANGED
@@ -133,8 +133,17 @@ class HTTPChecker(Checker):
|
|
133
133
|
raise_error: bool = True,
|
134
134
|
is_async: bool = False,
|
135
135
|
show_done_info: bool = True,
|
136
|
+
should_clear_xcom: bool = False,
|
137
|
+
should_stop_looper: bool = False,
|
136
138
|
) -> Callable[..., bool]:
|
137
|
-
return super().to_function(
|
139
|
+
return super().to_function(
|
140
|
+
env_prefix=env_prefix,
|
141
|
+
raise_error=raise_error,
|
142
|
+
is_async=is_async,
|
143
|
+
show_done_info=show_done_info,
|
144
|
+
should_clear_xcom=should_clear_xcom,
|
145
|
+
should_stop_looper=should_stop_looper,
|
146
|
+
)
|
138
147
|
|
139
148
|
async def run(self, *args: Any, **kwargs: Any) -> bool:
|
140
149
|
self._config = HttpConnectionConfig(
|
zrb/task/looper.py
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
from zrb.helper.accessories.color import colored
|
2
|
+
from zrb.helper.callable import run_async
|
3
|
+
from zrb.helper.log import logger
|
4
|
+
from zrb.helper.typing import Callable, List, Mapping, Optional
|
5
|
+
|
6
|
+
logger.debug(colored("Loading zrb.task.looper", attrs=["dark"]))
|
7
|
+
|
8
|
+
|
9
|
+
class Looper:
|
10
|
+
def __init__(self):
|
11
|
+
self._queue: Mapping[str, List[Optional[bool]]] = {}
|
12
|
+
self._should_stop = False
|
13
|
+
|
14
|
+
async def pop(self, identifier: str) -> Optional[bool]:
|
15
|
+
if identifier not in self._queue or len(self._queue[identifier]) == 0:
|
16
|
+
return None
|
17
|
+
return self._queue[identifier].pop(0)
|
18
|
+
|
19
|
+
def stop(self):
|
20
|
+
self._should_stop = True
|
21
|
+
|
22
|
+
def is_registered(self, identifier: str) -> bool:
|
23
|
+
return identifier in self._queue
|
24
|
+
|
25
|
+
async def register(self, identifier: str, function: Callable[..., Optional[bool]]):
|
26
|
+
if identifier in self._queue:
|
27
|
+
return
|
28
|
+
self._queue[identifier] = []
|
29
|
+
while not self._should_stop:
|
30
|
+
try:
|
31
|
+
result = await run_async(function)
|
32
|
+
if result is not None:
|
33
|
+
if not result:
|
34
|
+
continue
|
35
|
+
while len(self._queue[identifier]) > 1000:
|
36
|
+
self._queue[identifier].pop(0)
|
37
|
+
self._queue[identifier].append(result)
|
38
|
+
except KeyboardInterrupt:
|
39
|
+
self.stop()
|
40
|
+
break
|
41
|
+
|
42
|
+
|
43
|
+
looper = Looper()
|
zrb/task/path_checker.py
CHANGED
@@ -99,8 +99,17 @@ class PathChecker(Checker):
|
|
99
99
|
raise_error: bool = True,
|
100
100
|
is_async: bool = False,
|
101
101
|
show_done_info: bool = True,
|
102
|
+
should_clear_xcom: bool = False,
|
103
|
+
should_stop_looper: bool = False,
|
102
104
|
) -> Callable[..., bool]:
|
103
|
-
return super().to_function(
|
105
|
+
return super().to_function(
|
106
|
+
env_prefix=env_prefix,
|
107
|
+
raise_error=raise_error,
|
108
|
+
is_async=is_async,
|
109
|
+
show_done_info=show_done_info,
|
110
|
+
should_clear_xcom=should_clear_xcom,
|
111
|
+
should_stop_looper=should_stop_looper,
|
112
|
+
)
|
104
113
|
|
105
114
|
async def run(self, *args: Any, **kwargs: Any) -> bool:
|
106
115
|
self._rendered_path = self.render_str(self._path)
|
zrb/task/path_watcher.py
CHANGED
@@ -25,7 +25,7 @@ from zrb.task.any_task_event_handler import (
|
|
25
25
|
OnTriggered,
|
26
26
|
OnWaiting,
|
27
27
|
)
|
28
|
-
from zrb.task.
|
28
|
+
from zrb.task.watcher import Watcher
|
29
29
|
from zrb.task_env.env import Env
|
30
30
|
from zrb.task_env.env_file import EnvFile
|
31
31
|
from zrb.task_group.group import Group
|
@@ -37,7 +37,7 @@ TPathWatcher = TypeVar("TPathWatcher", bound="PathWatcher")
|
|
37
37
|
|
38
38
|
|
39
39
|
@typechecked
|
40
|
-
class PathWatcher(
|
40
|
+
class PathWatcher(Watcher):
|
41
41
|
"""
|
42
42
|
PathWatcher will wait for any changes specified on path.
|
43
43
|
|
@@ -49,6 +49,8 @@ class PathWatcher(Checker):
|
|
49
49
|
- <task-name>.deleted-file
|
50
50
|
"""
|
51
51
|
|
52
|
+
__init_times: Mapping[str, Mapping[str, float]] = {}
|
53
|
+
|
52
54
|
def __init__(
|
53
55
|
self,
|
54
56
|
name: str = "watch-path",
|
@@ -77,7 +79,7 @@ class PathWatcher(Checker):
|
|
77
79
|
watch_deleted_files: bool = True,
|
78
80
|
should_execute: Union[bool, JinjaTemplate, Callable[..., bool]] = True,
|
79
81
|
):
|
80
|
-
|
82
|
+
Watcher.__init__(
|
81
83
|
self,
|
82
84
|
name=name,
|
83
85
|
group=group,
|
@@ -107,7 +109,6 @@ class PathWatcher(Checker):
|
|
107
109
|
self._watch_deleted_files = watch_deleted_files
|
108
110
|
self._rendered_path: str = ""
|
109
111
|
self._rendered_ignored_paths: List[str] = []
|
110
|
-
self._init_times: Mapping[str, float] = {}
|
111
112
|
|
112
113
|
def copy(self) -> TPathWatcher:
|
113
114
|
return super().copy()
|
@@ -118,8 +119,17 @@ class PathWatcher(Checker):
|
|
118
119
|
raise_error: bool = True,
|
119
120
|
is_async: bool = False,
|
120
121
|
show_done_info: bool = True,
|
122
|
+
should_clear_xcom: bool = False,
|
123
|
+
should_stop_looper: bool = False,
|
121
124
|
) -> Callable[..., bool]:
|
122
|
-
return super().to_function(
|
125
|
+
return super().to_function(
|
126
|
+
env_prefix=env_prefix,
|
127
|
+
raise_error=raise_error,
|
128
|
+
is_async=is_async,
|
129
|
+
show_done_info=show_done_info,
|
130
|
+
should_clear_xcom=should_clear_xcom,
|
131
|
+
should_stop_looper=should_stop_looper,
|
132
|
+
)
|
123
133
|
|
124
134
|
async def run(self, *args: Any, **kwargs: Any) -> bool:
|
125
135
|
self._rendered_path = self.render_str(self._path)
|
@@ -128,7 +138,9 @@ class PathWatcher(Checker):
|
|
128
138
|
for ignored_path in self._get_rendered_ignored_paths()
|
129
139
|
if ignored_path != ""
|
130
140
|
]
|
131
|
-
|
141
|
+
identifier = self.get_identifier()
|
142
|
+
if identifier not in self.__init_times:
|
143
|
+
self.__init_times[identifier] = self._get_mod_times()
|
132
144
|
return await super().run(*args, **kwargs)
|
133
145
|
|
134
146
|
def _get_rendered_ignored_paths(self) -> List[str]:
|
@@ -136,41 +148,49 @@ class PathWatcher(Checker):
|
|
136
148
|
return [self.render_str(self._ignored_path)]
|
137
149
|
return [self.render_str(ignored_path) for ignored_path in self._ignored_path]
|
138
150
|
|
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
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
151
|
+
def create_loop_inspector(self) -> Callable[..., Optional[bool]]:
|
152
|
+
def loop_inspect() -> bool:
|
153
|
+
label = f"Watching {self._rendered_path}"
|
154
|
+
identifier = self.get_identifier()
|
155
|
+
try:
|
156
|
+
init_times = self.__init_times[identifier]
|
157
|
+
mod_times = self._get_mod_times()
|
158
|
+
except Exception as e:
|
159
|
+
self.show_progress(f"{label} Cannot inspect")
|
160
|
+
raise e
|
161
|
+
# watch changes
|
162
|
+
if self._watch_new_files:
|
163
|
+
new_files = mod_times.keys() - init_times.keys()
|
164
|
+
for file in new_files:
|
165
|
+
self.print_out_dark(f"{label} [+] New file detected: {file}")
|
166
|
+
self.set_task_xcom("new-file", file)
|
167
|
+
self.set_task_xcom("file", file)
|
168
|
+
self.__init_times[identifier] = self._get_mod_times()
|
169
|
+
return True
|
170
|
+
if self._watch_deleted_files:
|
171
|
+
deleted_files = init_times.keys() - mod_times.keys()
|
172
|
+
for file in deleted_files:
|
173
|
+
self.print_out_dark(f"{label} [-] File deleted: {file}")
|
174
|
+
self.set_task_xcom("deleted-file", file)
|
175
|
+
self.set_task_xcom("file", file)
|
176
|
+
self.__init_times[identifier] = self._get_mod_times()
|
177
|
+
return True
|
178
|
+
if self._watch_modified_files:
|
179
|
+
modified_files = {
|
180
|
+
file
|
181
|
+
for file, mod_time in mod_times.items()
|
182
|
+
if file in mod_times and init_times[file] != mod_time
|
183
|
+
}
|
184
|
+
for file in modified_files:
|
185
|
+
self.print_out_dark(f"{label} [/] File modified: {file}")
|
186
|
+
self.set_task_xcom("modified-file", file)
|
187
|
+
self.set_task_xcom("file", file)
|
188
|
+
self.__init_times[identifier] = self._get_mod_times()
|
189
|
+
return True
|
190
|
+
self.show_progress(f"{label} (Nothing changed)")
|
191
|
+
return False
|
192
|
+
|
193
|
+
return loop_inspect
|
174
194
|
|
175
195
|
def _get_mod_times(self) -> Mapping[str, float]:
|
176
196
|
matches = get_file_names(
|
zrb/task/port_checker.py
CHANGED
@@ -109,8 +109,17 @@ class PortChecker(Checker):
|
|
109
109
|
raise_error: bool = True,
|
110
110
|
is_async: bool = False,
|
111
111
|
show_done_info: bool = True,
|
112
|
+
should_clear_xcom: bool = False,
|
113
|
+
should_stop_looper: bool = False,
|
112
114
|
) -> Callable[..., bool]:
|
113
|
-
return super().to_function(
|
115
|
+
return super().to_function(
|
116
|
+
env_prefix=env_prefix,
|
117
|
+
raise_error=raise_error,
|
118
|
+
is_async=is_async,
|
119
|
+
show_done_info=show_done_info,
|
120
|
+
should_clear_xcom=should_clear_xcom,
|
121
|
+
should_stop_looper=should_stop_looper,
|
122
|
+
)
|
114
123
|
|
115
124
|
async def run(self, *args: Any, **kwargs: Any) -> bool:
|
116
125
|
self._config = PortConfig(
|
zrb/task/resource_maker.py
CHANGED
@@ -144,8 +144,17 @@ class ResourceMaker(BaseTask):
|
|
144
144
|
raise_error: bool = True,
|
145
145
|
is_async: bool = False,
|
146
146
|
show_done_info: bool = True,
|
147
|
+
should_clear_xcom: bool = False,
|
148
|
+
should_stop_looper: bool = False,
|
147
149
|
) -> Callable[..., bool]:
|
148
|
-
return super().to_function(
|
150
|
+
return super().to_function(
|
151
|
+
env_prefix=env_prefix,
|
152
|
+
raise_error=raise_error,
|
153
|
+
is_async=is_async,
|
154
|
+
show_done_info=show_done_info,
|
155
|
+
should_clear_xcom=should_clear_xcom,
|
156
|
+
should_stop_looper=should_stop_looper,
|
157
|
+
)
|
149
158
|
|
150
159
|
async def run(self, *args: Any, **kwargs: Any) -> bool:
|
151
160
|
# render parameters
|
zrb/task/server.py
CHANGED
@@ -86,34 +86,33 @@ class Controller:
|
|
86
86
|
task = self._get_task()
|
87
87
|
|
88
88
|
async def fn() -> Any:
|
89
|
+
task.print_out_dark(f"Starting controller: {self._name}")
|
89
90
|
task_fn = task.to_function(is_async=True)
|
90
91
|
return await task_fn(*self._args, **self._kwargs)
|
91
92
|
|
92
93
|
return fn
|
93
94
|
|
94
95
|
def _get_task(self) -> AnyTask:
|
95
|
-
|
96
|
-
actions
|
97
|
-
|
96
|
+
actions = [action.copy() for action in self._actions]
|
97
|
+
actions.insert(0, self._get_remonitor_task())
|
98
|
+
triggers = [trigger.copy() for trigger in self._triggers]
|
98
99
|
task: AnyTask = FlowTask(
|
99
|
-
name=
|
100
|
+
name=to_kebab_case(self._name),
|
100
101
|
inputs=self._inputs,
|
101
102
|
envs=self._envs,
|
102
103
|
env_files=self._env_files,
|
103
|
-
steps=[
|
104
|
+
steps=[triggers, actions],
|
104
105
|
)
|
105
106
|
return task
|
106
107
|
|
107
|
-
def
|
108
|
-
kebab_name = to_kebab_case(self._name)
|
109
|
-
|
108
|
+
def _get_remonitor_task(self) -> AnyTask:
|
110
109
|
async def on_ready(task: AnyTask):
|
111
110
|
task = self._get_task()
|
112
111
|
fn = task.to_function(is_async=True)
|
113
112
|
await fn()
|
114
113
|
|
115
114
|
return BaseTask(
|
116
|
-
name=f"{
|
115
|
+
name=f"monitor-{to_kebab_case(self._name)}",
|
117
116
|
on_ready=on_ready,
|
118
117
|
)
|
119
118
|
|
zrb/task/time_watcher.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import asyncio
|
1
2
|
import datetime
|
2
3
|
|
3
4
|
import croniter
|
@@ -10,6 +11,7 @@ from zrb.helper.typing import (
|
|
10
11
|
Callable,
|
11
12
|
Iterable,
|
12
13
|
JinjaTemplate,
|
14
|
+
Mapping,
|
13
15
|
Optional,
|
14
16
|
TypeVar,
|
15
17
|
Union,
|
@@ -24,7 +26,7 @@ from zrb.task.any_task_event_handler import (
|
|
24
26
|
OnTriggered,
|
25
27
|
OnWaiting,
|
26
28
|
)
|
27
|
-
from zrb.task.
|
29
|
+
from zrb.task.watcher import Watcher
|
28
30
|
from zrb.task_env.env import Env
|
29
31
|
from zrb.task_env.env_file import EnvFile
|
30
32
|
from zrb.task_group.group import Group
|
@@ -36,7 +38,7 @@ TTimeWatcher = TypeVar("TTimeWatcher", bound="TimeWatcher")
|
|
36
38
|
|
37
39
|
|
38
40
|
@typechecked
|
39
|
-
class TimeWatcher(
|
41
|
+
class TimeWatcher(Watcher):
|
40
42
|
"""
|
41
43
|
TimeWatcher will wait for any changes specified on path.
|
42
44
|
|
@@ -44,6 +46,8 @@ class TimeWatcher(Checker):
|
|
44
46
|
and <task-name>.scheduled-time xcom will be set.
|
45
47
|
"""
|
46
48
|
|
49
|
+
__scheduled_times: Mapping[str, Mapping[str, datetime.datetime]] = {}
|
50
|
+
|
47
51
|
def __init__(
|
48
52
|
self,
|
49
53
|
name: str = "watch-path",
|
@@ -68,7 +72,7 @@ class TimeWatcher(Checker):
|
|
68
72
|
progress_interval: Union[int, float] = 30,
|
69
73
|
should_execute: Union[bool, JinjaTemplate, Callable[..., bool]] = True,
|
70
74
|
):
|
71
|
-
|
75
|
+
Watcher.__init__(
|
72
76
|
self,
|
73
77
|
name=name,
|
74
78
|
group=group,
|
@@ -92,7 +96,6 @@ class TimeWatcher(Checker):
|
|
92
96
|
should_execute=should_execute,
|
93
97
|
)
|
94
98
|
self._schedule = schedule
|
95
|
-
self._scheduled_time: Optional[datetime.datetime] = None
|
96
99
|
self._rendered_schedule: str = ""
|
97
100
|
|
98
101
|
def copy(self) -> TTimeWatcher:
|
@@ -104,23 +107,48 @@ class TimeWatcher(Checker):
|
|
104
107
|
raise_error: bool = True,
|
105
108
|
is_async: bool = False,
|
106
109
|
show_done_info: bool = True,
|
110
|
+
should_clear_xcom: bool = False,
|
111
|
+
should_stop_looper: bool = False,
|
107
112
|
) -> Callable[..., bool]:
|
108
|
-
return super().to_function(
|
113
|
+
return super().to_function(
|
114
|
+
env_prefix=env_prefix,
|
115
|
+
raise_error=raise_error,
|
116
|
+
is_async=is_async,
|
117
|
+
show_done_info=show_done_info,
|
118
|
+
should_clear_xcom=should_clear_xcom,
|
119
|
+
should_stop_looper=should_stop_looper,
|
120
|
+
)
|
109
121
|
|
110
122
|
async def run(self, *args: Any, **kwargs: Any) -> bool:
|
111
123
|
self._rendered_schedule = self.render_str(self._schedule)
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
self._scheduled_time = cron.get_next(datetime.datetime)
|
116
|
-
self.set_task_xcom(key="scheduled-time", value=self._scheduled_time)
|
124
|
+
identifier = self.get_identifier()
|
125
|
+
if identifier not in self.__scheduled_times:
|
126
|
+
self.__scheduled_times[identifier] = self._get_next_schedule_time()
|
117
127
|
return await super().run(*args, **kwargs)
|
118
128
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
129
|
+
def create_loop_inspector(self) -> Callable[..., Optional[bool]]:
|
130
|
+
async def loop_inspect() -> bool:
|
131
|
+
await asyncio.sleep(0.1)
|
132
|
+
label = f"Watching {self._rendered_schedule}"
|
133
|
+
identifier = self.get_identifier()
|
134
|
+
scheduled_time = self.__scheduled_times[identifier]
|
135
|
+
self.set_task_xcom(key="scheduled-time", value=scheduled_time)
|
136
|
+
now = datetime.datetime.now()
|
137
|
+
if now > scheduled_time:
|
138
|
+
self.print_out_dark(f"{label} (Meet {scheduled_time})")
|
139
|
+
self.__scheduled_times[identifier] = self._get_next_schedule_time()
|
140
|
+
return True
|
141
|
+
self.show_progress(f"{label} (Waiting for {scheduled_time})")
|
142
|
+
return False
|
143
|
+
|
144
|
+
return loop_inspect
|
145
|
+
|
146
|
+
def _get_next_schedule_time(self) -> datetime.datetime:
|
147
|
+
cron = self._get_cron()
|
148
|
+
return cron.get_next(datetime.datetime)
|
149
|
+
|
150
|
+
def _get_cron(self) -> Any:
|
151
|
+
margin = datetime.timedelta(seconds=0.001)
|
152
|
+
slightly_before_now = datetime.datetime.now() - margin
|
153
|
+
cron = croniter.croniter(self._rendered_schedule, slightly_before_now)
|
154
|
+
return cron
|
zrb/task/watcher.py
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
import asyncio
|
2
|
+
|
3
|
+
from zrb.helper.accessories.color import colored
|
4
|
+
from zrb.helper.accessories.name import get_random_name
|
5
|
+
from zrb.helper.log import logger
|
6
|
+
from zrb.helper.typecheck import typechecked
|
7
|
+
from zrb.helper.typing import Any, Callable, Iterable, Optional, Union
|
8
|
+
from zrb.task.any_task import AnyTask
|
9
|
+
from zrb.task.any_task_event_handler import (
|
10
|
+
OnFailed,
|
11
|
+
OnReady,
|
12
|
+
OnRetry,
|
13
|
+
OnSkipped,
|
14
|
+
OnStarted,
|
15
|
+
OnTriggered,
|
16
|
+
OnWaiting,
|
17
|
+
)
|
18
|
+
from zrb.task.checker import Checker
|
19
|
+
from zrb.task.looper import looper
|
20
|
+
from zrb.task_env.env import Env
|
21
|
+
from zrb.task_env.env_file import EnvFile
|
22
|
+
from zrb.task_group.group import Group
|
23
|
+
from zrb.task_input.any_input import AnyInput
|
24
|
+
|
25
|
+
logger.debug(colored("Loading zrb.task.watcher", attrs=["dark"]))
|
26
|
+
|
27
|
+
|
28
|
+
@typechecked
|
29
|
+
class Watcher(Checker):
|
30
|
+
__looper = looper
|
31
|
+
|
32
|
+
def __init__(
|
33
|
+
self,
|
34
|
+
name: str = "watch",
|
35
|
+
group: Optional[Group] = None,
|
36
|
+
inputs: Iterable[AnyInput] = [],
|
37
|
+
envs: Iterable[Env] = [],
|
38
|
+
env_files: Iterable[EnvFile] = [],
|
39
|
+
icon: Optional[str] = None,
|
40
|
+
color: Optional[str] = None,
|
41
|
+
description: str = "",
|
42
|
+
upstreams: Iterable[AnyTask] = [],
|
43
|
+
fallbacks: Iterable[AnyTask] = [],
|
44
|
+
on_triggered: Optional[OnTriggered] = None,
|
45
|
+
on_waiting: Optional[OnWaiting] = None,
|
46
|
+
on_skipped: Optional[OnSkipped] = None,
|
47
|
+
on_started: Optional[OnStarted] = None,
|
48
|
+
on_ready: Optional[OnReady] = None,
|
49
|
+
on_retry: Optional[OnRetry] = None,
|
50
|
+
on_failed: Optional[OnFailed] = None,
|
51
|
+
checking_interval: Union[int, float] = 0.1,
|
52
|
+
progress_interval: Union[int, float] = 30,
|
53
|
+
expected_result: bool = True,
|
54
|
+
should_execute: Union[bool, str, Callable[..., bool]] = True,
|
55
|
+
):
|
56
|
+
Checker.__init__(
|
57
|
+
self,
|
58
|
+
name=name,
|
59
|
+
group=group,
|
60
|
+
inputs=inputs,
|
61
|
+
envs=envs,
|
62
|
+
env_files=env_files,
|
63
|
+
icon=icon,
|
64
|
+
color=color,
|
65
|
+
description=description,
|
66
|
+
upstreams=upstreams,
|
67
|
+
fallbacks=fallbacks,
|
68
|
+
on_triggered=on_triggered,
|
69
|
+
on_waiting=on_waiting,
|
70
|
+
on_skipped=on_skipped,
|
71
|
+
on_started=on_started,
|
72
|
+
on_ready=on_ready,
|
73
|
+
on_retry=on_retry,
|
74
|
+
on_failed=on_failed,
|
75
|
+
checking_interval=checking_interval,
|
76
|
+
should_execute=should_execute,
|
77
|
+
progress_interval=progress_interval,
|
78
|
+
expected_result=expected_result,
|
79
|
+
)
|
80
|
+
self._identifier = get_random_name()
|
81
|
+
|
82
|
+
def get_identifier(self):
|
83
|
+
return self._identifier
|
84
|
+
|
85
|
+
async def run(self, *args: Any, **kwargs: Any) -> bool:
|
86
|
+
if not looper.is_registered(self._identifier):
|
87
|
+
asyncio.create_task(
|
88
|
+
looper.register(self._identifier, self.create_loop_inspector())
|
89
|
+
)
|
90
|
+
return await super().run(*args, **kwargs)
|
91
|
+
|
92
|
+
async def inspect(self, *args, **kwargs: Any) -> Optional[bool]:
|
93
|
+
result = await looper.pop(self._identifier)
|
94
|
+
return result
|
95
|
+
|
96
|
+
def create_loop_inspector(self) -> Callable[..., Optional[bool]]:
|
97
|
+
def loop_inspect() -> Optional[bool]:
|
98
|
+
return None
|
99
|
+
|
100
|
+
return loop_inspect
|
@@ -1,11 +1,11 @@
|
|
1
|
-
zrb/__init__.py,sha256=
|
1
|
+
zrb/__init__.py,sha256=KH6bpJxEldzDMn-39IdUxEs9Ir5qUeqW_iC56iQKPMk,2814
|
2
2
|
zrb/__main__.py,sha256=-_k0XOahDF-06n41Uly-oUMkZ8XDSxO-WUUImWz6GiA,171
|
3
3
|
zrb/action/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
zrb/action/runner.py,sha256=
|
4
|
+
zrb/action/runner.py,sha256=oizUiLa4wa4CjXppbw_YUFlkAUSwapfoQ1YAo9TEY30,5079
|
5
5
|
zrb/advertisement.py,sha256=eqdQvr2IDS2ZTiOhg2R12wq0A5tnaoPATaH5nd1xfC8,699
|
6
6
|
zrb/builtin/__init__.py,sha256=QrJY08zBC55xkJa_kNhGAWEnhHwATZbNGxEEXEn-Ywk,3247
|
7
7
|
zrb/builtin/_helper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
-
zrb/builtin/_helper/reccuring_action.py,sha256=
|
8
|
+
zrb/builtin/_helper/reccuring_action.py,sha256=3YeMtGM13iwSV8kMJ64wuGDwAgKB7KD2nuaqKXuMRPw,1186
|
9
9
|
zrb/builtin/base64/__init__.py,sha256=Dl5eG_I7xvigiEp4mURXoF8J78Y2UixaDmI1O74bsrY,218
|
10
10
|
zrb/builtin/base64/_group.py,sha256=4aDDjvtoZUpXBst4TPDxsJvXhlefvQjUaSOteyJP83w,109
|
11
11
|
zrb/builtin/base64/_input.py,sha256=dQA-svhwA7qrtGRpe2jYjVuwvQxxyq9MKIR-e1ay8ks,128
|
@@ -27,7 +27,7 @@ zrb/builtin/devtool/install/gvm/download.sh,sha256=Z4IDsTS4gOeWiezhI-TrRv2nFgMsl
|
|
27
27
|
zrb/builtin/devtool/install/gvm/finalize.sh,sha256=Han_IDq5XwxNsxyAVc99PoW3fdjTnYtv6rsr5KRhtEE,538
|
28
28
|
zrb/builtin/devtool/install/gvm/gvm.py,sha256=jD5HzHA4eXHwFeSzKUVAp8PMXiibPNF_Rwq01NaEZIo,1693
|
29
29
|
zrb/builtin/devtool/install/gvm/resource/config.sh,sha256=M_r6XjtoYZjx8rJaT3FIwVl3HUd7lJF5_KqUSEJQeo4,253
|
30
|
-
zrb/builtin/devtool/install/helix/helix.py,sha256=
|
30
|
+
zrb/builtin/devtool/install/helix/helix.py,sha256=XQzTbokyAXy9-UMBPp8woIOPNFF0vxWcrg0fr4mYj4E,2010
|
31
31
|
zrb/builtin/devtool/install/helix/install-language-server.sh,sha256=ZkV_ARwhTnLjjbAhJe8Pvp1hyRYVn176DYwg7ObkQ1w,1040
|
32
32
|
zrb/builtin/devtool/install/helix/install.sh,sha256=Dsg65aEnpU8YnlvHwiKoxRpj8Jo8j3mejB4bTi2eeKo,1375
|
33
33
|
zrb/builtin/devtool/install/helix/resource/config.toml,sha256=35IwzDzXGfSnUH3O3nyd2IzDVOWyKqj6Kb3QuympXCE,305
|
@@ -1280,7 +1280,7 @@ zrb/builtin/project/create/template/src/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeu
|
|
1280
1280
|
zrb/builtin/project/create/template/template.env,sha256=Y_11yIi7fA5aIOHxrcexFXNxz1UqXaEiIgqUHBazy0w,102
|
1281
1281
|
zrb/builtin/project/create/template/zrb_init.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1282
1282
|
zrb/builtin/say.py,sha256=KHuzgwitmWQy5g7N11qqs9iV-66vvAl0Uyke9hdc-Eg,3859
|
1283
|
-
zrb/builtin/schedule.py,sha256=
|
1283
|
+
zrb/builtin/schedule.py,sha256=yzprSE8oPgtXssK1sW3YpaqhTHcECTQWnuuIweEqBNw,1048
|
1284
1284
|
zrb/builtin/ubuntu/__init__.py,sha256=79JyTzx6pyhtEa7hrsUTNaAQ7xlrgDX1KU74OG8mhic,486
|
1285
1285
|
zrb/builtin/ubuntu/_group.py,sha256=6VhCi-wZRuwvmELlvqvVSOfYLnibP8SQIT2GpaDPtOA,115
|
1286
1286
|
zrb/builtin/ubuntu/install/__init__.py,sha256=AoGq7pPn8FWoRXrEwiaX1ZBBQTzFpqIjpwIx4aajpa8,472
|
@@ -1292,7 +1292,7 @@ zrb/builtin/ubuntu/install/toys.py,sha256=VlWb8_aHW1kRK6vpjpAveNByc1FlsMPLFXl1X9
|
|
1292
1292
|
zrb/builtin/ubuntu/update.py,sha256=m3UREE6DhwlbdkQpuug2sfEM6fBLZn0ZGClt_EOsZ_I,372
|
1293
1293
|
zrb/builtin/update.py,sha256=89i_fPUlL27IXczLI7Lr7k4STMpnxyw2je8daCKUTQo,225
|
1294
1294
|
zrb/builtin/version.py,sha256=vjbmSeOSEjT0SgdeQHGslwFCQMukwVZkOOkusZGZNcU,394
|
1295
|
-
zrb/builtin/watch_changes.py,sha256=
|
1295
|
+
zrb/builtin/watch_changes.py,sha256=Vr__e_T31nnbefcPftvyn78dT3-UXqNRpH0KO-COeKQ,1220
|
1296
1296
|
zrb/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1297
1297
|
zrb/config/config.py,sha256=6uDxOLmHHstLCosj2miBVxlO9dMTIoXYedqaff8EVBU,1567
|
1298
1298
|
zrb/helper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -1302,7 +1302,7 @@ zrb/helper/accessories/icon.py,sha256=uKm3w5G1fV454MUhz_CZMy48AD99kBV9j2zRlJWzB1
|
|
1302
1302
|
zrb/helper/accessories/name.py,sha256=e1uvU3MzuvDb5j6YIWBA048y4qeM-LfrxRKWlMehliE,1638
|
1303
1303
|
zrb/helper/accessories/untyped_color.py,sha256=4wRbHSClbCzPRWtW-Cy2agOMozANVi7u4p8lMXMSuJg,194
|
1304
1304
|
zrb/helper/advertisement.py,sha256=-J9xVxf6AmcB0Uy-D4tFl-IRIZsdKTy07wIoE59jMnc,896
|
1305
|
-
zrb/helper/callable.py,sha256=
|
1305
|
+
zrb/helper/callable.py,sha256=G_seq9gAricPjzlUdZs2rswQEt8sfnKQo1EFKi9JYyQ,478
|
1306
1306
|
zrb/helper/cli.py,sha256=Ux0zkKYahrM_aVQkkuPxfOuMNmTrCIWxdOIgNJvu5OY,2177
|
1307
1307
|
zrb/helper/codemod/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1308
1308
|
zrb/helper/codemod/add_argument_to_function.py,sha256=Xh5Tlb4iO3cv4dRR12ms9kf0j-atVSnCh88TuqCof8I,1435
|
@@ -1355,35 +1355,37 @@ zrb/shell-scripts/notify.ps1,sha256=6_xPoIwuxARpYljcjVV-iRJS3gJqGfx-B6kj719cJ9o,
|
|
1355
1355
|
zrb/shell-scripts/rsync-util.sh,sha256=QzdhSBvUNMxB4U2B4m0Dxg9czGckRjB7Vk4A1ObG0-k,353
|
1356
1356
|
zrb/shell-scripts/ssh-util.sh,sha256=9lXDzw6oO8HuA4vdbfps_uQMMwKyNYX9fZkZgpK52g8,401
|
1357
1357
|
zrb/task/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1358
|
-
zrb/task/any_task.py,sha256=
|
1358
|
+
zrb/task/any_task.py,sha256=1jc0qVZs1yIMfGuInktgH7EqDbI8IqmsaSlH5VijThc,39435
|
1359
1359
|
zrb/task/any_task_event_handler.py,sha256=AjTC6lIcprutRusNBGl83EifQe4TbZzxdlVIR4ndWN4,524
|
1360
1360
|
zrb/task/base_remote_cmd_task.py,sha256=tZi3jODMXfTkDAmWiFR2YdA-b4-TDTP1uLtO0ulmM34,10101
|
1361
1361
|
zrb/task/base_task/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1362
|
-
zrb/task/base_task/base_task.py,sha256=
|
1362
|
+
zrb/task/base_task/base_task.py,sha256=qnQSG-nAppmm38JY11wC03-0mZSOjjk-XJ62leco2rw,20354
|
1363
1363
|
zrb/task/base_task/component/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1364
1364
|
zrb/task/base_task/component/base_task_model.py,sha256=YlEuvYSzlrK83Kds07bu2drKSw3rKyl7qIR1qwIPNZk,10376
|
1365
1365
|
zrb/task/base_task/component/common_task_model.py,sha256=JoAAf8EvuPx31fCK_TBxX_TBeHZrZyFDjLeK8ts0w3A,12285
|
1366
1366
|
zrb/task/base_task/component/pid_model.py,sha256=RjJIqOpavucDssnd3q3gT4q8QnP8I9SUdlv1b9pR7kU,292
|
1367
1367
|
zrb/task/base_task/component/renderer.py,sha256=9wP2IW811Ta81IoPWmeQ7yVc7eG-uaSnOVbEyeaOIuk,4439
|
1368
1368
|
zrb/task/base_task/component/trackers.py,sha256=gM9eOukMh6kvNJnRsHscQ_JN--Haa2YA4bIufqh8upE,1950
|
1369
|
-
zrb/task/checker.py,sha256=
|
1370
|
-
zrb/task/cmd_task.py,sha256=
|
1369
|
+
zrb/task/checker.py,sha256=fn6gmcCUHsar458NQ4Af4-kt2skcyibd0ewsPTRd5-w,3383
|
1370
|
+
zrb/task/cmd_task.py,sha256=_wjF9MbKGA0EAr_df47AMC0lROCiaJTUyxT-AFQKKJo,14181
|
1371
1371
|
zrb/task/decorator.py,sha256=j62l7ITIRZtk_qE97d4naVl9gbbMoi2eEXOPOmYdF8M,3039
|
1372
1372
|
zrb/task/docker_compose_task.py,sha256=fnFEOAS9yEi2ve7pSzN9guXOVeYt8HYTdQvtjk-yoRQ,14886
|
1373
1373
|
zrb/task/flow_task.py,sha256=QIIZgq9C7e-kvTRJ0Y1Slb5AQyy15N9H4NZxdFR3FI8,4867
|
1374
|
-
zrb/task/http_checker.py,sha256=
|
1374
|
+
zrb/task/http_checker.py,sha256=DRIwXjC8StucHo2nP1duM3Ime3zzw1BQH8ib2bFZVmA,5692
|
1375
|
+
zrb/task/looper.py,sha256=0eM3wEIC_RbThg60MRbK4Az16vt81O5p12cORAYTfnI,1430
|
1375
1376
|
zrb/task/notifier.py,sha256=19E4EcFgFZ0thU9p2P1dGUYR04721pa0K3lqsj6a4Xc,6217
|
1376
1377
|
zrb/task/parallel.py,sha256=-coMuiFlS29GpBgW6plPVaCLesgzzD0bYib29OvhXFg,1193
|
1377
|
-
zrb/task/path_checker.py,sha256=
|
1378
|
-
zrb/task/path_watcher.py,sha256=
|
1379
|
-
zrb/task/port_checker.py,sha256=
|
1378
|
+
zrb/task/path_checker.py,sha256=yvMgGlmMQhlaX3Wlq5yI7-nzEpyCFoXHEOFOdlfI6-o,4673
|
1379
|
+
zrb/task/path_watcher.py,sha256=UGaGYzWExoVQDK6smXEKsd0leO3FZOQYHnpHgZ9hiZU,7420
|
1380
|
+
zrb/task/port_checker.py,sha256=IoVIP0QjxKz2SLgnK2GIaxn4WASk6ZKf4cQlKog0Fw8,4592
|
1380
1381
|
zrb/task/recurring_task.py,sha256=FNxV7n4h9AzUCU8oKXwAS_A9j1newS-esWjmMsC33vE,7430
|
1381
1382
|
zrb/task/remote_cmd_task.py,sha256=rmLB5uCcbbfZBy8-nAZI8mgnNd-J2d4SBemLEDwSlV4,3951
|
1382
|
-
zrb/task/resource_maker.py,sha256=
|
1383
|
+
zrb/task/resource_maker.py,sha256=jQSO7PVIuTZi__JcrpRC4Ni_xmuJszJiMAxH_qfJPhs,7644
|
1383
1384
|
zrb/task/rsync_task.py,sha256=bgCeZQTG-4isvjZGGs_05oOEkkwGc930NTyuUYUm_cg,4187
|
1384
|
-
zrb/task/server.py,sha256=
|
1385
|
+
zrb/task/server.py,sha256=w0gO73tt9PLWXVtgY-oe6qzvODtxVcizBGCUjRrhp5w,6478
|
1385
1386
|
zrb/task/task.py,sha256=dHv4cmnd0QFPT9PwrfmHpxTaXj86mm8xf7_jAj_engI,329
|
1386
|
-
zrb/task/time_watcher.py,sha256=
|
1387
|
+
zrb/task/time_watcher.py,sha256=xx82w8ygpL-6pUbeuWjsxSVLSZhkWVWHsAoZUXPV7Jk,5075
|
1388
|
+
zrb/task/watcher.py,sha256=m72YhUKtQsE4mZSm1y2MKiSdfj6HZo3rj9f3nQLU7Oo,3252
|
1387
1389
|
zrb/task/wiki_task.py,sha256=Mcugk_6Pd7pzubi2ZP4eegJs8e9niYKh-9mCrNHXE_g,4330
|
1388
1390
|
zrb/task_env/constant.py,sha256=ySdHv2dawWE-UoeBHl8FEOmrBl4vfkRI67TIBdkK6l8,220
|
1389
1391
|
zrb/task_env/env.py,sha256=C9IzavEtWlpap4C92XONi1ID-RK9gDDLQKl5rYGBsyc,5195
|
@@ -1401,8 +1403,8 @@ zrb/task_input/int_input.py,sha256=d2fXcm5fCo09472eMAm6PdzLQD82ZBV9ARq5CjKepAo,4
|
|
1401
1403
|
zrb/task_input/password_input.py,sha256=g_g8ZWAzDaHx4h2EHY3UCGvTigC6esAUBzXU0T9nDUk,4192
|
1402
1404
|
zrb/task_input/str_input.py,sha256=BNflOhrJvST9bWK0rGdCi7C7y-QDvHj9ISQMRmujIWU,4200
|
1403
1405
|
zrb/task_input/task_input.py,sha256=x1sGHsoSYAYMdQBrCLmcvZa_ZmGggMPj3goAQzewUKI,2181
|
1404
|
-
zrb-0.
|
1405
|
-
zrb-0.
|
1406
|
-
zrb-0.
|
1407
|
-
zrb-0.
|
1408
|
-
zrb-0.
|
1406
|
+
zrb-0.17.1.dist-info/LICENSE,sha256=WfnGCl8G60EYOPAEkuc8C9m9pdXWDe08NsKj3TBbxsM,728
|
1407
|
+
zrb-0.17.1.dist-info/METADATA,sha256=hswyEpXbHtSdNOnq4_PQPuDruzGo9795YOZpSi6lkfM,16460
|
1408
|
+
zrb-0.17.1.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
1409
|
+
zrb-0.17.1.dist-info/entry_points.txt,sha256=xTgXc1kBKYhJHEujdaSPHUcJT3-hbyP1mLgwkv-5sSk,40
|
1410
|
+
zrb-0.17.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|