"Fossies" - the Fresh Open Source Software Archive 
Member "polysh-polysh-0.13/polysh/dispatchers.py" (11 May 2020, 4466 Bytes) of package /linux/privat/polysh-polysh-0.13.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style:
standard) with prefixed line numbers.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "dispatchers.py" see the
Fossies "Dox" file reference documentation.
1 """Polysh - Dispatchers
2
3 Copyright (c) 2006 Guillaume Chazarain <guichaz@gmail.com>
4 Copyright (c) 2018 InnoGames GmbH
5 """
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19 import asyncore
20 import fcntl
21 import struct
22 import sys
23 import termios
24 from typing import List
25 from typing import Tuple
26
27 from polysh import remote_dispatcher
28 from polysh import display_names
29 from polysh.terminal_size import terminal_size
30
31
32 def _split_port(hostname: str) -> Tuple[str, str]:
33 """ Splits a string(hostname, given by the user) into hostname and port,
34 returns a tuple """
35 s = hostname.split(':', 1)
36 if len(s) > 1:
37 return s[0], s[1]
38 else:
39 return s[0], '22'
40
41
42 def all_instances() -> List[remote_dispatcher.RemoteDispatcher]:
43 """Iterator over all the remote_dispatcher instances"""
44 return sorted([i for i in asyncore.socket_map.values() if
45 isinstance(i, remote_dispatcher.RemoteDispatcher)],
46 key=lambda i: i.display_name or '')
47
48
49 def count_awaited_processes() -> Tuple[int, int]:
50 """Return a tuple with the number of awaited processes and the total
51 number"""
52 awaited = 0
53 total = 0
54 for i in all_instances():
55 if i.enabled:
56 total += 1
57 if i.state is not remote_dispatcher.STATE_IDLE:
58 awaited += 1
59 return awaited, total
60
61
62 def all_terminated() -> bool:
63 """For each remote shell determine if its terminated"""
64 instances_found = False
65 for i in all_instances():
66 instances_found = True
67 if i.state not in (remote_dispatcher.STATE_TERMINATED,
68 remote_dispatcher.STATE_DEAD):
69 return False
70 return instances_found
71
72
73 def update_terminal_size() -> None:
74 """Propagate the terminal size to the remote shells accounting for the
75 place taken by the longest name"""
76 w, h = terminal_size()
77 w = max(w - display_names.max_display_name_length - 2, min(w, 10))
78 # python bug http://python.org/sf/1112949 on amd64
79 # from ajaxterm.py
80 bug = struct.unpack('i', struct.pack('I', termios.TIOCSWINSZ))[0]
81 packed_size = struct.pack('HHHH', h, w, 0, 0)
82 term_size = w, h
83 for i in all_instances():
84 if i.enabled and i.term_size != term_size:
85 i.term_size = term_size
86 fcntl.ioctl(i.fd, bug, packed_size)
87
88
89 def format_info(info_list: List[List[bytes]]) -> List[bytes]:
90 """Turn a 2-dimension list of strings into a 1-dimension list of strings
91 with correct spacing"""
92 max_lengths = []
93 if info_list:
94 nr_columns = len(info_list[0])
95 else:
96 nr_columns = 0
97 for i in range(nr_columns):
98 max_lengths.append(max([len(info[i]) for info in info_list]))
99
100 flattened_info_list = [] # type: List[bytes]
101 for info_id in range(len(info_list)):
102 info = info_list[info_id]
103 for str_id in range(len(info) - 1):
104 # Don't justify the last column (i.e. the last printed line)
105 # as it can get much longer in some shells than in others
106 orig_str = info[str_id]
107 indent = max_lengths[str_id] - len(orig_str)
108 info[str_id] = orig_str + indent * b' '
109 flattened_info_list.append(b' '.join(info) + b'\n')
110
111 return flattened_info_list
112
113
114 def create_remote_dispatchers(hosts: List[str]) -> None:
115 last_message = ''
116 for i, host in enumerate(hosts):
117 if remote_dispatcher.options.interactive:
118 last_message = 'Started %d/%d remote processes\r' % (i, len(hosts))
119 sys.stdout.write(last_message)
120 sys.stdout.flush()
121 try:
122 hostname, port = _split_port(host)
123 remote_dispatcher.RemoteDispatcher(hostname, port)
124 except OSError:
125 print()
126 raise
127
128 if last_message:
129 sys.stdout.write(' ' * len(last_message) + '\r')
130 sys.stdout.flush()