"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()