"""File System Proxy.

Provide an OS-neutral view on a file system, locally or remotely.
The functionality is geared towards implementing some sort of
rdist-like utility between a Mac and a UNIX system.

The module defines three classes:

FSProxyLocal  -- used for local access
FSProxyServer -- used on the server side of remote access
FSProxyClient -- used on the client side of remote access

The remote classes are instantiated with an IP address and an optional
verbosity flag.
"""

import server
import client
import md5
import os
import fnmatch
from stat import *
import time
import fnmatch

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):
        return name[0] == '.'

    def _hide(self, name):
        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 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()
