Added a toggle so that work can be paused
This commit is contained in:
parent
0239c19e7e
commit
d7cedba890
3 changed files with 74 additions and 39 deletions
4
TODO
4
TODO
|
|
@ -8,10 +8,11 @@ Todo
|
||||||
- Need to use conventional version numbers for pypi. See pep0440.
|
- Need to use conventional version numbers for pypi. See pep0440.
|
||||||
- Add ESC as an alternative to 'q' for quit. If looking at Help, ESC should just
|
- Add ESC as an alternative to 'q' for quit. If looking at Help, ESC should just
|
||||||
exit the help screen.
|
exit the help screen.
|
||||||
- Add means to pause and unpause all current jobs.
|
|
||||||
- Have a sandbox for unsafe (or all) tools.
|
- Have a sandbox for unsafe (or all) tools.
|
||||||
- Statuses' pretty names and variable names don't match.
|
- Statuses' pretty names and variable names don't match.
|
||||||
- Report on python doctests. (also coverage of)
|
- Report on python doctests. (also coverage of)
|
||||||
|
- Treat any compressed file as though it is uncompressed. But the metadata tool
|
||||||
|
should still report on the original compressed file.
|
||||||
|
|
||||||
|
|
||||||
Done
|
Done
|
||||||
|
|
@ -146,6 +147,7 @@ Done
|
||||||
- Ignore other input while help screen is showing.
|
- Ignore other input while help screen is showing.
|
||||||
- Have an option to turn off all automatic work.
|
- Have an option to turn off all automatic work.
|
||||||
<- The 'working' switch does this
|
<- The 'working' switch does this
|
||||||
|
- Add means to pause and unpause all current jobs.
|
||||||
|
|
||||||
A-syntax, B-tests, C-auto docs, D-lint, E-coverage, F-profile, G-tidy, H-import deps
|
A-syntax, B-tests, C-auto docs, D-lint, E-coverage, F-profile, G-tidy, H-import deps
|
||||||
A B C D E F G H
|
A B C D E F G H
|
||||||
|
|
|
||||||
|
|
@ -26,15 +26,15 @@
|
||||||
│ [0m[38;2;0;255;0m[48;2;0;0;0mn[0m[38;2;255;255;255m[48;2;0;0;0m - Move to the next issue. [0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
│ [0m[38;2;0;255;0m[48;2;0;0;0mn[0m[38;2;255;255;255m[48;2;0;0;0m - Move to the next issue. [0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
||||||
│ [0m[38;2;0;255;0m[48;2;0;0;0mN[0m[38;2;255;255;255m[48;2;0;0;0m - Move to the next issue of the c[0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
│ [0m[38;2;0;255;0m[48;2;0;0;0mN[0m[38;2;255;255;255m[48;2;0;0;0m - Move to the next issue of the c[0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
||||||
│ [0m[38;2;0;255;0m[48;2;0;0;0mo[0m[38;2;255;255;255m[48;2;0;0;0m - Order files by type, or by dire[0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
│ [0m[38;2;0;255;0m[48;2;0;0;0mo[0m[38;2;255;255;255m[48;2;0;0;0m - Order files by type, or by dire[0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
||||||
|
│ [0m[38;2;0;255;0m[48;2;0;0;0mp[0m[38;2;255;255;255m[48;2;0;0;0m - Pause work. (toggle) [0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
||||||
│ [0m[38;2;0;255;0m[48;2;0;0;0mw[0m[38;2;255;255;255m[48;2;0;0;0m - Watch the filesystem for change[0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
│ [0m[38;2;0;255;0m[48;2;0;0;0mw[0m[38;2;255;255;255m[48;2;0;0;0m - Watch the filesystem for change[0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
||||||
│ [0m[38;2;0;255;0m[48;2;0;0;0ms[0m[38;2;255;255;255m[48;2;0;0;0m - Change the appearance of result[0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
│ [0m[38;2;0;255;0m[48;2;0;0;0ms[0m[38;2;255;255;255m[48;2;0;0;0m - Change the appearance of result[0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
||||||
│ [0m[38;2;0;255;0m[48;2;0;0;0mq[0m[38;2;255;255;255m[48;2;0;0;0m - Quit. [0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
│ [0m[38;2;0;255;0m[48;2;0;0;0mq[0m[38;2;255;255;255m[48;2;0;0;0m - Quit. [0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
||||||
│ [0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
│ [0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
||||||
│Statuses: [0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
│Statuses: [0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
||||||
│ Normal [0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
│ Normal [0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
||||||
│ [0m[38;2;0;255;0m[48;2;0;0;0m [0m[38;2;255;255;255m[48;2;0;0;0m No problems [0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
│ [0m[38;2;0;255;0m[48;2;0;0;0m [0m[38;2;255;255;255m[48;2;0;0;0m No problems │
|
||||||
│ [0m[38;2;255;0;0m[48;2;0;0;0m [0m[38;2;255;255;255m[48;2;0;0;0m Problems [0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m│
|
│ [0m[38;2;255;0;0m[48;2;0;0;0m [0m[38;2;255;255;255m[48;2;0;0;0m Problems │
|
||||||
│ [0m[38;2;100;100;100m[48;2;0;0;0m [0m[38;2;255;255;255m[48;2;0;0;0m Not applicable │
|
│ [0m[38;2;100;100;100m[48;2;0;0;0m [0m[38;2;255;255;255m[48;2;0;0;0m Not applicable │
|
||||||
│ [0m[38;2;255;255;0m[48;2;0;0;0m [0m[38;2;255;255;255m[48;2;0;0;0m Running │
|
|
||||||
│[0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m │
|
│[0m[38;2;255;255;255m[48;2;100;100;100m [0m[38;2;255;255;255m[48;2;0;0;0m │
|
||||||
└──────────────────────────────────────┘[0m
|
└──────────────────────────────────────┘[0m
|
||||||
69
vigil
69
vigil
|
|
@ -32,6 +32,7 @@ Keys:
|
||||||
*n - Move to the next issue.
|
*n - Move to the next issue.
|
||||||
*N - Move to the next issue of the current tool.
|
*N - Move to the next issue of the current tool.
|
||||||
*o - Order files by type, or by directory location. (toggle)
|
*o - Order files by type, or by directory location. (toggle)
|
||||||
|
*p - Pause work. (toggle)
|
||||||
*w - Watch the filesystem for changes. (toggle)
|
*w - Watch the filesystem for changes. (toggle)
|
||||||
*s - Change the appearance of result statuses. (toggle)
|
*s - Change the appearance of result statuses. (toggle)
|
||||||
*q - Quit.
|
*q - Quit.
|
||||||
|
|
@ -588,6 +589,7 @@ class Screen:
|
||||||
self._is_log_visible = True
|
self._is_log_visible = True
|
||||||
self._is_help_visible = False
|
self._is_help_visible = False
|
||||||
self._is_watching_filesystem = False
|
self._is_watching_filesystem = False
|
||||||
|
self._is_paused = False
|
||||||
self.toggle_watch_filesystem()
|
self.toggle_watch_filesystem()
|
||||||
self._make_widgets()
|
self._make_widgets()
|
||||||
self._make_keymap()
|
self._make_keymap()
|
||||||
|
|
@ -722,6 +724,17 @@ class Screen:
|
||||||
self._main_loop.remove_reader(self._watch_manager.get_fd())
|
self._main_loop.remove_reader(self._watch_manager.get_fd())
|
||||||
self._watch_manager = None
|
self._watch_manager = None
|
||||||
|
|
||||||
|
def toggle_pause(self):
|
||||||
|
self._is_paused = not self._is_paused
|
||||||
|
self._log.log_command("Paused work." if self._is_paused else
|
||||||
|
"Continuing work.")
|
||||||
|
if self._is_paused:
|
||||||
|
for runner in self.runners:
|
||||||
|
runner.pause()
|
||||||
|
else:
|
||||||
|
for runner in self.runners:
|
||||||
|
runner.continue_()
|
||||||
|
|
||||||
def quit_(self):
|
def quit_(self):
|
||||||
raise KeyboardInterrupt
|
raise KeyboardInterrupt
|
||||||
|
|
||||||
|
|
@ -777,16 +790,19 @@ class Screen:
|
||||||
action(self)
|
action(self)
|
||||||
self._appearance_changed_event.set()
|
self._appearance_changed_event.set()
|
||||||
|
|
||||||
_STATUS_BAR = _highlight_chars(" *help *quit *d,*c,*j,*k:navigate *turn"
|
_STATUS_BAR = _highlight_chars(
|
||||||
" *log *edit *next *watch *order *statuses",
|
" *help *quit *d,*c,*j,*k:navigate *turn *log *edit *next *pause"
|
||||||
Log.GREEN_STYLE)
|
" *watch *order *statuses", Log.GREEN_STYLE)
|
||||||
|
|
||||||
@functools.lru_cache(maxsize=2)
|
@functools.lru_cache(maxsize=2)
|
||||||
def _get_status_bar_appearance(self, width, is_directory_sort,
|
def _get_status_bar_appearance(self, width, is_directory_sort,
|
||||||
is_watching_filesystem, progress_bar_size):
|
is_watching_filesystem, is_paused,
|
||||||
|
progress_bar_size):
|
||||||
ordering_text = "directory" if is_directory_sort else "type "
|
ordering_text = "directory" if is_directory_sort else "type "
|
||||||
watching_text = "watching" if is_watching_filesystem else "--------"
|
watching_text = "watching" if is_watching_filesystem else "--------"
|
||||||
indicators = " %s order:%s " % (watching_text, ordering_text)
|
paused_text = "paused" if is_paused else "------"
|
||||||
|
indicators = " %s %s order:%s " % (paused_text, watching_text,
|
||||||
|
ordering_text)
|
||||||
spacing = " " * (width - len(self._STATUS_BAR) - len(indicators))
|
spacing = " " * (width - len(self._STATUS_BAR) - len(indicators))
|
||||||
bar = (self._STATUS_BAR[:width - len(indicators)] + spacing +
|
bar = (self._STATUS_BAR[:width - len(indicators)] + spacing +
|
||||||
indicators)[:width]
|
indicators)[:width]
|
||||||
|
|
@ -809,7 +825,7 @@ class Screen:
|
||||||
self._summary.result_total)
|
self._summary.result_total)
|
||||||
status_bar_appearance = self._get_status_bar_appearance(
|
status_bar_appearance = self._get_status_bar_appearance(
|
||||||
width, self._summary.is_directory_sort,
|
width, self._summary.is_directory_sort,
|
||||||
self._is_watching_filesystem, progress_bar_size)
|
self._is_watching_filesystem, self._is_paused, progress_bar_size)
|
||||||
return (self._layouts[self._is_log_visible][self._is_listing_portrait]
|
return (self._layouts[self._is_log_visible][self._is_listing_portrait]
|
||||||
.appearance((width, height-len(status_bar_appearance))) +
|
.appearance((width, height-len(status_bar_appearance))) +
|
||||||
status_bar_appearance)
|
status_bar_appearance)
|
||||||
|
|
@ -823,7 +839,8 @@ class Screen:
|
||||||
({"K", "end"}, listing_right), ({"o"}, toggle_sort),
|
({"K", "end"}, listing_right), ({"o"}, toggle_sort),
|
||||||
({"n"}, move_to_next_issue), ({"N"}, move_to_next_issue_of_tool),
|
({"n"}, move_to_next_issue), ({"N"}, move_to_next_issue_of_tool),
|
||||||
({"e"}, edit_file), ({"s"}, toggle_status_style),
|
({"e"}, edit_file), ({"s"}, toggle_status_style),
|
||||||
({"w"}, toggle_watch_filesystem), ({"q"}, quit_)]
|
({"w"}, toggle_watch_filesystem), ({"q"}, quit_),
|
||||||
|
({"p"}, toggle_pause)]
|
||||||
|
|
||||||
|
|
||||||
def get_cpu_temperature():
|
def get_cpu_temperature():
|
||||||
|
|
@ -872,6 +889,12 @@ class Worker:
|
||||||
self.child_connection.send([tool, path])
|
self.child_connection.send([tool, path])
|
||||||
return self.child_connection.recv()
|
return self.child_connection.recv()
|
||||||
|
|
||||||
|
def pause(self):
|
||||||
|
os.kill(self.process.pid, signal.SIGSTOP)
|
||||||
|
|
||||||
|
def continue_(self):
|
||||||
|
os.kill(self.process.pid, signal.SIGCONT)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
os.kill(self.process.pid, signal.SIGKILL)
|
os.kill(self.process.pid, signal.SIGKILL)
|
||||||
|
|
||||||
|
|
@ -901,6 +924,12 @@ class Runner:
|
||||||
pass
|
pass
|
||||||
jobs_added_event.clear()
|
jobs_added_event.clear()
|
||||||
|
|
||||||
|
def pause(self):
|
||||||
|
self.worker.pause()
|
||||||
|
|
||||||
|
def continue_(self):
|
||||||
|
self.worker.continue_()
|
||||||
|
|
||||||
|
|
||||||
_UPDATE_THREAD_STOPPED = False
|
_UPDATE_THREAD_STOPPED = False
|
||||||
|
|
||||||
|
|
@ -914,7 +943,7 @@ def update_screen(main_widget, appearance_changed_event):
|
||||||
fill3.patch_screen(main_widget)
|
fill3.patch_screen(main_widget)
|
||||||
|
|
||||||
|
|
||||||
def main(root_path, urwid_screen):
|
def main(root_path):
|
||||||
global _UPDATE_THREAD_STOPPED
|
global _UPDATE_THREAD_STOPPED
|
||||||
os.chdir(root_path) # FIX: Don't change directory if possible.
|
os.chdir(root_path) # FIX: Don't change directory if possible.
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
|
|
@ -942,21 +971,27 @@ def main(root_path, urwid_screen):
|
||||||
summary.sync_with_filesystem()
|
summary.sync_with_filesystem()
|
||||||
log.log_message("Program started.")
|
log.log_message("Program started.")
|
||||||
jobs_added_event.set()
|
jobs_added_event.set()
|
||||||
update_display_thread = threading.Thread(
|
|
||||||
target=update_screen, args=(screen, appearance_changed_event),
|
|
||||||
daemon=True)
|
|
||||||
update_display_thread.start()
|
|
||||||
loop.add_reader(sys.stdin, screen.on_keypressed, urwid_screen)
|
|
||||||
runners = [Runner() for index in range(multiprocessing.cpu_count() * 2)]
|
runners = [Runner() for index in range(multiprocessing.cpu_count() * 2)]
|
||||||
|
screen.runners = runners
|
||||||
for runner in runners:
|
for runner in runners:
|
||||||
args = (summary, log, jobs_added_event, appearance_changed_event)
|
args = (summary, log, jobs_added_event, appearance_changed_event)
|
||||||
threading.Thread(target=runner.job_runner, args=args,
|
threading.Thread(target=runner.job_runner, args=args,
|
||||||
daemon=True).start()
|
daemon=True).start()
|
||||||
|
if screen._is_paused:
|
||||||
|
for runner in runners:
|
||||||
|
runner.pause()
|
||||||
|
|
||||||
def on_window_resize(n, frame):
|
def on_window_resize(n, frame):
|
||||||
appearance_changed_event.set()
|
appearance_changed_event.set()
|
||||||
signal.signal(signal.SIGWINCH, on_window_resize)
|
signal.signal(signal.SIGWINCH, on_window_resize)
|
||||||
appearance_changed_event.set()
|
appearance_changed_event.set()
|
||||||
|
update_display_thread = threading.Thread(
|
||||||
|
target=update_screen, args=(screen, appearance_changed_event),
|
||||||
|
daemon=True)
|
||||||
|
with terminal.hidden_cursor():
|
||||||
|
with terminal.urwid_screen() as urwid_screen:
|
||||||
|
update_display_thread.start()
|
||||||
|
loop.add_reader(sys.stdin, screen.on_keypressed, urwid_screen)
|
||||||
try:
|
try:
|
||||||
loop.run_forever()
|
loop.run_forever()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
|
@ -972,8 +1007,8 @@ def main(root_path, urwid_screen):
|
||||||
# Cannot pickle generators, locks, sockets or events.
|
# Cannot pickle generators, locks, sockets or events.
|
||||||
(summary.closest_placeholder_generator, summary._lock,
|
(summary.closest_placeholder_generator, summary._lock,
|
||||||
summary._jobs_added_event, screen._appearance_changed_event,
|
summary._jobs_added_event, screen._appearance_changed_event,
|
||||||
screen._main_loop, screen._watch_manager,
|
screen._main_loop, screen._watch_manager, screen.runners,
|
||||||
log._appearance_changed_event) = [None] * 7
|
log._appearance_changed_event) = [None] * 8
|
||||||
open_compressed = functools.partial(gzip.open, compresslevel=1)
|
open_compressed = functools.partial(gzip.open, compresslevel=1)
|
||||||
dump_pickle_safe(screen, pickle_path, open=open_compressed)
|
dump_pickle_safe(screen, pickle_path, open=open_compressed)
|
||||||
|
|
||||||
|
|
@ -996,9 +1031,7 @@ if __name__ == "__main__":
|
||||||
root_path = os.path.abspath(sys.argv[1])
|
root_path = os.path.abspath(sys.argv[1])
|
||||||
with terminal.console_title("vigil: " + os.path.basename(root_path)):
|
with terminal.console_title("vigil: " + os.path.basename(root_path)):
|
||||||
manage_cache(root_path)
|
manage_cache(root_path)
|
||||||
with terminal.hidden_cursor():
|
main(root_path)
|
||||||
with terminal.urwid_screen() as urwid_screen:
|
|
||||||
main(root_path, urwid_screen)
|
|
||||||
else:
|
else:
|
||||||
usage = __doc__.replace("*", "")
|
usage = __doc__.replace("*", "")
|
||||||
print(usage)
|
print(usage)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue