Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/olpc/datastore/utils.py
blob: b2afae0e5d07319b5c778fc4a027f5a88844a849 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import dbus

class Singleton(type):
    """A singleton metaclass

    >>> class MyManager(object):
    ...    __metaclass__ = Singleton
    >>> a = MyManager()
    >>> b = MyManager()
    >>> assert a is b
    
    """
    def __init__(cls,name,bases,dic):
        super(Singleton,cls).__init__(name,bases,dic)
        cls._instance=None
    def __call__(cls,*args,**kw):
        if cls._instance is None:
            cls._instance=super(Singleton,cls).__call__(*args,**kw)
        return cls._instance
    
class partial:
    def __init__(self, fun, *args, **kwargs):
        self.fun = fun
        self.pending = args
        self.kwargs = kwargs
        
    def __call__(self, *args, **kwargs):
        if kwargs and self.kwargs:
            kw = self.kwargs.copy()
            kw.update(kwargs)
        else:
            kw = kwargs or self.kwargs

        return self.fun(*(self.pending + args), **kw)

def once(method):
    "A decorator that runs a method only once."
    attrname = "_called"
    def decorated(self, *args, **kwargs):
        try:
            return getattr(method, attrname)
        except AttributeError:
            r = method(self, *args, **kwargs)
            setattr(method, attrname, r)
            return r
    return decorated
        


def create_uid():
    # this is linux specific but easily changed
    # Python 2.5 has universal support for this built in
    return open('/proc/sys/kernel/random/uuid', 'r').read()[:-1]


def options_for(dict, prefix, invert=False):
    """return a dict of the filtered properties for keys with prefix.
    prefix will be removed

    If invert is True then only those keys not matching prefix are returned.
    
    >>> assert options_for({'app.a.option' : 1, 'app.b.option' : 2}, 'app.b.')['option'] == 2
    """
    d = {}
    l = len(prefix)
    for k, v in dict.iteritems():
        if k.startswith(prefix):
            if invert is False:d[k[l:]] = v
        elif invert is True:
            d[k] = v
            
    return d
    
    

def _convert(arg):
    # this recursively processes arguments sent over dbus and yields
    # normalized versions
    if isinstance(arg, (dbus.String, dbus.UTF8String)):
        try: return arg.encode('utf-8')
        except: return str(arg)

    if isinstance(arg, (dbus.Dictionary, dict)):
        d = {}
        for k, v in arg.iteritems():
            # here we call str on the lhs making it suitable for
            # passing as keywords args
            d[str(_convert(k))] = _convert(v)
        return d

    if isinstance(arg, dbus.Array):
        a = []
        for item in arg:
            a.append(_convert(item))
        return a
    return arg

    
def sanitize_dbus(method):
    # decorator to produce an alternative version of arguments based on pure Python
    # types.
    def decorator(self, *args, **kwargs):
        n = []
        for arg in args: n.append(_convert(arg))
        kw = _convert(kwargs)
        return method(self, *n, **kw)
    return decorator