- commit
- 3e4fb5fe618fa504c517a29b139c038e46034f5a
- parent
- e2d5a20dde83949cc3801aad579caad9151cbe40
- Author
- Tobias Bengfort <tobias.bengfort@gmx.net>
- Date
- 2015-05-08 17:04
normalize field keys
Diffstat
| M | cctool.py | 55 | +++++++++++++++++++++++++++++++++++++++---------------- |
| M | tests.py | 4 | ++-- |
2 files changed, 41 insertions, 18 deletions
diff --git a/cctool.py b/cctool.py
@@ -173,6 +173,21 @@ def merged(data, key): 173 173 return list(tmp.values()) + missing 174 174 175 175 -1 176 def map_keys(mdict, _map, reverse=False, exclusive=True): -1 177 if reverse: -1 178 _map = dict((value, key) for key, value in _map.items()) -1 179 -1 180 outdict = MultiDict() -1 181 -1 182 for key in mdict: -1 183 if key in _map: -1 184 outdict.append(_map[key], mdict[key]) -1 185 elif not exclusive: -1 186 outdict.append(key, mdict[key]) -1 187 -1 188 return outdict -1 189 -1 190 176 191 class Format(object): 177 192 """Baseclass with an API similar to the marshal, pickle and json modules. 178 193 @@ -214,13 +229,16 @@ class BSDCal(Format): 214 229 215 230 216 231 class ICal(Format):217 -1 fields = ['attach', 'categories', 'class', 'comment', 'description', 'geo',218 -1 'location', 'percent-complete', 'priority', 'resources', 'status',219 -1 'summary', 'completed', 'dtend', 'due', 'dtstart', 'duration', 'freebusy',220 -1 'transp', 'tzid', 'tzname', 'tzoffsetfrom', 'tzoffsetto', 'tzurl',221 -1 'attendee', 'contact', 'organizer', 'recurrence-id', 'related-to', 'url',222 -1 'uid', 'exdate', 'rdate', 'rrule', 'action', 'repeat', 'trigger',223 -1 'created', 'dtstamp', 'last-modified', 'sequence']-1 232 fields = { -1 233 'categories': 'tag', -1 234 'comment': 'comment', -1 235 'description': 'description', -1 236 'location': 'location', -1 237 'summary': 'summary', -1 238 'dtend': 'dtend', -1 239 'dtstart': 'dtstart', -1 240 'url': 'url', -1 241 } 224 242 225 243 @classmethod 226 244 def _iter_events(cls, component): @@ -264,7 +282,7 @@ class ICal(Format): 264 282 except ValueError: 265 283 break 266 284 else:267 -1 yield d-1 285 yield map_keys(d, cls.fields) 268 286 269 287 @classmethod 270 288 def dump(cls, data, fh): @@ -275,8 +293,9 @@ class ICal(Format): 275 293 calendar.add('prodid', '-//XI//NONSGML CCTOOL//') 276 294 calendar.add('version', '2.0') 277 295278 -1 for event in data:-1 296 for _event in data: 279 297 vevent = icalendar.Event() -1 298 event = map_keys(_event, cls.fields, reverse=True) 280 299 for key in event: 281 300 if key in cls.fields: 282 301 for value in event[key]: @@ -287,10 +306,11 @@ class ICal(Format): 287 306 288 307 289 308 class ABook(Format):290 -1 fields = ['name', 'nick', 'bday', 'email', 'url', 'tag',-1 309 fields = dict((x, x) for x in [ -1 310 'name', 'nick', 'bday', 'email', 'url', 'tag', 291 311 'address_lines', 'city', 'state', 'zip', 'country', 292 312 'phone', 'workphone', 'mobile',293 -1 'xmpp', 'icq', 'msn', 'twitter', 'pgp']-1 313 'xmpp', 'icq', 'msn', 'twitter', 'pgp']) 294 314 295 315 @classmethod 296 316 def load(cls, fh): @@ -307,14 +327,15 @@ class ABook(Format): 307 327 d[key] = [datetime.strptime(value, '%Y-%m-%d')] 308 328 else: 309 329 d[key] = value.split(u',')310 -1 yield d-1 330 yield map_keys(d, cls.fields) 311 331 312 332 @classmethod 313 333 def dump(cls, data, fh): 314 334 _fh = codecs.getwriter('utf8')(fh) 315 335 cp = ConfigParser() 316 336 i = 0317 -1 for item in data:-1 337 for _item in data: -1 338 item = map_keys(_item, cls.fields, reverse=True) 318 339 section = _str(i) 319 340 cp.add_section(section) 320 341 for key in item: @@ -346,8 +367,10 @@ if not isinstance(ldif, Exception): 346 367 347 368 348 369 class LDIF(Format):349 -1 fields = ['dn', 'objectclass', 'modifytimestamp',350 -1 'mail', 'givenName', 'sn', 'cn']-1 370 fields = { -1 371 'cn': 'name', -1 372 'mail': 'email', -1 373 } 351 374 352 375 @classmethod 353 376 def load(cls, fh): @@ -360,7 +383,7 @@ class LDIF(Format): 360 383 log.warning("ValueError after reading %i records: %s", 361 384 parser.records_read, err) 362 385 for entry in parser.entries.values():363 -1 yield MultiDict(entry)-1 386 yield map_keys(MultiDict(entry), cls.fields) 364 387 365 388 366 389 class DateTimeJSONEncoder(json.JSONEncoder):
diff --git a/tests.py b/tests.py
@@ -94,8 +94,8 @@ class TestBSDCal(_TestFormat): 94 94 class TestICal(_TestFormat): 95 95 def setUp(self): 96 96 self.format = cctool.ICal()97 -1 self.data = [cctool.MultiDict({u'uid': [u'20140519T210153Z-13022@tobias-eee']})]98 -1 self.text = b'BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//XI//NONSGML CCTOOL//\r\nBEGIN:VEVENT\r\nUID:20140519T210153Z-13022@tobias-eee\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n'-1 97 self.data = [cctool.MultiDict({u'summary': [u'lorem ipsum']})] -1 98 self.text = b'BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//XI//NONSGML CCTOOL//\r\nBEGIN:VEVENT\r\nSUMMARY:lorem ipsum\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n' 99 99 100 100 101 101 class TestABook(_TestFormat):