- commit
- 29525d5bc74b58588bf9a1042ffcd2715256ef8d
- parent
- 1ba29f54a7d3ffff8cb69b7d6e39f64307ad0efe
- Author
- Tobias Bengfort <tobias.bengfort@gmx.net>
- Date
- 2014-04-20 20:34
multidict
Diffstat
| M | cctool.py | 75 | +++++++++++++++++++++++++++++++++++++++++++++++++------------ |
1 files changed, 61 insertions, 14 deletions
diff --git a/cctool.py b/cctool.py
@@ -25,7 +25,6 @@ 25 25 # - filter/convert for valid fields 26 26 # - doc 27 27 # - tests28 -1 # - multidicts29 28 # - merge 30 29 # - sort 31 30 # - filter @@ -50,6 +49,47 @@ except ImportError as e: 50 49 vobject = e 51 50 52 51 -1 52 NOTSET = object() -1 53 -1 54 -1 55 class MultiDict(dict): -1 56 """Dict subclass with multiple values for each key. -1 57 -1 58 >>> d = MultiDict() -1 59 >>> d['foo'] = [] -1 60 >>> 'foo' in d -1 61 False -1 62 >>> d['foo'] = [1, 2, 3] -1 63 >>> 'foo' in d -1 64 True -1 65 >>> d['foo'] -1 66 [1, 2, 3] -1 67 >>> d.first('foo') -1 68 1 -1 69 """ -1 70 -1 71 def __contains__(self, key): -1 72 return super(MultiDict, self).__contains__(key) and self[key] != [] -1 73 -1 74 def first(self, key, default=NOTSET): -1 75 if key in self: -1 76 return self[key][0] -1 77 elif default is not NOTSET : -1 78 return default -1 79 else: -1 80 raise KeyError -1 81 -1 82 def join(self, key, default=NOTSET, sep=u','): -1 83 if key in self and len(self[key]) == 1: -1 84 return self[key][0] -1 85 elif key in self: -1 86 return sep.join(self[key]) -1 87 elif default is not NOTSET : -1 88 return default -1 89 else: -1 90 raise KeyError -1 91 -1 92 53 93 class Format(object): 54 94 @classmethod 55 95 def load(cls, fh): @@ -75,9 +115,9 @@ class BSDCal(Format): 75 115 def dump(cls, data, fh): 76 116 for item in data: 77 117 if u'dtstart' in item and u'summary' in item:78 -1 fh.write('%s\t%s\n' % (item['dtstart'], item['summary']))-1 118 fh.write('%s\t%s\n' % (item.first('dtstart'), item.join('summary'))) 79 119 if u'bday' in item and u'name' in item:80 -1 fh.write('%s\t%s\n' % (item['bday'], item['name']))-1 120 fh.write('%s\t%s\n' % (item.first('bday'), item.join('name'))) 81 121 82 122 83 123 class ICal(Format): @@ -88,7 +128,10 @@ class ICal(Format): 88 128 89 129 for calendar in vobject.readComponents(fh): 90 130 for event in calendar.vevent_list:91 -1 yield {k: v[0].value for (k, v) in event.contents.iteritems()}-1 131 d = MultiDict() -1 132 for key, value in event.contents.iteritems(): -1 133 d[key] = [i.value for i in value] -1 134 yield d 92 135 93 136 @classmethod 94 137 def dump(cls, data, fh): @@ -98,8 +141,8 @@ class ICal(Format): 98 141 ical = vobject.iCalendar() 99 142 for event in data: 100 143 vevent = ical.add('vevent')101 -1 for key, value in event.iteritems():102 -1 vevent.add(key).value = value-1 144 for key in event: -1 145 vevent.add(key).value = event.join(key) 103 146 ical.serialize(fh) 104 147 105 148 @@ -112,7 +155,7 @@ class ABook(Format): 112 155 cp.readfp(fh) 113 156 for section in cp.sections(): 114 157 if section != u'format':115 -1 yield dict(cp.items(section))-1 158 yield MultiDict({k: [v] for (k, v) in cp.items(section)}) 116 159 117 160 @classmethod 118 161 def dump(cls, data, fh): @@ -121,8 +164,8 @@ class ABook(Format): 121 164 for item in data: 122 165 section = unicode(i) 123 166 cp.add_section(section)124 -1 for key, value in item.iteritems():125 -1 cp.set(section, key, unicode(value))-1 167 for key in item: -1 168 cp.set(section, key, item.join(key)) 126 169 i += 1 127 170 cp.write(fh) 128 171 @@ -146,7 +189,8 @@ class LDIF(Format): 146 189 parser.parse() 147 190 except ValueError: 148 191 log.warning("ValueError after reading %i records" % parser.records_read)149 -1 return parser.entries.itervalues()-1 192 for entry in parser.entries.itervalues(): -1 193 yield MultiDict(entry) 150 194 151 195 @classmethod 152 196 def dump(cls, fh): @@ -162,7 +206,10 @@ class VCard(Format): 162 206 raise vobject 163 207 164 208 for vcard in vobject.readComponents(fh):165 -1 yield {k: v[0].value for (k, v) in vcard.contents.iteritems()}-1 209 d = MultiDict() -1 210 for key, value in vcard.contents.iteritems(): -1 211 d[key] = [i.value for i in value] -1 212 yield d 166 213 167 214 @classmethod 168 215 def dump(cls, data, fh): @@ -171,15 +218,15 @@ class VCard(Format): 171 218 172 219 for item in data: 173 220 vcard = vobject.vCard()174 -1 for key, value in item.iteritems():175 -1 vcard.add(key).value = value-1 221 for key in item: -1 222 vcard.add(key).value = item.join(key) 176 223 vcard.serialize(fh) 177 224 178 225 179 226 class JSON(Format): 180 227 @classmethod 181 228 def load(cls, fh):182 -1 return json.load(fh)-1 229 return [MultiDict(i) for i in json.load(fh)] 183 230 184 231 @classmethod 185 232 def dump(cls, data, fh):