Mercurial > hg > gcmultimerge
view multimerge.py @ 2:34c3a08a4a37
Copyright, etc.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 04 Jul 2016 12:49:53 +0300 |
parents | 74f172565752 |
children | 1e254756d0a5 |
line wrap: on
line source
#!/usr/bin/python ### ### Google Calendar MultiMerge v0.000001 ### (C) 2016 Matti 'ccr' Hamalainen <ccr@tnsp.org> ### ### Python 2.7 <= x < 3 required! Please refer to ### README.txt for information on other depencies. ### import os import sys import signal import re import time import datetime import httplib2 import ConfigParser import oauth2client from oauth2client import client from oauth2client import tools from googleapiclient import discovery ### ### Misc. helper functions ### ## Wrapper for print() that does not break when redirecting stdin/out ## because of piped output not having a defined encoding. We default ## to UTF-8 encoding in output here. def gcm_print(smsg): gcm_msgbuf.append(smsg.encode("UTF-8")) if sys.stdout.encoding != None: print(smsg.encode(sys.stdout.encoding)) else: print(smsg.encode("UTF-8")) ## Fatal errors def gcm_fatal(smsg): gcm_print(u"ERROR: "+ smsg) sys.exit(1) ## Debug messages def gcm_debug(smsg): if cfg.debug: gcm_print(u"DBG: "+ smsg) else: gcm_msgbuf.append(u"DBG: "+ smsg.encode("UTF-8")) ## Handle SIGINT signals here def gcm_signal_handler(signal, frame): gcm_print("\nQuitting due to SIGINT / Ctrl+C!") sys.exit(0) def gcm_get_credentials(mcfg): store = oauth2client.file.Storage(mcfg.credential_file) credentials = store.get() if not credentials or credentials.invalid: flow = client.flow_from_clientsecrets(mcfg.secret_file, mcfg.scope) flow.user_agent = mcfg.app_name credentials = tools.run_flow(flow, store, mcfg) if not credentials or credentials.invalid: gcm_fatal("Failed to authenticate / invalid credentials.") return credentials def gcm_dump_events(events): for event in events: ev_start = event["start"].get("dateTime", event["start"].get("date")) ev_end = event["end"].get("dateTime", event["end"].get("date")) gcm_print(u"{0:25} - {1:25} : {2}".format(ev_start, ev_end, event["summary"])) class GCMSettings(dict): def __init__(self): self.m_data = {} self.m_saveable = {} self.m_translate = {} def __getattr__(self, name): if name in self.m_data: return self.m_data[name] else: gcm_fatal("GCMSettings.__getattr__(): No such attribute '"+ name +"'.") def mtranslate(self, name, value): if name in self.m_translate and self.m_translate[name]: return self.m_translate[name](value) else: return value def mdef(self, name, saveable, validate, translate, value): self.m_saveable[name] = saveable self.m_data[name] = self.mtranslate(name, value) def mset(self, name, value): if name in self.m_data: self.m_data[name] = self.mtranslate(name, value) else: gcm_fatal("GCMSettings.mset(): No such attribute '"+ name +"'.") def mget(self, name): if name in self.m_data: return self.m_data[name] else: return None ### ### Main program starts ### gcm_msgbuf = [] signal.signal(signal.SIGINT, gcm_signal_handler) ## Settings cfg = GCMSettings() cfg.mdef("debug", True, gcm_is_bool, gcm_trans_bool, False) cfg.mdef("source_regex", True, gcm_is_string, None, "^R:\s*(.*?)\s*\(\s*(.+?)\s*\)\s*$") cfg.mdef("source_regmap", False, gcm_is_list, gcm_trans_list, [1, 2]) cfg.mdef("source_regmap_len", False, None, None, len(cfg.source_regmap)) cfg.mdef("dest_name", True, gcm_is_string, None, u"Raahen kansainvälisyystoiminta") cfg.mdef("dest_id", True, gcm_is_string, None, None) cfg.mdef("noauth_local_webserver", False, None, None, True) #cfg.mdef("auth_host_name", False, None, None, "localhost") #cfg.mdef("auth_host_port", False, None, None, [8080, 8090]) cfg.mdef("logging_level", True, gcm_is_log_level, gcm_trans_log_level, "ERROR") # No need to touch these cfg.mdef("app_name", False, None, None, "Google Calendar MultiMerge") cfg.mdef("scope", False, None, None, "https://www.googleapis.com/auth/calendar") #cfg.mdef("scope", False, None, None, "https://www.googleapis.com/auth/calendar.readonly") cfg.mdef("secret_file", True, gcm_is_filename, None, "client_secret.json") cfg.mdef("credential_file", True, gcm_is_filename, None, "client_credentials.json") ## Initialize and authorize API connection credentials = gcm_get_credentials(cfg) http = credentials.authorize(httplib2.Http()) service = discovery.build("calendar", "v3", http=http) ## Fetch complete calendar list gcm_debug("Fetching available calendars ..") calendars = [] calPageToken = None while True: # We want everything except deleted and hidden calendars calResult = service.calendarList().list( showHidden=False, showDeleted=False, pageToken=calPageToken ).execute() calendars.extend(calResult.get("items", [])) calPageToken = calResult.get("nextPageToken") if not calPageToken: break if len(calendars) == 0: gcm_fatal("No calendars found?")