<commit_before>import getpass
import gevent
import threading

from gsh.plugin import BaseExecutor, BaseInnerExecutor


class _ParamikoThread(threading.Thread):
    def __init__(self, executor):
        self.executor = executor
        super(_ParamikoThread, self).__init__()

    def run(self):
        # Defer import since most people won't want to use this executor
        # and I don't want it to be required to use gsh.
        import paramiko

        try:
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(self.executor.hostname, password=self.executor.parent.password)

            command = " ".join(self.executor.command)
            stdin, stdout, stderr = ssh.exec_command(command)


            for line in stdout.read().splitlines():
                self.executor.update(self.executor.hostname, "stdout", line)

            for line in stderr.read().splitlines():
                self.executor.update(self.executor.hostname, "stderr", line)

            ssh.close()
            self.executor.rv = stdout.channel.recv_exit_status()
        except paramiko.BadAuthenticationType, err:
            self.executor.update(self.executor.hostname, "stderr", "GSH: Failed to login.")
            self.executor.rv = 1

<commit_msg>Hacks to get paramiko working interactively<commit_after>import cStringIO
import getpass
import gevent
import select
import socket
import termios
import threading
import tty

from gsh.plugin import BaseExecutor, BaseInnerExecutor


class _ParamikoThread(threading.Thread):
    def __init__(self, executor):
        self.executor = executor
        super(_ParamikoThread, self).__init__()

    def interactive(self, ssh, command):
        stdout = cStringIO.StringIO()
        stderr = cStringIO.StringIO()
        chan = ssh.invoke_shell()
        ssh.get_transport()

        for cmd in command.split("\n"):
            cmd = cmd.strip()
            if not cmd:
                continue
            chan.send(cmd + "\n")

        while True:
            read, write, error = select.select([chan], [], [])
            if chan in read:
                try:
                    out = chan.recv(1024)
                    if not out:
                        break
                    stdout.write(out)
                except socket.timeout():
                    pass

        chan.close()
        stdout.seek(0)
        stderr.seek(0)
        return stdout, stderr


    def run(self):
        # Defer import since most people won't want to use this executor
        # and I don't want it to be required to use gsh.
        import paramiko

        try:
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(self.executor.hostname, password=self.executor.parent.password)

            command = " ".join(self.executor.command)

            if "interactive" in self.executor.parent.args:
                stdout, stderr = self.interactive(ssh, command)
                rv = 0  # Find a way to get rv later.
            else:
                stdin, stdout, stderr = ssh.exec_command(command)
                rv = stdout.channel.recv_exit_status()

            for line in stdout.read().splitlines():
                self.executor.update(self.executor.hostname, "stdout", line)

            for line in stderr.read().splitlines():
                self.executor.update(self.executor.hostname, "stderr", line)

            ssh.close()
            self.executor.rv = rv
        except paramiko.BadAuthenticationType, err:
            self.executor.update(self.executor.hostname, "stderr", "GSH: Failed to login.")
            self.executor.rv = 1


{'fraction_non_alphanumeric': 0.09397590361445783, 'fraction_numerical': 0.0024096385542168677, 'mean_word_length': 1.9840255591054312, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7299427', 'n_tokens_mistral': 1079, 'n_tokens_neox': 1012, 'n_words': 257}