cinap_lenrekadd hg and python4bb9e2215 years agoHistory
322 lines · 8.3 KB · Python
RawDownload
"""File System Proxy. Provide an OS-neutral view on a file system, locally or remotely.The functionality is geared towards implementing some sort ofrdist-like utility between a Mac and a UNIX system. The module defines three classes: FSProxyLocal  -- used for local accessFSProxyServer -- used on the server side of remote accessFSProxyClient -- used on the client side of remote access The remote classes are instantiated with an IP address and an optionalverbosity flag.""" import serverimport clientimport md5import osimport fnmatchfrom stat import *import timeimport fnmatch if os.name == 'mac':    import macfs    maxnamelen = 31else:    macfs = None    maxnamelen = 255 skipnames = (os.curdir, os.pardir)  class FSProxyLocal:     def __init__(self):        self._dirstack = []        self._ignore = ['*.pyc'] + self._readignore()     def _close(self):        while self._dirstack:            self.back()     def _readignore(self):        file = self._hide('ignore')        try:            f = open(file)        except IOError:            file = self._hide('synctree.ignorefiles')            try:                f = open(file)            except IOError:                return []        ignore = []        while 1:            line = f.readline()            if not line: break            if line[-1] == '\n': line = line[:-1]            ignore.append(line)        f.close()        return ignore     def _hidden(self, name):        if os.name == 'mac':            return name[0] == '(' and name[-1] == ')'        else:            return name[0] == '.'     def _hide(self, name):        if os.name == 'mac':            return '(%s)' % name        else:            return '.%s' % name     def visible(self, name):        if len(name) > maxnamelen: return 0        if name[-1] == '~': return 0        if name in skipnames: return 0        if self._hidden(name): return 0        head, tail = os.path.split(name)        if head or not tail: return 0        if macfs:            if os.path.exists(name) and not os.path.isdir(name):                try:                    fs = macfs.FSSpec(name)                    c, t = fs.GetCreatorType()                    if t != 'TEXT': return 0                except macfs.error, msg:                    print "***", name, msg                    return 0        else:            if os.path.islink(name): return 0            if '\0' in open(name, 'rb').read(512): return 0        for ign in self._ignore:            if fnmatch.fnmatch(name, ign): return 0        return 1     def check(self, name):        if not self.visible(name):            raise os.error, "protected name %s" % repr(name)     def checkfile(self, name):        self.check(name)        if not os.path.isfile(name):            raise os.error, "not a plain file %s" % repr(name)     def pwd(self):        return os.getcwd()     def cd(self, name):        self.check(name)        save = os.getcwd(), self._ignore        os.chdir(name)        self._dirstack.append(save)        self._ignore = self._ignore + self._readignore()     def back(self):        if not self._dirstack:            raise os.error, "empty directory stack"        dir, ignore = self._dirstack[-1]        os.chdir(dir)        del self._dirstack[-1]        self._ignore = ignore     def _filter(self, files, pat = None):        if pat:            def keep(name, pat = pat):                return fnmatch.fnmatch(name, pat)            files = filter(keep, files)        files = filter(self.visible, files)        files.sort()        return files     def list(self, pat = None):        files = os.listdir(os.curdir)        return self._filter(files, pat)     def listfiles(self, pat = None):        files = os.listdir(os.curdir)        files = filter(os.path.isfile, files)        return self._filter(files, pat)     def listsubdirs(self, pat = None):        files = os.listdir(os.curdir)        files = filter(os.path.isdir, files)        return self._filter(files, pat)     def exists(self, name):        return self.visible(name) and os.path.exists(name)     def isdir(self, name):        return self.visible(name) and os.path.isdir(name)     def islink(self, name):        return self.visible(name) and os.path.islink(name)     def isfile(self, name):        return self.visible(name) and os.path.isfile(name)     def sum(self, name):        self.checkfile(name)        BUFFERSIZE = 1024*8        f = open(name)        sum = md5.new()        while 1:            buffer = f.read(BUFFERSIZE)            if not buffer:                break            sum.update(buffer)        return sum.digest()     def size(self, name):        self.checkfile(name)        return os.stat(name)[ST_SIZE]     def mtime(self, name):        self.checkfile(name)        return time.localtime(os.stat(name)[ST_MTIME])     def stat(self, name):        self.checkfile(name)        size = os.stat(name)[ST_SIZE]        mtime = time.localtime(os.stat(name)[ST_MTIME])        return size, mtime     def info(self, name):        sum = self.sum(name)        size = os.stat(name)[ST_SIZE]        mtime = time.localtime(os.stat(name)[ST_MTIME])        return sum, size, mtime     def _list(self, function, list):        if list is None:            list = self.listfiles()        res = []        for name in list:            try:                res.append((name, function(name)))            except (os.error, IOError):                res.append((name, None))        return res     def sumlist(self, list = None):        return self._list(self.sum, list)     def statlist(self, list = None):        return self._list(self.stat, list)     def mtimelist(self, list = None):        return self._list(self.mtime, list)     def sizelist(self, list = None):        return self._list(self.size, list)     def infolist(self, list = None):        return self._list(self.info, list)     def _dict(self, function, list):        if list is None:            list = self.listfiles()        dict = {}        for name in list:            try:                dict[name] = function(name)            except (os.error, IOError):                pass        return dict     def sumdict(self, list = None):        return self.dict(self.sum, list)     def sizedict(self, list = None):        return self.dict(self.size, list)     def mtimedict(self, list = None):        return self.dict(self.mtime, list)     def statdict(self, list = None):        return self.dict(self.stat, list)     def infodict(self, list = None):        return self._dict(self.info, list)     def read(self, name, offset = 0, length = -1):        self.checkfile(name)        f = open(name)        f.seek(offset)        if length == 0:            data = ''        elif length < 0:            data = f.read()        else:            data = f.read(length)        f.close()        return data     def create(self, name):        self.check(name)        if os.path.exists(name):            self.checkfile(name)            bname = name + '~'            try:                os.unlink(bname)            except os.error:                pass            os.rename(name, bname)        f = open(name, 'w')        f.close()     def write(self, name, data, offset = 0):        self.checkfile(name)        f = open(name, 'r+')        f.seek(offset)        f.write(data)        f.close()     def mkdir(self, name):        self.check(name)        os.mkdir(name, 0777)     def rmdir(self, name):        self.check(name)        os.rmdir(name)  class FSProxyServer(FSProxyLocal, server.Server):     def __init__(self, address, verbose = server.VERBOSE):        FSProxyLocal.__init__(self)        server.Server.__init__(self, address, verbose)     def _close(self):        server.Server._close(self)        FSProxyLocal._close(self)     def _serve(self):        server.Server._serve(self)        # Retreat into start directory        while self._dirstack: self.back()  class FSProxyClient(client.Client):     def __init__(self, address, verbose = client.VERBOSE):        client.Client.__init__(self, address, verbose)  def test():    import string    import sys    if sys.argv[1:]:        port = string.atoi(sys.argv[1])    else:        port = 4127    proxy = FSProxyServer(('', port))    proxy._serverloop()  if __name__ == '__main__':    test()