degal/utils.py
author Tero Marttila <terom@fixme.fi>
Fri, 03 Jul 2009 00:00:51 +0300
changeset 147 283a15412709
parent 139 d3167c40e7b9
permissions -rw-r--r--
remove obsolete shorturl.py
44
533b7e8b5d3b strip copyright/license boilerplate from modules, except dexif and formatbytes
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
     1
"""
533b7e8b5d3b strip copyright/license boilerplate from modules, except dexif and formatbytes
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
     2
    Miscellaneous utilities
533b7e8b5d3b strip copyright/license boilerplate from modules, except dexif and formatbytes
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
     3
"""
533b7e8b5d3b strip copyright/license boilerplate from modules, except dexif and formatbytes
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
     4
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
     5
import functools
23
10841abbc01f taggr2, which is starting to shape up
terom
parents: 20
diff changeset
     6
96
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
     7
class LazyProperty (object) :
12
c2d8e9a754a1 Major code restructuring. Version is now 0.5, templates use Mako, and the code is split off into several files under lib/
terom
parents:
diff changeset
     8
    """
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
     9
        Lazy-loaded cached properties.
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    10
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    11
        This functions by overriding the class's property attribute with the actual value attribute in the instance's
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    12
        dict, causing all future attribute lookups to return that directly.
96
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    13
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    14
        >>> class Foo (object) :
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    15
        ...     counter = 0
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    16
        ...     @lazy_load
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    17
        ...     def foo (self) :
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    18
        ...             self.counter += 1
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    19
        ...             return self.counter
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    20
        ... 
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    21
        >>> foo = Foo(); foo.foo, foo.foo, foo.counter
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    22
        (1, 1, 1)
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    23
12
c2d8e9a754a1 Major code restructuring. Version is now 0.5, templates use Mako, and the code is split off into several files under lib/
terom
parents:
diff changeset
    24
    """
c2d8e9a754a1 Major code restructuring. Version is now 0.5, templates use Mako, and the code is split off into several files under lib/
terom
parents:
diff changeset
    25
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    26
    def __init__ (self, func) :
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    27
        """
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    28
            Initialize with no value
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    29
        """
75
18b3b1926720 fix utils.LazyProperty
Tero Marttila <terom@fixme.fi>
parents: 73
diff changeset
    30
        
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    31
        # the getter function
75
18b3b1926720 fix utils.LazyProperty
Tero Marttila <terom@fixme.fi>
parents: 73
diff changeset
    32
        self.func = func
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    33
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    34
        # the attribute name
75
18b3b1926720 fix utils.LazyProperty
Tero Marttila <terom@fixme.fi>
parents: 73
diff changeset
    35
        self.name = func.__name__
19
8d3ffd87cb0b * move cgi-bin to de-cgi-bin so it doesn't conflict with my default alias... need to come up with a real solution to this
terom
parents: 18
diff changeset
    36
73
8897352630a5 misc. stuff in gallery.py utils.py
Tero Marttila <terom@fixme.fi>
parents: 59
diff changeset
    37
    def run (self, obj) :
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    38
        """
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    39
            Run the background func and return the to-be-cached value.
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    40
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    41
            `obj` is the object instance
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    42
        """
28
70b6c13d084f fancy new log format
terom
parents: 27
diff changeset
    43
75
18b3b1926720 fix utils.LazyProperty
Tero Marttila <terom@fixme.fi>
parents: 73
diff changeset
    44
        return self.func(obj)
73
8897352630a5 misc. stuff in gallery.py utils.py
Tero Marttila <terom@fixme.fi>
parents: 59
diff changeset
    45
 
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    46
    def store (self, obj, value) :
73
8897352630a5 misc. stuff in gallery.py utils.py
Tero Marttila <terom@fixme.fi>
parents: 59
diff changeset
    47
        """
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    48
            Store the cached value, overring ourself
73
8897352630a5 misc. stuff in gallery.py utils.py
Tero Marttila <terom@fixme.fi>
parents: 59
diff changeset
    49
        """
96
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    50
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    51
#        print "[%x] %r.__dict__[%r] = %r" % (id(obj), obj, self.name, value)
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    52
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    53
        obj.__dict__[self.name] = value
73
8897352630a5 misc. stuff in gallery.py utils.py
Tero Marttila <terom@fixme.fi>
parents: 59
diff changeset
    54
75
18b3b1926720 fix utils.LazyProperty
Tero Marttila <terom@fixme.fi>
parents: 73
diff changeset
    55
    def __get__ (self, obj, owner) :
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    56
        """
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    57
            Generate the value, store it as the attribute and return it.
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    58
        """
96
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    59
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    60
        # compute value
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    61
        value = self.run(obj)
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    62
84
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    63
        # store it
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    64
        self.store(obj, value)
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    65
        
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    66
        # return it
891545a38a2b change utils.LazyProperty to store the cached value using obj.__dict__
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    67
        return value
96
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
    68
    
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    69
class LazyIteratorProperty (LazyProperty) :
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    70
    """
109
66a01c0806f1 backout config.read_only as a useless feature
Tero Marttila <terom@fixme.fi>
parents: 96
diff changeset
    71
        A lazy-loaded property that automatically converts an iterator/genexp into a non-mutable tuple.
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    72
    """
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    73
73
8897352630a5 misc. stuff in gallery.py utils.py
Tero Marttila <terom@fixme.fi>
parents: 59
diff changeset
    74
    def run (self, obj) :
109
66a01c0806f1 backout config.read_only as a useless feature
Tero Marttila <terom@fixme.fi>
parents: 96
diff changeset
    75
        return tuple(self.func(obj))
59
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    76
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    77
lazy_load = LazyProperty
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    78
lazy_load_iter = LazyIteratorProperty
fbbe956229cc remove old utils and write some new ones
Tero Marttila <terom@fixme.fi>
parents: 44
diff changeset
    79
128
f66bb9f6126a fix Image.cleanup to not do AttributeErrors
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    80
def unload (obj, *attrs) :
f66bb9f6126a fix Image.cleanup to not do AttributeErrors
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    81
    """
f66bb9f6126a fix Image.cleanup to not do AttributeErrors
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    82
        Un-load the named attributes from the given object.
f66bb9f6126a fix Image.cleanup to not do AttributeErrors
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    83
    """
f66bb9f6126a fix Image.cleanup to not do AttributeErrors
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    84
    
f66bb9f6126a fix Image.cleanup to not do AttributeErrors
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    85
    for attr in attrs :
f66bb9f6126a fix Image.cleanup to not do AttributeErrors
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    86
        if attr in obj.__dict__ :
139
d3167c40e7b9 remove old scripts/cgi-bin stuff. They wouldn't work as such with the new version, and replacements can be written while referring to the history
Tero Marttila <terom@fixme.fi>
parents: 128
diff changeset
    87
            # this will drop refcounts and free resources, so it may take some execution time
128
f66bb9f6126a fix Image.cleanup to not do AttributeErrors
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    88
            del obj.__dict__[attr]
f66bb9f6126a fix Image.cleanup to not do AttributeErrors
Tero Marttila <terom@fixme.fi>
parents: 120
diff changeset
    89
120
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
    90
def first (iterable) :
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
    91
    """
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
    92
        Returns the first item from the iterable that evaluates to True, otherwise None.
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
    93
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
    94
        >>> first((0, 1))
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
    95
        1
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
    96
        >>> first("abc")
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
    97
        'a'
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
    98
        >>> first(('', list(), (), False))
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
    99
    """
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
   100
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
   101
    for item in iterable :
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
   102
        if item :
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
   103
            return item
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
   104
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
   105
    else :
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
   106
        return None
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
   107
55cb7fc9c8fb add new exif.py to abstract between different exif libraries, and add partially working support for pyexiv2 and EXIFpy
Tero Marttila <terom@fixme.fi>
parents: 109
diff changeset
   108
96
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
   109
# testing
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
   110
if __name__ == '__main__' :
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
   111
    import doctest
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
   112
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
   113
    doctest.testmod()
d9cf1e272e90 fix LazyProperty to not inherit from property, so as to act as a non-data descriptor, which can then be overriden by per-instance __dict__ values
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
   114