Example #1
0
class FReader(object):
    """
    """
    NORMAL = 1
    SSH = 2

    def __init__(self, path):
        """
        :param path:
        :return:
        """
        self.path = path
        self.abs_path = os.path.abspath(path)
        {True: self.connect_remote_file, False: self.connect_local_file}[path.find(":") != -1](path)
        self._buffer = ""
        self.queue = Queue.Queue()
        self.line = []

    def connect_remote_file(self, path):
        host, remote_file = path.split(':', 1)
        self.basename = os.path.basename(remote_file)
        self.fd = Popen(["ssh", "-o BatchMode=yes", host, "tail", "-f", remote_file],
                        stdin=PIPE, stdout=PIPE, close_fds=True)
        self._t = self.SSH

    def connect_local_file(self, path):
        self._t = self.NORMAL
        self.fd = open(path)
        self.basename = os.path.basename(path)

    @property
    def file_name(self):
        return self.basename

    def __hash__(self):
        return self.fd.__hash__()

    def read_line(self):
        self._buffer = ""
        fd = self.fd.fileno()
        fl = fcntl.fcntl(fd, fcntl.F_GETFL)
        fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
        try:
            self._buffer += self.fd.read(1)
            while self._buffer[-1] != '\n':
                self._buffer += self.fd.read(1)
            return True
        except IOError:
            return False
        finally:
            fcntl.fcntl(fd, fcntl.F_SETFL, fl)

    def read(self):
        if self.is_ssh_file:
            self.fd.poll()
        if self.read_line():
            return self._buffer
        else:
            return ""

    @property
    def is_ssh_file(self):
        return self._t == self.SSH