1# -*- coding: utf-8 -*-
2
3## Amazon S3 manager
4## Author: Michal Ludvig <michal@logix.cz>
5##         http://www.logix.cz/michal
6## License: GPL Version 2
7## Copyright: TGRMN Software and contributors
8
9from __future__ import absolute_import, print_function
10
11from .BidirMap import BidirMap
12
13class SortedDictIterator(object):
14    def __init__(self, sorted_dict, keys):
15        self.sorted_dict = sorted_dict
16        self.keys = keys
17
18    def __next__(self):
19        try:
20            return self.keys.pop(0)
21        except IndexError:
22            raise StopIteration
23
24    next = __next__
25
26class SortedDict(dict):
27    def __init__(self, mapping = {}, ignore_case = True, **kwargs):
28        """
29        WARNING: SortedDict() with ignore_case==True will
30                 drop entries differing only in capitalisation!
31                 Eg: SortedDict({'auckland':1, 'Auckland':2}).keys() => ['Auckland']
32                 With ignore_case==False it's all right
33        """
34        dict.__init__(self, mapping, **kwargs)
35        self.ignore_case = ignore_case
36
37    def keys(self):
38        # TODO fix
39        # Probably not anymore memory efficient on python2
40        # as now 2 copies of keys to sort them.
41        keys = dict.keys(self)
42        if self.ignore_case:
43            # Translation map
44            xlat_map = BidirMap()
45            for key in keys:
46                xlat_map[key.lower()] = key
47            # Lowercase keys
48            lc_keys = sorted(xlat_map.keys())
49            return [xlat_map[k] for k in lc_keys]
50        else:
51            keys = sorted(keys)
52            return keys
53
54    def __iter__(self):
55        return SortedDictIterator(self, self.keys())
56
57    def __getitem__(self, index):
58        """Override to support the "get_slice" for python3 """
59        if isinstance(index, slice):
60            r = SortedDict(ignore_case = self.ignore_case)
61            for k in self.keys()[index]:
62                r[k] = self[k]
63        else:
64            r = super(SortedDict, self).__getitem__(index)
65        return r
66
67
68if __name__ == "__main__":
69    d = { 'AWS' : 1, 'Action' : 2, 'america' : 3, 'Auckland' : 4, 'America' : 5 }
70    sd = SortedDict(d)
71    print("Wanted: Action, america, Auckland, AWS,    [ignore case]")
72    print("Got:   ", end=' ')
73    for key in sd:
74        print("%s," % key, end=' ')
75    print("   [used: __iter__()]")
76    d = SortedDict(d, ignore_case = False)
77    print("Wanted: AWS, Action, America, Auckland, america,    [case sensitive]")
78    print("Got:   ", end=' ')
79    for key in d.keys():
80        print("%s," % key, end=' ')
81    print("   [used: keys()]")
82
83# vim:et:ts=4:sts=4:ai
84