comparison multimerge.py @ 54:86d3a8eddbd7

Unicodeify.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 05 Jul 2016 21:15:54 +0300
parents ea62e0ed05ae
children 5b78f62b7de7
comparison
equal deleted inserted replaced
53:ea62e0ed05ae 54:86d3a8eddbd7
56 try: 56 try:
57 smtpH = smtplib.SMTP('localhost') 57 smtpH = smtplib.SMTP('localhost')
58 smtpH.sendmail(cfg.email_sender, cfg.email_to, msg.as_string()) 58 smtpH.sendmail(cfg.email_sender, cfg.email_to, msg.as_string())
59 smtpH.quit() 59 smtpH.quit()
60 except: 60 except:
61 gcm_print("FATAL: Oh crap, e-mail sending failed.") 61 gcm_print(u"FATAL: Oh crap, e-mail sending failed.")
62 sys.exit(1) 62 sys.exit(1)
63 63
64 64
65 ## Debug messages 65 ## Debug messages
66 def gcm_debug(smsg): 66 def gcm_debug(smsg):
70 gcm_msgbuf.append(u"DBG: {0}".format(smsg)) 70 gcm_msgbuf.append(u"DBG: {0}".format(smsg))
71 71
72 72
73 ## Handler for SIGINT signals 73 ## Handler for SIGINT signals
74 def gcm_signal_handler(signal, frame): 74 def gcm_signal_handler(signal, frame):
75 gcm_print("\nQuitting due to SIGINT / Ctrl+C!") 75 gcm_print(u"\nQuitting due to SIGINT / Ctrl+C!")
76 sys.exit(0) 76 sys.exit(0)
77 77
78 78
79 ## Function for handling Google API credentials 79 ## Function for handling Google API credentials
80 def gcm_get_credentials(mcfg): 80 def gcm_get_credentials(mcfg):
295 cfg.mdef("credential_file", True, cfg.is_filename, None, "client_credentials.json") 295 cfg.mdef("credential_file", True, cfg.is_filename, None, "client_credentials.json")
296 296
297 297
298 ## Read, parse and validate configuration file 298 ## Read, parse and validate configuration file
299 if len(sys.argv) > 1: 299 if len(sys.argv) > 1:
300 gcm_debug("Reading configuration from '{0}'.".format(sys.argv[1])) 300 gcm_debug(u"Reading configuration from '{0}'.".format(sys.argv[1]))
301 try: 301 try:
302 cfgparser = ConfigParser.RawConfigParser() 302 cfgparser = ConfigParser.RawConfigParser()
303 cfgparser.readfp(codecs.open(sys.argv[1], "r", "UTF-8")) 303 cfgparser.readfp(codecs.open(sys.argv[1], "r", "UTF-8"))
304 except Exception as e: 304 except Exception as e:
305 gcm_fatal("Failed to read configuration file '{0}': {1}".format(sys.argv[1], str(e))) 305 gcm_fatal("Failed to read configuration file '{0}': {1}".format(sys.argv[1], str(e)))
353 http = credentials.authorize(httplib2.Http()) 353 http = credentials.authorize(httplib2.Http())
354 service = discovery.build("calendar", "v3", http=http) 354 service = discovery.build("calendar", "v3", http=http)
355 355
356 356
357 ## Fetch complete calendar list 357 ## Fetch complete calendar list
358 gcm_debug("Fetching available calendars ..") 358 gcm_debug(u"Fetching available calendars ..")
359 calendars = [] 359 calendars = []
360 cal_token = None 360 cal_token = None
361 while True: 361 while True:
362 # We want everything except deleted and hidden calendars 362 # We want everything except deleted and hidden calendars
363 result = service.calendarList().list( 363 result = service.calendarList().list(
408 gcm_debug(u"Fetching calendar events .. ") 408 gcm_debug(u"Fetching calendar events .. ")
409 src_events = [] 409 src_events = []
410 color_id = 0 410 color_id = 0
411 for calendar in src_calendars: 411 for calendar in src_calendars:
412 color_id = color_id + 1 412 color_id = color_id + 1
413 gcm_debug("- "+calendar["id"]) 413 gcm_debug(u"- "+calendar["id"])
414 result = service.events().list( 414 result = service.events().list(
415 timeZone="EEST", 415 timeZone="EEST",
416 calendarId=calendar["id"], 416 calendarId=calendar["id"],
417 singleEvents=True, 417 singleEvents=True,
418 showDeleted=False, 418 showDeleted=False,
444 else: 444 else:
445 gcm_debug(u"No current events.") 445 gcm_debug(u"No current events.")
446 446
447 447
448 ## Start merging events .. 448 ## Start merging events ..
449 gcm_debug("Re-merging events to target calendar ..")
450 dst_gcm_ids = frozenset(map(lambda x: x["gcm_id"], dst_events)) 449 dst_gcm_ids = frozenset(map(lambda x: x["gcm_id"], dst_events))
451 src_ids = frozenset(map(lambda x: x["id"], src_events)) 450 src_ids = frozenset(map(lambda x: x["id"], src_events))
452 dst_ids = frozenset(map(lambda x: x["id"], dst_events)) 451 dst_ids = frozenset(map(lambda x: x["id"], dst_events))
452 gcm_debug(u"Re-merging events to target calendar ..")
453 453
454 for event in src_events: 454 for event in src_events:
455 # Does the event exist already in the target? 455 # Does the event exist already in the target?
456 if event["gcm_id"] in dst_gcm_ids: 456 if event["gcm_id"] in dst_gcm_ids:
457 ## Yes. Thus, we just update the event. 457 ## Yes. Thus, we just update the event.
458 #print "IS in dst_gcm_ids: "+ event["id"] +" : "+ event["gcm_id"] 458 #print "IS in dst_gcm_ids: "+ event["id"] +" : "+ event["gcm_id"]
459 # Check if event NEEDS updating .. aka compare data 459 # Check if event NEEDS updating .. aka compare data
460 gcm_debug(u"Updating event {0}".format(event["gcm_id"]))
460 d_event = gcm_get_event_by_gcm_id(dst_events, event["gcm_id"]) 461 d_event = gcm_get_event_by_gcm_id(dst_events, event["gcm_id"])
461 if d_event and gcm_compare_events(event, d_event): 462 if d_event and gcm_compare_events(event, d_event):
462 try: 463 try:
463 new_event = service.events().update(calendarId=cfg.dest_id, eventId=event["id"], body=event).execute() 464 new_event = service.events().update(calendarId=cfg.dest_id, eventId=event["id"], body=event).execute()
464 except Exception as e: 465 except Exception as e:
465 gcm_fatal("Failed to update event:\n{0}\n\nERROR: {1}\n".format(event, str(e))) 466 gcm_fatal("Failed to update event:\n{0}\n\nERROR: {1}\n".format(event, str(e)))
466 else: 467 else:
467 gcm_debug("No need to update event {0}.".format(event["gcm_id"])) 468 gcm_debug(u"No need to update event {0}.".format(event["gcm_id"]))
468 else: 469 else:
469 ## Event does not seem to exist. Insert new event. 470 ## Event does not seem to exist. Insert new event.
471 gcm_debug(u"Inserting new event {0}".format(event["gcm_id"]))
470 event.pop("iCalUID", None) # Remove the iCalUID, having it conflicts with event ID 472 event.pop("iCalUID", None) # Remove the iCalUID, having it conflicts with event ID
471 event["id"] = event["gcm_id"] # Replace Google generated ID with our own 473 event["id"] = event["gcm_id"] # Replace Google generated ID with our own
472 try: 474 try:
473 new_event = service.events().insert(calendarId=cfg.dest_id, body=event).execute() 475 new_event = service.events().insert(calendarId=cfg.dest_id, body=event).execute()
474 except Exception as e: 476 except Exception as e:
475 gcm_fatal("Failed to insert new event:\n{0}\n\nERROR: {1}\n".format(event, str(e))) 477 gcm_fatal("Failed to insert new event:\n{0}\n\nERROR: {1}\n".format(event, str(e)))
476 478
477 ## Remove "stale" events 479 ## Remove "stale" events
480 gcm_debug(u"Purging stale events ..")
478 for event in dst_events: 481 for event in dst_events:
479 if not event["id"] in src_ids: 482 if not event["id"] in src_ids:
480 try: 483 try:
481 service.events().delete(calendarId=cfg.dest_id, eventId=event["id"]).execute() 484 service.events().delete(calendarId=cfg.dest_id, eventId=event["id"]).execute()
482 except Exception as e: 485 except Exception as e:
483 gcm_fatal("Failed to delete stale event:\n{0}\n\nERROR: {1}\n".format(event, str(e))) 486 gcm_fatal("Failed to delete stale event:\n{0}\n\nERROR: {1}\n".format(event, str(e)))
484 487
485 488
486 gcm_debug("Finished.") 489 gcm_debug(u"Finished.")