0001import os
0002from ohm.descriptors import simple_repr
0003
0004class NoDefault(object): pass
0005
0006class file_property(object):
0007
0008    def __init__(self, filename, encoding=None,
0009                 default=NoDefault):
0010        self.filename = filename
0011        self.encoding = encoding
0012        self.default = default
0013
0014    def __get__(self, obj, type=None):
0015        if obj is None:
0016            return self
0017        fn = self.get_filename(obj)
0018        if not os.path.exists(fn):
0019            if self.default is NoDefault:
0020                raise AttributeError(
0021                    "Attribute for file %r undefined" % os.path.basename(fn))
0022            return self.default
0023        f = open(fn, 'rb')
0024        c = f.read()
0025        f.close()
0026        if self.encoding:
0027            c = c.decode(self.encoding)
0028        return c
0029
0030    def __set__(self, obj, value):
0031        fn = self.get_filename(obj)
0032        if self.default is not NoDefault and value == self.default:
0033            if os.path.exists(fn):
0034                os.unlink(fn)
0035            return
0036        if self.encoding:
0037            if isinstance(value, str):
0038                raise ValueError(
0039                    "Only unicode values allowed in attribute (not str like %r)" % value)
0040            elif not isinstance(value, unicode):
0041                raise ValueError(
0042                    "Only unicode values allowed in attribute (not %r)" % value)
0043            value = value.encode(self.encoding)
0044        else:
0045            if isinstance(value, unicode):
0046                raise ValueError(
0047                    "Only str values allowed in attribute (not unicode like %r)" % value)
0048            elif not isinstance(value, str):
0049                raise ValueError(
0050                    "Only str values allowed in attribute (not %r)" % value)
0051        f = open(fn, 'wb')
0052        f.write(value)
0053        f.close()
0054
0055    def __delete__(self, obj):
0056        fn = self.get_filename(obj)
0057        if not os.path.exists(fn):
0058            raise AttributeError(
0059                "Attribute undefined")
0060        os.unlink(fn)
0061
0062    def get_filename(self, obj):
0063        return os.path.join(obj.base_dir, self.filename)
0064
0065    def __repr__(self):
0066        kw = {}
0067        if self.encoding:
0068            kw['encoding'] = self.encoding
0069        if self.default is not NoDefault:
0070            kw['default'] = self.default
0071        return simple_repr('file_property', self.filename, **kw)